supercov 0.0.13 → 0.0.14
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/README.md +12 -11
- package/docs/performance.md +20 -4
- package/docs/workspace-isolation.md +1 -1
- package/package.json +7 -7
- package/runtime/javascript/atomic.js +21 -1
- package/runtime/javascript/launchSupervisor.js +6 -0
- package/runtime/javascript/playwright.js +15 -10
- package/runtime/javascript/playwrightReporter.js +17 -6
- package/runtime/javascript/register.mjs +27 -6
- package/runtime/javascript/runtime.js +46 -0
package/README.md
CHANGED
|
@@ -129,10 +129,11 @@ npx supercov diff <older-run> <newer-run>
|
|
|
129
129
|
npx supercov merge <first-run-id> <second-run-id>
|
|
130
130
|
```
|
|
131
131
|
|
|
132
|
-
`supercov runs`
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
132
|
+
`supercov runs` always includes coverage percentages. Supercov derives a
|
|
133
|
+
missing disposable query view from the run's immutable evidence before printing
|
|
134
|
+
that row; whether the view was already available is never exposed in the CLI.
|
|
135
|
+
`supercov runs <run-id>` prints the same summary as
|
|
136
|
+
`supercov runs <run-id> coverage`.
|
|
136
137
|
|
|
137
138
|
Coverage queries use `--filter all` by default, matching conventional coverage
|
|
138
139
|
tools: every executed attempt contributes, including attempts that later fail.
|
|
@@ -244,17 +245,17 @@ state writes use sibling-temp files, fsync, and atomic rename; lock acquisition
|
|
|
244
245
|
uses exclusive creation and fsync. Published `run.json` is the durable terminal
|
|
245
246
|
record, so terminal work state is not retained.
|
|
246
247
|
|
|
247
|
-
Retention is deterministic because
|
|
248
|
+
Retention is deterministic because run records store their UTC start time:
|
|
248
249
|
|
|
249
250
|
```sh
|
|
250
|
-
npx supercov
|
|
251
|
-
npx supercov
|
|
252
|
-
npx supercov clean --keep 20 #
|
|
251
|
+
npx supercov clean # removes all stored runs and the shared build cache
|
|
252
|
+
npx supercov clean --dry-run # previews the default full cleanup
|
|
253
|
+
npx supercov clean --keep 20 # explicitly retains the 20 newest runs
|
|
253
254
|
```
|
|
254
255
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
256
|
+
Cleanup never runs automatically. `clean` removes explicit history beyond the
|
|
257
|
+
requested retention, orphan/terminal transient data, and the shared build
|
|
258
|
+
cache. It acquires the same lock
|
|
258
259
|
as a coverage run, refuse to race an active run, and never touch files outside
|
|
259
260
|
`.supercov/`.
|
|
260
261
|
|
package/docs/performance.md
CHANGED
|
@@ -43,6 +43,20 @@ reported separately from Supercov's recorded phases.
|
|
|
43
43
|
|
|
44
44
|
## Reference measurement, not a guarantee
|
|
45
45
|
|
|
46
|
+
On 2026-08-26, the 30-test Essential SEO Playwright suite running across seven
|
|
47
|
+
cycle-restored VMs produced a 43.02 s uncovered control and two valid warm
|
|
48
|
+
Supercov measurements of 46.30 s and 40.20 s. The slower covered sample is
|
|
49
|
+
1.076x the control and therefore remains below the current 1.1x realistic-suite
|
|
50
|
+
target; the faster result illustrates why multiple alternating pairs are still
|
|
51
|
+
required for a statistically stable benchmark. The 40.20 s run spent 38.63 s
|
|
52
|
+
inside the unchanged test command and 1.04 s total on initialization, workspace
|
|
53
|
+
refresh, adapter restoration and evidence publication. It attributed 6,727
|
|
54
|
+
server records across 30 remote launches with zero corrupt evidence records.
|
|
55
|
+
|
|
56
|
+
VM-image creation is not included in these warm comparisons. A changed engine
|
|
57
|
+
fingerprint intentionally caused a one-time 119 s rebake before the first
|
|
58
|
+
post-change run; comparing that cold run with a warm control would be invalid.
|
|
59
|
+
|
|
46
60
|
On 2026-08-24, the 29-test Essential SEO offline suite on the development Mac
|
|
47
61
|
produced this warm pair:
|
|
48
62
|
|
|
@@ -73,8 +87,10 @@ Before raw-evidence-only storage, the reference run retained 4.5 MB of reports
|
|
|
73
87
|
and 1.7 MB across 178 loose evidence files. Its canonical compressed JSON was
|
|
74
88
|
0.9 MB. The execution evidence alone packed to about 121 KiB; current archives
|
|
75
89
|
also embed the exact denominator manifest and are the sole coverage artifact.
|
|
76
|
-
Every CLI query derives its view from the archive
|
|
77
|
-
|
|
90
|
+
Every CLI query derives its view from the archive. The first query builds a
|
|
91
|
+
disposable integrity-bound binary index; later queries reuse it while the run
|
|
92
|
+
identity remains valid. The index is an implementation detail and can always be
|
|
93
|
+
deleted and reconstructed.
|
|
78
94
|
These numbers are application- and filesystem-specific optimization baselines.
|
|
79
95
|
An exact matching Vite build is also reused across runs, removing the measured
|
|
80
96
|
4.87-second repeated build; any source/configuration/toolchain-key change falls
|
|
@@ -88,8 +104,8 @@ phase and 40.49 seconds total: 0.07 seconds initialization, 0.36 seconds
|
|
|
88
104
|
workspace refresh, 0.05 seconds adapter setup, 39.84 seconds in the unchanged
|
|
89
105
|
test command, and 0.12 seconds evidence validation/archive publication. Fresh
|
|
90
106
|
process queries for summary, files, and gaps each took 0.16–0.20 seconds on
|
|
91
|
-
this run
|
|
92
|
-
naturally variable part of the total.
|
|
107
|
+
this run before the reusable query index was introduced. Test execution is
|
|
108
|
+
still the dominant and naturally variable part of the total.
|
|
93
109
|
|
|
94
110
|
## Isolation strategy trade-offs
|
|
95
111
|
|
|
@@ -16,7 +16,7 @@ is below the project's `.supercov/` directory:
|
|
|
16
16
|
| `work/<run>/state.json` | In-flight lifecycle record; removed after atomic run publication. |
|
|
17
17
|
| `work/<run>/run-publication/` | Incomplete run staging; atomically renamed or removed on recovery. |
|
|
18
18
|
| `evidence/<run>/` | Loose in-flight evidence; packed and removed after publication. |
|
|
19
|
-
| `runs/<run>/` | Immutable `evidence.raw.gz` (manifest plus raw execution evidence) and `run.json`; retained until explicit
|
|
19
|
+
| `runs/<run>/` | Immutable `evidence.raw.gz` (manifest plus raw execution evidence) and `run.json`; retained until explicit `clean`. Derived query views are cached only after their first query. |
|
|
20
20
|
| `cache/instrumented-workspace/<project>/` | Stable physical fallback and provider snapshot cache. |
|
|
21
21
|
| `cache/instrumented-workspace/.<project>.staging-*` | Unpublished cache transaction; removed on error or recovery. |
|
|
22
22
|
| `cache/instrumented-workspace/.<project>.previous-*` | Last complete cache generation during publication; restored or removed on recovery. |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "supercov",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.14",
|
|
4
4
|
"description": "Zero-edit, runner-aware coverage completeness for JavaScript test suites",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -63,12 +63,12 @@
|
|
|
63
63
|
"prepublishOnly": "npm run release:check"
|
|
64
64
|
},
|
|
65
65
|
"optionalDependencies": {
|
|
66
|
-
"@supercov/cli-darwin-arm64": "0.0.
|
|
67
|
-
"@supercov/cli-darwin-x64": "0.0.
|
|
68
|
-
"@supercov/cli-linux-arm64-gnu": "0.0.
|
|
69
|
-
"@supercov/cli-linux-arm64-musl": "0.0.
|
|
70
|
-
"@supercov/cli-linux-x64-gnu": "0.0.
|
|
71
|
-
"@supercov/cli-linux-x64-musl": "0.0.
|
|
66
|
+
"@supercov/cli-darwin-arm64": "0.0.14",
|
|
67
|
+
"@supercov/cli-darwin-x64": "0.0.14",
|
|
68
|
+
"@supercov/cli-linux-arm64-gnu": "0.0.14",
|
|
69
|
+
"@supercov/cli-linux-arm64-musl": "0.0.14",
|
|
70
|
+
"@supercov/cli-linux-x64-gnu": "0.0.14",
|
|
71
|
+
"@supercov/cli-linux-x64-musl": "0.0.14"
|
|
72
72
|
},
|
|
73
73
|
"peerDependencies": {
|
|
74
74
|
"@playwright/test": ">=1.55.0",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { mkdirSync, openSync, closeSync, fsyncSync, renameSync, rmSync, writeFileSync, } from "node:fs";
|
|
1
|
+
import { appendFileSync, existsSync, mkdirSync, openSync, closeSync, fsyncSync, renameSync, rmSync, writeFileSync, } from "node:fs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { dirname } from "node:path";
|
|
4
4
|
function fsyncDirectory(path) {
|
|
@@ -38,6 +38,26 @@ export function atomicWriteFileSync(path, data, options) {
|
|
|
38
38
|
rmSync(temporary, { force: true });
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
+
/** Append one recoverable JSONL record and make the completed line durable. */
|
|
42
|
+
export function appendJsonLineDurableSync(path, data) {
|
|
43
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
44
|
+
const existed = existsSync(path);
|
|
45
|
+
const descriptor = openSync(path, "a", 0o600);
|
|
46
|
+
try {
|
|
47
|
+
writeFileSync(descriptor, data.endsWith("\n") ? data : `${data}\n`);
|
|
48
|
+
fsyncSync(descriptor);
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
closeSync(descriptor);
|
|
52
|
+
}
|
|
53
|
+
if (!existed)
|
|
54
|
+
fsyncDirectory(dirname(path));
|
|
55
|
+
}
|
|
56
|
+
/** Append a complete local record; process exit closes it before publication. */
|
|
57
|
+
export function appendJsonLineSync(path, data) {
|
|
58
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
59
|
+
appendFileSync(path, data.endsWith("\n") ? data : `${data}\n`, { mode: 0o600 });
|
|
60
|
+
}
|
|
41
61
|
/** Atomically publish a fully prepared file or directory and persist its entry. */
|
|
42
62
|
export function atomicRenameSync(source, destination) {
|
|
43
63
|
mkdirSync(dirname(destination), { recursive: true });
|
|
@@ -190,6 +190,7 @@ export function guestCoverageEnvironment(mapping, coverageEnvironment = process.
|
|
|
190
190
|
...translated,
|
|
191
191
|
SUPERCOV_PROJECT_ROOT: mapping.guestRoot,
|
|
192
192
|
SUPERCOV_CJS_INTERCEPT: "1",
|
|
193
|
+
SUPERCOV_DURABLE_EVIDENCE_EACH_TEST: "1",
|
|
193
194
|
NODE_OPTIONS: appendNodeImport(existingEnvironment.NODE_OPTIONS, registerUrl),
|
|
194
195
|
};
|
|
195
196
|
}
|
|
@@ -556,6 +557,11 @@ export function installLaunchSupervisor() {
|
|
|
556
557
|
const originalLoad = moduleLoader._load;
|
|
557
558
|
moduleLoader._load = function supercovCapabilityLoad(request, parent, isMain) {
|
|
558
559
|
const exports = originalLoad.call(this, request, parent, isMain);
|
|
560
|
+
// A user's test command may itself be implemented by an installed
|
|
561
|
+
// package. That package can import a VM/container/process SDK without
|
|
562
|
+
// any project-owned module ever crossing the SDK boundary. Inspect all
|
|
563
|
+
// newly loaded export graphs (deduplicated by `exportedValues`) so
|
|
564
|
+
// capability discovery remains provider- and runner-neutral.
|
|
559
565
|
inspectExports(exports);
|
|
560
566
|
return exports;
|
|
561
567
|
};
|
|
@@ -12,10 +12,11 @@ import { mkdirSync, readFileSync, rmSync } from "node:fs";
|
|
|
12
12
|
import http from "node:http";
|
|
13
13
|
import https from "node:https";
|
|
14
14
|
import { syncBuiltinESMExports } from "node:module";
|
|
15
|
-
import {
|
|
15
|
+
import { relative, resolve, sep } from "node:path";
|
|
16
16
|
import * as standardPlaywright from "@playwright/test";
|
|
17
|
+
import * as coverageRuntime from "./runtime.js";
|
|
17
18
|
import { inferTestProvenance } from "./provenance.js";
|
|
18
|
-
import {
|
|
19
|
+
import { appendJsonLineDurableSync, appendJsonLineSync } from "./atomic.js";
|
|
19
20
|
import { COVERAGE_PHASE_HEADER, COVERAGE_PHASE_COOKIE, COVERAGE_SCOPE_COOKIE, COVERAGE_SCOPE_HEADER, COVERAGE_CARRIER_ENV, encodeCoverageCarrier, encodeCoverageScope, serverEvidenceDirectory, serverEvidencePath, } from "./transport.js";
|
|
20
21
|
export * from "@playwright/test";
|
|
21
22
|
const generatedTargetModule = "__SUPERCOV_PLAYWRIGHT_MODULE__";
|
|
@@ -32,6 +33,8 @@ const adapter = (targetModule === "@playwright/test"
|
|
|
32
33
|
const base = (adapter[targetTestExport] ?? adapter.test);
|
|
33
34
|
const baseExpect = adapter.expect;
|
|
34
35
|
const GENERATED_EVIDENCE_DIRECTORY = "__SUPERCOV_EVIDENCE_DIRECTORY__";
|
|
36
|
+
const evidenceWriterIdentity = () => (process.env.SUPERCOV_EXECUTION_LOG_SHARD ?? `pid-${process.pid}`)
|
|
37
|
+
.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
35
38
|
const GENERATED_RUN_ID = "__SUPERCOV_RUN_ID__";
|
|
36
39
|
const PHASE_STORAGE_KEY = "__supercov_phase";
|
|
37
40
|
const ACTION_METHODS = new Set([
|
|
@@ -329,6 +332,11 @@ class CoveragePhaseController {
|
|
|
329
332
|
},
|
|
330
333
|
});
|
|
331
334
|
this.proxyCache.set(target, proxy);
|
|
335
|
+
// Playwright's built-in `page` fixture is created through the wrapped
|
|
336
|
+
// worker-scoped browser. The test-scoped fixture sees that proxy again;
|
|
337
|
+
// treating our own proxy as a fresh target would nest wrappers, emit two
|
|
338
|
+
// phases for one operation, and perform every browser activation twice.
|
|
339
|
+
this.proxyCache.set(proxy, proxy);
|
|
332
340
|
return proxy;
|
|
333
341
|
}
|
|
334
342
|
createPhase(kind, operation, causedByPhaseId, source = callerSource()) {
|
|
@@ -467,7 +475,7 @@ class CoveragePhaseController {
|
|
|
467
475
|
let activeController;
|
|
468
476
|
let bridgedAssertionDepth = 0;
|
|
469
477
|
const controllers = new Map();
|
|
470
|
-
const directRuntime = () => globalThis.__SUPERCOV_DIRECT_RUNTIME__;
|
|
478
|
+
const directRuntime = () => globalThis.__SUPERCOV_DIRECT_RUNTIME__ ?? coverageRuntime;
|
|
471
479
|
globalThis.__SUPERCOV_ASSERTION_PHASE_BRIDGE__ = (operation, source, callback) => {
|
|
472
480
|
const controller = activeController;
|
|
473
481
|
const runtime = directRuntime();
|
|
@@ -829,8 +837,6 @@ const instrumentedTest = base.extend({
|
|
|
829
837
|
// Emit an artifact even when this test touched no application source.
|
|
830
838
|
// A complete test-to-coverage matrix must also identify tests that are
|
|
831
839
|
// removable without changing coverage.
|
|
832
|
-
const outputPath = testInfo.outputPath("mcdc.json");
|
|
833
|
-
mkdirSync(dirname(outputPath), { recursive: true });
|
|
834
840
|
const testFile = relative(process.cwd(), testInfo.file)
|
|
835
841
|
.split(sep)
|
|
836
842
|
.join("/");
|
|
@@ -854,7 +860,6 @@ const instrumentedTest = base.extend({
|
|
|
854
860
|
server,
|
|
855
861
|
};
|
|
856
862
|
const serialized = `${JSON.stringify(payload)}\n`;
|
|
857
|
-
atomicWriteFileSync(outputPath, serialized);
|
|
858
863
|
// Pool runners may cycle-restore a VM immediately after Playwright
|
|
859
864
|
// exits, which can discard or overwrite the normal artifact copy.
|
|
860
865
|
// Write one uniquely named, one-shot evidence file to the runner's
|
|
@@ -865,10 +870,10 @@ const instrumentedTest = base.extend({
|
|
|
865
870
|
: GENERATED_EVIDENCE_DIRECTORY);
|
|
866
871
|
if (evidenceDirectory) {
|
|
867
872
|
const resolvedDirectory = resolve(process.cwd(), evidenceDirectory);
|
|
868
|
-
const
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
873
|
+
const append = process.env.SUPERCOV_DURABLE_EVIDENCE_EACH_TEST === "1"
|
|
874
|
+
? appendJsonLineDurableSync
|
|
875
|
+
: appendJsonLineSync;
|
|
876
|
+
append(resolve(resolvedDirectory, `playwright-worker-${evidenceWriterIdentity()}-${process.pid}.mcdc.jsonl`), serialized);
|
|
872
877
|
}
|
|
873
878
|
}
|
|
874
879
|
finally {
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { mkdirSync } from "node:fs";
|
|
2
1
|
import { relative, resolve, sep } from "node:path";
|
|
3
2
|
import { inferTestProvenance } from "./provenance.js";
|
|
4
|
-
import {
|
|
3
|
+
import { appendJsonLineDurableSync, appendJsonLineSync } from "./atomic.js";
|
|
5
4
|
const GENERATED_EVIDENCE_DIRECTORY = "__SUPERCOV_EVIDENCE_DIRECTORY__";
|
|
5
|
+
const evidenceWriterIdentity = () => (process.env.SUPERCOV_EXECUTION_LOG_SHARD ?? `pid-${process.pid}`)
|
|
6
|
+
.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
6
7
|
/** Records outcomes even when browser or fixture startup fails before coverage. */
|
|
7
8
|
export default class SupercovPlaywrightReporter {
|
|
9
|
+
records = [];
|
|
8
10
|
onTestEnd(test, result) {
|
|
9
11
|
const evidenceDirectory = process.env["SUPERCOV_EVIDENCE_DIR"] ??
|
|
10
12
|
(GENERATED_EVIDENCE_DIRECTORY.startsWith("__")
|
|
@@ -32,9 +34,18 @@ export default class SupercovPlaywrightReporter {
|
|
|
32
34
|
browser: [],
|
|
33
35
|
server: [],
|
|
34
36
|
};
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
this.records.push(payload);
|
|
38
|
+
}
|
|
39
|
+
onEnd() {
|
|
40
|
+
const evidenceDirectory = process.env["SUPERCOV_EVIDENCE_DIR"] ??
|
|
41
|
+
(GENERATED_EVIDENCE_DIRECTORY.startsWith("__")
|
|
42
|
+
? undefined
|
|
43
|
+
: GENERATED_EVIDENCE_DIRECTORY);
|
|
44
|
+
if (!evidenceDirectory || this.records.length === 0)
|
|
45
|
+
return;
|
|
46
|
+
const append = process.env.SUPERCOV_DURABLE_EVIDENCE_EACH_TEST === "1"
|
|
47
|
+
? appendJsonLineDurableSync
|
|
48
|
+
: appendJsonLineSync;
|
|
49
|
+
append(resolve(process.cwd(), evidenceDirectory, `playwright-status-${evidenceWriterIdentity()}-${process.pid}.mcdc.jsonl`), `${this.records.map(record => JSON.stringify(record)).join("\n")}\n`);
|
|
39
50
|
}
|
|
40
51
|
}
|
|
@@ -64,11 +64,18 @@ if (verboseDiagnostics && !process.__SUPERCOV_DIAGNOSTIC_REPORTER__) {
|
|
|
64
64
|
});
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
-
//
|
|
68
|
-
//
|
|
69
|
-
//
|
|
70
|
-
|
|
71
|
-
process.
|
|
67
|
+
// Runner adapters and instrumented modules import the runtime when they need
|
|
68
|
+
// it. Keeping the preload itself thin avoids evaluating the full collector in
|
|
69
|
+
// npm launchers, web-server supervisors, and other Node children that never
|
|
70
|
+
// execute measured JavaScript.
|
|
71
|
+
if (process.env.SUPERCOV_DURABLE_EVIDENCE_EACH_TEST === "1") {
|
|
72
|
+
// A translated remote/VM command can execute an ahead-of-run transformed
|
|
73
|
+
// test through an opaque runner that bypasses the ordinary Playwright or
|
|
74
|
+
// node:test import boundary. The remote-launch adapter marks that process;
|
|
75
|
+
// initialize the runtime before its transformed module can evaluate.
|
|
76
|
+
globalThis.__SUPERCOV_DIRECT_RUNTIME__ ??= await import("./runtime.js");
|
|
77
|
+
process.__SUPERCOV_DIRECT_RUNTIME__ ??= globalThis.__SUPERCOV_DIRECT_RUNTIME__;
|
|
78
|
+
}
|
|
72
79
|
// Workers are independent Node processes and an explicit `execArgv: []`
|
|
73
80
|
// otherwise strips the preload that supplies the isolated runtime. Preserve
|
|
74
81
|
// every user option while adding exactly one Supercov import.
|
|
@@ -107,6 +114,7 @@ const generatedPlaywrightConfig = process.env.SUPERCOV_GENERATED_PLAYWRIGHT_CONF
|
|
|
107
114
|
const generatedJestConfig = process.env.SUPERCOV_GENERATED_JEST_CONFIG;
|
|
108
115
|
const entrypoint = process.argv[1]?.replaceAll("\\", "/") ?? "";
|
|
109
116
|
const playwrightTarget = process.env.SUPERCOV_PLAYWRIGHT_MODULE;
|
|
117
|
+
const projectRoot = process.env.SUPERCOV_PROJECT_ROOT?.replaceAll("\\", "/").replace(/\/$/, "");
|
|
110
118
|
const nodeTestWrapper = new URL("./nodeTest.js", import.meta.url).href;
|
|
111
119
|
const nodeAssertWrapper = new URL("./nodeAssert.js", import.meta.url).href;
|
|
112
120
|
const nodeAssertStrictWrapper = new URL("./nodeAssertStrict.js", import.meta.url).href;
|
|
@@ -190,6 +198,7 @@ if (generatedPlaywrightConfig &&
|
|
|
190
198
|
}
|
|
191
199
|
if (process.env.SUPERCOV_CJS_INTERCEPT === "1" &&
|
|
192
200
|
process.env.SUPERCOV_INSIDE_PLAYWRIGHT === "1" &&
|
|
201
|
+
!isPlaywrightEntrypoint &&
|
|
193
202
|
process.env.SUPERCOV_INSIDE_VITEST !== "1" &&
|
|
194
203
|
process.env.VITEST !== "true") {
|
|
195
204
|
const target = playwrightTarget ?? "@playwright/test";
|
|
@@ -222,7 +231,18 @@ if (process.env.SUPERCOV_CJS_INTERCEPT === "1" &&
|
|
|
222
231
|
// itself imports the native built-in from Supercov's generated directory, so
|
|
223
232
|
// only first-party callers are redirected and recursion is impossible.
|
|
224
233
|
if (process.env.SUPERCOV_CJS_INTERCEPT === "1") {
|
|
225
|
-
const
|
|
234
|
+
const entrypointBelongsToProject = Boolean(projectRoot && entrypoint.startsWith(`${projectRoot}/`));
|
|
235
|
+
const runnerCanLoadProjectCode = entrypointBelongsToProject ||
|
|
236
|
+
entrypoint === "" ||
|
|
237
|
+
process.env.SUPERCOV_INSIDE_VITEST === "1" ||
|
|
238
|
+
(process.env.SUPERCOV_INSIDE_PLAYWRIGHT === "1" && !isPlaywrightEntrypoint);
|
|
239
|
+
if (!runnerCanLoadProjectCode) {
|
|
240
|
+
// Package-manager and Playwright coordinator processes propagate the
|
|
241
|
+
// preload to their children but never evaluate project test modules.
|
|
242
|
+
// Their worker/child entrypoints install these synchronous CJS hooks.
|
|
243
|
+
// Avoid paying to import three runner adapters in every launcher.
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
226
246
|
const nodeTestAdapter = await import(__rewriteRelativeImportExtension(nodeTestWrapper));
|
|
227
247
|
const cjsNodeTestAdapter = Object.assign(nodeTestAdapter.test, nodeTestAdapter);
|
|
228
248
|
const nodeAssertAdapter = await import(__rewriteRelativeImportExtension(nodeAssertWrapper));
|
|
@@ -248,4 +268,5 @@ if (process.env.SUPERCOV_CJS_INTERCEPT === "1") {
|
|
|
248
268
|
: cjsNodeAssertAdapter;
|
|
249
269
|
return originalLoad.call(this, request, parent, isMain);
|
|
250
270
|
};
|
|
271
|
+
}
|
|
251
272
|
}
|
|
@@ -1014,6 +1014,52 @@ function mcdcEnd(frame, value) {
|
|
|
1014
1014
|
}
|
|
1015
1015
|
return value;
|
|
1016
1016
|
}
|
|
1017
|
+
const directRuntimeApi = {
|
|
1018
|
+
activateCoverageScope,
|
|
1019
|
+
beginBufferedServerEvidence,
|
|
1020
|
+
bindCoverageContext,
|
|
1021
|
+
coverageCarrier,
|
|
1022
|
+
coverageContextEnvironment,
|
|
1023
|
+
coverageContextHeaders,
|
|
1024
|
+
coverageHit,
|
|
1025
|
+
coverageHitV2,
|
|
1026
|
+
coverageSnapshot,
|
|
1027
|
+
decodeProbeV2Vector,
|
|
1028
|
+
defaultEntered,
|
|
1029
|
+
defaultSelected,
|
|
1030
|
+
enableRuntimeSnapshotEvidence,
|
|
1031
|
+
flushBufferedBackgroundEvidence,
|
|
1032
|
+
flushBufferedServerEvidence,
|
|
1033
|
+
loopBegin,
|
|
1034
|
+
loopEnd,
|
|
1035
|
+
loopEntered,
|
|
1036
|
+
mcdcBegin,
|
|
1037
|
+
mcdcCondition,
|
|
1038
|
+
mcdcEnd,
|
|
1039
|
+
mcdcEndV2,
|
|
1040
|
+
optionalCallBegin,
|
|
1041
|
+
optionalCallContinued,
|
|
1042
|
+
optionalCallEnd,
|
|
1043
|
+
optionalCallReached,
|
|
1044
|
+
optionalSelect,
|
|
1045
|
+
parenthesizedAssignmentValue,
|
|
1046
|
+
registerProbeV2,
|
|
1047
|
+
resetCoverage,
|
|
1048
|
+
selectionBegin,
|
|
1049
|
+
selectionEnd,
|
|
1050
|
+
selectionRight,
|
|
1051
|
+
takeNodeAssertionPhases,
|
|
1052
|
+
tryBegin,
|
|
1053
|
+
tryCatch,
|
|
1054
|
+
tryEnd,
|
|
1055
|
+
withCoverageCarrier,
|
|
1056
|
+
withNodeAssertionPhase,
|
|
1057
|
+
withRequestPhase,
|
|
1058
|
+
writeExclusiveBackgroundRecord
|
|
1059
|
+
};
|
|
1060
|
+
globalThis.__SUPERCOV_DIRECT_RUNTIME__ ??= directRuntimeApi;
|
|
1061
|
+
if (typeof process !== "undefined")
|
|
1062
|
+
process.__SUPERCOV_DIRECT_RUNTIME__ ??= directRuntimeApi;
|
|
1017
1063
|
export {
|
|
1018
1064
|
activateCoverageScope,
|
|
1019
1065
|
beginBufferedServerEvidence,
|