diff --git a/tools/coverage/coverage-policy.json b/tools/coverage/coverage-policy.json index c2a71be3f..d97aa5185 100644 --- a/tools/coverage/coverage-policy.json +++ b/tools/coverage/coverage-policy.json @@ -12,6 +12,7 @@ "name": "web", "root": "apps/web", "sourceRoot": "apps/web/src", + "jestRootMode": "project", "validationCommand": "pnpm nx test web", "e2eTags": ["@web", "@m3u", "@pwa", "@settings"] }, diff --git a/tools/coverage/e2e-v8-web.mjs b/tools/coverage/e2e-v8-web.mjs index 54c33ef42..4a23c49c4 100644 --- a/tools/coverage/e2e-v8-web.mjs +++ b/tools/coverage/e2e-v8-web.mjs @@ -90,7 +90,8 @@ function summarizeJsEntry(entry) { }; } -const rawFiles = listFiles(path.join(workspaceRoot, 'dist'), (file) => +const rawCoverageRoot = path.join(workspaceRoot, 'apps/web-e2e/test-results'); +const rawFiles = listFiles(rawCoverageRoot, (file) => file.endsWith('.json') && file.includes(`${path.sep}v8-coverage${path.sep}`) ); const entriesByUrl = new Map(); @@ -116,12 +117,22 @@ const outputDir = path.join(workspaceRoot, 'coverage/e2e-v8/web'); mkdirSync(outputDir, { recursive: true }); writeFileSync( path.join(outputDir, 'summary.json'), - `${JSON.stringify({ rawFiles: rawFiles.length, scripts: summaries }, null, 4)}\n` + `${JSON.stringify( + { + rawCoverageRoot: path.relative(workspaceRoot, rawCoverageRoot), + rawFiles: rawFiles.length, + scripts: summaries, + }, + null, + 4 + )}\n` ); writeFileSync( path.join(outputDir, 'summary.md'), `# Web E2E V8 Coverage +Raw coverage root: ${path.relative(workspaceRoot, rawCoverageRoot)} + Raw coverage files: ${rawFiles.length} This experimental report is Chromium/V8 byte coverage from Playwright's browser diff --git a/tools/coverage/run-tier-a-coverage.mjs b/tools/coverage/run-tier-a-coverage.mjs index 21d9f6115..ecf553363 100644 --- a/tools/coverage/run-tier-a-coverage.mjs +++ b/tools/coverage/run-tier-a-coverage.mjs @@ -72,6 +72,17 @@ function collectCoverageArgs(project, jestRootMode) { ]; } +function jestRootModeFor(project) { + const mode = project.jestRootMode ?? 'workspace'; + if (mode !== 'workspace' && mode !== 'project') { + throw new Error( + `Tier A project ${project.name} has unsupported jestRootMode: ${mode}` + ); + } + + return mode; +} + function buildNxArgs(project) { const projectJson = readProjectJson(project); const testTarget = projectJson.targets?.test; @@ -80,16 +91,19 @@ function buildNxArgs(project) { } if (testTarget.executor === '@nx/jest:jest') { - return ['nx', 'run', `${project.name}:test`, '--configuration=ci', '--output-style=static']; + return [ + 'nx', + 'run', + `${project.name}:test`, + '--configuration=ci', + '--codeCoverage', + `--coverageDirectory=${coverageDirFor(project, 'workspace')}`, + '--output-style=static', + ]; } if (testTarget.executor === 'nx:run-commands') { - const command = Array.isArray(testTarget.options?.command) - ? testTarget.options.command.join(' ') - : String(testTarget.options?.command ?? ''); - const jestRootMode = command.includes('apps/web/jest.config.ts') - ? 'project' - : 'workspace'; + const jestRootMode = jestRootModeFor(project); return [ 'nx',