The pure modules remain independent of chrome.*. Node tests also import the
actual worker and popup controllers with disposable API fixtures, or execute the
shipping injected script and viewer in an isolated VM. These tests check application
control flow; they do not emulate Chrome or establish current YouTube compatibility.
npm run check # syntax, manifest, tests, generated docs and paths
npm test # 114 tests on the built-in Node runner
node --test test/pdf.test.js # one suite
node --test --test-name-pattern=wrapText
npm run build # manifest preflight and zip packaging
npm run docs:generate # refresh committed retrieval artifacts
There are no npm dependencies or install step. CI runs on Node 22, 24 and 26;
.nvmrc selects Node 22. The core job also compiles the optional Python scripts. A separate artwork job
installs the existing optional Pillow 13.0.0 dependency in a fresh CI virtual
environment and runs its synthetic tests. Packaging requires both jobs to pass.
| File | Tests | Behavior checked |
|---|---|---|
test/youtube.test.js |
15 | URL allowlist, JSON variable identity, malformed track metadata, language precedence |
test/transcript.test.js |
16 | JSON/XML parsing, finite timing, literal escaped text, bounded malformed XML scanning, paragraph options |
test/pdf.test.js |
21 | Independent width fixtures, PDF xref offsets and malformed counts, escaping, pagination, geometry and portable filenames |
test/service-worker.test.js |
11 | Actual message handler, body timeout, safe logs, panel language, fallback, tab ownership and cleanup, outbound URL validation |
test/popup.test.js |
15 | Stale responses, failed refetches, Print failures and unique keys, download completion/interruption, preference failures |
test/content-script.test.js |
10 | Blank spans, metadata-shaped captions, hidden/ambiguous rows, invalid timestamps, open retries and delayed expanded panels |
test/viewer.test.js |
6 | Isolated handoff consumption and storage failure reporting |
test/tooling.test.js |
20 | Missing package inputs, preserved archive, index coverage/containment/pruning, manifest versions/icons/entrypoints |
Tests restore global API fixtures after each case. Node isolates test files in separate processes and runs files concurrently by default. Cases that replace globals remain sequential within their file. No real sleeps are used. The XML stress case has an execution timeout to guard against pathological scanning; it is a regression bound, not a benchmark or held-out evaluation.
The Python artwork scripts already depend on Pillow. In a disposable Python 3.11+ environment with Pillow 13.0.0 installed, run:
python -W error::ResourceWarning -m unittest discover -s test -p '*_test.py'
Four tests use synthetic images in temporary directories. They check that wide captures cannot cover copy, incompatible crop dimensions fail before output, and missing-font fallback preserves size and emits a warning. They never rewrite the committed icons or screenshots. The npm/core CI path needs neither Pillow nor an installation step; the separate artwork CI job installs Pillow only in its fresh virtual environment.
Require meaningful assertions for important and changed/risky paths, including error outcomes and safe diagnostic fields. No numeric line-percentage threshold is enforced. Bug regressions must fail against the affected old behavior. The PDF oracle checks byte-accurate object offsets and known glyph widths rather than a character-count approximation. Do not replace behavioral assertions with execution-only tests.
A disposable Chrome 157 profile exercised the final extension under a process-tree egress guard on 2026-11-12. Direct caption fetch with synthetic responses, preference persistence, PDF download, named language picker, unique Print handoff, payload deletion and long-token wrapping passed. Only its owned TCP debugging port was allowed. Native panel navigation timed out under the guard; final panel behavior is covered by the synthetic worker and DOM regressions. An earlier disposable native-panel fixture passed before these guard controls. That historical run was not audited for semantic-dispatch effects. No existing browser profile or installed extension was changed. This validates Chrome API wiring and DOM behavior.
A separate public-video attempt loaded the extension and returned the existing
blocked error. It did not establish live caption compatibility. A full live
manual plan remains required before a store release: human/auto captions, language
selection, new/reused tabs, download, print preview with Unicode, no-caption and
bad-URL errors, and a long video. For panel fallback, verify that Auto reports
unknown language; an explicit language that cannot be downloaded must fail clearly.
Keep fixtures synthetic and local. Import or execute the actual shipping entrypoint. Assert both the visible result and relevant cleanup/logging effects. Browser and live-video results must identify their scope; neither mocks nor saved screenshots prove that current YouTube markup works.
The resumed local tests ran through the batch-owned process-tree egress guard,
with scratch HOME/data/config/cache/model/auth paths and explicit synthetic browser
API/network doubles. This extension has no model/provider dependency. Child CLI
fixtures inherit the guard. No test source invokes Git or creates Git commits.
The fixture roots use transcript-tooling-*, transcript-assets-*, and
transcript-mutation-* under scratch temporary directories. Earlier baseline
runs preceded these controls and do not prove semantic-dispatch isolation.
The follow-up regressions produced 18 assertion failures against the affected pre-fix behavior, plus a missing-font failure. Mutation checks independently reject a removed expanded-panel guard, user-tab cleanup, an emptied pruned index, and removal of the CLI timeout. The timeout mutant required a two-second owned process-group watchdog; its process group was then stopped. The real CLI helper uses a five-second deadline, and its deliberate hanging-child test uses 200ms.
The bounded final delivery repairs produced 22 additional failing assertions on the pre-repair behavior. The final suite has 114 passing Node cases and four Pillow cases. Eight guarded mutants exercise the expanded-panel wait, user-tab preservation, prune survivors, typing before submission, empty Print handoff, nested raw-transport errors, child deadlines and full copy-column overlap. The first proposed nested-error mutant hit an already sanitized exception; the final mutant logs the raw transport error and is correctly rejected. This is regression evidence, not a third blind audit or a live-service compatibility claim.