Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions tests/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,16 @@ property in transit for two frames. That is fixed in the theme, which is why no
reading here carries such a wait — a wait in front of a reading whose subject never
moves is a mechanism that cannot fail and cannot help.

A wait states its end as well as its fact, and only Playwright's own waits state one by
default. `page.evaluate` takes no timeout in any binding, so a promise awaited inside it
— an animation's `finished`, a module's load, a listener's next call — is a wait nothing
bounds. It does not fail in thirty seconds naming its test; it spends the job's whole
step bound, and the share of the suite already handed to that worker never runs. Race
the await against a `setTimeout` that rejects naming what never arrived, as the fold in
`test_a_thread_reopened_mid_fold_folds_again_when_it_settles` and the diff render in
`test_render_anchors.py` do, or state the fact from inside the page and read it with
`wait_for_function`.

### A state the page passes through is not a state to poll for

Use Playwright's `expect(...)` for a state that will become stable and remain true.
Expand Down
10 changes: 9 additions & 1 deletion tests/test_render_conversations.py
Original file line number Diff line number Diff line change
Expand Up @@ -1128,10 +1128,18 @@ def test_a_thread_reopened_mid_fold_folds_again_when_it_settles(browser, serve):
# once: its node left the list when the thread reopened, and the record it must
# not clear on its way is the live fold's. Cleared, the thread is pulled out of
# the list in the middle of the motion carrying it away.
# The await states its own end. `page.evaluate` takes no timeout in any binding, so
# an animation that never settles `finished` is a wait nothing bounds: on run
# 33165671503 this one didn't, and what should have been this test failing in thirty
# seconds under its own name was the job's whole 45-minute bound, spent here, with
# the quarter of the suite already handed to this worker never run. Thirty seconds
# because that is where every other browser wait in the suite runs out, and the
# rejection comes back through `evaluate` naming the motion that stopped.
page.evaluate(
"async (i) => { const m = window.__lfHeld[i];"
" m.play(); m.currentTime = m.effect.getComputedTiming().duration;"
" await m.finished; }",
" await Promise.race([m.finished, new Promise((_, ranOut) => setTimeout("
" () => ranOut(new Error(`held fold ${i} never ran out`)), 30_000))]); }",
before,
)
expect(going.locator(f'.lf-msg[data-mid="{reply["id"]}"]')).to_have_count(1)
Expand Down
Loading