test: Make browser e2e tests deterministic and leak-free - #1952
Open
jeswr wants to merge 2 commits into
Open
Conversation
The e2e tests slept a fixed 1000ms after clicking execute/clear and then asserted on div[id=result]; on slow runners the reasoner takes longer than the sleep, so the assertion reads an empty div (#704). Replace both sleeps with page.waitForFunction() polling the result div (non-empty after execute, then assert the exact expected text; empty after clear) with a generous 90s timeout inside the existing 120s jest timeout. Also move the browser lifecycle into try/finally so browser.close() always runs: when an assertion threw, the leaked browser kept the jest worker alive, which is the mechanism behind the historic 60-minute Windows CI hangs (#385). Closes #704 Closes #385 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jeswr
enabled auto-merge (squash)
July 4, 2026 21:29
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🚧 DRAFT — for @jeswr to review first
Closes #704
Closes #385
The two mechanisms (from the triage)
execute, the test slept a fixedsetTimeout(res, 1000)and then asserted ondiv[id=result]. The page's execute handler fills that div only afterawait eyereasoner.n3reasoner(...)completes, so on a slow runner the assertion races the reasoner and reads an empty div — exactly theExpected: "@prefix : .:Socrates a :Mortal." / Received: ""failure in the linked CI run.page.close()/browser.close()were the last statements of the test body. When any assertion threw, they never ran; the leaked browser kept the jest worker from exiting ("A worker process has failed to exit gracefully..."), which is the mechanism behind the historic 60-minute Windows CI timeouts.Change
page.waitForFunction()pollingdiv[id=result]textContent: non-empty afterexecute(then assert the exact expected text), empty afterclear. Each wait has a generous 90s timeout, inside the existing 120s jest timeout, so a genuine failure still terminates promptly instead of hanging.try/finallysobrowser.close()(which also closes its pages) always runs, pass or fail.No assertion is weakened — the same exact-text expectations remain.
Validation
Playwright cannot run on this (production-shared, browserless) box, so the CI matrix on this PR is the validation for the behavioural change. Locally validated:
tsc --noEmittype-check of__tests__/e2e-test.ts(the repo tsconfig only includeslib/): exit 0🤖 Generated with Claude Code