e2e: wait for repo_status=ready and bump test timeout

Two issues uncovered by the page-snapshot dump after the agent
state-dir fix:

* The host page server-renders `Run backup now` as disabled
  while repo_status != ready, and the page has no live-refresh
  on that field. The test was navigating right after status
  flipped to 'online' but before auto-init had completed (~3s
  later), so the rendered HTML still showed init_running and
  the click was a no-op. Wait for repo_status === 'ready'
  before navigating.

* playwright.config.ts pinned the per-test timeout at 60s,
  but the test itself uses 60s + 120s of internal waits.
  Bump to 240s so the test fails on real regressions instead
  of timing out on its own internal budget.

Renamed the test description away from "under a minute" since
it overpromises against the new timeout. The performance SLO
belongs in a separate test if we want to assert it.
This commit is contained in:
2026-05-08 22:00:24 +01:00
parent cc6844605f
commit 5925d09e8b
3 changed files with 21 additions and 9 deletions
+5 -1
View File
@@ -10,7 +10,11 @@ const baseURL = process.env.RM_BASE_URL ?? 'http://127.0.0.1:8080';
export default defineConfig({
testDir: './tests',
timeout: 60_000,
// 4 minutes — the smoke test waits for: enrolment + bootstrap
// (~5s), auto-init landing (~10s), backup completion (~120s
// budget). 60s is far too tight in CI; 4m gives headroom even
// on a contended runner without masking real regressions.
timeout: 240_000,
expect: { timeout: 10_000 },
fullyParallel: false,
retries: process.env.CI ? 1 : 0,
+1
View File
@@ -10,6 +10,7 @@ export interface HostJSON {
id: string;
name: string;
status: string;
repo_status?: string;
last_backup_status?: string;
}
+15 -8
View File
@@ -18,7 +18,7 @@ import {
} from './lib/server';
test.describe('smoke: enrol-via-announce → backup', () => {
test('happy path completes in under a minute', async ({ page, request }) => {
test('happy path: enrol → accept → backup → succeeded', async ({ page, request }) => {
const { username, password } = await bootstrapAdmin(request);
await loginViaUI(page, username, password);
@@ -38,16 +38,23 @@ test.describe('smoke: enrol-via-announce → backup', () => {
password: 'e2e-repo-password',
});
// Wait for the host to come online + auto-init to land.
const onlineHost = await waitForHostStatus(
// Wait for the host to come online AND for auto-init to
// finish. Coming online happens as soon as the agent's
// bearer-authed WS attaches (~1s after accept); repo_status
// flips to 'ready' once the auto-init job completes (a
// couple of seconds later). Loading the host page before
// that leaves the Run-backup button disabled because the
// server-rendered HTML reflects the still-in-progress init,
// and the page has no live-refresh on that field.
const readyHost = await waitForHostStatus(
request, cookie,
(h) => h.status === 'online',
60_000,
(h) => h.status === 'online' && h.repo_status === 'ready',
90_000,
);
expect(onlineHost.id).toBeTruthy();
expect(readyHost.id).toBeTruthy();
// Trigger a backup via the UI form-post (HX-Redirect to /jobs/{id}).
await page.goto(`${baseURL}/hosts/${onlineHost.id}`);
await page.goto(`${baseURL}/hosts/${readyHost.id}`);
await Promise.all([
page.waitForURL(/\/jobs\//),
page.locator('form[action$="/run-backup"] button[type="submit"]').first().click(),
@@ -60,7 +67,7 @@ test.describe('smoke: enrol-via-announce → backup', () => {
// surfaces.
const finishedHost = await waitForHostStatus(
request, cookie,
(h) => h.id === onlineHost.id && h.last_backup_status === 'succeeded',
(h) => h.id === readyHost.id && h.last_backup_status === 'succeeded',
120_000,
);
expect(finishedHost.last_backup_status).toBe('succeeded');