Skip to content

fix: enforce pinned Node, repair weekly coverage, and speed up CI - #326

Merged
jackhai9 merged 4 commits into
mainfrom
chore/enforce-node-runtime
Oct 26, 2026
Merged

jackhai9 merged 4 commits into
mainfrom
chore/enforce-node-runtime

Conversation

@jackhai9

Copy link
Copy Markdown
Owner

Summary

Three focused commits that make local runs trustworthy, restore the weekly coverage job, and shorten PR CI.

1. Enforce the pinned Node runtime (chore)

  • The runtime was pinned only in .nvmrc; shells that skipped nvm use (including non-interactive agent shells) ran on Node 22. There, import.meta.main is undefined, so the exact-file runner and coverage CLIs skipped all work and exited 0 — a false green for test:affected / test:coverage.
  • package.json devEngines makes npm install/ci/run/test/exec refuse any other runtime (EBADDEVENGINES).
  • Repository CLIs assert the .nvmrc version at module load, before their entry guards (reusing the existing assertProjectNodeVersion, moved to scripts/node-runtime.mjs).
  • A contract test keeps devEngines aligned with .nvmrc; AGENTS.md and docs/test-policy.md document per-command runtime selection.

2. Repair the weekly coverage job (fix(coverage))

  • Since the multi-tab specs (feat: integrate chart storage optimization into orderbook v2.7.218 #306, fix: stop other-symbol tabs from restoring deleted drawings #307, fix: preserve data panel positions across viewport changes #317), the fixture covered only the default page: reloading a page opened with context.newPage() or closing the default page mid-test failed 11 scenarios in coverage mode only.
  • Coverage now follows every page in the scenario context (started before it can navigate, written before it closes); the report accepts several CDP sessions per scenario and rejects duplicate sessions. A self-test spec covers open/reload/close.
  • With complete collection the gate showed 85.52%: the byte-pinned copies of Binance's native webpack factories (mirror-module.js 7/438, drawing-save-module.js 5/206 branches) were counted as production source. They are now mapped like bundled dependencies; hand-written chart-storage modules stay in scope.
  • chart-save-coalescer.js was 2 branches short of its 90% critical gate; two real failure paths gain behavior tests.

3. Speed up PR CI (perf(ci))

  • Playwright ran 621 scenarios on one worker (~8.8 min of a 10-14 min job). Spec files use isolated contexts with routed fixtures, so they now run on half the logical CPUs (2 workers on 4-vCPU runners); tests inside a file stay ordered. The instrumented coverage layer stays serial.
  • Changes limited to .gitignore files no longer select the full suite.

Validation

  • npm test on Node 24.16.0 — 2626 passed; npm run lint:tests, npm run test:test-policy (64 passed), and git diff --check passed.
  • Node 22.17.0: npm test now fails with EBADDEVENGINES; running scripts/test-selection/node-runner.mjs or scripts/test-coverage/run.mjs directly exits 1 with Use the project Node version 24.16.0 from .nvmrc (nvm use); received 22.17.0 (before: the runner exited 0 with no output).
  • Coverage mode, the three previously failing spec files: 11 failed / 19 passed before, 30 passed after (59 captures, 16 scenarios with several page sessions, all session IDs unique).
  • Full npm run test:coverage locally: 622 browser scenarios passed (serial, 9.3 min); aggregate branch coverage 90.17%; gate passed, including the critical modules.
  • Full Playwright suite, plain mode, local 8-CPU machine: 1 worker 7.7 min, 2 workers 3.9 min, 4 workers 2.4 min; 622 passed in every run. In coverage mode with 4 workers one timing-sensitive scenario exceeded its 3 s expectation (it passes 3/3 alone), so the instrumented layer stays serial.
  • Not exercised: live Binance pages and Tampermonkey (no userscript source or behavior change). PR CI timing is observed on this PR.

🤖 Generated with Claude Code

jackhai9 and others added 4 commits October 26, 2026 16:21
The repository pinned Node 24.16.0 only in .nvmrc, so shells that did not run
`nvm use` (including non-interactive agent shells) ran on the machine default.
On older Node, `import.meta.main` is undefined: the exact-file runner and the
coverage CLIs skipped all work and exited 0, which made affected runs look green.

- package.json devEngines makes npm install/ci/run/test/exec refuse any other runtime.
- Repository CLIs assert the .nvmrc version at module load, before their entry guards.
- A contract test keeps devEngines aligned with .nvmrc.
- AGENTS.md and the test policy document per-command runtime selection for agent shells.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ctories

The weekly coverage run has failed since multi-tab specs were added: the fixture
covered only the default page, so reloading a page opened with context.newPage()
or closing the default page mid-test broke collection (11 failing scenarios).

- Coverage now starts on every page opened in the scenario context before it can
  navigate, and writes a page's capture before that page closes.
- The report accepts several CDP sessions per scenario while rejecting duplicates.
- The byte-pinned copies of Binance's native webpack factories are mapped like
  bundled dependencies instead of counting as production source.
- Two continuous/removal save failure paths gain behavior tests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…nges

Pull request runs spent most of their time running 621 Playwright scenarios on
one worker. Spec files use isolated contexts and routed fixtures, so they now run
on half the logical CPUs (two workers on 4-vCPU runners); the instrumented
coverage layer stays serial because precise block coverage slows every page.
Changes limited to .gitignore files no longer select the full test suite.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The scenario waited for a bare consumed status, which the automatic plan also
writes before and between its transfers. On slower runners the test injected
new account activity while the first plan was still transferring, so the
activity observation could not mark the episode active. Wait for the
automatic_completed record and both transfers instead. Under 8-worker stress
the previous wait failed 22 of 40 runs; the new wait passed 40 of 40.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@jackhai9
jackhai9 merged commit f9f2ab8 into main Oct 26, 2026
3 checks passed
@jackhai9
jackhai9 deleted the chore/enforce-node-runtime branch October 26, 2026 12:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant