Problem
The e2e test `Dataset > displays download file manifest` (`e2e/anvil/anvil-dataset.spec.ts:101`) intermittently fails in CI on Firefox:
```
[firefox] › e2e/anvil/anvil-dataset.spec.ts:101:7 › Dataset › displays download file manifest
Error: expect(locator).toHaveCount(expected) failed
Locator: locator('.MuiButton-root').filter({ hasText: 'Request Link' })
Expected: 1
Received: 0
Timeout: 15000ms
- waiting for locator('.MuiButton-root').filter({ hasText: 'Request Link' })
18 × locator resolved to 0 elements
114 |
115 | // Ensure there is exactly one button.
116 | await expect(buttons).toHaveCount(1);
```
Root cause
The test does:
```ts
await clickCard(page, TITLE_TEXT_REQUEST_FILE_MANIFEST);
const buttons = page.locator(`${MUI_CLASSES.BUTTON}`, { hasText: BUTTON_TEXT_REQUEST_LINK });
await expect(buttons).toHaveCount(1);
```
There's no explicit wait between `clickCard` (which navigates to `/datasets/{id}/export/download-manifest`) and the assertion on the destination page's button. The button locator polls a page that hasn't finished navigating, hits "0 elements" 18× over 15s, and times out — even though the click succeeded.
The parallel test "displays download file manifest selected data" (line 122) wraps the same `clickCard` in `Promise.all([waitForRequest, clickCard])`, which gates on the network request and incidentally waits for navigation. The plain assertion-only test has no such gate.
Fix
Add an explicit `waitForURL` after `clickCard` so the assertion only runs once we're actually on the manifest page:
```ts
await clickCard(page, TITLE_TEXT_REQUEST_FILE_MANIFEST);
await page.waitForURL(/\/export\/download-manifest/);
const buttons = page.locator(...);
await expect(buttons).toHaveCount(1);
```
If the click ever fails to navigate, `waitForURL` throws with a clear "URL didn't match" error instead of the cryptic 15s 0-elements timeout.
Out of scope
A broader rewrite of this spec (test-id locators, role-based queries, dispatchEvent for click-swallowing, etc.) was considered but deferred — the spec is otherwise stable and the structure predates the locator conventions used in `anvil-filters.spec.ts` but isn't itself flaky. This issue addresses just the one observed flake.
Acceptance criteria
- `Dataset > displays download file manifest` passes reliably on Firefox across multiple CI runs.
- No other tests in the spec change.
Problem
The e2e test `Dataset > displays download file manifest` (`e2e/anvil/anvil-dataset.spec.ts:101`) intermittently fails in CI on Firefox:
```
[firefox] › e2e/anvil/anvil-dataset.spec.ts:101:7 › Dataset › displays download file manifest
Error: expect(locator).toHaveCount(expected) failed
Locator: locator('.MuiButton-root').filter({ hasText: 'Request Link' })
Expected: 1
Received: 0
Timeout: 15000ms
18 × locator resolved to 0 elements
114 |
115 | // Ensure there is exactly one button.
Root cause
The test does:
```ts
await clickCard(page, TITLE_TEXT_REQUEST_FILE_MANIFEST);
const buttons = page.locator(`${MUI_CLASSES.BUTTON}`, { hasText: BUTTON_TEXT_REQUEST_LINK });
await expect(buttons).toHaveCount(1);
```
There's no explicit wait between `clickCard` (which navigates to `/datasets/{id}/export/download-manifest`) and the assertion on the destination page's button. The button locator polls a page that hasn't finished navigating, hits "0 elements" 18× over 15s, and times out — even though the click succeeded.
The parallel test "displays download file manifest selected data" (line 122) wraps the same `clickCard` in `Promise.all([waitForRequest, clickCard])`, which gates on the network request and incidentally waits for navigation. The plain assertion-only test has no such gate.
Fix
Add an explicit `waitForURL` after `clickCard` so the assertion only runs once we're actually on the manifest page:
```ts
await clickCard(page, TITLE_TEXT_REQUEST_FILE_MANIFEST);
await page.waitForURL(/\/export\/download-manifest/);
const buttons = page.locator(...);
await expect(buttons).toHaveCount(1);
```
If the click ever fails to navigate, `waitForURL` throws with a clear "URL didn't match" error instead of the cryptic 15s 0-elements timeout.
Out of scope
A broader rewrite of this spec (test-id locators, role-based queries, dispatchEvent for click-swallowing, etc.) was considered but deferred — the spec is otherwise stable and the structure predates the locator conventions used in `anvil-filters.spec.ts` but isn't itself flaky. This issue addresses just the one observed flake.
Acceptance criteria