feat(ui): reload the SPA on maintenance recovery
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Has been skipped
CI / integration (pull_request) Has been skipped
CI / ui (pull_request) Successful in 1m6s
CI / conformance (pull_request) Successful in 9s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m47s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Has been skipped
CI / integration (pull_request) Has been skipped
CI / ui (pull_request) Successful in 1m6s
CI / conformance (pull_request) Successful in 9s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m47s
The deploy that ends a maintenance window may ship a client-incompatible change (wire/schema bump), and the in-session bundle is the old one. On recovery, reload to pick up the fresh client instead of just hiding the overlay. Ordering is safe: the edge maintenance flag (deploy/prod-deploy.sh) spans the WHOLE roll and clears only at script exit — after the gateway (which serves the embedded SPA) has rolled — so the edge 503s everything until the entire deploy is live; recovery therefore always serves the new SPA. A window.__maint.recover() hook + e2e cover the reload.
This commit is contained in:
@@ -20,3 +20,19 @@ test('maintenance overlay covers the app and lifts on recovery', async ({ page }
|
||||
await page.evaluate(() => (window as unknown as { __maint: { off(): void } }).__maint.off());
|
||||
await expect(page.getByRole('alertdialog')).toHaveCount(0);
|
||||
});
|
||||
|
||||
test('recovery reloads the SPA to pick up the fresh client', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.evaluate(() => (window as unknown as { __maint: { on(): void } }).__maint.on());
|
||||
await expect(page.getByRole('alertdialog')).toBeVisible();
|
||||
|
||||
// Real recovery reloads the page (the deploy may have shipped an incompatible client, and the
|
||||
// running bundle is the old one). Wait for the forced navigation, then confirm the app
|
||||
// re-bootstrapped: the overlay is gone (the store reset by the reload) and the login is back.
|
||||
await Promise.all([
|
||||
page.waitForEvent('load'),
|
||||
page.evaluate(() => (window as unknown as { __maint: { recover(): void } }).__maint.recover()),
|
||||
]);
|
||||
await expect(page.getByRole('alertdialog')).toHaveCount(0);
|
||||
await expect(page.getByRole('button', { name: /guest/i })).toBeVisible();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user