tests: fix two-tab collab baseline race + build the jspi harnesses in CI

1) pcbnew/eeschema two-tab 'a local move propagates A->B' read the
   pre-move baseline AFTER kicadCollabTestMoveFirst. The move is queued
   through CallAfter + the apply coroutine, and the drain can land
   between two consecutive page.evaluate round-trips — when it does
   (~50% under CI load, reproduced locally with --repeat-each) orig
   captures the ALREADY-MOVED position and the not-toBe poll waits on
   itself. Wire tracing showed the bridge working: the moved delta
   emits, nothing reverts. Fix: baseline from kicadCollabSnapshot
   BEFORE the move. 12/12 green at --repeat-each=4 (was ~50% red).

2) jspi-firefox suites 404'd their harness modules: jspi-stack and
   jspi-coroutine build via ad-hoc build.sh (Phase 3 Makefile wiring
   TODO) which CI never ran. Wire both into build-wasm-test.sh (its
   hash is already in the testapps cache key), and add the _pt pthread
   variant that index.html?pt=1 loads but nothing built. jspi-firefox
   8/8 green locally.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PmR6goSk7JC17h7fkgGvHG
This commit is contained in:
Gergő Törcsvári 2026-08-14 21:46:24 +02:00
commit db84293af1
No known key found for this signature in database
GPG key ID: 8E75F2CDE64E5322
4 changed files with 54 additions and 11 deletions

View file

@ -254,9 +254,19 @@ test.describe("eeschema collab bridge — two tabs (BroadcastChannel)", () => {
await startCollab(tabA);
await startCollab(tabB);
// Read the pre-move baseline BEFORE triggering the move: TestMoveFirst
// queues the commit through CallAfter + the apply coroutine, and the drain
// can land between two consecutive page.evaluate round-trips. A GetPos
// taken after the call raced that drain (~50% under CI load) and captured
// the ALREADY-MOVED position, so the not-toBe poll waited on itself.
const preSnap = await tabA.evaluate(() => JSON.parse(window.Module.kicadCollabSnapshot()));
const prePos = new Map<string, string>(
preSnap.added.map((i: { id: string; x: number; y: number }) => [i.id, `${i.x},${i.y}`]),
);
const uuid = await tabA.evaluate(() => window.Module.kicadCollabTestMoveFirst(2_000_000, 0));
expect(uuid).toMatch(/[0-9a-f-]{36}/);
const orig = await tabA.evaluate((id) => window.Module.kicadCollabGetPos(id), uuid);
const orig = prePos.get(uuid);
expect(orig, "moved item present in pre-move snapshot").toBeTruthy();
// Wait until tab A's item actually moved (guards against a no-op false pass).
await expect

View file

@ -460,9 +460,19 @@ test.describe("pcbnew collab bridge — two tabs (BroadcastChannel)", () => {
await startCollab(tabA);
await startCollab(tabB);
// Read the pre-move baseline BEFORE triggering the move: TestMoveFirst
// queues the commit through CallAfter + the apply coroutine, and the drain
// can land between two consecutive page.evaluate round-trips. A GetPos
// taken after the call raced that drain (~50% under CI load) and captured
// the ALREADY-MOVED position, so the not-toBe poll waited on itself.
const preSnap = await tabA.evaluate(() => JSON.parse(window.Module.kicadCollabSnapshot()));
const prePos = new Map<string, string>(
preSnap.added.map((i: { id: string; x: number; y: number }) => [i.id, `${i.x},${i.y}`]),
);
const uuid = await tabA.evaluate(() => window.Module.kicadCollabTestMoveFirst(2_000_000, 0));
expect(uuid).toMatch(/[0-9a-f-]{36}/);
const orig = await tabA.evaluate((id) => window.Module.kicadCollabGetPos(id), uuid);
const orig = prePos.get(uuid);
expect(orig, "moved item present in pre-move snapshot").toBeTruthy();
await expect
.poll(() => tabA.evaluate((id) => window.Module.kicadCollabGetPos(id), uuid), {