Skip to content

Commit e56ef7c

Browse files
intendednullclaude
andauthored
docs(event-based-waits): close out spec — flip [draft]→[landed] + Realised-state addendum (#657)
Audit-and-align pass surfaced 13 findings against docs/specs/2026-04-27-event-based-waits-design.md. All four implementation PRs are landed (test-hooks feature, Peer wrapper, data-state lifecycle, ratchet + flake harness) — the system works as designed for in-scope flows, but the body drifts from the realised implementation. Rather than rewrite the body (which would lose the design rationale), added a "Realised state" addendum after the existing 2026-04-28 erratum covering: - tab_bar excluded from data-state lifecycle (no CSS transition; commit 0f79399) - bottom_sheet drives on transform (opacity = reduced-motion fallback) - grove_drawer accepts both transform and opacity - action-sheet drives on transform - std::mem::forget instead of StoredValue (wasm32 process IS the app) - EventReceiver::subscribe_now (race-free) instead of subscribe_events() - clock.ts as 4th helper module - longPress page.clock migration deferred (legacy still uses waitForTimeout; opt-in longPressWithClock unused) - waitUntilHeadsEqual default timeout is 90s, not 30s — tuned for iroh-gossip cold-start cost (~30s dial-timeout window) - crates/web/src/test_hooks/ is a directory (mod.rs, dispatcher.rs, snapshot.rs, wire.rs), not a single file - Comprehensive WASM self-tests in test_hooks_browser.rs (browser.rs carries data-state lifecycle tests only) - dev-quick missing FEATURES="" parameter (minor follow-up) - CI gaps: check-no-test-hooks-in-prod.sh + test-e2e-flake exist but are wired to `just check-all` only, not to GitHub Actions workflows (tracked as follow-up) Body preserved as original target (corrected only by the 2026-04-28 erratum). Realised-state addendum is authoritative for current implementation shape. Added Implementation plan back-pointer (5 plans) per the docs-organization convention. README master index flipped [active] → [landed]. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 257cbe7 commit e56ef7c

2 files changed

Lines changed: 65 additions & 2 deletions

File tree

docs/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ See also: [`plans/STATUS.md`](plans/STATUS.md) — point-in-time audit of which
151151

152152
- [E2E test architecture](specs/2026-04-21-e2e-test-architecture-design.md) — tier decision tree pushing tests to the lowest level covering each behavior. `[draft]`
153153
- [Test architecture](specs/2026-04-13-test-architecture.md) — earlier test philosophy and per-crate coverage targets. `[superseded]`
154-
- [Event-based waits in Playwright suite](specs/2026-04-27-event-based-waits-design.md) — replaces magic-number sleeps with `WillowTestHooks` WASM API and `data-state` lifecycle. `[active]`
154+
- [Event-based waits in Playwright suite](specs/2026-04-27-event-based-waits-design.md) — replaces magic-number sleeps with `WillowTestHooks` WASM API and `data-state` lifecycle. `[landed]`
155155
- [Multi-peer E2E browser tests](specs/2026-03-24-multi-peer-e2e-tests-design.md) — Playwright suite covering sync, permissions, and mobile flows across four browser projects. `[landed]`
156156

157157
**Plans**

docs/specs/2026-04-27-event-based-waits-design.md

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# Event-Based Waits in Playwright Suite — Design
22

33
**Date:** 2026-04-27
4-
**Status:** draft
4+
**Status:** landed — `test-hooks` cargo feature + WASM API, push dispatcher, `data-state` lifecycle, `Peer` wrapper, ESLint rule, ratchet script, flake harness all shipped across PRs 1–4. Two CI gates from §CI gate (symbol-leak check + flake harness) are wired to local `just check-all` only; CI workflow wiring is a follow-up tracked in the *Realised state* note below.
5+
**Implementation plan:** [`docs/plans/2026-04-27-event-based-waits-pr1-test-hooks-foundation.md`](../plans/2026-04-27-event-based-waits-pr1-test-hooks-foundation.md), [`docs/plans/2026-04-28-event-based-waits-pr1-errata.md`](../plans/2026-04-28-event-based-waits-pr1-errata.md), [`docs/plans/2026-04-29-event-based-waits-pr2-peer-wrapper.md`](../plans/2026-04-29-event-based-waits-pr2-peer-wrapper.md), [`docs/plans/2026-04-30-event-based-waits-pr3-data-state-lifecycle.md`](../plans/2026-04-30-event-based-waits-pr3-data-state-lifecycle.md), [`docs/plans/2026-04-30-event-based-waits-pr4-ratchet-flake-harness.md`](../plans/2026-04-30-event-based-waits-pr4-ratchet-flake-harness.md)
56
**Branch:** `claude/event-based-waits-RNFZ9`
67

78
> **2026-04-28 erratum.** Investigation during PR-1 execution found that
@@ -13,6 +14,68 @@
1314
> sections below have been updated; the old shape is preserved in
1415
> `docs/plans/2026-04-28-event-based-waits-pr1-errata.md`.
1516
17+
> **Realised state (post-2026-05 audit).** The four PRs landed and the
18+
> system works as designed for the in-scope flows, but the body below
19+
> drifts from the realised implementation in several places. Diffs:
20+
>
21+
> - **`tab_bar.rs` was excluded** from the `data-state` lifecycle because
22+
> neither of its candidate elements has a CSS transition; recorded in
23+
> commit 0f79399 ("docs(web): record tab_bar lifecycle decision"). The
24+
> lifecycle now applies to four components + the action-sheet overlay,
25+
> not five. §Scope, §`data-state` attribute pattern Components-
26+
> receiving-the-lifecycle, and the driving-property list are stale on
27+
> this point.
28+
> - **Driving-property table fix.** `bottom_sheet.rs` drives on
29+
> `transform` (its listener accepts both `transform` and `opacity`
30+
> with `opacity` as the reduced-motion fallback); `grove_drawer.rs`
31+
> similarly accepts both; the action-sheet markup in `message.rs`
32+
> drives on `transform`. The body's list is incomplete on these points.
33+
> - **`std::mem::forget` instead of `StoredValue`** for the push
34+
> dispatcher in `app.rs`. `wasm32`'s process *is* the app, so leaking
35+
> the dispatcher handle is the simpler correct shape. The `StoredValue`
36+
> lifecycle paragraph in §Push dispatcher is superseded.
37+
> - **`EventReceiver::subscribe_now`** is used instead of
38+
> `ClientHandle::subscribe_events()``subscribe_now` is the race-free
39+
> path that avoids the boot-window where async-subscribe would drop
40+
> boot-time events. Comment at `app.rs:167-169` documents the rationale;
41+
> the spec's §Push dispatcher phrasing should defer to that.
42+
> - **`clock.ts` exists** as a fourth helper module at
43+
> `e2e/helpers/clock.ts` (wraps `page.clock.install`/`runFor`). The
44+
> §Helpers redesign directory listing omits it.
45+
> - **`longPress` did NOT migrate to `page.clock`** — the original
46+
> `longPress` still uses `waitForTimeout`; an opt-in
47+
> `longPressWithClock` exists but has no callers. §`page.clock for
48+
> real durations` step 1 is stale; the migration is deferred.
49+
> - **`waitUntilHeadsEqual` default timeout is 90s, not 30s** (per
50+
> `e2e/test-hooks.ts:193`). Justification recorded in code: iroh-gossip
51+
> cold-start cost — the relay log shows ~30s of dial timeouts before
52+
> the first peer-pair handshake completes. §Wait-until-heads-equal
53+
> sketch and §Three-patterns-purged item 3 need this reality.
54+
> - **`crates/web/src/test_hooks/` is a directory**, not a file. Four
55+
> submodules: `mod.rs`, `dispatcher.rs`, `snapshot.rs`, `wire.rs`. The
56+
> spec's references to `crates/web/src/test_hooks.rs` should be a
57+
> directory path.
58+
> - **Comprehensive WASM self-tests live in `crates/web/tests/test_hooks_browser.rs`**,
59+
> not `crates/web/tests/browser.rs` (which only carries the
60+
> `data-state` lifecycle tests + a single mount sanity test). §PR 1
61+
> references the wrong file for the bulk of the test set.
62+
> - **`dev-quick` did not get the `FEATURES=""` parameter** that `dev`
63+
> carries. Spec §`just dev` paragraph implies symmetric
64+
> parameterisation; not realised. Minor follow-up.
65+
> - **CI gaps.** `scripts/check-no-test-hooks-in-prod.sh` exists and is
66+
> called from `just check-all`, but no GitHub Actions workflow runs
67+
> `check-all` or that script directly. Similarly, no path-filtered
68+
> workflow runs `just test-e2e-flake N=10` on PRs that modify `e2e/`.
69+
> Both gates exist as local-only today. §CI gate and the PR-4
70+
> `Migrated specs must pass N=10 in CI` claim describe intent that
71+
> has not been wired to CI yet. Tracked as follow-up.
72+
>
73+
> The body below is preserved as the original design (corrected only by
74+
> the earlier 2026-04-28 erratum). The *Realised state* list above is
75+
> authoritative for current implementation shape; do not edit the body
76+
> in place to match it — that would lose the design rationale that drove
77+
> the four PRs.
78+
1679
## Problem
1780

1881
The Playwright suite leans on time-based waits as flake compensation. Audit of `e2e/` (8 spec files, 1814 LOC):

0 commit comments

Comments
 (0)