mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-09-14 12:42:08 +02:00
stop background flash on tab switches, unblock Audit/Usage demos (#6562)
This commit is contained in:
@@ -121,6 +121,81 @@ test.describe("Settings dialog", () => {
|
||||
await restored.click();
|
||||
});
|
||||
|
||||
test("intra-modal tab switching updates URL via replaceState, never pushState", async ({
|
||||
page,
|
||||
}) => {
|
||||
// Mechanism test for the "background flash" fix. Before the fix, every
|
||||
// tab click called `navigate(...)` which fired React Router's location
|
||||
// subscribers - HomePage, QuickAccessBar, FileManagerView, ... - and the
|
||||
// layer behind the Mantine overlay repainted, causing backdrop-filter
|
||||
// blur to recompute and visibly flash. After the fix, only the very
|
||||
// first nav into /settings/* is allowed to go through React Router (so
|
||||
// HomePage's location-watching effect opens the modal and the back
|
||||
// button has a real history entry to pop). Every subsequent tab click
|
||||
// updates the URL bar via raw `window.history.replaceState`, which
|
||||
// React Router does NOT subscribe to. We assert this directly by
|
||||
// counting calls.
|
||||
await page.addInitScript(() => {
|
||||
const w = window as unknown as {
|
||||
__historyOps: { push: number; replace: number };
|
||||
};
|
||||
w.__historyOps = { push: 0, replace: 0 };
|
||||
const origPush = window.history.pushState.bind(window.history);
|
||||
const origReplace = window.history.replaceState.bind(window.history);
|
||||
window.history.pushState = function (...args) {
|
||||
w.__historyOps.push++;
|
||||
return origPush(
|
||||
...(args as Parameters<typeof window.history.pushState>),
|
||||
);
|
||||
};
|
||||
window.history.replaceState = function (...args) {
|
||||
w.__historyOps.replace++;
|
||||
return origReplace(
|
||||
...(args as Parameters<typeof window.history.replaceState>),
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
await page.goto("/", { waitUntil: "domcontentloaded" });
|
||||
await openSettings(page);
|
||||
|
||||
const generalNav = page.locator('[data-tour="admin-general-nav"]').first();
|
||||
const hotkeysNav = page.locator('[data-tour="admin-hotkeys-nav"]').first();
|
||||
await expect(generalNav).toBeVisible({ timeout: 5_000 });
|
||||
|
||||
// First nav into /settings/* takes the React Router path (push). We
|
||||
// snapshot both counters AFTER this to isolate the intra-modal delta.
|
||||
await generalNav.click();
|
||||
await page.waitForURL(/\/settings\/general/, { timeout: 5_000 });
|
||||
const baseline = await page.evaluate(() => {
|
||||
const w = window as unknown as {
|
||||
__historyOps: { push: number; replace: number };
|
||||
};
|
||||
return { ...w.__historyOps };
|
||||
});
|
||||
|
||||
// Now do 4 round-trips between two tabs - 8 intra-modal clicks total.
|
||||
for (let i = 0; i < 4; i++) {
|
||||
await hotkeysNav.click();
|
||||
await page.waitForURL(/\/settings\/hotkeys/, { timeout: 5_000 });
|
||||
await generalNav.click();
|
||||
await page.waitForURL(/\/settings\/general/, { timeout: 5_000 });
|
||||
}
|
||||
|
||||
const after = await page.evaluate(() => {
|
||||
const w = window as unknown as {
|
||||
__historyOps: { push: number; replace: number };
|
||||
};
|
||||
return { ...w.__historyOps };
|
||||
});
|
||||
|
||||
// Zero pushes during 8 intra-modal clicks - the regression would show
|
||||
// up here as `after.push - baseline.push >= 1`.
|
||||
expect(after.push - baseline.push).toBe(0);
|
||||
// Exactly 8 replaces - one per click.
|
||||
expect(after.replace - baseline.replace).toBe(8);
|
||||
});
|
||||
|
||||
test("close returns to origin URL even after switching tabs (no history pile-up)", async ({
|
||||
page,
|
||||
}) => {
|
||||
|
||||
Reference in New Issue
Block a user