mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-08 04:05:54 -05:00
Fix E2E test
This commit is contained in:
@@ -22,6 +22,7 @@ import {
|
||||
useFetchers,
|
||||
useHref,
|
||||
useLoaderData,
|
||||
useLocation,
|
||||
useMatches,
|
||||
useNavigate,
|
||||
useNavigation,
|
||||
@@ -445,6 +446,7 @@ function HydrationTestIndicator() {
|
||||
const navigation = useNavigation();
|
||||
const revalidator = useRevalidator();
|
||||
const fetchers = useFetchers();
|
||||
const location = useLocation();
|
||||
|
||||
if (!isHydrated) return null;
|
||||
|
||||
@@ -469,6 +471,10 @@ function HydrationTestIndicator() {
|
||||
data-testid="hydrated"
|
||||
data-router-idle={routerIdle ? "true" : undefined}
|
||||
data-router-busy={routerIdle ? undefined : busy.join(" | ")}
|
||||
// the rendered search, trailing the browser's own by a commit: only
|
||||
// once the toast params are gone from here have the forms keyed on
|
||||
// the location (see SendouForm) finished remounting
|
||||
data-location-search={location.search}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -331,11 +331,15 @@ export async function submit(page: Page, target?: string | Locator) {
|
||||
await button.click();
|
||||
});
|
||||
|
||||
// Toast flash params are stripped right after via a replace navigation
|
||||
// (without revalidation); wait for it so it can't abort a later click.
|
||||
await page.waitForURL((url) => !/__(?:success|error)=/.test(url.href), {
|
||||
timeout: 5_000,
|
||||
});
|
||||
// An action's toast redirect adds flash params that a replace navigation
|
||||
// strips right after (without revalidation), remounting every form on the
|
||||
// page twice. Waiting on the rendered search rather than the browser's URL
|
||||
// covers the commit those remounts land in, which trails the history entry
|
||||
// — otherwise the second remount tears down whatever the test opens next.
|
||||
await page.waitForSelector(
|
||||
'[data-testid="hydrated"]:not([data-location-search*="__success"]):not([data-location-search*="__error"])',
|
||||
{ state: "attached", timeout: 5_000 },
|
||||
);
|
||||
}
|
||||
|
||||
export async function waitForPOSTResponse(page: Page, cb: () => Promise<void>) {
|
||||
@@ -344,6 +348,22 @@ export async function waitForPOSTResponse(page: Page, cb: () => Promise<void>) {
|
||||
const MAX_ATTEMPTS = 3;
|
||||
const PER_ATTEMPT_TIMEOUT = 10_000;
|
||||
|
||||
// The busy marker only appears once React commits the submission, which on a
|
||||
// loaded machine lands well after the POST left the browser. Watching for it
|
||||
// from before the click keeps the idle of the *previous* render from being
|
||||
// read as the action having settled below.
|
||||
const routerWentBusy = page
|
||||
.waitForFunction(
|
||||
() =>
|
||||
document
|
||||
.querySelector('[data-testid="hydrated"]')
|
||||
?.getAttribute("data-router-idle") !== "true",
|
||||
undefined,
|
||||
{ timeout: PER_ATTEMPT_TIMEOUT },
|
||||
)
|
||||
// a POST that no fetcher or navigation drives never turns the router busy
|
||||
.catch(() => {});
|
||||
|
||||
// React Aria buttons fire their handler on press end. Occasionally a click
|
||||
// registers the press start (the button goes `:active`) but the press never
|
||||
// completes into a submit, so no POST fires — e.g. when a re-render lands
|
||||
@@ -367,6 +387,7 @@ export async function waitForPOSTResponse(page: Page, cb: () => Promise<void>) {
|
||||
// The POST's revalidation (and any redirect it drives) is still in flight;
|
||||
// an interaction landing mid-flight aborts it, and routes that opt out of
|
||||
// revalidation on navigation (e.g. to.$id) then keep the stale data.
|
||||
await routerWentBusy;
|
||||
await expectRouterIdle(page);
|
||||
|
||||
return response!;
|
||||
|
||||
Reference in New Issue
Block a user