Skip to content

feat(vitest-pool-workers): add Istanbul coverage support#12590

Closed
TyposBro wants to merge 1 commit intocloudflare:mainfrom
TyposBro:feat/vitest-pool-workers-coverage
Closed

feat(vitest-pool-workers): add Istanbul coverage support#12590
TyposBro wants to merge 1 commit intocloudflare:mainfrom
TyposBro:feat/vitest-pool-workers-coverage

Conversation

@TyposBro
Copy link

@TyposBro TyposBro commented Feb 17, 2026

Summary

Adds Istanbul code coverage support for @cloudflare/vitest-pool-workers. Previously, running tests with coverage.provider: 'istanbul' always reported 0% because coverage data populated inside the workerd runtime never bridged back to the Node.js process.

Changes across 4 files (+163 lines):

  • src/pool/module-fallback.ts — Istanbul instrumentation for user source files loaded through the module fallback service (files not handled by Vite transforms). Uses dynamic import of istanbul-lib-instrument (transitive dep of @vitest/coverage-istanbul).

  • src/worker/lib/cloudflare/test-runner.ts — Collects globalThis.__VITEST_COVERAGE__ after all test files complete and sends it to the pool via the loopback service.

  • src/pool/loopback.ts — Handles /coverage POST route. Merges incoming coverage data (statement, function, and branch counters) into globalThis.__VITEST_COVERAGE__ on the Node.js side where Vitest's coverage provider reads it.

  • src/pool/index.ts — Enables coverage instrumentation in executeMethod() when ctx.config.coverage.enabled is true.

How it works

  1. When coverage is enabled, the pool initializes an Istanbul instrumenter for the module fallback service
  2. Files loaded through module fallback (bypassing Vite transforms) are instrumented with Istanbul
  3. Files loaded through Vite transforms are instrumented by Vitest's own Istanbul plugin
  4. After tests complete in workerd, the test runner reads globalThis.__VITEST_COVERAGE__ and POSTs it to the pool's loopback service
  5. The loopback handler merges coverage data into the Node.js process's global scope
  6. Vitest's Istanbul coverage provider picks up the data and generates reports

Testing

Verified with a real project:

  • 53 test files, 1,342 tests — all passing
  • Coverage reports show real numbers (e.g., 90% for individual files, 17.5% overall)
  • Previously reported 0% across the board

Test plan

  • Verify single test file produces non-zero coverage
  • Verify full test suite (53 files) produces coverage without errors
  • Verify coverage data includes correct statement/branch/function counts
  • Verify no impact on test runs without coverage enabled

Closes #12589


Open with Devin

@TyposBro TyposBro requested a review from a team as a code owner February 17, 2026 20:22
@changeset-bot
Copy link

changeset-bot bot commented Feb 17, 2026

🦋 Changeset detected

Latest commit: 9b91902

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

devin-ai-integration[bot]

This comment was marked as resolved.

@TyposBro TyposBro force-pushed the feat/vitest-pool-workers-coverage branch from 1d9eb45 to 8862a36 Compare February 17, 2026 20:34
devin-ai-integration[bot]

This comment was marked as resolved.

@TyposBro TyposBro force-pushed the feat/vitest-pool-workers-coverage branch from 8862a36 to ad2d307 Compare February 18, 2026 03:59
When using @cloudflare/vitest-pool-workers with Istanbul coverage,
coverage data is populated inside the workerd runtime but never bridges
back to the Node.js process where Vitest's coverage provider reads it.

This change adds:
- Coverage data bridging from workerd to Node.js via the loopback service
- Istanbul instrumentation for files loaded through the module fallback
  service (files not handled by Vite transforms)
- Coverage data merging in the pool to handle parallel test execution

The test runner collects globalThis.__VITEST_COVERAGE__ after tests
complete and sends it to the pool's loopback handler, which merges it
into the Node.js process. The module fallback service also instruments
user source files with Istanbul when coverage is enabled, ensuring files
loaded outside of Vite's transform pipeline are also covered.

Closes #12589
@TyposBro TyposBro force-pushed the feat/vitest-pool-workers-coverage branch from ad2d307 to 9b91902 Compare February 18, 2026 04:05
@TyposBro
Copy link
Author

Addressed latest review feedback in 9b91902:

  1. Provider checkenableCoverageInstrumentation() now only activates when ctx.config.coverage.provider === 'istanbul', preventing V8 coverage from being corrupted by Istanbul transforms.

  2. CJS named-export detection (from previous review) — Original uninstrumented source is preserved and passed to getCjsNamedExports() so the CJS lexer sees clean code.

Both fixes plus the earlier null-check and retry-prevention fixes are included in this commit.

@TyposBro TyposBro closed this by deleting the head repository Feb 20, 2026
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.

feat: Add Istanbul coverage support for @cloudflare/vitest-pool-workers

1 participant

Comments