Flaky E2E: saved-search save→navigate race (saved-search.spec.ts:212, :422)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 9.9k
- Forks
- 471
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 117
Description
Summary
Two E2E tests in packages/app/tests/e2e/features/search/saved-search.spec.ts are intermittently flaky under parallel load. Both fail at the save → navigate step: after clicking Save in the saved-search modal, the app does not navigate to the /search/<id> permalink, so SavedSearchModalComponent.saveSearchAndWaitForNavigation() times out on page.waitForURL(/\/search\/[a-f0-9]+/).
Affected tests:
saved-search.spec.ts:212— should load saved search when navigating from another pagesaved-search.spec.ts:422— should update ORDER BY when switching sources multiple times
Observed ~1-in-3 under --repeat-each=3 across the full saved-search spec (9 workers, dev-mode server). Both recover on Playwright retry, so they show as flaky.
Evidence (this is an app race, not a test-helper issue)
At failure the page is on the plain, unsaved search view, not the saved-search detail page:
- WHERE / ORDER BY / SELECT config is all correct and results are loaded.
- The action bar shows "Save" (not "Update"), and there is no saved-search name title → the search was never persisted into the detail view.
- No error toast, and the API logs show no
POST /saved-searcherror → the save request itself is not erroring. - The modal has closed and the URL is still
/search?...&orderBy=...(the pre-save searched URL), never/search/<id>.
So the create request succeeds but the client-side router.push('/search/${savedSearch.id}${window.location.search}') in DBSearchPage.tsx (onSubmit, ~line 546) is effectively lost/clobbered under load — the navigation appears to race with the search-config URL update and/or the ['saved-search'] query invalidation (useCreateSavedSearch onSuccess in packages/app/src/savedSearch.ts).
Discriminator: tests 56 and 293 use the same createSavedSearch + router.push path and pass solidly (3/3, no retries) after an unrelated fix. 212/422 differ in that they perform an explicit search-then-save with a custom WHERE/ORDER BY, which is what appears to open the race window.
Ruled out
- Not a lost submit click — a guarded submit-retry in the test helper did not help (the modal does close; re-clicking is a no-op). Reverted.
- Not a duplicate-name / shared-DB artifact — other fixed-name saved-search tests create the same name 3× and pass.
- Not an autocomplete-overlay or CodeMirror keystroke-drop flake (those were the separately-fixed pie-chart and
setCustomSELECTissues).
Suggested investigation
- In
DBSearchPage.tsxonSubmit(create branch), confirm whether a concurrent search-config URL update or a redirect-on-"saved-search-not-found" (while['saved-search']is still refetching after invalidation) overrides therouter.push('/search/<id>'). - Consider navigating using the freshly returned
savedSearchobject / seeding the query cache beforerouter.push, or making the saved-search detail route tolerant of the item not yet being in cache instead of falling back to/search.
Repro
make dev-e2e FILE=saved-search ARGS="--repeat-each=3"
Failure signature:
TimeoutError: page.waitForURL: Timeout 15000ms exceeded.
navigated to "http://localhost:.../search?source=...&orderBy=ServiceName%20ASC&..."
at components/SavedSearchModalComponent.ts (saveSearchAndWaitForNavigation)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Run make dev-e2e FILE=saved-search ARGS="--repeat-each=3" and inspect the failing tests at lines 212 and 422 in packages/app/tests/e2e/features/search/saved-search.spec.ts. Trace the create branch in DBSearchPage.tsx around onSubmit and useCreateSavedSearch in packages/app/src/savedSearch.ts, focusing on navigation, URL updates, and query invalidation. Done means the save reliably reaches /search/<id> without retries under parallel repeated runs.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- playwright, react, typescript
- Domain
- frontend, testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100