mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 13:01:00 +00:00
Arm the response waiter before navigating, so a response that lands during the initial load is still observed instead of timing out on an event that already happened, and poll for the returning refetch rather than sleeping a fixed span that a loaded machine can outrun.
71 lines
2.9 KiB
TypeScript
71 lines
2.9 KiB
TypeScript
import { expect, test } from "@playwright/test";
|
|
|
|
import { STORAGE_STATE_PATH } from "./setup/global-setup";
|
|
|
|
/**
|
|
* #316 follow-up — does the medications list refetch when you navigate
|
|
* back to the page?
|
|
*
|
|
* Reporter: "TanStack Query is not fetching data on the medications page
|
|
* or other areas when the data is stale, even when I navigate between
|
|
* pages." In Next.js App Router a route-level page UNMOUNTS on navigation
|
|
* away and remounts on return, so the query observer is recreated — but
|
|
* the global `staleTime: 5min` makes `refetchOnMount: true` skip the
|
|
* fetch while the cached data is still "fresh", so the page shows a
|
|
* potentially stale list with no network round-trip.
|
|
*
|
|
* This spec counts `/api/medications` requests across a client-side
|
|
* round-trip (medications → dashboard → medications). The DESIRED
|
|
* (post-fix) behaviour is a fresh fetch on return; pre-fix the count
|
|
* stays at 1, which is the reproduction.
|
|
*
|
|
* Desktop-only: the assertion is about query behaviour, and the sidebar
|
|
* nav links it clicks live behind a drawer on the mobile project.
|
|
*/
|
|
test.use({ storageState: STORAGE_STATE_PATH });
|
|
|
|
test("medications list refetches on client-side navigation back to the page", async ({
|
|
page,
|
|
}, testInfo) => {
|
|
test.skip(
|
|
testInfo.project.name.includes("mobile"),
|
|
"sidebar nav links are drawer-gated on mobile; query behaviour is project-independent",
|
|
);
|
|
let medsRequests = 0;
|
|
page.on("request", (req) => {
|
|
try {
|
|
const u = new URL(req.url());
|
|
if (u.pathname === "/api/medications") medsRequests += 1;
|
|
} catch {
|
|
/* non-URL request — ignore */
|
|
}
|
|
});
|
|
|
|
// Initial load — the list query mounts and fetches once. Arm the waiter
|
|
// BEFORE navigating: `goto` resolves on load, so a response that already
|
|
// arrived would never be seen by a listener attached afterwards, and the
|
|
// wait would time out on an event that had long since happened.
|
|
const firstListFetch = page.waitForResponse(
|
|
(r) => new URL(r.url()).pathname === "/api/medications",
|
|
);
|
|
await page.goto("/medications");
|
|
await firstListFetch;
|
|
expect(medsRequests).toBe(1);
|
|
|
|
// Client-side nav AWAY (dashboard) then BACK — App Router unmounts and
|
|
// remounts the medications page. A full page.goto() would reset the
|
|
// client cache and always refetch, so we click the sidebar links.
|
|
await page.locator('a[href="/"]').first().click();
|
|
await page.waitForURL("**/");
|
|
await page.locator('a[href="/medications"]').first().click();
|
|
await page.waitForURL("**/medications");
|
|
|
|
// Desired: the return mounts a fresh observer that refetches. Pre-fix
|
|
// the 5-min staleTime masks it and this stays at 1 (the bug). Poll rather
|
|
// than sleeping a fixed span: it returns the moment the refetch lands, and
|
|
// it does not turn a slow CI machine into a false failure.
|
|
await expect
|
|
.poll(() => medsRequests, { timeout: 10_000 })
|
|
.toBeGreaterThanOrEqual(2);
|
|
});
|