@rpcbase/test 0.333.0 → 0.335.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/clearDatabase.js +4 -1
- package/dist/clearDatabase.js.map +1 -1
- package/dist/cli.js +93 -57
- package/dist/cli.js.map +1 -1
- package/dist/coverage/collect.js +3 -1
- package/dist/coverage/collect.js.map +1 -1
- package/dist/coverage/config-loader.js +20 -36
- package/dist/coverage/config-loader.js.map +1 -1
- package/dist/coverage/config.js +19 -8
- package/dist/coverage/config.js.map +1 -1
- package/dist/coverage/console-text-report.js +23 -13
- package/dist/coverage/console-text-report.js.map +1 -1
- package/dist/coverage/files.js +25 -28
- package/dist/coverage/files.js.map +1 -1
- package/dist/coverage/fixtures.js +3 -1
- package/dist/coverage/fixtures.js.map +1 -1
- package/dist/coverage/global-setup.js +4 -1
- package/dist/coverage/global-setup.js.map +1 -1
- package/dist/coverage/index.js +3 -1
- package/dist/coverage/index.js.map +1 -1
- package/dist/coverage/report.js +55 -62
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/reporter.js +4 -1
- package/dist/coverage/reporter.js.map +1 -1
- package/dist/coverage/v8-tracker.js +18 -14
- package/dist/coverage/v8-tracker.js.map +1 -1
- package/dist/index.js +10 -3
- package/dist/index.js.map +1 -1
- package/dist/serverCoverage.js +6 -2
- package/dist/serverCoverage.js.map +1 -1
- package/dist/vitest.config.js +14 -14
- package/dist/vitest.config.js.map +1 -1
- package/package.json +1 -1
package/dist/clearDatabase.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import mongoose from "mongoose";
|
|
2
2
|
async function clearDatabase(dbName) {
|
|
3
|
-
const {
|
|
3
|
+
const {
|
|
4
|
+
DB_PORT,
|
|
5
|
+
APP_NAME
|
|
6
|
+
} = process.env;
|
|
4
7
|
const connectionString = `mongodb://localhost:${DB_PORT}/${APP_NAME}-${dbName}`;
|
|
5
8
|
const connection = await mongoose.createConnection(connectionString).asPromise();
|
|
6
9
|
await connection.dropDatabase();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clearDatabase.js","sources":["../src/clearDatabase.ts"],"sourcesContent":["import mongoose from \"mongoose\"\n\n\nexport async function clearDatabase(dbName: string): Promise<void> {\n const { DB_PORT, APP_NAME } = process.env\n\n const connectionString = `mongodb://localhost:${DB_PORT}/${APP_NAME}-${dbName}`\n\n // console.log(\"will clear DB:\", connectionString)\n\n const connection = await mongoose\n .createConnection(connectionString)\n .asPromise()\n\n // Drop the database\n await connection.dropDatabase()\n\n await connection.close()\n}\n"],"names":[],"mappings":";AAGA,
|
|
1
|
+
{"version":3,"file":"clearDatabase.js","sources":["../src/clearDatabase.ts"],"sourcesContent":["import mongoose from \"mongoose\"\n\n\nexport async function clearDatabase(dbName: string): Promise<void> {\n const { DB_PORT, APP_NAME } = process.env\n\n const connectionString = `mongodb://localhost:${DB_PORT}/${APP_NAME}-${dbName}`\n\n // console.log(\"will clear DB:\", connectionString)\n\n const connection = await mongoose\n .createConnection(connectionString)\n .asPromise()\n\n // Drop the database\n await connection.dropDatabase()\n\n await connection.close()\n}\n"],"names":["clearDatabase","dbName","DB_PORT","APP_NAME","process","env","connectionString","connection","mongoose","createConnection","asPromise","dropDatabase","close"],"mappings":";AAGA,eAAsBA,cAAcC,QAA+B;AACjE,QAAM;AAAA,IAAEC;AAAAA,IAASC;AAAAA,EAAAA,IAAaC,QAAQC;AAEtC,QAAMC,mBAAmB,uBAAuBJ,OAAO,IAAIC,QAAQ,IAAIF,MAAM;AAI7E,QAAMM,aAAa,MAAMC,SACtBC,iBAAiBH,gBAAgB,EACjCI,UAAAA;AAGH,QAAMH,WAAWI,aAAAA;AAEjB,QAAMJ,WAAWK,MAAAA;AACnB;"}
|
package/dist/cli.js
CHANGED
|
@@ -51,7 +51,9 @@ async function runTests() {
|
|
|
51
51
|
}
|
|
52
52
|
let testError = null;
|
|
53
53
|
try {
|
|
54
|
-
await runVitest(vitestCoverage, combinedCoverage?.config ?? null, filteredArgs, {
|
|
54
|
+
await runVitest(vitestCoverage, combinedCoverage?.config ?? null, filteredArgs, {
|
|
55
|
+
disableCoverage: auto
|
|
56
|
+
});
|
|
55
57
|
console.log("\nRunning Playwright Tests...");
|
|
56
58
|
const playwrightArgs = auto ? await resolveAutoPlaywrightArgs({
|
|
57
59
|
userArgs: filteredArgs,
|
|
@@ -60,7 +62,9 @@ async function runTests() {
|
|
|
60
62
|
showMapping
|
|
61
63
|
}) : filteredArgs;
|
|
62
64
|
if (playwrightArgs) {
|
|
63
|
-
await runPlaywright(playwrightArgs, {
|
|
65
|
+
await runPlaywright(playwrightArgs, {
|
|
66
|
+
disableCoverage: auto
|
|
67
|
+
});
|
|
64
68
|
}
|
|
65
69
|
} catch (error) {
|
|
66
70
|
testError = error;
|
|
@@ -86,7 +90,9 @@ runTests().then(() => process.exit(0)).catch((error) => {
|
|
|
86
90
|
}
|
|
87
91
|
process.exit(1);
|
|
88
92
|
});
|
|
89
|
-
async function runVitest(coverage, combinedConfig, userArgs, {
|
|
93
|
+
async function runVitest(coverage, combinedConfig, userArgs, {
|
|
94
|
+
disableCoverage = false
|
|
95
|
+
} = {}) {
|
|
90
96
|
const vitestArgs = ["run", "--passWithNoTests"];
|
|
91
97
|
const vitestConfig = resolveVitestConfig();
|
|
92
98
|
const hasCustomConfig = userArgs.some((arg) => {
|
|
@@ -106,7 +112,9 @@ async function runVitest(coverage, combinedConfig, userArgs, { disableCoverage =
|
|
|
106
112
|
}
|
|
107
113
|
if (coverage?.enabled && !disableCoverage) {
|
|
108
114
|
const nodeCoverageDir = resolveNodeCoverageDir(combinedConfig ?? coverage.config);
|
|
109
|
-
await fs.mkdir(nodeCoverageDir, {
|
|
115
|
+
await fs.mkdir(nodeCoverageDir, {
|
|
116
|
+
recursive: true
|
|
117
|
+
});
|
|
110
118
|
env.NODE_V8_COVERAGE = nodeCoverageDir;
|
|
111
119
|
}
|
|
112
120
|
await spawnWithLogs({
|
|
@@ -138,8 +146,13 @@ async function buildSpecsMapFromCoverage({
|
|
|
138
146
|
throw new Error("[specs-map] No spec files found under spec/**/*.spec{,.desktop,.mobile}.ts");
|
|
139
147
|
}
|
|
140
148
|
const filesMapDir = path.join(config.testResultsRoot, "files-map");
|
|
141
|
-
await fs.rm(filesMapDir, {
|
|
142
|
-
|
|
149
|
+
await fs.rm(filesMapDir, {
|
|
150
|
+
recursive: true,
|
|
151
|
+
force: true
|
|
152
|
+
});
|
|
153
|
+
await fs.mkdir(filesMapDir, {
|
|
154
|
+
recursive: true
|
|
155
|
+
});
|
|
143
156
|
for (const specSourceFile of specSourceFiles) {
|
|
144
157
|
const specProjectPath = path.relative(config.rootDir, specSourceFile);
|
|
145
158
|
const specWorkspacePath = toPosixPath(path.relative(workspaceRoot, specSourceFile));
|
|
@@ -160,20 +173,14 @@ async function buildSpecsMapFromCoverage({
|
|
|
160
173
|
const coveredFiles = await collectCoveredFiles(config);
|
|
161
174
|
const impactedFiles = coveredFiles.map((filePath) => toPosixPath(path.relative(workspaceRoot, filePath))).filter((relativePath) => relativePath && !relativePath.startsWith("../") && relativePath !== "..").sort();
|
|
162
175
|
const outputFile = path.join(filesMapDir, `${specProjectPath}.json`);
|
|
163
|
-
await fs.mkdir(path.dirname(outputFile), {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
},
|
|
172
|
-
null,
|
|
173
|
-
2
|
|
174
|
-
),
|
|
175
|
-
"utf8"
|
|
176
|
-
);
|
|
176
|
+
await fs.mkdir(path.dirname(outputFile), {
|
|
177
|
+
recursive: true
|
|
178
|
+
});
|
|
179
|
+
await fs.writeFile(outputFile, JSON.stringify({
|
|
180
|
+
spec: specWorkspacePath,
|
|
181
|
+
files: impactedFiles,
|
|
182
|
+
failed
|
|
183
|
+
}, null, 2), "utf8");
|
|
177
184
|
if (failed) {
|
|
178
185
|
throw error;
|
|
179
186
|
}
|
|
@@ -198,9 +205,7 @@ async function resolveAutoPlaywrightArgs({
|
|
|
198
205
|
}
|
|
199
206
|
const workspaceRoot = findWorkspaceRoot(process.cwd());
|
|
200
207
|
const gitChanges = getGitChanges(workspaceRoot);
|
|
201
|
-
const renameMap = new Map(
|
|
202
|
-
gitChanges.filter((change) => change.kind === "rename").map((change) => [change.oldPath, change.newPath])
|
|
203
|
-
);
|
|
208
|
+
const renameMap = new Map(gitChanges.filter((change) => change.kind === "rename").map((change) => [change.oldPath, change.newPath]));
|
|
204
209
|
const specRootAbs = path.join(config.rootDir, "spec");
|
|
205
210
|
const matchesCollectCoverageFrom = createCollectCoverageMatcher(config.collectCoverageFrom, config.rootDir);
|
|
206
211
|
const directSpecChanges = /* @__PURE__ */ new Set();
|
|
@@ -246,7 +251,10 @@ async function resolveAutoPlaywrightArgs({
|
|
|
246
251
|
continue;
|
|
247
252
|
}
|
|
248
253
|
const files = Array.isArray(json?.files) ? json.files.filter((entry) => typeof entry === "string") : [];
|
|
249
|
-
parsedMaps.push({
|
|
254
|
+
parsedMaps.push({
|
|
255
|
+
spec,
|
|
256
|
+
files
|
|
257
|
+
});
|
|
250
258
|
}
|
|
251
259
|
if (parsedMaps.length === 0) {
|
|
252
260
|
console.warn("[auto] Specs map is empty; running full Playwright suite.");
|
|
@@ -353,7 +361,11 @@ async function resolveAutoPlaywrightArgs({
|
|
|
353
361
|
}
|
|
354
362
|
async function findFilesMapJson(filesMapDir) {
|
|
355
363
|
const patterns = ["spec/**/*.spec{,.desktop,.mobile}.ts.json", "spec/**/*.spec{,.desktop,.mobile}.tsx.json"];
|
|
356
|
-
const matches = await fg(patterns, {
|
|
364
|
+
const matches = await fg(patterns, {
|
|
365
|
+
cwd: filesMapDir,
|
|
366
|
+
absolute: true,
|
|
367
|
+
onlyFiles: true
|
|
368
|
+
}).catch(() => []);
|
|
357
369
|
return matches.sort();
|
|
358
370
|
}
|
|
359
371
|
function getGitChanges(workspaceRoot) {
|
|
@@ -421,7 +433,11 @@ function isSpecSourceFile(absolutePath, specRootAbsolute) {
|
|
|
421
433
|
}
|
|
422
434
|
async function findSpecSourceFiles(projectRoot) {
|
|
423
435
|
const patterns = ["spec/**/*.spec{,.desktop,.mobile}.ts", "spec/**/*.spec{,.desktop,.mobile}.tsx"];
|
|
424
|
-
const matches = await fg(patterns, {
|
|
436
|
+
const matches = await fg(patterns, {
|
|
437
|
+
cwd: projectRoot,
|
|
438
|
+
absolute: true,
|
|
439
|
+
onlyFiles: true
|
|
440
|
+
});
|
|
425
441
|
return matches.sort();
|
|
426
442
|
}
|
|
427
443
|
function resolvePlaywrightSpecFile(specProjectPath) {
|
|
@@ -466,10 +482,10 @@ function findWorkspaceRoot(projectRoot) {
|
|
|
466
482
|
dir = parent;
|
|
467
483
|
}
|
|
468
484
|
}
|
|
469
|
-
function runPlaywright(userArgs, {
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
) ? path.join(process.cwd(), "playwright.config.ts") : path.join(moduleDir, "playwright.config.ts");
|
|
485
|
+
function runPlaywright(userArgs, {
|
|
486
|
+
disableCoverage = false
|
|
487
|
+
} = {}) {
|
|
488
|
+
const configPath = fs$1.existsSync(path.join(process.cwd(), "playwright.config.ts")) ? path.join(process.cwd(), "playwright.config.ts") : path.join(moduleDir, "playwright.config.ts");
|
|
473
489
|
const hasCustomConfig = userArgs.some((arg) => {
|
|
474
490
|
if (arg === "--config" || arg === "-c") {
|
|
475
491
|
return true;
|
|
@@ -521,7 +537,9 @@ function resolveCliPath() {
|
|
|
521
537
|
const searchRoots = [process.cwd(), moduleDir];
|
|
522
538
|
for (const base of searchRoots) {
|
|
523
539
|
try {
|
|
524
|
-
const pkgPath = require$1.resolve("@playwright/test/package.json", {
|
|
540
|
+
const pkgPath = require$1.resolve("@playwright/test/package.json", {
|
|
541
|
+
paths: [base]
|
|
542
|
+
});
|
|
525
543
|
const cliPath = path.join(path.dirname(pkgPath), "cli.js");
|
|
526
544
|
if (fs$1.existsSync(cliPath)) {
|
|
527
545
|
return cliPath;
|
|
@@ -535,7 +553,9 @@ function resolveVitestLauncher() {
|
|
|
535
553
|
const searchRoots = [process.cwd(), moduleDir];
|
|
536
554
|
for (const base of searchRoots) {
|
|
537
555
|
try {
|
|
538
|
-
const pkgPath = require$1.resolve("vitest/package.json", {
|
|
556
|
+
const pkgPath = require$1.resolve("vitest/package.json", {
|
|
557
|
+
paths: [base]
|
|
558
|
+
});
|
|
539
559
|
const pkgDir = path.dirname(pkgPath);
|
|
540
560
|
const pkgJson = JSON.parse(fs$1.readFileSync(pkgPath, "utf8"));
|
|
541
561
|
const binPath = typeof pkgJson.bin === "string" ? pkgJson.bin : pkgJson.bin?.vitest;
|
|
@@ -569,11 +589,7 @@ function resolveVitestConfig() {
|
|
|
569
589
|
return fs$1.existsSync(bundledConfig) ? bundledConfig : null;
|
|
570
590
|
}
|
|
571
591
|
function findVitestConfig(baseDir) {
|
|
572
|
-
const candidates = [
|
|
573
|
-
"vitest.config.ts",
|
|
574
|
-
"vitest.config.js",
|
|
575
|
-
"vitest.config.mjs"
|
|
576
|
-
];
|
|
592
|
+
const candidates = ["vitest.config.ts", "vitest.config.js", "vitest.config.mjs"];
|
|
577
593
|
for (const file of candidates) {
|
|
578
594
|
const fullPath = path.join(baseDir, file);
|
|
579
595
|
if (fs$1.existsSync(fullPath)) {
|
|
@@ -597,7 +613,9 @@ async function loadVitestCoverageConfig() {
|
|
|
597
613
|
};
|
|
598
614
|
}
|
|
599
615
|
async function loadPlaywrightCoverageConfig() {
|
|
600
|
-
const options = await loadCoverageOptions({
|
|
616
|
+
const options = await loadCoverageOptions({
|
|
617
|
+
optional: true
|
|
618
|
+
});
|
|
601
619
|
if (!options) {
|
|
602
620
|
return null;
|
|
603
621
|
}
|
|
@@ -618,14 +636,23 @@ function resolveCombinedCoverage(playwrightCoverage, vitestCoverage) {
|
|
|
618
636
|
}
|
|
619
637
|
async function cleanCoverageArtifacts(config) {
|
|
620
638
|
await removeCoverageFiles(config);
|
|
621
|
-
await fs.rm(config.coverageReportDir, {
|
|
622
|
-
|
|
639
|
+
await fs.rm(config.coverageReportDir, {
|
|
640
|
+
recursive: true,
|
|
641
|
+
force: true
|
|
642
|
+
});
|
|
643
|
+
await fs.rm(resolveNodeCoverageDir(config), {
|
|
644
|
+
recursive: true,
|
|
645
|
+
force: true
|
|
646
|
+
});
|
|
623
647
|
}
|
|
624
648
|
function resolveNodeCoverageDir(config) {
|
|
625
649
|
return path.join(config.rootDir, "build", "vitest", "test-results", "node-coverage");
|
|
626
650
|
}
|
|
627
651
|
async function convertNodeCoverage(coverage) {
|
|
628
|
-
const {
|
|
652
|
+
const {
|
|
653
|
+
config,
|
|
654
|
+
nodeCoverageDir
|
|
655
|
+
} = coverage;
|
|
629
656
|
const entries = await fs.readdir(nodeCoverageDir).catch(() => []);
|
|
630
657
|
const scripts = [];
|
|
631
658
|
const scriptRoots = resolveCollectCoverageRoots(config.collectCoverageFrom, config.rootDir);
|
|
@@ -661,9 +688,14 @@ async function convertNodeCoverage(coverage) {
|
|
|
661
688
|
return;
|
|
662
689
|
}
|
|
663
690
|
const outDir = path.join(config.rootDir, "build", "vitest", "coverage");
|
|
664
|
-
await fs.mkdir(outDir, {
|
|
691
|
+
await fs.mkdir(outDir, {
|
|
692
|
+
recursive: true
|
|
693
|
+
});
|
|
665
694
|
const outputFile = path.join(outDir, config.coverageFileName);
|
|
666
|
-
await fs.writeFile(outputFile, JSON.stringify({
|
|
695
|
+
await fs.writeFile(outputFile, JSON.stringify({
|
|
696
|
+
testId: "vitest",
|
|
697
|
+
scripts
|
|
698
|
+
}, null, 2), "utf8");
|
|
667
699
|
}
|
|
668
700
|
async function finalizeCoverage(config) {
|
|
669
701
|
try {
|
|
@@ -720,14 +752,10 @@ function spawnWithLogs({
|
|
|
720
752
|
return new Promise((resolve, reject) => {
|
|
721
753
|
const stdoutBuffer = [];
|
|
722
754
|
const stderrBuffer = [];
|
|
723
|
-
const child = spawn(
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
shell: false,
|
|
728
|
-
env
|
|
729
|
-
}
|
|
730
|
-
);
|
|
755
|
+
const child = spawn(launcher.command, [...launcher.args || [], ...args], {
|
|
756
|
+
shell: false,
|
|
757
|
+
env
|
|
758
|
+
});
|
|
731
759
|
child.stdout?.on("data", (data) => {
|
|
732
760
|
if (!isAider) {
|
|
733
761
|
process.stdout.write(data);
|
|
@@ -774,12 +802,20 @@ function withRegisterShim(baseEnv) {
|
|
|
774
802
|
}
|
|
775
803
|
function ensureJsxRuntimeShim(projectRoot) {
|
|
776
804
|
const shimDir = path.join(projectRoot, "node_modules", "playwright");
|
|
777
|
-
fs$1.mkdirSync(shimDir, {
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
805
|
+
fs$1.mkdirSync(shimDir, {
|
|
806
|
+
recursive: true
|
|
807
|
+
});
|
|
808
|
+
const shims = [{
|
|
809
|
+
file: "jsx-runtime.js",
|
|
810
|
+
target: "react/jsx-runtime"
|
|
811
|
+
}, {
|
|
812
|
+
file: "jsx-dev-runtime.js",
|
|
813
|
+
target: "react/jsx-dev-runtime"
|
|
814
|
+
}];
|
|
815
|
+
for (const {
|
|
816
|
+
file,
|
|
817
|
+
target
|
|
818
|
+
} of shims) {
|
|
783
819
|
const filePath = path.join(shimDir, file);
|
|
784
820
|
if (!fs$1.existsSync(filePath)) {
|
|
785
821
|
const content = `export * from "${target}";
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sources":["../src/cli.ts"],"sourcesContent":["import { spawn, spawnSync } from \"node:child_process\"\nimport fs from \"node:fs\"\nimport fsPromises from \"node:fs/promises\"\nimport path from \"node:path\"\nimport { createRequire } from \"node:module\"\nimport { fileURLToPath } from \"node:url\"\n\nimport fg from \"fast-glob\"\n\nimport { createCoverageConfig } from \"./coverage/config\"\nimport { createCollectCoverageMatcher, isInsideAnyRoot, resolveCollectCoverageRoots } from \"./coverage/collect\"\nimport { loadCoverageOptions } from \"./coverage/config-loader\"\nimport { removeCoverageFiles } from \"./coverage/files\"\nimport { collectCoveredFiles, CoverageThresholdError, generateCoverageReport } from \"./coverage/report\"\nimport type { CoverageConfig } from \"./coverage/types\"\n\n\nconst require = createRequire(import.meta.url)\nconst moduleDir = path.dirname(fileURLToPath(import.meta.url))\n\nconst shouldForceTty =\n !process.stdout.isTTY\n && process.env.FORCE_COLOR === \"true\"\n\nif (shouldForceTty) {\n require(\"./register-tty.cjs\")\n}\n\n\nconst VITEST_COVERAGE_CANDIDATES = [\"src/coverage.json\"]\n\nconst COMBINED_COVERAGE_ENV_VAR = \"RB_TEST_COMBINED_COVERAGE\"\n\nconst isAider = process.env.IS_AIDER === \"yes\"\n\nif (process.env.IS_AIDER !== undefined && process.env.IS_AIDER !== \"yes\") {\n console.warn(\"Warning: IS_AIDER is set to a value other than 'yes'.\")\n}\n\ntype CoverageState = { config: CoverageConfig; enabled: boolean } | null\n\nasync function runTests(): Promise<void> {\n const userArgs = process.argv.slice(2)\n const buildSpecsMap = userArgs.includes(\"--build-specs-map\")\n const auto = userArgs.includes(\"--auto\")\n const showMapping = userArgs.includes(\"--show-mapping\")\n const filteredArgs = userArgs.filter((arg) => arg !== \"--build-specs-map\" && arg !== \"--auto\" && arg !== \"--show-mapping\")\n\n if (buildSpecsMap && auto) {\n throw new Error(\"[rb-test] --auto cannot be combined with --build-specs-map\")\n }\n\n if (showMapping && !auto) {\n throw new Error(\"[rb-test] --show-mapping requires --auto\")\n }\n\n const playwrightCoverage = await loadPlaywrightCoverageConfig()\n const vitestCoverage = await loadVitestCoverageConfig()\n const combinedCoverage = resolveCombinedCoverage(playwrightCoverage, vitestCoverage)\n\n if (buildSpecsMap) {\n await buildSpecsMapFromCoverage({\n userArgs: filteredArgs,\n playwrightCoverage,\n vitestCoverage,\n combinedCoverage,\n })\n return\n }\n\n const shouldGenerateCoverageReport = combinedCoverage?.enabled && !auto\n\n if (shouldGenerateCoverageReport) {\n await cleanCoverageArtifacts(combinedCoverage.config)\n }\n\n let testError = null\n\n try {\n await runVitest(vitestCoverage, combinedCoverage?.config ?? null, filteredArgs, { disableCoverage: auto })\n console.log(\"\\nRunning Playwright Tests...\")\n const playwrightArgs = auto\n ? await resolveAutoPlaywrightArgs({\n userArgs: filteredArgs,\n playwrightCoverage,\n vitestCoverage,\n showMapping,\n })\n : filteredArgs\n if (playwrightArgs) {\n await runPlaywright(playwrightArgs, { disableCoverage: auto })\n }\n } catch (error: any) {\n testError = error\n }\n\n if (shouldGenerateCoverageReport) {\n if (testError) {\n console.warn(\"[coverage] skipping report generation because tests failed\")\n } else {\n try {\n await finalizeCoverage(combinedCoverage.config)\n } catch (error) {\n testError = error\n }\n }\n }\n\n if (testError) {\n throw testError\n }\n}\n\nrunTests()\n .then(() => process.exit(0))\n .catch((error) => {\n if (!(error instanceof CoverageThresholdError)) {\n console.error(error?.stack ?? String(error))\n }\n process.exit(1)\n })\n\nasync function runVitest(\n coverage: CoverageState,\n combinedConfig: CoverageConfig | null,\n userArgs: string[],\n { disableCoverage = false }: { disableCoverage?: boolean } = {},\n): Promise<void> {\n const vitestArgs = [\"run\", \"--passWithNoTests\"]\n const vitestConfig = resolveVitestConfig()\n\n const hasCustomConfig = userArgs.some((arg) => {\n if (arg === \"--config\" || arg === \"-c\") {\n return true\n }\n return arg.startsWith(\"--config=\")\n })\n\n if (vitestConfig && !hasCustomConfig) {\n vitestArgs.push(\"--config\", vitestConfig)\n }\n vitestArgs.push(...userArgs)\n\n const launcher = resolveVitestLauncher()\n const env = withRegisterShim(process.env)\n\n if (disableCoverage) {\n env.RB_DISABLE_COVERAGE = \"1\"\n }\n\n if (coverage?.enabled && !disableCoverage) {\n // Vitest runs in a Node.js process, so we use Node's built-in V8 coverage output (NODE_V8_COVERAGE) here.\n // Playwright coverage is collected separately via CDP in Chromium; server coverage is handled via /api/dev/coverage start/stop.\n const nodeCoverageDir = resolveNodeCoverageDir(combinedConfig ?? coverage.config)\n await fsPromises.mkdir(nodeCoverageDir, { recursive: true })\n env.NODE_V8_COVERAGE = nodeCoverageDir\n }\n\n await spawnWithLogs({\n name: \"Vitest\",\n launcher,\n args: vitestArgs,\n env,\n successMessage: \"Vitest suite passed!\",\n failureMessage: \"Vitest failed\",\n })\n\n if (coverage?.enabled && !disableCoverage) {\n await convertNodeCoverage({\n config: combinedConfig ?? coverage.config,\n nodeCoverageDir: resolveNodeCoverageDir(combinedConfig ?? coverage.config),\n })\n }\n}\n\nasync function buildSpecsMapFromCoverage({\n userArgs,\n combinedCoverage,\n}: {\n userArgs: string[]\n combinedCoverage: CoverageState\n [key: string]: unknown\n}): Promise<void> {\n if (!combinedCoverage?.enabled) {\n throw new Error(\"[specs-map] Coverage must be enabled to build the specs map.\")\n }\n\n const config = combinedCoverage.config\n const workspaceRoot = findWorkspaceRoot(process.cwd())\n\n const specSourceFiles = await findSpecSourceFiles(config.rootDir)\n if (specSourceFiles.length === 0) {\n throw new Error(\"[specs-map] No spec files found under spec/**/*.spec{,.desktop,.mobile}.ts\")\n }\n\n const filesMapDir = path.join(config.testResultsRoot, \"files-map\")\n await fsPromises.rm(filesMapDir, { recursive: true, force: true })\n await fsPromises.mkdir(filesMapDir, { recursive: true })\n\n for (const specSourceFile of specSourceFiles) {\n const specProjectPath = path.relative(config.rootDir, specSourceFile)\n const specWorkspacePath = toPosixPath(path.relative(workspaceRoot, specSourceFile))\n const testFile = resolvePlaywrightSpecFile(specProjectPath)\n\n console.log(`\\n[specs-map] Running ${specWorkspacePath}`)\n\n await removeCoverageFiles(config)\n\n let error = null\n let failed = false\n try {\n await runPlaywright([...userArgs, testFile])\n } catch (runError: any) {\n error = runError\n failed = true\n console.error(`[specs-map] Failed: ${specWorkspacePath}`)\n console.error(runError?.stack ?? String(runError))\n }\n\n const coveredFiles = await collectCoveredFiles(config)\n const impactedFiles = coveredFiles\n .map((filePath) => toPosixPath(path.relative(workspaceRoot, filePath)))\n .filter((relativePath) => relativePath && !relativePath.startsWith(\"../\") && relativePath !== \"..\")\n .sort()\n\n const outputFile = path.join(filesMapDir, `${specProjectPath}.json`)\n await fsPromises.mkdir(path.dirname(outputFile), { recursive: true })\n await fsPromises.writeFile(\n outputFile,\n JSON.stringify(\n {\n spec: specWorkspacePath,\n files: impactedFiles,\n failed,\n },\n null,\n 2,\n ),\n \"utf8\",\n )\n\n if (failed) {\n throw error\n }\n }\n}\n\ntype GitChange =\n | { kind: \"rename\"; oldPath: string; newPath: string }\n | { kind: \"path\"; path: string }\n\nasync function resolveAutoPlaywrightArgs({\n userArgs,\n playwrightCoverage,\n vitestCoverage,\n showMapping = false,\n}: {\n userArgs: string[]\n playwrightCoverage: CoverageState\n vitestCoverage: CoverageState\n showMapping?: boolean\n [key: string]: unknown\n}): Promise<string[] | null> {\n const config = playwrightCoverage?.config ?? vitestCoverage?.config ?? null\n if (!config) {\n console.warn(\"[auto] Coverage config not found; running full Playwright suite.\")\n return userArgs\n }\n\n const filesMapDir = path.join(config.testResultsRoot, \"files-map\")\n const mapFiles = await findFilesMapJson(filesMapDir)\n if (mapFiles.length === 0) {\n console.warn(\"[auto] Specs map not found; running full Playwright suite.\")\n return userArgs\n }\n\n const workspaceRoot = findWorkspaceRoot(process.cwd())\n const gitChanges = getGitChanges(workspaceRoot)\n const renameMap = new Map<string, string>(\n gitChanges\n .filter((change): change is { kind: \"rename\"; oldPath: string; newPath: string } => change.kind === \"rename\")\n .map((change) => [change.oldPath, change.newPath]),\n )\n\n const specRootAbs = path.join(config.rootDir, \"spec\")\n const matchesCollectCoverageFrom = createCollectCoverageMatcher(config.collectCoverageFrom, config.rootDir)\n\n const directSpecChanges = new Set<string>()\n const sourceChanges: GitChange[] = []\n\n for (const change of gitChanges) {\n if (change.kind === \"rename\") {\n const oldAbs = path.join(workspaceRoot, change.oldPath)\n const newAbs = path.join(workspaceRoot, change.newPath)\n\n if (isSpecSourceFile(newAbs, specRootAbs) && fs.existsSync(newAbs)) {\n directSpecChanges.add(change.newPath)\n }\n\n const oldMatches = matchesCollectCoverageFrom(oldAbs)\n const newMatches = matchesCollectCoverageFrom(newAbs)\n if (oldMatches || newMatches) {\n sourceChanges.push(change)\n }\n continue\n }\n\n const abs = path.join(workspaceRoot, change.path)\n\n if (isSpecSourceFile(abs, specRootAbs) && fs.existsSync(abs)) {\n directSpecChanges.add(change.path)\n }\n\n if (matchesCollectCoverageFrom(abs)) {\n sourceChanges.push(change)\n }\n }\n\n if (directSpecChanges.size === 0 && sourceChanges.length === 0) {\n console.log(\"[auto] No relevant git changes.\")\n return null\n }\n\n const parsedMaps: Array<{ spec: string; files: string[] }> = []\n for (const file of mapFiles) {\n const json = await readJson(file)\n if (!json) {\n continue\n }\n\n if (json.failed === true) {\n console.warn(\"[auto] Specs map contains failed entries; running full Playwright suite.\")\n return userArgs\n }\n\n const spec = typeof json?.spec === \"string\" ? json.spec : null\n if (!spec) {\n continue\n }\n\n const files = Array.isArray(json?.files)\n ? (json.files as unknown[]).filter((entry): entry is string => typeof entry === \"string\")\n : []\n parsedMaps.push({ spec, files })\n }\n\n if (parsedMaps.length === 0) {\n console.warn(\"[auto] Specs map is empty; running full Playwright suite.\")\n return userArgs\n }\n\n const specsByImpactedFile = new Map<string, string[]>()\n\n for (const entry of parsedMaps) {\n const resolvedSpec = resolveRenamedPath(entry.spec, renameMap)\n for (const file of entry.files) {\n const list = specsByImpactedFile.get(file) ?? []\n list.push(resolvedSpec)\n specsByImpactedFile.set(file, list)\n }\n }\n\n const unmappedSourceChanges = sourceChanges.filter((change) => {\n if (change.kind === \"path\") {\n return !specsByImpactedFile.has(change.path)\n }\n return !specsByImpactedFile.has(change.oldPath) && !specsByImpactedFile.has(change.newPath)\n })\n\n if (unmappedSourceChanges.length > 0) {\n console.warn(\"[auto] Unmapped source changes detected:\")\n for (const change of unmappedSourceChanges) {\n if (change.kind === \"path\") {\n console.warn(` - ${change.path}`)\n } else {\n console.warn(` - ${change.oldPath} -> ${change.newPath}`)\n }\n }\n }\n\n const selectedSpecs = new Set<string>(directSpecChanges)\n const triggersBySpec = new Map<string, Set<string>>()\n\n for (const spec of directSpecChanges) {\n if (showMapping) {\n triggersBySpec.set(spec, new Set([spec]))\n }\n }\n\n for (const change of sourceChanges) {\n if (change.kind === \"path\") {\n const specs = specsByImpactedFile.get(change.path) ?? []\n specs.forEach((spec) => selectedSpecs.add(spec))\n if (showMapping) {\n for (const spec of specs) {\n const current = triggersBySpec.get(spec) ?? new Set()\n current.add(change.path)\n triggersBySpec.set(spec, current)\n }\n }\n continue\n }\n\n const oldSpecs = specsByImpactedFile.get(change.oldPath) ?? []\n oldSpecs.forEach((spec) => selectedSpecs.add(spec))\n const newSpecs = specsByImpactedFile.get(change.newPath) ?? []\n newSpecs.forEach((spec) => selectedSpecs.add(spec))\n if (showMapping) {\n const key = `${change.oldPath} -> ${change.newPath}`\n const allSpecs = new Set([...oldSpecs, ...newSpecs])\n for (const spec of allSpecs) {\n const current = triggersBySpec.get(spec) ?? new Set()\n current.add(key)\n triggersBySpec.set(spec, current)\n }\n }\n }\n\n const missingSpecs: string[] = []\n const specsToRun = Array.from(selectedSpecs)\n .filter((spec) => {\n const abs = path.join(workspaceRoot, spec)\n if (fs.existsSync(abs)) {\n return true\n }\n missingSpecs.push(spec)\n return false\n })\n .sort()\n if (missingSpecs.length > 0) {\n console.warn(`[auto] Ignoring ${missingSpecs.length} missing spec file(s):`)\n for (const spec of missingSpecs.sort()) {\n console.warn(` - ${spec}`)\n }\n }\n\n if (specsToRun.length === 0) {\n console.log(\"[auto] No impacted specs.\")\n return null\n }\n\n if (showMapping) {\n console.log(\"[auto] Mapping:\")\n for (const spec of specsToRun) {\n const triggers = Array.from(triggersBySpec.get(spec) ?? []).sort()\n if (triggers.length === 0) {\n continue\n }\n console.log(` - ${spec}`)\n for (const trigger of triggers) {\n console.log(` <- ${trigger}`)\n }\n }\n }\n\n const playwrightFiles = specsToRun\n .map((specWorkspacePath) => path.join(workspaceRoot, specWorkspacePath))\n .filter((specAbs) => isSubpath(specAbs, config.rootDir))\n .map((specAbs) => {\n const specProjectPath = path.relative(config.rootDir, specAbs)\n return resolvePlaywrightSpecFile(specProjectPath)\n })\n\n const totalSpecFiles = (await findSpecSourceFiles(config.rootDir)).length\n console.log(`[auto] Running ${playwrightFiles.length}/${totalSpecFiles} spec file(s).`)\n return [...userArgs, ...playwrightFiles]\n}\n\nasync function findFilesMapJson(filesMapDir: string): Promise<string[]> {\n const patterns = [\"spec/**/*.spec{,.desktop,.mobile}.ts.json\", \"spec/**/*.spec{,.desktop,.mobile}.tsx.json\"]\n const matches = await fg(patterns, { cwd: filesMapDir, absolute: true, onlyFiles: true }).catch(() => [])\n return matches.sort()\n}\n\nfunction getGitChanges(workspaceRoot: string): GitChange[] {\n const result = spawnSync(\"git\", [\"status\", \"--porcelain=1\", \"-z\"], {\n cwd: workspaceRoot,\n encoding: \"utf8\",\n })\n\n if (result.status !== 0) {\n throw new Error(`[auto] Failed to read git status: ${result.stderr || \"unknown error\"}`)\n }\n\n const tokens = String(result.stdout ?? \"\").split(\"\\0\").filter(Boolean)\n const changes: GitChange[] = []\n\n for (let i = 0; i < tokens.length; i += 1) {\n const record = tokens[i]\n if (record.length < 4) {\n continue\n }\n\n const status = record.slice(0, 2)\n const pathPart = toPosixPath(record.slice(3))\n\n if (isRenameOrCopyStatus(status)) {\n const next = tokens[i + 1]\n if (typeof next !== \"string\") {\n continue\n }\n changes.push({\n kind: \"rename\",\n oldPath: pathPart,\n newPath: toPosixPath(next),\n })\n i += 1\n continue\n }\n\n changes.push({\n kind: \"path\",\n path: pathPart,\n })\n }\n\n return changes\n}\n\nfunction isRenameOrCopyStatus(status: string): boolean {\n return status.includes(\"R\") || status.includes(\"C\")\n}\n\nfunction resolveRenamedPath(original: string, renameMap: Map<string, string>): string {\n let current = original\n const visited = new Set<string>()\n\n while (!visited.has(current)) {\n const next = renameMap.get(current)\n if (!next) {\n break\n }\n visited.add(current)\n current = next\n }\n\n return current\n}\n\nfunction isSubpath(candidate: string, root: string): boolean {\n const relative = path.relative(root, candidate)\n return relative === \"\" || (!relative.startsWith(\"..\") && !path.isAbsolute(relative))\n}\n\nfunction isSpecSourceFile(absolutePath: string, specRootAbsolute: string): boolean {\n if (!isSubpath(absolutePath, specRootAbsolute)) {\n return false\n }\n\n return /\\.spec(?:\\.(?:desktop|mobile))?\\.tsx?$/.test(absolutePath)\n}\n\nasync function findSpecSourceFiles(projectRoot: string): Promise<string[]> {\n const patterns = [\"spec/**/*.spec{,.desktop,.mobile}.ts\", \"spec/**/*.spec{,.desktop,.mobile}.tsx\"]\n const matches = await fg(patterns, { cwd: projectRoot, absolute: true, onlyFiles: true })\n return matches.sort()\n}\n\nfunction resolvePlaywrightSpecFile(specProjectPath: string): string {\n const buildSpecRoot = path.join(process.cwd(), \"build\", \"spec\")\n const isBuildSpecProject = fs.existsSync(buildSpecRoot)\n\n if (!isBuildSpecProject) {\n return specProjectPath\n }\n\n const builtCandidate = normalizeBuiltSpecPath(path.join(\"build\", specProjectPath))\n const builtAbsolute = path.resolve(process.cwd(), builtCandidate)\n if (!fs.existsSync(builtAbsolute)) {\n throw new Error(`[specs-map] Missing built spec file: ${builtCandidate}`)\n }\n\n return builtCandidate\n}\n\nfunction normalizeBuiltSpecPath(filePath: string): string {\n if (filePath.endsWith(\".ts\") || filePath.endsWith(\".tsx\")) {\n return `${filePath.replace(/\\.tsx?$/, \"\")}.js`\n }\n return filePath\n}\n\nfunction toPosixPath(input: unknown): string {\n return String(input ?? \"\").split(path.sep).join(\"/\")\n}\n\nfunction findWorkspaceRoot(projectRoot: string): string {\n let dir = path.resolve(projectRoot)\n\n while (true) {\n const pkgPath = path.join(dir, \"package.json\")\n try {\n if (fs.existsSync(pkgPath)) {\n const parsed = JSON.parse(fs.readFileSync(pkgPath, \"utf8\"))\n if (parsed && typeof parsed === \"object\" && parsed.workspaces) {\n return dir\n }\n }\n } catch {\n //\n }\n\n const parent = path.dirname(dir)\n if (parent === dir) {\n return path.resolve(projectRoot)\n }\n dir = parent\n }\n}\n\nfunction runPlaywright(\n userArgs: string[],\n { disableCoverage = false }: { disableCoverage?: boolean } = {},\n): Promise<void> {\n // Determine config file path\n const configPath = fs.existsSync(\n path.join(process.cwd(), \"playwright.config.ts\"),\n )\n ? path.join(process.cwd(), \"playwright.config.ts\")\n : path.join(moduleDir, \"playwright.config.ts\")\n\n const hasCustomConfig = userArgs.some((arg) => {\n if (arg === \"--config\" || arg === \"-c\") {\n return true\n }\n\n return arg.startsWith(\"--config=\")\n })\n\n const playwrightArgs = [\"test\"]\n\n if (!hasCustomConfig) {\n playwrightArgs.push(\"--config\", configPath)\n }\n\n playwrightArgs.push(...userArgs)\n\n ensureJsxRuntimeShim(process.cwd())\n const launcher = resolvePlaywrightLauncher()\n const env = withRegisterShim(process.env)\n env[COMBINED_COVERAGE_ENV_VAR] = \"1\"\n if (disableCoverage) {\n env.RB_DISABLE_COVERAGE = \"1\"\n }\n\n return spawnWithLogs({\n name: \"Playwright\",\n launcher,\n args: playwrightArgs,\n env,\n successMessage: \"Playwright suite passed!\",\n failureMessage: \"Playwright failed\",\n })\n}\n\ntype SpawnLauncher = {\n command: string\n args?: string[]\n}\n\nfunction resolvePlaywrightLauncher(): SpawnLauncher {\n const cliPath = resolveCliPath()\n if (cliPath) {\n return {\n command: process.execPath,\n args: [cliPath],\n }\n }\n\n const localBin = path.resolve(process.cwd(), \"node_modules/.bin/playwright\")\n if (fs.existsSync(localBin)) {\n return {\n command: localBin,\n args: [],\n }\n }\n\n return {\n command: \"playwright\",\n args: [],\n }\n}\n\nfunction resolveCliPath(): string | null {\n const searchRoots = [process.cwd(), moduleDir]\n\n for (const base of searchRoots) {\n try {\n const pkgPath = require.resolve(\"@playwright/test/package.json\", { paths: [base] })\n const cliPath = path.join(path.dirname(pkgPath), \"cli.js\")\n if (fs.existsSync(cliPath)) {\n return cliPath\n }\n } catch (_error) {\n // continue searching\n }\n }\n\n return null\n}\n\nfunction resolveVitestLauncher(): SpawnLauncher {\n const searchRoots = [process.cwd(), moduleDir]\n\n for (const base of searchRoots) {\n try {\n const pkgPath = require.resolve(\"vitest/package.json\", { paths: [base] })\n const pkgDir = path.dirname(pkgPath)\n const pkgJson = JSON.parse(fs.readFileSync(pkgPath, \"utf8\"))\n const binPath = typeof pkgJson.bin === \"string\" ? pkgJson.bin : pkgJson.bin?.vitest\n if (binPath) {\n return {\n command: process.execPath,\n args: [path.join(pkgDir, binPath)],\n }\n }\n } catch (_error) {\n // continue searching\n }\n }\n\n const localBin = path.resolve(process.cwd(), \"node_modules/.bin/vitest\")\n if (fs.existsSync(localBin)) {\n return {\n command: localBin,\n args: [],\n }\n }\n\n return {\n command: \"vitest\",\n args: [],\n }\n}\n\nfunction resolveVitestConfig(): string | null {\n const userConfig = findVitestConfig(process.cwd())\n if (userConfig) {\n return userConfig\n }\n\n const bundledConfig = path.join(moduleDir, \"vitest.config.js\")\n return fs.existsSync(bundledConfig) ? bundledConfig : null\n}\n\nfunction findVitestConfig(baseDir: string): string | null {\n const candidates = [\n \"vitest.config.ts\",\n \"vitest.config.js\",\n \"vitest.config.mjs\",\n ]\n\n for (const file of candidates) {\n const fullPath = path.join(baseDir, file)\n if (fs.existsSync(fullPath)) {\n return fullPath\n }\n }\n\n return null\n}\n\nasync function loadVitestCoverageConfig(): Promise<CoverageState> {\n const options = await loadCoverageOptions({\n optional: true,\n candidates: VITEST_COVERAGE_CANDIDATES,\n })\n if (!options) {\n return null\n }\n\n const config = createCoverageConfig(options)\n\n return {\n config,\n enabled: config.coverageEnabled,\n }\n}\n\nasync function loadPlaywrightCoverageConfig(): Promise<CoverageState> {\n const options = await loadCoverageOptions({ optional: true })\n if (!options) {\n return null\n }\n\n const config = createCoverageConfig(options)\n\n return {\n config,\n enabled: config.coverageEnabled,\n }\n}\n\nfunction resolveCombinedCoverage(playwrightCoverage: CoverageState, vitestCoverage: CoverageState): CoverageState {\n if (playwrightCoverage?.enabled) {\n return playwrightCoverage\n }\n\n if (vitestCoverage?.enabled) {\n return vitestCoverage\n }\n\n return null\n}\n\nasync function cleanCoverageArtifacts(config: CoverageConfig): Promise<void> {\n await removeCoverageFiles(config)\n await fsPromises.rm(config.coverageReportDir, { recursive: true, force: true })\n await fsPromises.rm(resolveNodeCoverageDir(config), { recursive: true, force: true })\n}\n\nfunction resolveNodeCoverageDir(config: CoverageConfig): string {\n return path.join(config.rootDir, \"build\", \"vitest\", \"test-results\", \"node-coverage\")\n}\n\nasync function convertNodeCoverage(coverage: { config: CoverageConfig; nodeCoverageDir: string }): Promise<void> {\n const { config, nodeCoverageDir } = coverage\n\n const entries = await fsPromises.readdir(nodeCoverageDir).catch(() => [])\n const scripts = []\n const scriptRoots = resolveCollectCoverageRoots(config.collectCoverageFrom, config.rootDir)\n\n for (const entry of entries) {\n if (!entry.endsWith(\".json\")) {\n continue\n }\n\n const fullPath = path.join(nodeCoverageDir, entry)\n const payload = await readJson(fullPath)\n const results = Array.isArray(payload?.result) ? payload.result : []\n\n for (const script of results) {\n const normalized = normalizeNodeScriptUrl(script.url, config.rootDir)\n if (!normalized) {\n continue\n }\n\n if (isNodeModulesPath(normalized.absolutePath)) {\n continue\n }\n\n if (!isInsideAnyRoot(normalized.absolutePath, scriptRoots)) {\n continue\n }\n\n const source = await fsPromises.readFile(normalized.absolutePath, \"utf8\").catch(() => \"\")\n\n scripts.push({\n absolutePath: normalized.absolutePath,\n relativePath: normalized.relativePath,\n source,\n functions: script.functions ?? [],\n url: script.url,\n })\n }\n }\n\n if (scripts.length === 0) {\n return\n }\n\n const outDir = path.join(config.rootDir, \"build\", \"vitest\", \"coverage\")\n await fsPromises.mkdir(outDir, { recursive: true })\n const outputFile = path.join(outDir, config.coverageFileName)\n await fsPromises.writeFile(outputFile, JSON.stringify({ testId: \"vitest\", scripts }, null, 2), \"utf8\")\n}\n\nasync function finalizeCoverage(config: CoverageConfig): Promise<void> {\n try {\n await generateCoverageReport(config)\n } catch (error: any) {\n if (error instanceof CoverageThresholdError) {\n console.error(error.message)\n }\n throw error\n }\n}\n\nasync function readJson(filePath: string): Promise<any | null> {\n try {\n const raw = await fsPromises.readFile(filePath, \"utf8\")\n return JSON.parse(raw)\n } catch {\n return null\n }\n}\n\nfunction normalizeNodeScriptUrl(\n rawUrl: string,\n rootDir: string,\n): { absolutePath: string; relativePath: string } | null {\n if (!rawUrl || rawUrl.startsWith(\"node:\")) {\n return null\n }\n\n let absolutePath = null\n\n try {\n if (rawUrl.startsWith(\"file://\")) {\n absolutePath = fileURLToPath(rawUrl)\n }\n } catch (_err) {\n // ignore invalid URLs\n }\n\n if (!absolutePath && path.isAbsolute(rawUrl)) {\n absolutePath = rawUrl\n }\n\n if (!absolutePath) {\n return null\n }\n\n const normalized = path.normalize(absolutePath)\n\n return {\n absolutePath: normalized,\n relativePath: path.relative(rootDir, normalized),\n }\n}\n\nfunction isNodeModulesPath(filePath: unknown): boolean {\n return path\n .normalize(String(filePath ?? \"\"))\n .split(path.sep)\n .includes(\"node_modules\")\n}\n\nfunction spawnWithLogs({\n name,\n launcher,\n args,\n env,\n successMessage,\n failureMessage,\n}: {\n name: string\n launcher: SpawnLauncher\n args: string[]\n env: NodeJS.ProcessEnv\n successMessage?: string\n failureMessage?: string\n}): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const stdoutBuffer: string[] = []\n const stderrBuffer: string[] = []\n\n const child = spawn(\n launcher.command,\n [...(launcher.args || []), ...args],\n {\n shell: false,\n env,\n },\n )\n\n child.stdout?.on(\"data\", (data) => {\n if (!isAider) {\n process.stdout.write(data)\n }\n stdoutBuffer.push(data.toString())\n })\n\n child.stderr?.on(\"data\", (data) => {\n if (!isAider) {\n process.stderr.write(data)\n }\n stderrBuffer.push(data.toString())\n })\n\n child.on(\"close\", (code) => {\n if (code === 0) {\n if (successMessage) {\n console.log(successMessage)\n }\n resolve()\n } else {\n console.error(failureMessage || `${name} failed:`)\n\n if (isAider) {\n if (stdoutBuffer.length > 0) {\n console.error(stdoutBuffer.join(\"\"))\n }\n\n if (stderrBuffer.length > 0) {\n console.error(stderrBuffer.join(\"\"))\n }\n }\n\n reject(new Error(`${name} failed with exit code: ${code}`))\n }\n })\n\n child.on(\"error\", (error) => {\n console.error(`Error spawning ${name}:`, error)\n reject(error)\n })\n })\n}\n\nfunction withRegisterShim(baseEnv: NodeJS.ProcessEnv): NodeJS.ProcessEnv {\n const nodeOptions = appendNodeRequire(baseEnv.NODE_OPTIONS, path.join(moduleDir, \"register-tty.cjs\"))\n return {\n ...baseEnv,\n NODE_OPTIONS: nodeOptions,\n }\n}\n\nfunction ensureJsxRuntimeShim(projectRoot: string): void {\n const shimDir = path.join(projectRoot, \"node_modules\", \"playwright\")\n fs.mkdirSync(shimDir, { recursive: true })\n const shims = [\n { file: \"jsx-runtime.js\", target: \"react/jsx-runtime\" },\n { file: \"jsx-dev-runtime.js\", target: \"react/jsx-dev-runtime\" },\n ]\n\n for (const { file, target } of shims) {\n const filePath = path.join(shimDir, file)\n if (!fs.existsSync(filePath)) {\n const content = `export * from \"${target}\";\\nexport { default } from \"${target}\";\\n`\n fs.writeFileSync(filePath, content, \"utf8\")\n }\n }\n}\n\nfunction appendNodeRequire(existing: string | undefined, modulePath: string): string {\n const flag = `--require=${modulePath}`\n if (!existing || existing.length === 0) {\n return flag\n }\n return `${existing} ${flag}`\n}\n"],"names":["require","fsPromises","fs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","sources":["../src/cli.ts"],"sourcesContent":["import { spawn, spawnSync } from \"node:child_process\"\nimport fs from \"node:fs\"\nimport fsPromises from \"node:fs/promises\"\nimport path from \"node:path\"\nimport { createRequire } from \"node:module\"\nimport { fileURLToPath } from \"node:url\"\n\nimport fg from \"fast-glob\"\n\nimport { createCoverageConfig } from \"./coverage/config\"\nimport { createCollectCoverageMatcher, isInsideAnyRoot, resolveCollectCoverageRoots } from \"./coverage/collect\"\nimport { loadCoverageOptions } from \"./coverage/config-loader\"\nimport { removeCoverageFiles } from \"./coverage/files\"\nimport { collectCoveredFiles, CoverageThresholdError, generateCoverageReport } from \"./coverage/report\"\nimport type { CoverageConfig } from \"./coverage/types\"\n\n\nconst require = createRequire(import.meta.url)\nconst moduleDir = path.dirname(fileURLToPath(import.meta.url))\n\nconst shouldForceTty =\n !process.stdout.isTTY\n && process.env.FORCE_COLOR === \"true\"\n\nif (shouldForceTty) {\n require(\"./register-tty.cjs\")\n}\n\n\nconst VITEST_COVERAGE_CANDIDATES = [\"src/coverage.json\"]\n\nconst COMBINED_COVERAGE_ENV_VAR = \"RB_TEST_COMBINED_COVERAGE\"\n\nconst isAider = process.env.IS_AIDER === \"yes\"\n\nif (process.env.IS_AIDER !== undefined && process.env.IS_AIDER !== \"yes\") {\n console.warn(\"Warning: IS_AIDER is set to a value other than 'yes'.\")\n}\n\ntype CoverageState = { config: CoverageConfig; enabled: boolean } | null\n\nasync function runTests(): Promise<void> {\n const userArgs = process.argv.slice(2)\n const buildSpecsMap = userArgs.includes(\"--build-specs-map\")\n const auto = userArgs.includes(\"--auto\")\n const showMapping = userArgs.includes(\"--show-mapping\")\n const filteredArgs = userArgs.filter((arg) => arg !== \"--build-specs-map\" && arg !== \"--auto\" && arg !== \"--show-mapping\")\n\n if (buildSpecsMap && auto) {\n throw new Error(\"[rb-test] --auto cannot be combined with --build-specs-map\")\n }\n\n if (showMapping && !auto) {\n throw new Error(\"[rb-test] --show-mapping requires --auto\")\n }\n\n const playwrightCoverage = await loadPlaywrightCoverageConfig()\n const vitestCoverage = await loadVitestCoverageConfig()\n const combinedCoverage = resolveCombinedCoverage(playwrightCoverage, vitestCoverage)\n\n if (buildSpecsMap) {\n await buildSpecsMapFromCoverage({\n userArgs: filteredArgs,\n playwrightCoverage,\n vitestCoverage,\n combinedCoverage,\n })\n return\n }\n\n const shouldGenerateCoverageReport = combinedCoverage?.enabled && !auto\n\n if (shouldGenerateCoverageReport) {\n await cleanCoverageArtifacts(combinedCoverage.config)\n }\n\n let testError = null\n\n try {\n await runVitest(vitestCoverage, combinedCoverage?.config ?? null, filteredArgs, { disableCoverage: auto })\n console.log(\"\\nRunning Playwright Tests...\")\n const playwrightArgs = auto\n ? await resolveAutoPlaywrightArgs({\n userArgs: filteredArgs,\n playwrightCoverage,\n vitestCoverage,\n showMapping,\n })\n : filteredArgs\n if (playwrightArgs) {\n await runPlaywright(playwrightArgs, { disableCoverage: auto })\n }\n } catch (error: any) {\n testError = error\n }\n\n if (shouldGenerateCoverageReport) {\n if (testError) {\n console.warn(\"[coverage] skipping report generation because tests failed\")\n } else {\n try {\n await finalizeCoverage(combinedCoverage.config)\n } catch (error) {\n testError = error\n }\n }\n }\n\n if (testError) {\n throw testError\n }\n}\n\nrunTests()\n .then(() => process.exit(0))\n .catch((error) => {\n if (!(error instanceof CoverageThresholdError)) {\n console.error(error?.stack ?? String(error))\n }\n process.exit(1)\n })\n\nasync function runVitest(\n coverage: CoverageState,\n combinedConfig: CoverageConfig | null,\n userArgs: string[],\n { disableCoverage = false }: { disableCoverage?: boolean } = {},\n): Promise<void> {\n const vitestArgs = [\"run\", \"--passWithNoTests\"]\n const vitestConfig = resolveVitestConfig()\n\n const hasCustomConfig = userArgs.some((arg) => {\n if (arg === \"--config\" || arg === \"-c\") {\n return true\n }\n return arg.startsWith(\"--config=\")\n })\n\n if (vitestConfig && !hasCustomConfig) {\n vitestArgs.push(\"--config\", vitestConfig)\n }\n vitestArgs.push(...userArgs)\n\n const launcher = resolveVitestLauncher()\n const env = withRegisterShim(process.env)\n\n if (disableCoverage) {\n env.RB_DISABLE_COVERAGE = \"1\"\n }\n\n if (coverage?.enabled && !disableCoverage) {\n // Vitest runs in a Node.js process, so we use Node's built-in V8 coverage output (NODE_V8_COVERAGE) here.\n // Playwright coverage is collected separately via CDP in Chromium; server coverage is handled via /api/dev/coverage start/stop.\n const nodeCoverageDir = resolveNodeCoverageDir(combinedConfig ?? coverage.config)\n await fsPromises.mkdir(nodeCoverageDir, { recursive: true })\n env.NODE_V8_COVERAGE = nodeCoverageDir\n }\n\n await spawnWithLogs({\n name: \"Vitest\",\n launcher,\n args: vitestArgs,\n env,\n successMessage: \"Vitest suite passed!\",\n failureMessage: \"Vitest failed\",\n })\n\n if (coverage?.enabled && !disableCoverage) {\n await convertNodeCoverage({\n config: combinedConfig ?? coverage.config,\n nodeCoverageDir: resolveNodeCoverageDir(combinedConfig ?? coverage.config),\n })\n }\n}\n\nasync function buildSpecsMapFromCoverage({\n userArgs,\n combinedCoverage,\n}: {\n userArgs: string[]\n combinedCoverage: CoverageState\n [key: string]: unknown\n}): Promise<void> {\n if (!combinedCoverage?.enabled) {\n throw new Error(\"[specs-map] Coverage must be enabled to build the specs map.\")\n }\n\n const config = combinedCoverage.config\n const workspaceRoot = findWorkspaceRoot(process.cwd())\n\n const specSourceFiles = await findSpecSourceFiles(config.rootDir)\n if (specSourceFiles.length === 0) {\n throw new Error(\"[specs-map] No spec files found under spec/**/*.spec{,.desktop,.mobile}.ts\")\n }\n\n const filesMapDir = path.join(config.testResultsRoot, \"files-map\")\n await fsPromises.rm(filesMapDir, { recursive: true, force: true })\n await fsPromises.mkdir(filesMapDir, { recursive: true })\n\n for (const specSourceFile of specSourceFiles) {\n const specProjectPath = path.relative(config.rootDir, specSourceFile)\n const specWorkspacePath = toPosixPath(path.relative(workspaceRoot, specSourceFile))\n const testFile = resolvePlaywrightSpecFile(specProjectPath)\n\n console.log(`\\n[specs-map] Running ${specWorkspacePath}`)\n\n await removeCoverageFiles(config)\n\n let error = null\n let failed = false\n try {\n await runPlaywright([...userArgs, testFile])\n } catch (runError: any) {\n error = runError\n failed = true\n console.error(`[specs-map] Failed: ${specWorkspacePath}`)\n console.error(runError?.stack ?? String(runError))\n }\n\n const coveredFiles = await collectCoveredFiles(config)\n const impactedFiles = coveredFiles\n .map((filePath) => toPosixPath(path.relative(workspaceRoot, filePath)))\n .filter((relativePath) => relativePath && !relativePath.startsWith(\"../\") && relativePath !== \"..\")\n .sort()\n\n const outputFile = path.join(filesMapDir, `${specProjectPath}.json`)\n await fsPromises.mkdir(path.dirname(outputFile), { recursive: true })\n await fsPromises.writeFile(\n outputFile,\n JSON.stringify(\n {\n spec: specWorkspacePath,\n files: impactedFiles,\n failed,\n },\n null,\n 2,\n ),\n \"utf8\",\n )\n\n if (failed) {\n throw error\n }\n }\n}\n\ntype GitChange =\n | { kind: \"rename\"; oldPath: string; newPath: string }\n | { kind: \"path\"; path: string }\n\nasync function resolveAutoPlaywrightArgs({\n userArgs,\n playwrightCoverage,\n vitestCoverage,\n showMapping = false,\n}: {\n userArgs: string[]\n playwrightCoverage: CoverageState\n vitestCoverage: CoverageState\n showMapping?: boolean\n [key: string]: unknown\n}): Promise<string[] | null> {\n const config = playwrightCoverage?.config ?? vitestCoverage?.config ?? null\n if (!config) {\n console.warn(\"[auto] Coverage config not found; running full Playwright suite.\")\n return userArgs\n }\n\n const filesMapDir = path.join(config.testResultsRoot, \"files-map\")\n const mapFiles = await findFilesMapJson(filesMapDir)\n if (mapFiles.length === 0) {\n console.warn(\"[auto] Specs map not found; running full Playwright suite.\")\n return userArgs\n }\n\n const workspaceRoot = findWorkspaceRoot(process.cwd())\n const gitChanges = getGitChanges(workspaceRoot)\n const renameMap = new Map<string, string>(\n gitChanges\n .filter((change): change is { kind: \"rename\"; oldPath: string; newPath: string } => change.kind === \"rename\")\n .map((change) => [change.oldPath, change.newPath]),\n )\n\n const specRootAbs = path.join(config.rootDir, \"spec\")\n const matchesCollectCoverageFrom = createCollectCoverageMatcher(config.collectCoverageFrom, config.rootDir)\n\n const directSpecChanges = new Set<string>()\n const sourceChanges: GitChange[] = []\n\n for (const change of gitChanges) {\n if (change.kind === \"rename\") {\n const oldAbs = path.join(workspaceRoot, change.oldPath)\n const newAbs = path.join(workspaceRoot, change.newPath)\n\n if (isSpecSourceFile(newAbs, specRootAbs) && fs.existsSync(newAbs)) {\n directSpecChanges.add(change.newPath)\n }\n\n const oldMatches = matchesCollectCoverageFrom(oldAbs)\n const newMatches = matchesCollectCoverageFrom(newAbs)\n if (oldMatches || newMatches) {\n sourceChanges.push(change)\n }\n continue\n }\n\n const abs = path.join(workspaceRoot, change.path)\n\n if (isSpecSourceFile(abs, specRootAbs) && fs.existsSync(abs)) {\n directSpecChanges.add(change.path)\n }\n\n if (matchesCollectCoverageFrom(abs)) {\n sourceChanges.push(change)\n }\n }\n\n if (directSpecChanges.size === 0 && sourceChanges.length === 0) {\n console.log(\"[auto] No relevant git changes.\")\n return null\n }\n\n const parsedMaps: Array<{ spec: string; files: string[] }> = []\n for (const file of mapFiles) {\n const json = await readJson(file)\n if (!json) {\n continue\n }\n\n if (json.failed === true) {\n console.warn(\"[auto] Specs map contains failed entries; running full Playwright suite.\")\n return userArgs\n }\n\n const spec = typeof json?.spec === \"string\" ? json.spec : null\n if (!spec) {\n continue\n }\n\n const files = Array.isArray(json?.files)\n ? (json.files as unknown[]).filter((entry): entry is string => typeof entry === \"string\")\n : []\n parsedMaps.push({ spec, files })\n }\n\n if (parsedMaps.length === 0) {\n console.warn(\"[auto] Specs map is empty; running full Playwright suite.\")\n return userArgs\n }\n\n const specsByImpactedFile = new Map<string, string[]>()\n\n for (const entry of parsedMaps) {\n const resolvedSpec = resolveRenamedPath(entry.spec, renameMap)\n for (const file of entry.files) {\n const list = specsByImpactedFile.get(file) ?? []\n list.push(resolvedSpec)\n specsByImpactedFile.set(file, list)\n }\n }\n\n const unmappedSourceChanges = sourceChanges.filter((change) => {\n if (change.kind === \"path\") {\n return !specsByImpactedFile.has(change.path)\n }\n return !specsByImpactedFile.has(change.oldPath) && !specsByImpactedFile.has(change.newPath)\n })\n\n if (unmappedSourceChanges.length > 0) {\n console.warn(\"[auto] Unmapped source changes detected:\")\n for (const change of unmappedSourceChanges) {\n if (change.kind === \"path\") {\n console.warn(` - ${change.path}`)\n } else {\n console.warn(` - ${change.oldPath} -> ${change.newPath}`)\n }\n }\n }\n\n const selectedSpecs = new Set<string>(directSpecChanges)\n const triggersBySpec = new Map<string, Set<string>>()\n\n for (const spec of directSpecChanges) {\n if (showMapping) {\n triggersBySpec.set(spec, new Set([spec]))\n }\n }\n\n for (const change of sourceChanges) {\n if (change.kind === \"path\") {\n const specs = specsByImpactedFile.get(change.path) ?? []\n specs.forEach((spec) => selectedSpecs.add(spec))\n if (showMapping) {\n for (const spec of specs) {\n const current = triggersBySpec.get(spec) ?? new Set()\n current.add(change.path)\n triggersBySpec.set(spec, current)\n }\n }\n continue\n }\n\n const oldSpecs = specsByImpactedFile.get(change.oldPath) ?? []\n oldSpecs.forEach((spec) => selectedSpecs.add(spec))\n const newSpecs = specsByImpactedFile.get(change.newPath) ?? []\n newSpecs.forEach((spec) => selectedSpecs.add(spec))\n if (showMapping) {\n const key = `${change.oldPath} -> ${change.newPath}`\n const allSpecs = new Set([...oldSpecs, ...newSpecs])\n for (const spec of allSpecs) {\n const current = triggersBySpec.get(spec) ?? new Set()\n current.add(key)\n triggersBySpec.set(spec, current)\n }\n }\n }\n\n const missingSpecs: string[] = []\n const specsToRun = Array.from(selectedSpecs)\n .filter((spec) => {\n const abs = path.join(workspaceRoot, spec)\n if (fs.existsSync(abs)) {\n return true\n }\n missingSpecs.push(spec)\n return false\n })\n .sort()\n if (missingSpecs.length > 0) {\n console.warn(`[auto] Ignoring ${missingSpecs.length} missing spec file(s):`)\n for (const spec of missingSpecs.sort()) {\n console.warn(` - ${spec}`)\n }\n }\n\n if (specsToRun.length === 0) {\n console.log(\"[auto] No impacted specs.\")\n return null\n }\n\n if (showMapping) {\n console.log(\"[auto] Mapping:\")\n for (const spec of specsToRun) {\n const triggers = Array.from(triggersBySpec.get(spec) ?? []).sort()\n if (triggers.length === 0) {\n continue\n }\n console.log(` - ${spec}`)\n for (const trigger of triggers) {\n console.log(` <- ${trigger}`)\n }\n }\n }\n\n const playwrightFiles = specsToRun\n .map((specWorkspacePath) => path.join(workspaceRoot, specWorkspacePath))\n .filter((specAbs) => isSubpath(specAbs, config.rootDir))\n .map((specAbs) => {\n const specProjectPath = path.relative(config.rootDir, specAbs)\n return resolvePlaywrightSpecFile(specProjectPath)\n })\n\n const totalSpecFiles = (await findSpecSourceFiles(config.rootDir)).length\n console.log(`[auto] Running ${playwrightFiles.length}/${totalSpecFiles} spec file(s).`)\n return [...userArgs, ...playwrightFiles]\n}\n\nasync function findFilesMapJson(filesMapDir: string): Promise<string[]> {\n const patterns = [\"spec/**/*.spec{,.desktop,.mobile}.ts.json\", \"spec/**/*.spec{,.desktop,.mobile}.tsx.json\"]\n const matches = await fg(patterns, { cwd: filesMapDir, absolute: true, onlyFiles: true }).catch(() => [])\n return matches.sort()\n}\n\nfunction getGitChanges(workspaceRoot: string): GitChange[] {\n const result = spawnSync(\"git\", [\"status\", \"--porcelain=1\", \"-z\"], {\n cwd: workspaceRoot,\n encoding: \"utf8\",\n })\n\n if (result.status !== 0) {\n throw new Error(`[auto] Failed to read git status: ${result.stderr || \"unknown error\"}`)\n }\n\n const tokens = String(result.stdout ?? \"\").split(\"\\0\").filter(Boolean)\n const changes: GitChange[] = []\n\n for (let i = 0; i < tokens.length; i += 1) {\n const record = tokens[i]\n if (record.length < 4) {\n continue\n }\n\n const status = record.slice(0, 2)\n const pathPart = toPosixPath(record.slice(3))\n\n if (isRenameOrCopyStatus(status)) {\n const next = tokens[i + 1]\n if (typeof next !== \"string\") {\n continue\n }\n changes.push({\n kind: \"rename\",\n oldPath: pathPart,\n newPath: toPosixPath(next),\n })\n i += 1\n continue\n }\n\n changes.push({\n kind: \"path\",\n path: pathPart,\n })\n }\n\n return changes\n}\n\nfunction isRenameOrCopyStatus(status: string): boolean {\n return status.includes(\"R\") || status.includes(\"C\")\n}\n\nfunction resolveRenamedPath(original: string, renameMap: Map<string, string>): string {\n let current = original\n const visited = new Set<string>()\n\n while (!visited.has(current)) {\n const next = renameMap.get(current)\n if (!next) {\n break\n }\n visited.add(current)\n current = next\n }\n\n return current\n}\n\nfunction isSubpath(candidate: string, root: string): boolean {\n const relative = path.relative(root, candidate)\n return relative === \"\" || (!relative.startsWith(\"..\") && !path.isAbsolute(relative))\n}\n\nfunction isSpecSourceFile(absolutePath: string, specRootAbsolute: string): boolean {\n if (!isSubpath(absolutePath, specRootAbsolute)) {\n return false\n }\n\n return /\\.spec(?:\\.(?:desktop|mobile))?\\.tsx?$/.test(absolutePath)\n}\n\nasync function findSpecSourceFiles(projectRoot: string): Promise<string[]> {\n const patterns = [\"spec/**/*.spec{,.desktop,.mobile}.ts\", \"spec/**/*.spec{,.desktop,.mobile}.tsx\"]\n const matches = await fg(patterns, { cwd: projectRoot, absolute: true, onlyFiles: true })\n return matches.sort()\n}\n\nfunction resolvePlaywrightSpecFile(specProjectPath: string): string {\n const buildSpecRoot = path.join(process.cwd(), \"build\", \"spec\")\n const isBuildSpecProject = fs.existsSync(buildSpecRoot)\n\n if (!isBuildSpecProject) {\n return specProjectPath\n }\n\n const builtCandidate = normalizeBuiltSpecPath(path.join(\"build\", specProjectPath))\n const builtAbsolute = path.resolve(process.cwd(), builtCandidate)\n if (!fs.existsSync(builtAbsolute)) {\n throw new Error(`[specs-map] Missing built spec file: ${builtCandidate}`)\n }\n\n return builtCandidate\n}\n\nfunction normalizeBuiltSpecPath(filePath: string): string {\n if (filePath.endsWith(\".ts\") || filePath.endsWith(\".tsx\")) {\n return `${filePath.replace(/\\.tsx?$/, \"\")}.js`\n }\n return filePath\n}\n\nfunction toPosixPath(input: unknown): string {\n return String(input ?? \"\").split(path.sep).join(\"/\")\n}\n\nfunction findWorkspaceRoot(projectRoot: string): string {\n let dir = path.resolve(projectRoot)\n\n while (true) {\n const pkgPath = path.join(dir, \"package.json\")\n try {\n if (fs.existsSync(pkgPath)) {\n const parsed = JSON.parse(fs.readFileSync(pkgPath, \"utf8\"))\n if (parsed && typeof parsed === \"object\" && parsed.workspaces) {\n return dir\n }\n }\n } catch {\n //\n }\n\n const parent = path.dirname(dir)\n if (parent === dir) {\n return path.resolve(projectRoot)\n }\n dir = parent\n }\n}\n\nfunction runPlaywright(\n userArgs: string[],\n { disableCoverage = false }: { disableCoverage?: boolean } = {},\n): Promise<void> {\n // Determine config file path\n const configPath = fs.existsSync(\n path.join(process.cwd(), \"playwright.config.ts\"),\n )\n ? path.join(process.cwd(), \"playwright.config.ts\")\n : path.join(moduleDir, \"playwright.config.ts\")\n\n const hasCustomConfig = userArgs.some((arg) => {\n if (arg === \"--config\" || arg === \"-c\") {\n return true\n }\n\n return arg.startsWith(\"--config=\")\n })\n\n const playwrightArgs = [\"test\"]\n\n if (!hasCustomConfig) {\n playwrightArgs.push(\"--config\", configPath)\n }\n\n playwrightArgs.push(...userArgs)\n\n ensureJsxRuntimeShim(process.cwd())\n const launcher = resolvePlaywrightLauncher()\n const env = withRegisterShim(process.env)\n env[COMBINED_COVERAGE_ENV_VAR] = \"1\"\n if (disableCoverage) {\n env.RB_DISABLE_COVERAGE = \"1\"\n }\n\n return spawnWithLogs({\n name: \"Playwright\",\n launcher,\n args: playwrightArgs,\n env,\n successMessage: \"Playwright suite passed!\",\n failureMessage: \"Playwright failed\",\n })\n}\n\ntype SpawnLauncher = {\n command: string\n args?: string[]\n}\n\nfunction resolvePlaywrightLauncher(): SpawnLauncher {\n const cliPath = resolveCliPath()\n if (cliPath) {\n return {\n command: process.execPath,\n args: [cliPath],\n }\n }\n\n const localBin = path.resolve(process.cwd(), \"node_modules/.bin/playwright\")\n if (fs.existsSync(localBin)) {\n return {\n command: localBin,\n args: [],\n }\n }\n\n return {\n command: \"playwright\",\n args: [],\n }\n}\n\nfunction resolveCliPath(): string | null {\n const searchRoots = [process.cwd(), moduleDir]\n\n for (const base of searchRoots) {\n try {\n const pkgPath = require.resolve(\"@playwright/test/package.json\", { paths: [base] })\n const cliPath = path.join(path.dirname(pkgPath), \"cli.js\")\n if (fs.existsSync(cliPath)) {\n return cliPath\n }\n } catch (_error) {\n // continue searching\n }\n }\n\n return null\n}\n\nfunction resolveVitestLauncher(): SpawnLauncher {\n const searchRoots = [process.cwd(), moduleDir]\n\n for (const base of searchRoots) {\n try {\n const pkgPath = require.resolve(\"vitest/package.json\", { paths: [base] })\n const pkgDir = path.dirname(pkgPath)\n const pkgJson = JSON.parse(fs.readFileSync(pkgPath, \"utf8\"))\n const binPath = typeof pkgJson.bin === \"string\" ? pkgJson.bin : pkgJson.bin?.vitest\n if (binPath) {\n return {\n command: process.execPath,\n args: [path.join(pkgDir, binPath)],\n }\n }\n } catch (_error) {\n // continue searching\n }\n }\n\n const localBin = path.resolve(process.cwd(), \"node_modules/.bin/vitest\")\n if (fs.existsSync(localBin)) {\n return {\n command: localBin,\n args: [],\n }\n }\n\n return {\n command: \"vitest\",\n args: [],\n }\n}\n\nfunction resolveVitestConfig(): string | null {\n const userConfig = findVitestConfig(process.cwd())\n if (userConfig) {\n return userConfig\n }\n\n const bundledConfig = path.join(moduleDir, \"vitest.config.js\")\n return fs.existsSync(bundledConfig) ? bundledConfig : null\n}\n\nfunction findVitestConfig(baseDir: string): string | null {\n const candidates = [\n \"vitest.config.ts\",\n \"vitest.config.js\",\n \"vitest.config.mjs\",\n ]\n\n for (const file of candidates) {\n const fullPath = path.join(baseDir, file)\n if (fs.existsSync(fullPath)) {\n return fullPath\n }\n }\n\n return null\n}\n\nasync function loadVitestCoverageConfig(): Promise<CoverageState> {\n const options = await loadCoverageOptions({\n optional: true,\n candidates: VITEST_COVERAGE_CANDIDATES,\n })\n if (!options) {\n return null\n }\n\n const config = createCoverageConfig(options)\n\n return {\n config,\n enabled: config.coverageEnabled,\n }\n}\n\nasync function loadPlaywrightCoverageConfig(): Promise<CoverageState> {\n const options = await loadCoverageOptions({ optional: true })\n if (!options) {\n return null\n }\n\n const config = createCoverageConfig(options)\n\n return {\n config,\n enabled: config.coverageEnabled,\n }\n}\n\nfunction resolveCombinedCoverage(playwrightCoverage: CoverageState, vitestCoverage: CoverageState): CoverageState {\n if (playwrightCoverage?.enabled) {\n return playwrightCoverage\n }\n\n if (vitestCoverage?.enabled) {\n return vitestCoverage\n }\n\n return null\n}\n\nasync function cleanCoverageArtifacts(config: CoverageConfig): Promise<void> {\n await removeCoverageFiles(config)\n await fsPromises.rm(config.coverageReportDir, { recursive: true, force: true })\n await fsPromises.rm(resolveNodeCoverageDir(config), { recursive: true, force: true })\n}\n\nfunction resolveNodeCoverageDir(config: CoverageConfig): string {\n return path.join(config.rootDir, \"build\", \"vitest\", \"test-results\", \"node-coverage\")\n}\n\nasync function convertNodeCoverage(coverage: { config: CoverageConfig; nodeCoverageDir: string }): Promise<void> {\n const { config, nodeCoverageDir } = coverage\n\n const entries = await fsPromises.readdir(nodeCoverageDir).catch(() => [])\n const scripts = []\n const scriptRoots = resolveCollectCoverageRoots(config.collectCoverageFrom, config.rootDir)\n\n for (const entry of entries) {\n if (!entry.endsWith(\".json\")) {\n continue\n }\n\n const fullPath = path.join(nodeCoverageDir, entry)\n const payload = await readJson(fullPath)\n const results = Array.isArray(payload?.result) ? payload.result : []\n\n for (const script of results) {\n const normalized = normalizeNodeScriptUrl(script.url, config.rootDir)\n if (!normalized) {\n continue\n }\n\n if (isNodeModulesPath(normalized.absolutePath)) {\n continue\n }\n\n if (!isInsideAnyRoot(normalized.absolutePath, scriptRoots)) {\n continue\n }\n\n const source = await fsPromises.readFile(normalized.absolutePath, \"utf8\").catch(() => \"\")\n\n scripts.push({\n absolutePath: normalized.absolutePath,\n relativePath: normalized.relativePath,\n source,\n functions: script.functions ?? [],\n url: script.url,\n })\n }\n }\n\n if (scripts.length === 0) {\n return\n }\n\n const outDir = path.join(config.rootDir, \"build\", \"vitest\", \"coverage\")\n await fsPromises.mkdir(outDir, { recursive: true })\n const outputFile = path.join(outDir, config.coverageFileName)\n await fsPromises.writeFile(outputFile, JSON.stringify({ testId: \"vitest\", scripts }, null, 2), \"utf8\")\n}\n\nasync function finalizeCoverage(config: CoverageConfig): Promise<void> {\n try {\n await generateCoverageReport(config)\n } catch (error: any) {\n if (error instanceof CoverageThresholdError) {\n console.error(error.message)\n }\n throw error\n }\n}\n\nasync function readJson(filePath: string): Promise<any | null> {\n try {\n const raw = await fsPromises.readFile(filePath, \"utf8\")\n return JSON.parse(raw)\n } catch {\n return null\n }\n}\n\nfunction normalizeNodeScriptUrl(\n rawUrl: string,\n rootDir: string,\n): { absolutePath: string; relativePath: string } | null {\n if (!rawUrl || rawUrl.startsWith(\"node:\")) {\n return null\n }\n\n let absolutePath = null\n\n try {\n if (rawUrl.startsWith(\"file://\")) {\n absolutePath = fileURLToPath(rawUrl)\n }\n } catch (_err) {\n // ignore invalid URLs\n }\n\n if (!absolutePath && path.isAbsolute(rawUrl)) {\n absolutePath = rawUrl\n }\n\n if (!absolutePath) {\n return null\n }\n\n const normalized = path.normalize(absolutePath)\n\n return {\n absolutePath: normalized,\n relativePath: path.relative(rootDir, normalized),\n }\n}\n\nfunction isNodeModulesPath(filePath: unknown): boolean {\n return path\n .normalize(String(filePath ?? \"\"))\n .split(path.sep)\n .includes(\"node_modules\")\n}\n\nfunction spawnWithLogs({\n name,\n launcher,\n args,\n env,\n successMessage,\n failureMessage,\n}: {\n name: string\n launcher: SpawnLauncher\n args: string[]\n env: NodeJS.ProcessEnv\n successMessage?: string\n failureMessage?: string\n}): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const stdoutBuffer: string[] = []\n const stderrBuffer: string[] = []\n\n const child = spawn(\n launcher.command,\n [...(launcher.args || []), ...args],\n {\n shell: false,\n env,\n },\n )\n\n child.stdout?.on(\"data\", (data) => {\n if (!isAider) {\n process.stdout.write(data)\n }\n stdoutBuffer.push(data.toString())\n })\n\n child.stderr?.on(\"data\", (data) => {\n if (!isAider) {\n process.stderr.write(data)\n }\n stderrBuffer.push(data.toString())\n })\n\n child.on(\"close\", (code) => {\n if (code === 0) {\n if (successMessage) {\n console.log(successMessage)\n }\n resolve()\n } else {\n console.error(failureMessage || `${name} failed:`)\n\n if (isAider) {\n if (stdoutBuffer.length > 0) {\n console.error(stdoutBuffer.join(\"\"))\n }\n\n if (stderrBuffer.length > 0) {\n console.error(stderrBuffer.join(\"\"))\n }\n }\n\n reject(new Error(`${name} failed with exit code: ${code}`))\n }\n })\n\n child.on(\"error\", (error) => {\n console.error(`Error spawning ${name}:`, error)\n reject(error)\n })\n })\n}\n\nfunction withRegisterShim(baseEnv: NodeJS.ProcessEnv): NodeJS.ProcessEnv {\n const nodeOptions = appendNodeRequire(baseEnv.NODE_OPTIONS, path.join(moduleDir, \"register-tty.cjs\"))\n return {\n ...baseEnv,\n NODE_OPTIONS: nodeOptions,\n }\n}\n\nfunction ensureJsxRuntimeShim(projectRoot: string): void {\n const shimDir = path.join(projectRoot, \"node_modules\", \"playwright\")\n fs.mkdirSync(shimDir, { recursive: true })\n const shims = [\n { file: \"jsx-runtime.js\", target: \"react/jsx-runtime\" },\n { file: \"jsx-dev-runtime.js\", target: \"react/jsx-dev-runtime\" },\n ]\n\n for (const { file, target } of shims) {\n const filePath = path.join(shimDir, file)\n if (!fs.existsSync(filePath)) {\n const content = `export * from \"${target}\";\\nexport { default } from \"${target}\";\\n`\n fs.writeFileSync(filePath, content, \"utf8\")\n }\n }\n}\n\nfunction appendNodeRequire(existing: string | undefined, modulePath: string): string {\n const flag = `--require=${modulePath}`\n if (!existing || existing.length === 0) {\n return flag\n }\n return `${existing} ${flag}`\n}\n"],"names":["require","createRequire","import","url","moduleDir","path","dirname","fileURLToPath","shouldForceTty","process","stdout","isTTY","env","FORCE_COLOR","VITEST_COVERAGE_CANDIDATES","COMBINED_COVERAGE_ENV_VAR","isAider","IS_AIDER","undefined","console","warn","runTests","userArgs","argv","slice","buildSpecsMap","includes","auto","showMapping","filteredArgs","filter","arg","Error","playwrightCoverage","loadPlaywrightCoverageConfig","vitestCoverage","loadVitestCoverageConfig","combinedCoverage","resolveCombinedCoverage","buildSpecsMapFromCoverage","shouldGenerateCoverageReport","enabled","cleanCoverageArtifacts","config","testError","runVitest","disableCoverage","log","playwrightArgs","resolveAutoPlaywrightArgs","runPlaywright","error","finalizeCoverage","then","exit","catch","CoverageThresholdError","stack","String","coverage","combinedConfig","vitestArgs","vitestConfig","resolveVitestConfig","hasCustomConfig","some","startsWith","push","launcher","resolveVitestLauncher","withRegisterShim","RB_DISABLE_COVERAGE","nodeCoverageDir","resolveNodeCoverageDir","fsPromises","mkdir","recursive","NODE_V8_COVERAGE","spawnWithLogs","name","args","successMessage","failureMessage","convertNodeCoverage","workspaceRoot","findWorkspaceRoot","cwd","specSourceFiles","findSpecSourceFiles","rootDir","length","filesMapDir","join","testResultsRoot","rm","force","specSourceFile","specProjectPath","relative","specWorkspacePath","toPosixPath","testFile","resolvePlaywrightSpecFile","removeCoverageFiles","failed","runError","coveredFiles","collectCoveredFiles","impactedFiles","map","filePath","relativePath","sort","outputFile","writeFile","JSON","stringify","spec","files","mapFiles","findFilesMapJson","gitChanges","getGitChanges","renameMap","Map","change","kind","oldPath","newPath","specRootAbs","matchesCollectCoverageFrom","createCollectCoverageMatcher","collectCoverageFrom","directSpecChanges","Set","sourceChanges","oldAbs","newAbs","isSpecSourceFile","fs","existsSync","add","oldMatches","newMatches","abs","size","parsedMaps","file","json","readJson","Array","isArray","entry","specsByImpactedFile","resolvedSpec","resolveRenamedPath","list","get","set","unmappedSourceChanges","has","selectedSpecs","triggersBySpec","specs","forEach","current","oldSpecs","newSpecs","key","allSpecs","missingSpecs","specsToRun","from","triggers","trigger","playwrightFiles","specAbs","isSubpath","totalSpecFiles","patterns","matches","fg","absolute","onlyFiles","result","spawnSync","encoding","status","stderr","tokens","split","Boolean","changes","i","record","pathPart","isRenameOrCopyStatus","next","original","visited","candidate","root","isAbsolute","absolutePath","specRootAbsolute","test","projectRoot","buildSpecRoot","isBuildSpecProject","builtCandidate","normalizeBuiltSpecPath","builtAbsolute","resolve","endsWith","replace","input","sep","dir","pkgPath","parsed","parse","readFileSync","workspaces","parent","configPath","ensureJsxRuntimeShim","resolvePlaywrightLauncher","cliPath","resolveCliPath","command","execPath","localBin","searchRoots","base","paths","_error","pkgDir","pkgJson","binPath","bin","vitest","userConfig","findVitestConfig","bundledConfig","baseDir","candidates","fullPath","options","loadCoverageOptions","optional","createCoverageConfig","coverageEnabled","coverageReportDir","entries","readdir","scripts","scriptRoots","resolveCollectCoverageRoots","payload","results","script","normalized","normalizeNodeScriptUrl","isNodeModulesPath","isInsideAnyRoot","source","readFile","functions","outDir","coverageFileName","testId","generateCoverageReport","message","raw","rawUrl","_err","normalize","Promise","reject","stdoutBuffer","stderrBuffer","child","spawn","shell","on","data","write","toString","code","baseEnv","nodeOptions","appendNodeRequire","NODE_OPTIONS","shimDir","mkdirSync","shims","target","content","writeFileSync","existing","modulePath","flag"],"mappings":"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"}
|
package/dist/coverage/collect.js
CHANGED
|
@@ -15,7 +15,9 @@ function createCollectCoverageMatcher(patterns, rootDir) {
|
|
|
15
15
|
if (!body) {
|
|
16
16
|
continue;
|
|
17
17
|
}
|
|
18
|
-
const matcher = picomatch(body, {
|
|
18
|
+
const matcher = picomatch(body, {
|
|
19
|
+
dot: true
|
|
20
|
+
});
|
|
19
21
|
if (isExclude) {
|
|
20
22
|
excludeMatchers.push(matcher);
|
|
21
23
|
} else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collect.js","sources":["../../src/coverage/collect.ts"],"sourcesContent":["import path from \"node:path\"\n\nimport picomatch from \"picomatch\"\n\n\nexport function createCollectCoverageMatcher(patterns: unknown, rootDir: unknown): (absolutePath: string) => boolean {\n const normalizedRoot = path.resolve(String(rootDir ?? \"\"))\n\n const includeMatchers: Array<(candidate: string) => boolean> = []\n const excludeMatchers: Array<(candidate: string) => boolean> = []\n\n if (Array.isArray(patterns)) {\n for (const pattern of patterns) {\n const raw = String(pattern ?? \"\").trim()\n if (!raw) {\n continue\n }\n\n const isExclude = raw.startsWith(\"!\")\n const body = toPosix(isExclude ? raw.slice(1) : raw)\n if (!body) {\n continue\n }\n\n const matcher = picomatch(body, { dot: true })\n if (isExclude) {\n excludeMatchers.push(matcher)\n } else {\n includeMatchers.push(matcher)\n }\n }\n }\n\n if (includeMatchers.length === 0) {\n return () => false\n }\n\n return (absolutePath) => {\n const normalizedAbsolute = path.resolve(String(absolutePath ?? \"\"))\n if (!normalizedAbsolute) {\n return false\n }\n\n const relativePosix = toPosix(path.relative(normalizedRoot, normalizedAbsolute))\n const absolutePosix = toPosix(normalizedAbsolute)\n const candidates = new Set([absolutePosix, relativePosix])\n\n if (relativePosix) {\n candidates.add(`./${relativePosix}`)\n }\n\n const candidateList = Array.from(candidates)\n const included = includeMatchers.some((matcher) => candidateList.some((candidate) => matcher(candidate)))\n if (!included) {\n return false\n }\n\n return !excludeMatchers.some((matcher) => candidateList.some((candidate) => matcher(candidate)))\n }\n}\n\nexport function toPosix(input: unknown): string {\n return String(input ?? \"\").split(path.sep).join(\"/\")\n}\n\nexport function isInsideAnyRoot(absolutePath: string, roots: unknown): boolean {\n const normalizedAbsolute = path.resolve(String(absolutePath ?? \"\"))\n return (Array.isArray(roots) ? roots : []).some((root) => {\n const normalizedRoot = path.resolve(String(root ?? \"\"))\n const relative = path.relative(normalizedRoot, normalizedAbsolute)\n return relative === \"\" || (!relative.startsWith(\"..\") && !path.isAbsolute(relative))\n })\n}\n\nexport function resolveCollectCoverageRoots(patterns: unknown, rootDir: unknown): string[] {\n const resolvedRootDir = path.resolve(String(rootDir ?? \"\"))\n const roots = new Set([resolvedRootDir])\n\n if (!Array.isArray(patterns)) {\n return Array.from(roots)\n }\n\n for (const pattern of patterns) {\n const raw = String(pattern ?? \"\").trim()\n if (!raw) {\n continue\n }\n\n const cleaned = raw.startsWith(\"!\") ? raw.slice(1) : raw\n if (!cleaned) {\n continue\n }\n\n const prefix = staticGlobPrefix(cleaned)\n if (!prefix) {\n continue\n }\n\n roots.add(path.resolve(resolvedRootDir, prefix))\n }\n\n return Array.from(roots)\n}\n\nfunction staticGlobPrefix(pattern: unknown): string | null {\n const normalized = String(pattern ?? \"\").trim()\n if (!normalized) {\n return null\n }\n\n const firstGlobIndex = findFirstGlobIndex(normalized)\n const prefix = firstGlobIndex === -1 ? normalized : normalized.slice(0, firstGlobIndex)\n\n if (!prefix) {\n return null\n }\n\n if (prefix.endsWith(\"/\") || prefix.endsWith(path.sep)) {\n return prefix\n }\n\n const posix = prefix.split(path.sep).join(\"/\")\n return path.posix.dirname(posix)\n}\n\nfunction findFirstGlobIndex(value: string): number {\n for (let i = 0; i < value.length; i += 1) {\n const char = value[i]\n if (char === \"*\" || char === \"?\" || char === \"[\" || char === \"{\") {\n return i\n }\n }\n return -1\n}\n"],"names":[],"mappings":";;AAKO,
|
|
1
|
+
{"version":3,"file":"collect.js","sources":["../../src/coverage/collect.ts"],"sourcesContent":["import path from \"node:path\"\n\nimport picomatch from \"picomatch\"\n\n\nexport function createCollectCoverageMatcher(patterns: unknown, rootDir: unknown): (absolutePath: string) => boolean {\n const normalizedRoot = path.resolve(String(rootDir ?? \"\"))\n\n const includeMatchers: Array<(candidate: string) => boolean> = []\n const excludeMatchers: Array<(candidate: string) => boolean> = []\n\n if (Array.isArray(patterns)) {\n for (const pattern of patterns) {\n const raw = String(pattern ?? \"\").trim()\n if (!raw) {\n continue\n }\n\n const isExclude = raw.startsWith(\"!\")\n const body = toPosix(isExclude ? raw.slice(1) : raw)\n if (!body) {\n continue\n }\n\n const matcher = picomatch(body, { dot: true })\n if (isExclude) {\n excludeMatchers.push(matcher)\n } else {\n includeMatchers.push(matcher)\n }\n }\n }\n\n if (includeMatchers.length === 0) {\n return () => false\n }\n\n return (absolutePath) => {\n const normalizedAbsolute = path.resolve(String(absolutePath ?? \"\"))\n if (!normalizedAbsolute) {\n return false\n }\n\n const relativePosix = toPosix(path.relative(normalizedRoot, normalizedAbsolute))\n const absolutePosix = toPosix(normalizedAbsolute)\n const candidates = new Set([absolutePosix, relativePosix])\n\n if (relativePosix) {\n candidates.add(`./${relativePosix}`)\n }\n\n const candidateList = Array.from(candidates)\n const included = includeMatchers.some((matcher) => candidateList.some((candidate) => matcher(candidate)))\n if (!included) {\n return false\n }\n\n return !excludeMatchers.some((matcher) => candidateList.some((candidate) => matcher(candidate)))\n }\n}\n\nexport function toPosix(input: unknown): string {\n return String(input ?? \"\").split(path.sep).join(\"/\")\n}\n\nexport function isInsideAnyRoot(absolutePath: string, roots: unknown): boolean {\n const normalizedAbsolute = path.resolve(String(absolutePath ?? \"\"))\n return (Array.isArray(roots) ? roots : []).some((root) => {\n const normalizedRoot = path.resolve(String(root ?? \"\"))\n const relative = path.relative(normalizedRoot, normalizedAbsolute)\n return relative === \"\" || (!relative.startsWith(\"..\") && !path.isAbsolute(relative))\n })\n}\n\nexport function resolveCollectCoverageRoots(patterns: unknown, rootDir: unknown): string[] {\n const resolvedRootDir = path.resolve(String(rootDir ?? \"\"))\n const roots = new Set([resolvedRootDir])\n\n if (!Array.isArray(patterns)) {\n return Array.from(roots)\n }\n\n for (const pattern of patterns) {\n const raw = String(pattern ?? \"\").trim()\n if (!raw) {\n continue\n }\n\n const cleaned = raw.startsWith(\"!\") ? raw.slice(1) : raw\n if (!cleaned) {\n continue\n }\n\n const prefix = staticGlobPrefix(cleaned)\n if (!prefix) {\n continue\n }\n\n roots.add(path.resolve(resolvedRootDir, prefix))\n }\n\n return Array.from(roots)\n}\n\nfunction staticGlobPrefix(pattern: unknown): string | null {\n const normalized = String(pattern ?? \"\").trim()\n if (!normalized) {\n return null\n }\n\n const firstGlobIndex = findFirstGlobIndex(normalized)\n const prefix = firstGlobIndex === -1 ? normalized : normalized.slice(0, firstGlobIndex)\n\n if (!prefix) {\n return null\n }\n\n if (prefix.endsWith(\"/\") || prefix.endsWith(path.sep)) {\n return prefix\n }\n\n const posix = prefix.split(path.sep).join(\"/\")\n return path.posix.dirname(posix)\n}\n\nfunction findFirstGlobIndex(value: string): number {\n for (let i = 0; i < value.length; i += 1) {\n const char = value[i]\n if (char === \"*\" || char === \"?\" || char === \"[\" || char === \"{\") {\n return i\n }\n }\n return -1\n}\n"],"names":["createCollectCoverageMatcher","patterns","rootDir","normalizedRoot","path","resolve","String","includeMatchers","excludeMatchers","Array","isArray","pattern","raw","trim","isExclude","startsWith","body","toPosix","slice","matcher","picomatch","dot","push","length","absolutePath","normalizedAbsolute","relativePosix","relative","absolutePosix","candidates","Set","add","candidateList","from","included","some","candidate","input","split","sep","join","isInsideAnyRoot","roots","root","isAbsolute","resolveCollectCoverageRoots","resolvedRootDir","cleaned","prefix","staticGlobPrefix","normalized","firstGlobIndex","findFirstGlobIndex","endsWith","posix","dirname","value","i","char"],"mappings":"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"}
|