diff --git a/scripts/incident-browser-checks.md b/scripts/incident-browser-checks.md index 37f53e53e..3cf470fd2 100644 --- a/scripts/incident-browser-checks.md +++ b/scripts/incident-browser-checks.md @@ -94,7 +94,8 @@ pulse-heavy-run -- env PULSE_E2E_USE_LOCAL_BACKEND=1 PULSE_MOCK_MODE=false \ This opt-in test requires the managed, disposable backend. It activates that instance through the real configuration API, changes Recovery notifications through the production Schedule UI, verifies the staged value has not reached -the server, and clicks Save Changes. It checks the real PUT result, subsequent +the server, reloads to prove the unsaved edit is discarded, then edits again +and clicks Save Changes. It checks the real PUT result, subsequent GETs and rendered control after both page reload and managed backend restart with preserved data. It does not intercept HTTP or WebSocket responses and must not be run against a shared installation. The attachment contains only diff --git a/tests/integration/tests/97-alert-config-persistence.spec.ts b/tests/integration/tests/97-alert-config-persistence.spec.ts index 704bf12ef..637d7d7cb 100644 --- a/tests/integration/tests/97-alert-config-persistence.spec.ts +++ b/tests/integration/tests/97-alert-config-persistence.spec.ts @@ -70,8 +70,15 @@ test('saves recovery intent through the UI and preserves it across reload and re const initial = true; await expect(recovery).toHaveAttribute('aria-pressed', String(initial)); await recovery.click(); + await expect(recovery).toHaveAttribute('aria-pressed', String(!initial)); // A staged edit must not already have altered the server. expect((await readConfig()).schedule.notifyOnResolve).toBe(initial); + // Reload must discard the unsaved edit rather than restore browser-only state. + await page.reload({ waitUntil: 'domcontentloaded' }); + await expect(recovery).toHaveAttribute('aria-pressed', String(initial)); + expect((await readConfig()).schedule.notifyOnResolve).toBe(initial); + await recovery.click(); + await expect(recovery).toHaveAttribute('aria-pressed', String(!initial)); const saved = page.waitForResponse(response => new URL(response.url()).pathname === '/api/alerts/config' && response.request().method() === 'PUT'); await page.getByRole('button', { name: 'Save Changes', exact: true }).click(); @@ -87,7 +94,8 @@ test('saves recovery intent through the UI and preserves it across reload and re await expect(recovery).toHaveAttribute('aria-pressed', String(!initial)); expect(await readConfig()).toMatchObject(expected); await testInfo.attach('saved-intent-proof.json', { - body: Buffer.from(JSON.stringify({ expected, reload: true, backendRestart: true, + body: Buffer.from(JSON.stringify({ expected, unsavedEditDiscardedOnReload: true, + reload: true, backendRestart: true, mockedAlertEndpoints: false, destinationReceiptProven: false })), contentType: 'application/json', });