mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-13 06:32:03 +00:00
Merge remote-tracking branch 'origin/main' into release/v1.47.5
This commit is contained in:
commit
6994cb5ce8
6 files changed
+63
-17
No files matched your search
+2
-1
@@ -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),
|
||||
|
||||
@@ -68,7 +68,6 @@ self.addEventListener("activate", (event) => {
|
||||
self.registration.navigationPreload
|
||||
? self.registration.navigationPreload.enable()
|
||||
: Promise.resolve(),
|
||||
clearLeftoverAppBadge(),
|
||||
]).then(() => self.clients.claim()),
|
||||
);
|
||||
});
|
||||
@@ -353,16 +352,6 @@ 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.
|
||||
async function clearLeftoverAppBadge() {
|
||||
try {
|
||||
await self.navigator?.clearAppBadge?.();
|
||||
} catch {
|
||||
// Optional.
|
||||
}
|
||||
}
|
||||
|
||||
self.addEventListener("push", (event) => {
|
||||
if (!event.data) return;
|
||||
|
||||
|
||||
@@ -482,13 +482,15 @@ describe("sw.js — activate", () => {
|
||||
expect(harness.navPreload.enabled).toBe(true);
|
||||
});
|
||||
|
||||
it("clears the dose count an earlier release left on the app icon", async () => {
|
||||
it("leaves the app icon badge to the page, never touches it while activating", async () => {
|
||||
// A badge call from the worker can stall Chromium's worker thread, so the
|
||||
// activation never claims its pages. The page clears a leftover count.
|
||||
const harness = bootServiceWorker();
|
||||
const { badge } = swFakes(harness);
|
||||
|
||||
await dispatchActivate(harness);
|
||||
|
||||
expect(badge.cleared).toBe(true);
|
||||
expect(badge.cleared).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -8,7 +8,10 @@
|
||||
*/
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { shouldRegisterServiceWorker } from "../service-worker-registrar";
|
||||
import {
|
||||
clearLeftoverAppBadge,
|
||||
shouldRegisterServiceWorker,
|
||||
} from "../service-worker-registrar";
|
||||
|
||||
describe("shouldRegisterServiceWorker", () => {
|
||||
it("registers in production with window + serviceWorker support", () => {
|
||||
@@ -29,3 +32,37 @@ describe("shouldRegisterServiceWorker", () => {
|
||||
expect(shouldRegisterServiceWorker("production", true, false)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("clearLeftoverAppBadge", () => {
|
||||
function fakeWindow(standalone: boolean, hasApi = true) {
|
||||
const calls = { cleared: 0 };
|
||||
const win = {
|
||||
matchMedia: () => ({ matches: standalone }),
|
||||
navigator: hasApi
|
||||
? {
|
||||
clearAppBadge: async () => {
|
||||
calls.cleared += 1;
|
||||
},
|
||||
}
|
||||
: {},
|
||||
} as unknown as Window;
|
||||
return { win, calls };
|
||||
}
|
||||
|
||||
it("clears the icon badge in the installed app", () => {
|
||||
const { win, calls } = fakeWindow(true);
|
||||
clearLeftoverAppBadge(win);
|
||||
expect(calls.cleared).toBe(1);
|
||||
});
|
||||
|
||||
it("leaves a browser tab alone", () => {
|
||||
const { win, calls } = fakeWindow(false);
|
||||
clearLeftoverAppBadge(win);
|
||||
expect(calls.cleared).toBe(0);
|
||||
});
|
||||
|
||||
it("does nothing where the badge API does not exist", () => {
|
||||
const { win } = fakeWindow(true, false);
|
||||
expect(() => clearLeftoverAppBadge(win)).not.toThrow();
|
||||
});
|
||||
});
|
||||
@@ -19,6 +19,22 @@ export function shouldRegisterServiceWorker(
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Earlier releases set a dose count on the installed app's icon, and nothing
|
||||
* sets one now, so a leftover count would stay for good. Cleared from the page
|
||||
* of the installed app only, where the badge exists; never from the worker,
|
||||
* where the call can stall Chromium's worker thread.
|
||||
*/
|
||||
export function clearLeftoverAppBadge(win: Window): void {
|
||||
const standalone =
|
||||
win.matchMedia?.("(display-mode: standalone)").matches ?? false;
|
||||
const nav = win.navigator as Navigator & {
|
||||
clearAppBadge?: () => Promise<void>;
|
||||
};
|
||||
if (!standalone || typeof nav.clearAppBadge !== "function") return;
|
||||
nav.clearAppBadge().catch(() => undefined);
|
||||
}
|
||||
|
||||
/**
|
||||
* App-wide service-worker registration.
|
||||
*
|
||||
@@ -64,6 +80,7 @@ export function ServiceWorkerRegistrar(): null {
|
||||
.catch(() => {
|
||||
/* best effort — registration failure must never break the app */
|
||||
});
|
||||
clearLeftoverAppBadge(window);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -164,12 +164,12 @@ describe("useUrlFilterSync with FilterBar", () => {
|
||||
|
||||
it("writes a facet picked from the open menu as a new history entry", async () => {
|
||||
const { pill, history, pick } = await mount();
|
||||
const entries = window.history.length;
|
||||
await pick("Type", "Pulse");
|
||||
await expectSearch("?type=PULSE");
|
||||
// A push and no replace is the new entry. `history.length` is no proof:
|
||||
// the browser caps it, and other files in this frame push entries too.
|
||||
expect(history.pushes()).toEqual(["?type=PULSE"]);
|
||||
expect(history.replaces()).toEqual([]);
|
||||
expect(window.history.length).toBe(entries + 1);
|
||||
await expect.element(pill("Type: Pulse")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
|
||||
Reference in new issue
Block a user