tests: un-skip sweep — 26 tests revived on the JSPI build, failures re-gated with fresh evidence

Empirical pass over every skip/fixme whose premise the JSPI migration
could have changed. Revived (verified green):

- Firefox wasm-budget guards RETIRED (drift-trio, drift-trio-fuzz,
  drift-trio-scenarios, ysync-two-tab, ysync-libsymbols): the JSPI
  build (~half the asyncify size) fits three editor tabs inside
  Firefox 153's per-process budget — +20 firefox collab tests.
- roundtrip 'pcbnew preserves items through a yjs round trip': the
  asyncify-fragile envelope parse it waited on is gone — both engines.
- drift-trio-scenarios S4/S4b: converge now (was KNOWN ~5-8%).
- pcbnew-collab + eeschema-collab 'a local move propagates A→B'.
- web eeschema-fp-selector, read-only-editor's fixme'd writer-stream
  test, footprint-browse-remote read path (chromium; firefox gated:
  FootprintEnumerate rows never appear in 60s — slow wasm tier
  suspected).

Still broken, re-gated with re-verified reasons:

- 3d-viewer raytracer engine toggle: still inert, both engines.
- maximize display geometry: wxDisplay reports 0x0 in the harness.
- web editor WRITE bridge (symbol/footprint × remote/spike): wedges at
  the New Symbol/Footprint dialog step on both engines — the
  web-e2e-rot 01 gap stands for writes.

Verify runs: kicad+wx touched files 93 passed / 0 failed / 7 skipped
(intended gates); web touched files 7 passed / 0 failed / 9 skipped.
lint:determinism + lint:ci-coverage green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016X9eh1s5sTx1o9Em9KBuwR
This commit is contained in:
Viktor Vaczi 2026-08-13 18:43:36 +02:00
commit 3ee174e9b4
17 changed files with 56 additions and 33 deletions

View file

@ -56,6 +56,8 @@ test.describe('wxFrame::Maximize() Tests', () => {
// Note: wxDisplay::GetFromWindow() has a bug returning invalid display index // Note: wxDisplay::GetFromWindow() has a bug returning invalid display index
// This is a separate issue from the Maximize() functionality being tested // This is a separate issue from the Maximize() functionality being tested
// Re-verified broken 2026-08-13: wxDisplay reports 0x0 in this harness app
// (JSPI build) — the port's display-geometry query, not Maximize().
test.skip('Display geometry is reported correctly', async ({ page, testLogger }) => { test.skip('Display geometry is reported correctly', async ({ page, testLogger }) => {
await page.goto('/standalone/maximize/maximize_test.html'); await page.goto('/standalone/maximize/maximize_test.html');
const loaded = await tryLoadApp(page); const loaded = await tryLoadApp(page);

View file

@ -58,7 +58,8 @@ test.describe('3D viewer camera-move deadlock', () => {
// m_boardAdapter.m_Cfg while RenderEngineChanged() reads GetAppSettings<…>() — possibly // m_boardAdapter.m_Cfg while RenderEngineChanged() reads GetAppSettings<…>() — possibly
// different instances in the merged kicad_editor bundle. Unskip once the toggle works: // different instances in the merged kicad_editor bundle. Unskip once the toggle works:
// the engagement guard below then validates the engine flip loudly. // the engagement guard below then validates the engine flip loudly.
test.skip(true, 'KNOWN ISSUE: the raytracer engine toggle is inert on the webgl-era wasm ' test.skip(true, // re-verified still inert 2026-08-13 (both engines, JSPI build)
'KNOWN ISSUE: the raytracer engine toggle is inert on the webgl-era wasm '
+ 'build — the deadlock mechanism cannot be driven until it works (see comment)'); + 'build — the deadlock mechanism cannot be driven until it works (see comment)');
// One 187 MB wasm runtime is already heavy; keep this serial and generous. // One 187 MB wasm runtime is already heavy; keep this serial and generous.
test.describe.configure({ mode: 'serial' }); test.describe.configure({ mode: 'serial' });

View file

@ -56,10 +56,10 @@ test.beforeAll(() => {
}); });
function skipFirefox(): void { function skipFirefox(): void {
test.skip( // 2026-08-13: guard retired — the JSPI build (~half the asyncify size) fits
test.info().project.name.includes("firefox"), // three editor tabs inside Firefox 153's per-process wasm budget; the
"three heavy wasm tabs exceed Firefox's per-process wasm budget", // whole file passes on kicad-firefox. Kept as a hook in case the wall
); // returns with future growth.
} }
/** mulberry32 — tiny deterministic PRNG. */ /** mulberry32 — tiny deterministic PRNG. */

View file

@ -46,10 +46,10 @@ test.beforeAll(() => {
}); });
function skipFirefox(): void { function skipFirefox(): void {
test.skip( // 2026-08-13: guard retired — the JSPI build (~half the asyncify size) fits
test.info().project.name.includes("firefox"), // three editor tabs inside Firefox 153's per-process wasm budget; the
"three heavy wasm tabs exceed Firefox's per-process wasm budget", // whole file passes on kicad-firefox. Kept as a hook in case the wall
); // returns with future growth.
} }
/** Poll until every tab's silent save contains `marker`. */ /** Poll until every tab's silent save contains `marker`. */
@ -197,7 +197,8 @@ for (const ops of [SCH_OPS, PCB_OPS]) {
// runs). A real same-item conflict-resolution race that needs its own // runs). A real same-item conflict-resolution race that needs its own
// hunt — tracking: memory s4-value-race-divergence. The sequenced-edit // hunt — tracking: memory s4-value-race-divergence. The sequenced-edit
// scenarios (S1S3, S5S8) have never diverged and stay active. // scenarios (S1S3, S5S8) have never diverged and stay active.
test.fixme(`${label} S4: move-vs-delete, value-vs-value, move-vs-move`, async ({ // re-enabled 2026-08-13: converges on the JSPI build
test(`${label} S4: move-vs-delete, value-vs-value, move-vs-move`, async ({
context, context,
testLogger, testLogger,
}) => { }) => {
@ -241,7 +242,8 @@ for (const ops of [SCH_OPS, PCB_OPS]) {
// locally at single-worker). A real CRDT/apply race that needs its own // locally at single-worker). A real CRDT/apply race that needs its own
// hunt: capture both tabs' modelText diff at timeout, then bisect the // hunt: capture both tabs' modelText diff at timeout, then bisect the
// value-apply path. Tracking: memory s4-value-race-divergence. // value-apply path. Tracking: memory s4-value-race-divergence.
test.fixme(`${label} S4b: value-vs-value converges (KNOWN ~5-8% divergence)`, async ({ // re-enabled 2026-08-13: converges on the JSPI build
test(`${label} S4b: value-vs-value converges (KNOWN ~5-8% divergence)`, async ({
context, context,
testLogger, testLogger,
}) => { }) => {

View file

@ -51,10 +51,10 @@ test.beforeAll(() => {
/** Heavy editors exceed Firefox's per-content-process wasm budget at 2+ /** Heavy editors exceed Firefox's per-content-process wasm budget at 2+
* instances (see ysync-two-tab.spec.ts) at 3 it is strictly worse. */ * instances (see ysync-two-tab.spec.ts) at 3 it is strictly worse. */
function skipFirefox(): void { function skipFirefox(): void {
test.skip( // 2026-08-13: guard retired — the JSPI build (~half the asyncify size) fits
test.info().project.name.includes("firefox"), // three editor tabs inside Firefox 153's per-process wasm budget; the
"three heavy wasm tabs exceed Firefox's per-process wasm budget", // whole file passes on kicad-firefox. Kept as a hook in case the wall
); // returns with future growth.
} }
// ── pl_editor: green baseline validating the trio plumbing itself ──────────── // ── pl_editor: green baseline validating the trio plumbing itself ────────────

View file

@ -224,7 +224,8 @@ test.describe("eeschema collab bridge — single page", () => {
test.describe("eeschema collab bridge — two tabs (BroadcastChannel)", () => { test.describe("eeschema collab bridge — two tabs (BroadcastChannel)", () => {
// SKIP headless for the same reason as the single-page apply test (harness open=false → // SKIP headless for the same reason as the single-page apply test (harness open=false →
// SCH_COMMIT no-ops). Verified working in the real web app. // SCH_COMMIT no-ops). Verified working in the real web app.
test.skip("a local move propagates A→B", async ({ context, testLogger }) => { // re-enabled 2026-08-13: passes on the JSPI build (flaked once under 2-worker trio load; green solo)
test("a local move propagates A→B", async ({ context, testLogger }) => {
const channel = `ee-collab-e2e-${test.info().workerIndex}`; const channel = `ee-collab-e2e-${test.info().workerIndex}`;
const bundle = path.resolve(__dirname, "../apps/kicad/collab-bundle.js"); const bundle = path.resolve(__dirname, "../apps/kicad/collab-bundle.js");

View file

@ -437,7 +437,8 @@ test.describe("pcbnew collab bridge — single page", () => {
test.describe("pcbnew collab bridge — two tabs (BroadcastChannel)", () => { test.describe("pcbnew collab bridge — two tabs (BroadcastChannel)", () => {
// SKIP headless for the same reason as the single-page apply test (harness can't PAINT). // SKIP headless for the same reason as the single-page apply test (harness can't PAINT).
// Verified working in the real web app. // Verified working in the real web app.
test.skip("a local move propagates A→B", async ({ context, testLogger }) => { // re-enabled 2026-08-13: passes on the JSPI build (both engines)
test("a local move propagates A→B", async ({ context, testLogger }) => {
const channel = `pcb-collab-e2e-${test.info().workerIndex}`; const channel = `pcb-collab-e2e-${test.info().workerIndex}`;
const bundle = path.resolve(__dirname, "../apps/kicad/collab-bundle.js"); const bundle = path.resolve(__dirname, "../apps/kicad/collab-bundle.js");

View file

@ -510,7 +510,7 @@ test.describe("round trip: file → yjs → file", () => {
// fixture (via + gr_text + segments) therefore still loses those items on the // fixture (via + gr_text + segments) therefore still loses those items on the
// rebuild side. Un-fixme when the envelope parse is solved. Run with // rebuild side. Un-fixme when the envelope parse is solved. Run with
// --grep-invert skipped to see the live diff. // --grep-invert skipped to see the live diff.
test.fixme( test( // re-enabled 2026-08-13: the asyncify-fragile envelope parse is gone with JSPI — passes both engines
"pcbnew preserves items through a yjs round trip", "pcbnew preserves items through a yjs round trip",
async ({ context, testLogger }) => { async ({ context, testLogger }) => {
const { orig, regen } = await roundTrip(context, PCB); const { orig, regen } = await roundTrip(context, PCB);

View file

@ -157,10 +157,8 @@ test.describe("v2 items wire — lib_symbols travel (miss 08A)", () => {
context, context,
testLogger, testLogger,
}) => { }) => {
test.skip( // 2026-08-13: FF wasm-budget skip retired — the JSPI build fits two
test.info().project.name.includes("firefox"), // editor tabs on Firefox 153; passes on kicad-firefox.
"two kicad_editor tabs exceed Firefox's per-process wasm budget",
);
const room = `ysync-libsym-${test.info().workerIndex}`; const room = `ysync-libsym-${test.info().workerIndex}`;
const tabA = await context.newPage(); const tabA = await context.newPage();

View file

@ -353,10 +353,8 @@ for (const [cfg, label] of [
// same SpiderMonkey wall playwright-kicad.config.ts documents for x86 // same SpiderMonkey wall playwright-kicad.config.ts documents for x86
// CI, hit at 2× on ARM). V8 handles it: runs on chromium-ci in CI and // CI, hit at 2× on ARM). V8 handles it: runs on chromium-ci in CI and
// --project=chromium locally. // --project=chromium locally.
test.skip( // 2026-08-13: FF wasm-budget skip retired — the JSPI build fits two
test.info().project.name.includes("firefox"), // editor tabs on Firefox 153; passes on kicad-firefox.
"two kicad_editor tabs exceed Firefox's per-process wasm budget",
);
const room = `ysync-v2-${label}-bug01-${test.info().workerIndex}`; const room = `ysync-v2-${label}-bug01-${test.info().workerIndex}`;
const tabA = await context.newPage(); const tabA = await context.newPage();

View file

@ -35,7 +35,8 @@ async function canvasCenter(page: Page): Promise<{ x: number; y: number }> {
// legacy startModal pump was deleted at doc 20 D-1; modals are scheduler // legacy startModal pump was deleted at doc 20 D-1; modals are scheduler
// waits now — re-evaluate against the scheduler runtime; see also // waits now — re-evaluate against the scheduler runtime; see also
// docs/features/ngspice-split/README.md "The editor side"). // docs/features/ngspice-split/README.md "The editor side").
test.skip('symbol chooser footprint selector populates and preview renders (eeschema)', async ({ page }) => { test( // re-enabled 2026-08-13: the chooser fp-selector flow revived on the JSPI build (both engines)
'symbol chooser footprint selector populates and preview renders (eeschema)', async ({ page }) => {
test.setTimeout(420000); test.setTimeout(420000);
const logs: string[] = []; const logs: string[] = [];
page.on('console', (m) => logs.push(`[${m.type()}] ${m.text()}`)); page.on('console', (m) => logs.push(`[${m.type()}] ${m.text()}`));

View file

@ -84,7 +84,14 @@ async function dblclickRow(page: Page, re: RegExp): Promise<string | null> {
// KNOWN-BROKEN: the fp/sym editor kicadLibs enumerate/save flows are dead // KNOWN-BROKEN: the fp/sym editor kicadLibs enumerate/save flows are dead
// (docs/features/web-e2e-rot/01-editor-lib-bridge-flows.md). fixme, not fail: // (docs/features/web-e2e-rot/01-editor-lib-bridge-flows.md). fixme, not fail:
// on CI this dies in a 180s boot timeout per engine — running it buys no signal. // on CI this dies in a 180s boot timeout per engine — running it buys no signal.
test.fixme('footprint editor browses + loads a real ingested footprint (read path / version cap)', async ({ page }) => { // Re-enabled 2026-08-13: the read path revived on the JSPI build (chromium).
test(
'footprint editor browses + loads a real ingested footprint (read path / version cap)', async ({ page }) => {
test.skip(
test.info().project.name.includes('firefox'),
'FootprintEnumerate child rows never appear on Firefox within 60s — slow ' +
'wasm tier suspected (probed 2026-08-13); passes on chromium',
);
const logs: string[] = []; const logs: string[] = [];
page.on('console', (m) => logs.push(`[${m.type()}] ${m.text()}`)); page.on('console', (m) => logs.push(`[${m.type()}] ${m.text()}`));
page.on('pageerror', (e) => logs.push(`[pageerror] ${e.message}`)); page.on('pageerror', (e) => logs.push(`[pageerror] ${e.message}`));

View file

@ -43,7 +43,10 @@ async function clickTreeRow(page: Page, label: string): Promise<boolean> {
// KNOWN-BROKEN: the fp/sym editor kicadLibs enumerate/save flows are dead // KNOWN-BROKEN: the fp/sym editor kicadLibs enumerate/save flows are dead
// (docs/features/web-e2e-rot/01-editor-lib-bridge-flows.md). fixme, not fail: // (docs/features/web-e2e-rot/01-editor-lib-bridge-flows.md). fixme, not fail:
// on CI this dies in a 180s boot timeout per engine — running it buys no signal. // on CI this dies in a 180s boot timeout per engine — running it buys no signal.
test.fixme('footprint editor save persists to the backend (remote write round-trip)', async ({ page }) => { // Probed 2026-08-13 on the JSPI build: still dead — wedges at the New Symbol/
// Footprint dialog step on BOTH engines (web-e2e-rot 01 stands for writes).
test.fixme(
'footprint editor save persists to the backend (remote write round-trip)', async ({ page }) => {
const owner = `e2e-fp-${Date.now()}`; const owner = `e2e-fp-${Date.now()}`;
const logs: string[] = []; const logs: string[] = [];
page.on('console', (m) => logs.push(`[${m.type()}] ${m.text()}`)); page.on('console', (m) => logs.push(`[${m.type()}] ${m.text()}`));

View file

@ -34,7 +34,10 @@ async function bootFootprintEditor(page: Page): Promise<void> {
// KNOWN-BROKEN: the fp/sym editor kicadLibs enumerate/save flows are dead // KNOWN-BROKEN: the fp/sym editor kicadLibs enumerate/save flows are dead
// (docs/features/web-e2e-rot/01-editor-lib-bridge-flows.md). fixme, not fail: // (docs/features/web-e2e-rot/01-editor-lib-bridge-flows.md). fixme, not fail:
// on CI this dies in a 180s boot timeout per engine — running it buys no signal. // on CI this dies in a 180s boot timeout per engine — running it buys no signal.
test.fixme('footprint editor save routes through the pcbjam_fp write bridge (main thread)', async ({ page }) => { // Probed 2026-08-13 on the JSPI build: still dead — wedges at the New Symbol/
// Footprint dialog step on BOTH engines (web-e2e-rot 01 stands for writes).
test.fixme(
'footprint editor save routes through the pcbjam_fp write bridge (main thread)', async ({ page }) => {
const logs: string[] = []; const logs: string[] = [];
page.on('console', (m) => logs.push(`[${m.type()}] ${m.text()}`)); page.on('console', (m) => logs.push(`[${m.type()}] ${m.text()}`));
page.on('pageerror', (e) => logs.push(`[pageerror] ${e.message}`)); page.on('pageerror', (e) => logs.push(`[pageerror] ${e.message}`));

View file

@ -231,7 +231,7 @@ test("a writer's edits stream into the viewer live (and never the reverse)", asy
// for two fully WRITABLE tabs on a fresh kicad_editor build (the previous // for two fully WRITABLE tabs on a fresh kicad_editor build (the previous
// CI artifacts were built at an older kicad rev). Un-fixme once the // CI artifacts were built at an older kicad rev). Un-fixme once the
// envelope/parser mismatch is fixed on main. // envelope/parser mismatch is fixed on main.
test.fixme(); // fixme removed 2026-08-13: passes on the JSPI build (both engines):
const itemId = await writer.evaluate(() => const itemId = await writer.evaluate(() =>
(window as unknown as W).Module.kicadCollabTestSelectFirst(), (window as unknown as W).Module.kicadCollabTestSelectFirst(),

View file

@ -21,7 +21,10 @@ const BACKEND = process.env.BACKEND_URL ?? 'http://localhost:3060';
// KNOWN-BROKEN: the fp/sym editor kicadLibs enumerate/save flows are dead // KNOWN-BROKEN: the fp/sym editor kicadLibs enumerate/save flows are dead
// (docs/features/web-e2e-rot/01-editor-lib-bridge-flows.md). fixme, not fail: // (docs/features/web-e2e-rot/01-editor-lib-bridge-flows.md). fixme, not fail:
// on CI this dies in a 180s boot timeout per engine — running it buys no signal. // on CI this dies in a 180s boot timeout per engine — running it buys no signal.
test.fixme('symbol editor save persists to the backend (remote write round-trip)', async ({ page }) => { // Probed 2026-08-13 on the JSPI build: still dead — wedges at the New Symbol/
// Footprint dialog step on BOTH engines (web-e2e-rot 01 stands for writes).
test.fixme(
'symbol editor save persists to the backend (remote write round-trip)', async ({ page }) => {
// Unique owner per run so the test is isolated from prior runs. // Unique owner per run so the test is isolated from prior runs.
const owner = `e2e-${Date.now()}`; const owner = `e2e-${Date.now()}`;
const logs: string[] = []; const logs: string[] = [];

View file

@ -31,7 +31,10 @@ async function bootSymbolEditor(page: Page): Promise<void> {
// KNOWN-BROKEN: the fp/sym editor kicadLibs enumerate/save flows are dead // KNOWN-BROKEN: the fp/sym editor kicadLibs enumerate/save flows are dead
// (docs/features/web-e2e-rot/01-editor-lib-bridge-flows.md). fixme, not fail: // (docs/features/web-e2e-rot/01-editor-lib-bridge-flows.md). fixme, not fail:
// on CI this dies in a 180s boot timeout per engine — running it buys no signal. // on CI this dies in a 180s boot timeout per engine — running it buys no signal.
test.fixme('symbol editor save routes through the pcbjam write bridge (main thread)', async ({ page }) => { // Probed 2026-08-13 on the JSPI build: still dead — wedges at the New Symbol/
// Footprint dialog step on BOTH engines (web-e2e-rot 01 stands for writes).
test.fixme(
'symbol editor save routes through the pcbjam write bridge (main thread)', async ({ page }) => {
const logs: string[] = []; const logs: string[] = [];
page.on('console', (m) => logs.push(`[${m.type()}] ${m.text()}`)); page.on('console', (m) => logs.push(`[${m.type()}] ${m.text()}`));
page.on('pageerror', (e) => logs.push(`[pageerror] ${e.message}`)); page.on('pageerror', (e) => logs.push(`[pageerror] ${e.message}`));