fix(pwa): never let the badge call hold up the worker's activation

The new worker cleared a leftover app badge inside its activation and
waited for it. A browser that never settles that call keeps the worker
activating, so it never takes over its pages and every offline path is
gone. The badge is now cleared beside the activation, best effort.

The sign-in journey expects the page's own sentence for a wrong
password, not the server's text.
This commit is contained in:
Marc-André Bombeck committed 2026-11-12 15:02:11 +01:00
1 parent fbb3ad7852
commit 45a5d4e353
2 files changed
+6 -3

No files matched your search

+2 -1
View File
@@ -118,7 +118,8 @@ test.describe("login page", () => {
await page.getByTestId("login-password-submit").click();
expect((await answer).status()).toBe(401);
await expect(page.getByText("Invalid credentials")).toBeVisible();
// The page says it in its own words, not the server's.
await expect(page.getByText("Login failed")).toBeVisible();
await expect(page).toHaveURL(/\/auth\/login/);
expect(
(await context.cookies()).some((c) => c.name === SESSION_COOKIE),
+4 -2
View File
@@ -68,9 +68,11 @@ self.addEventListener("activate", (event) => {
self.registration.navigationPreload
? self.registration.navigationPreload.enable()
: Promise.resolve(),
clearLeftoverAppBadge(),
]).then(() => self.clients.claim()),
);
// Not part of the activation: a browser that never settles the badge call
// must not keep the worker from taking over its pages.
clearLeftoverAppBadge();
});
self.addEventListener("fetch", (event) => {
@@ -354,7 +356,7 @@ async function trimCache(cacheName, maxEntries) {
}
// Earlier releases set a dose count on the app icon; nothing sends one now,
// so clear what they left. Never fails the activation.
// so clear what they left. Best effort, outside the activation.
async function clearLeftoverAppBadge() {
try {
await self.navigator?.clearAppBadge?.();