mirror of
https://github.com/vxcontrol/pentagi.git
synced 2026-08-25 12:36:30 +00:00
test(e2e): prove the pager route by its history trail, not by sampling
Sampling window.location on a timer measured the host's speed: on an unloaded machine the sibling landed before the third sample, so the guard that the samples spanned the switch failed 3 runs in 4. Weakening it to a length check made it vacuous instead — the sampling loop always runs its full count. Record every pushState/replaceState the app makes and assert the exact sequence, which is what "without passing through the list" claims. Verified by routing the pager through the list: the trail assert names the detour. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
c45fbd401f
commit
3b948d68ea
@@ -32,43 +32,43 @@ test.describe('flow pager', { tag: ['@flows', '@smoke'] }, () => {
|
||||
test('steps to the sibling flow and back without passing through the list', async ({ page, pageErrorLog }) => {
|
||||
const header = page.locator('header');
|
||||
|
||||
await page.addInitScript(() => {
|
||||
const trail: string[] = [];
|
||||
|
||||
(window as unknown as { __routeTrail: string[] }).__routeTrail = trail;
|
||||
|
||||
for (const method of ['pushState', 'replaceState'] as const) {
|
||||
const original = history[method].bind(history);
|
||||
|
||||
history[method] = (state: unknown, unused: string, url?: null | string | URL) => {
|
||||
original(state, unused, url);
|
||||
trail.push(window.location.pathname);
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
await page.goto('/flows/5');
|
||||
await expect(header.getByText('E2E Alpha')).toBeVisible();
|
||||
|
||||
await page.route('**/graphql', async (route) => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 300));
|
||||
await route.fallback();
|
||||
// Drop the router's own normalising replaceState from the initial load.
|
||||
await page.evaluate(() => {
|
||||
(window as unknown as { __routeTrail: string[] }).__routeTrail.length = 0;
|
||||
});
|
||||
|
||||
await header.getByRole('button', { name: 'Next' }).click();
|
||||
|
||||
const samples = await page.evaluate(async () => {
|
||||
const taken = [];
|
||||
|
||||
for (let index = 0; index < 10; index += 1) {
|
||||
taken.push({
|
||||
hasPager: !!document.querySelector('header button[aria-label="Next"]'),
|
||||
isSiblingShown: document.querySelector('header')?.textContent?.includes('E2E Beta') ?? false,
|
||||
path: window.location.pathname,
|
||||
});
|
||||
await new Promise((resolve) => setTimeout(resolve, 30));
|
||||
}
|
||||
|
||||
return taken;
|
||||
});
|
||||
|
||||
await expect(page).toHaveURL(/\/flows\/6$/);
|
||||
await expect(header.getByText('E2E Beta')).toBeVisible();
|
||||
|
||||
// Guards the delay above as much as the pager: without it the sibling lands inside the
|
||||
// first sample and the loop measures nothing.
|
||||
expect(samples.filter((sample) => !sample.isSiblingShown).length).toBeGreaterThan(2);
|
||||
expect(samples.every((sample) => sample.hasPager)).toBe(true);
|
||||
expect(samples.map((sample) => sample.path)).not.toContain('/flows');
|
||||
await expect(header.getByRole('button', { name: 'Next' })).toBeVisible();
|
||||
|
||||
await header.getByRole('button', { name: 'Previous' }).click();
|
||||
|
||||
await expect(page).toHaveURL(/\/flows\/5$/);
|
||||
await expect(header.getByText('E2E Alpha')).toBeVisible();
|
||||
|
||||
const trail = await page.evaluate(() => (window as unknown as { __routeTrail: string[] }).__routeTrail);
|
||||
|
||||
expect(trail, 'the pager must step straight between siblings').toEqual(['/flows/6', '/flows/5']);
|
||||
expectCleanPage(pageErrorLog);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user