Skip to content

Commit c52026c

Browse files
authored
Merge pull request #1342 from Open-Source-Legal/claude/switch-coverage-v8-istanbul-3OENn
Switch Vitest unit coverage provider from v8 to Istanbul
2 parents a5173f5 + fc794d8 commit c52026c

4 files changed

Lines changed: 17 additions & 38 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Changed
11+
12+
- **Frontend Vitest unit coverage provider switched from V8 to Istanbul** (`frontend/vite.config.ts:210-230`, `frontend/package.json:154`, `frontend/yarn.lock`): The merged `frontend` Codecov flag was landing at ~44% even though `frontend-component` alone was at ~61% on the same code — impossible for a union-aggregated metric unless the three per-suite uploads were measuring on different yardsticks. Root cause: Vitest's `@vitest/coverage-v8` provider emits ~183 `DA:` records per source file (~86k across ~480 files) because V8's native coverage API reports hits for nearly every executable line — imports, declarations, block-closing `}`, etc. — as needed for engine profiling and DevTools. `vite-plugin-istanbul` (used by Playwright CT and E2E suites) emits ~61 `DA:` per file (~27k total) because it only instruments statements. Same code, ~3× denominator mismatch. When Codecov unions multiple uploads under one flag it keeps V8's larger line-number set; Istanbul hits from CT/E2E land on a subset of those line numbers and can never close the gap. Swapped the unit-coverage provider to Istanbul so all three suites report on the same universe. Swapped the `@vitest/coverage-v8` devDep for `@vitest/coverage-istanbul` at the same `^3.1.2` version to match the `vitest` major.minor, changed `coverage.provider` to `"istanbul"` in the Vitest config, regenerated `yarn.lock`, and updated the `all: true` rationale comment to stop singling out V8. The per-suite `flags:` tagging in `frontend.yml` / `frontend-e2e.yml` is unchanged — server-side aggregation still handles the merge. Verified locally: the new unit lcov reports ~451 `SF:` and ~24k `DA:` (previously ~86k), matching the CT/E2E scale. Trade-off: unit-test runtime under coverage grows somewhat (Istanbul transforms source pre-execution), likely 10–30s on this suite. `tsc --noEmit` clean.
13+
1014
### Fixed
1115

1216
- **Frontend coverage badge stuck on "unknown"** (`README.md:12`, `.github/workflows/codecov-notify.yml`, `.github/workflows/frontend.yml`, `.github/workflows/frontend-e2e.yml`, `frontend/package.json`, `frontend/yarn.lock`): PR #1322 pointed the README badge at a new merged `frontend` flag fed by a cross-workflow `lcov-result-merger@5` step inside `codecov-notify.yml`. Every `frontend-merged-coverage` upload since has landed at Codecov with `state: error` / `totals: null`, so the badge rendered "unknown" even though `frontend-unit` (31%), `frontend-component` (61%), and `frontend-e2e` (24%) were all processing correctly. Two defects in the merged lcov confirmed by local repro of the CI merge step: (1) `lcov-result-merger@5` emits a stripped lcov containing only `SF:`, `DA:`, `BRDA:`, `end_of_record` — it drops `TN:`, `FN`, `FNDA`, `FNF`, `FNH`, `LF`, `LH`, `BRF`, `BRH`, so line-summary fields required by Codecov's parser are absent; (2) Vitest v8 emits `src/...` (relative to `frontend/`) while `vite-plugin-istanbul` + `nyc report` emit `/home/runner/work/OpenContracts/OpenContracts/frontend/src/...` (absolute), and the merger keys on the literal path string so the same file appears as two records with conflicting hit counts. `codecov-notify.yml` also ran without `actions/checkout`, which Codecov's action docs explicitly recommend against. Fix: stop merging client-side and let Codecov aggregate server-side, since that is what flags are for. Each per-suite upload now declares two flags — `frontend-unit,frontend`, `frontend-component,frontend`, `frontend-e2e,frontend` — so the `frontend` flag total is the union of the three uploads computed by Codecov. `codecov-notify.yml` is reduced to its original gate-and-notify role (no artifact downloads, no `lcov-result-merger`, no merged upload). Deleted the `frontend-{unit,ct,e2e}-lcov` artifact publishes in `frontend.yml` / `frontend-e2e.yml`, removed the `lcov-result-merger@^5.0.1` devDep and the `coverage:merge` script from `frontend/package.json`, and pruned the orphaned entries from `frontend/yarn.lock`. README badge URL unchanged (`flag=frontend`).

frontend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@
151151
"@types/lodash.uniqueid": "^4.0.9",
152152
"@types/react-helmet-async": "^1.0.3",
153153
"@types/uuid": "^8.3.4",
154-
"@vitest/coverage-v8": "^3.1.2",
154+
"@vitest/coverage-istanbul": "^3.1.2",
155155
"fake-indexeddb": "^6.2.2",
156156
"husky": "^8.0.1",
157157
"jsdom": "^26.1.0",

frontend/vite.config.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ export default defineConfig(async () => {
208208
),
209209
},
210210
coverage: {
211-
provider: "v8",
211+
provider: "istanbul",
212212
reporter: ["text", "json", "html", "lcov"],
213213
reportsDirectory: "./coverage/unit",
214214
// Adjust coverage include/exclude if needed, based on the new test patterns
@@ -220,11 +220,11 @@ export default defineConfig(async () => {
220220
// Add any other files/patterns to exclude from coverage
221221
],
222222
// Count every file matched by `include`, not just files imported by a
223-
// test. Without this, v8 silently drops untested files from the lcov,
224-
// which inflates the `frontend-unit` ratio (small denominator) and
225-
// misaligns with the Istanbul-based component/e2e lcovs (which do
226-
// enumerate all source files). Aligning the two universes is required
227-
// for the merged `frontend` lcov to be meaningful.
223+
// test. Without this, the provider silently drops untested files from
224+
// the lcov, shrinking the `frontend-unit` denominator and misaligning
225+
// with the Istanbul-instrumented component/e2e lcovs (which enumerate
226+
// all source files). Aligning the per-file universe is required for
227+
// the merged `frontend` lcov to be meaningful.
228228
all: true,
229229
},
230230
},

frontend/yarn.lock

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,6 @@
77
resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.4.4.tgz#2856c55443d3d461693f32d2b96fb6ea92e1ffa9"
88
integrity sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==
99

10-
"@ampproject/remapping@^2.3.0":
11-
version "2.3.0"
12-
resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4"
13-
integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==
14-
dependencies:
15-
"@jridgewell/gen-mapping" "^0.3.5"
16-
"@jridgewell/trace-mapping" "^0.3.24"
17-
1810
"@apollo/client@^3.13.8":
1911
version "3.14.0"
2012
resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.14.0.tgz#eda34b85ee03c6c0828ba21782419c8699feaf0b"
@@ -366,11 +358,6 @@
366358
"@babel/helper-string-parser" "^7.27.1"
367359
"@babel/helper-validator-identifier" "^7.28.5"
368360

369-
"@bcoe/v8-coverage@^1.0.2":
370-
version "1.0.2"
371-
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz#bbe12dca5b4ef983a0d0af4b07b9bc90ea0ababa"
372-
integrity sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==
373-
374361
"@csstools/color-helpers@^5.1.0":
375362
version "5.1.0"
376363
resolved "https://registry.yarnpkg.com/@csstools/color-helpers/-/color-helpers-5.1.0.tgz#106c54c808cabfd1ab4c602d8505ee584c2996ef"
@@ -1264,7 +1251,7 @@
12641251
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba"
12651252
integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==
12661253

1267-
"@jridgewell/trace-mapping@^0.3.23", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.28", "@jridgewell/trace-mapping@^0.3.31":
1254+
"@jridgewell/trace-mapping@^0.3.23", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.28":
12681255
version "0.3.31"
12691256
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz#db15d6781c931f3a251a3dac39501c98a6082fd0"
12701257
integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==
@@ -2855,22 +2842,19 @@
28552842
"@types/babel__core" "^7.20.5"
28562843
react-refresh "^0.17.0"
28572844

2858-
"@vitest/coverage-v8@^3.1.2":
2845+
"@vitest/coverage-istanbul@^3.1.2":
28592846
version "3.2.4"
2860-
resolved "https://registry.yarnpkg.com/@vitest/coverage-v8/-/coverage-v8-3.2.4.tgz#a2d8d040288c1956a1c7d0a0e2cdcfc7a3319f13"
2861-
integrity sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==
2847+
resolved "https://registry.yarnpkg.com/@vitest/coverage-istanbul/-/coverage-istanbul-3.2.4.tgz#a622802975935a2357d890b367fffd0dfd7a5a99"
2848+
integrity sha512-IDlpuFJiWU9rhcKLkpzj8mFu/lpe64gVgnV15ZOrYx1iFzxxrxCzbExiUEKtwwXRvEiEMUS6iZeYgnMxgbqbxQ==
28622849
dependencies:
2863-
"@ampproject/remapping" "^2.3.0"
2864-
"@bcoe/v8-coverage" "^1.0.2"
2865-
ast-v8-to-istanbul "^0.3.3"
2850+
"@istanbuljs/schema" "^0.1.3"
28662851
debug "^4.4.1"
28672852
istanbul-lib-coverage "^3.2.2"
2853+
istanbul-lib-instrument "^6.0.3"
28682854
istanbul-lib-report "^3.0.1"
28692855
istanbul-lib-source-maps "^5.0.6"
28702856
istanbul-reports "^3.1.7"
2871-
magic-string "^0.30.17"
28722857
magicast "^0.3.5"
2873-
std-env "^3.9.0"
28742858
test-exclude "^7.0.1"
28752859
tinyrainbow "^2.0.0"
28762860

@@ -3122,15 +3106,6 @@ assertion-error@^2.0.1:
31223106
resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-2.0.1.tgz#f641a196b335690b1070bf00b6e7593fec190bf7"
31233107
integrity sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==
31243108

3125-
ast-v8-to-istanbul@^0.3.3:
3126-
version "0.3.8"
3127-
resolved "https://registry.yarnpkg.com/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.8.tgz#0a3faf070dc780dcebdf9d48af78dbd174a497a9"
3128-
integrity sha512-szgSZqUxI5T8mLKvS7WTjF9is+MVbOeLADU73IseOcrqhxr/VAvy6wfoVE39KnKzA7JRhjF5eUagNlHwvZPlKQ==
3129-
dependencies:
3130-
"@jridgewell/trace-mapping" "^0.3.31"
3131-
estree-walker "^3.0.3"
3132-
js-tokens "^9.0.1"
3133-
31343109
astral-regex@^2.0.0:
31353110
version "2.0.0"
31363111
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31"

0 commit comments

Comments
 (0)