monocart-coverage-reports 2.13.2 → 3.1.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/README.md +314 -116
- package/README.zh-Hans.md +315 -117
- package/lib/assets.js +6 -6
- package/lib/cli.js +191 -95
- package/lib/client/cdp-client.js +74 -43
- package/lib/client/coverage-client.js +24 -8
- package/lib/client/ws-session.js +115 -37
- package/lib/converter/ast-visitor.js +5 -7
- package/lib/converter/ast.js +29 -8
- package/lib/converter/collect-source-maps.js +42 -21
- package/lib/converter/converter.js +124 -129
- package/lib/converter/css-coverage.js +76 -0
- package/lib/converter/fake-source-coverage.js +64 -0
- package/lib/converter/find-original-range.js +214 -6
- package/lib/converter/flatten-source-maps.js +2 -4
- package/lib/converter/ignore.js +2 -4
- package/lib/converter/info-branch.js +5 -3
- package/lib/converter/info-function.js +5 -3
- package/lib/converter/info-statement.js +5 -3
- package/lib/converter/range-index.js +78 -0
- package/lib/converter/source-range-merge.js +103 -0
- package/lib/converter/untested.js +30 -60
- package/lib/default/options.js +13 -1
- package/lib/generate.js +44 -26
- package/lib/index.d.ts +52 -4
- package/lib/index.js +35 -41
- package/lib/istanbul/istanbul-summary.js +2 -2
- package/lib/istanbul/istanbul.js +35 -13
- package/lib/packages/monocart-coverage-assets.js +4 -3
- package/lib/packages/monocart-coverage-converter.js +27 -0
- package/lib/packages/monocart-coverage-vendor.js +2 -41
- package/lib/packages/monocart-coverage-vendor.js.LICENSE +3 -221
- package/lib/platform/concurrency.js +47 -43
- package/lib/platform/share.js +8 -1
- package/lib/register/hooks.js +19 -13
- package/lib/register/register.js +5 -3
- package/lib/reports/codacy.js +3 -5
- package/lib/reports/codecov.js +3 -5
- package/lib/reports/console-details.js +5 -5
- package/lib/reports/console-summary.js +4 -4
- package/lib/reports/custom.js +8 -24
- package/lib/reports/markdown-details.js +4 -6
- package/lib/reports/markdown-summary.js +4 -6
- package/lib/reports/raw.js +10 -12
- package/lib/reports/v8-json.js +3 -5
- package/lib/reports/v8.js +3 -5
- package/lib/utils/dedupe.js +1 -1
- package/lib/utils/gc.js +30 -14
- package/lib/utils/markdown.js +2 -2
- package/lib/utils/merge/merge.js +2 -4
- package/lib/utils/merge/range-tree.js +1 -1
- package/lib/utils/request.js +85 -73
- package/lib/utils/snapshot.js +4 -4
- package/lib/utils/source-path.js +26 -11
- package/lib/utils/util.js +67 -42
- package/lib/v8/v8-summary.js +2 -4
- package/lib/v8/v8.js +11 -11
- package/migrate-to-3.md +175 -0
- package/package.json +54 -42
- package/skills/monocart-coverage-reports/SKILL.md +106 -0
- package/skills/monocart-coverage-reports/references/best-practices.md +218 -0
- package/skills/monocart-coverage-reports/references/cli.md +108 -0
- package/skills/monocart-coverage-reports/references/collection.md +154 -0
- package/skills/monocart-coverage-reports/references/filtering-and-sourcemaps.md +170 -0
- package/skills/monocart-coverage-reports/references/reports-and-ci.md +219 -0
- package/skills/monocart-coverage-reports/references/repository-map.md +59 -0
- package/lib/index.mjs +0 -9
- package/lib/register/hooks.mjs +0 -3
- package/lib/register/register.mjs +0 -3
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# Reports, merging, and CI
|
|
2
|
+
|
|
3
|
+
## Select outputs
|
|
4
|
+
|
|
5
|
+
| Need | Report | Input support / artifact |
|
|
6
|
+
| --- | --- | --- |
|
|
7
|
+
| Native interactive V8/CSS report | `v8` | V8 only; `index.html` + assets |
|
|
8
|
+
| Native machine-readable V8 results | `v8-json` | V8 only; `coverage-report.json` |
|
|
9
|
+
| Istanbul UI | `html` | Istanbul or converted V8 |
|
|
10
|
+
| Interoperable coverage | `lcovonly` | Istanbul or converted V8; `lcov.info` |
|
|
11
|
+
| XML coverage | `cobertura`, `clover` | Istanbul or converted V8 |
|
|
12
|
+
| Istanbul maps / summary | `json`, `json-summary` | Not native V8 JSON and not MCR raw |
|
|
13
|
+
| Console | `console-summary`, `console-details` | V8 or Istanbul |
|
|
14
|
+
| CI summary | `markdown-summary`, `markdown-details` | `coverage-summary.md`, `coverage-details.md` |
|
|
15
|
+
| Upload data | `codecov`, `codacy` | `codecov.json`, `codacy.json` |
|
|
16
|
+
| Later merging | `raw` | Original inputs and sources, not rendered output |
|
|
17
|
+
|
|
18
|
+
Multiple report syntax is `reports: ['v8', ['html', { subdir: 'istanbul' }], 'lcovonly']`. Keep multiple HTML formats in separate paths. Native V8 report options use `outputFile`; Istanbul JSON/XML options commonly use `file` — check the declaration for the selected reporter rather than assuming one universal option.
|
|
19
|
+
|
|
20
|
+
For a portable single native HTML file, use a report descriptor **inside** the `reports` array:
|
|
21
|
+
|
|
22
|
+
```js
|
|
23
|
+
// inline.config.mjs
|
|
24
|
+
export default {
|
|
25
|
+
outputDir: './coverage-reports',
|
|
26
|
+
reports: [['v8', { inline: true }]]
|
|
27
|
+
};
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Do not use `reports: ['v8', { inline: true }]`: the separate object does not configure the V8 reporter. Otherwise upload the HTML **and its assets**. Do not claim Istanbul-only input can recover V8 bytes or CSS metrics. Custom reporters receive format-specific data; inspect the reporter interface and installed implementation rather than treating `CoverageResults` as a universal custom reporter payload.
|
|
31
|
+
|
|
32
|
+
## Enforce thresholds explicitly
|
|
33
|
+
|
|
34
|
+
`watermarks: [50, 80]` changes low/medium/high colors, not exit status. A strict `onEnd` implementation for a 3.x config:
|
|
35
|
+
|
|
36
|
+
```js
|
|
37
|
+
// mcr.config.mjs
|
|
38
|
+
export default {
|
|
39
|
+
outputDir: './coverage-reports',
|
|
40
|
+
reports: ['v8', 'v8-json', 'lcovonly', 'markdown-summary'],
|
|
41
|
+
onEnd(results) {
|
|
42
|
+
if (!results) throw new Error('No coverage results');
|
|
43
|
+
const thresholds = { lines: 80, branches: 70 };
|
|
44
|
+
const errors = [];
|
|
45
|
+
for (const [metric, minimum] of Object.entries(thresholds)) {
|
|
46
|
+
const summary = results.summary?.[metric];
|
|
47
|
+
const pct = summary?.pct;
|
|
48
|
+
if (!summary || summary.total === 0 ||
|
|
49
|
+
typeof pct !== 'number' || !Number.isFinite(pct) || pct < minimum) {
|
|
50
|
+
errors.push(`${metric}: ${pct ?? 'missing'}%, required ${minimum}% (nonempty)`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (errors.length) throw new Error(errors.join('\n'));
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
This deliberately fails absent/zero-total metrics; adapt that policy explicitly if a project legitimately has no branches. Do not coerce `''` into 0 or silently skip missing metrics. For API workflows, also check `generate()`'s return because no usable input can return early without invoking `onEnd`. For ordinary CLI workflows where missing collection must fail, verify a **fresh, nonempty** result as shown below; built-in `mcr test` already treats a missing generated report as an error on 3.x.
|
|
59
|
+
|
|
60
|
+
Use `process.exitCode = 1` or throw rather than calling `process.exit()` before asynchronous writes/cleanup finish. Preserve the test process's original failing status. Test the threshold-failure path, not just passing coverage.
|
|
61
|
+
|
|
62
|
+
## Reject stale reports and missing collection in CI
|
|
63
|
+
|
|
64
|
+
An ordinary CLI run can return success without calling `onEnd` when no usable input was collected. In that case `generate()` returns before its normal output cleanup: **`clean: true` and `cleanCache: true` do not guarantee old reports are removed**. Checking only whether an existing report file exists can therefore pass using a previous run's result.
|
|
65
|
+
|
|
66
|
+
Prefer a new, isolated output directory per CI run. If reusing a fixed directory, remove it **before** collecting, then require a newly generated machine-readable report with nonempty intended metrics. For the threshold config above, save these two scripts in the host root:
|
|
67
|
+
|
|
68
|
+
```js
|
|
69
|
+
// clean-coverage.mjs
|
|
70
|
+
import fs from 'node:fs';
|
|
71
|
+
|
|
72
|
+
// This must be a dedicated report directory, never a source or shared worker directory.
|
|
73
|
+
fs.rmSync('./coverage-reports', { recursive: true, force: true });
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
```js
|
|
77
|
+
// verify-coverage.mjs
|
|
78
|
+
import fs from 'node:fs';
|
|
79
|
+
|
|
80
|
+
const results = JSON.parse(fs.readFileSync('./coverage-reports/coverage-report.json', 'utf8'));
|
|
81
|
+
const lines = results.summary?.lines;
|
|
82
|
+
if (!Array.isArray(results.files) || results.files.length === 0 ||
|
|
83
|
+
!lines || !(lines.total > 0) || typeof lines.pct !== 'number' || !Number.isFinite(lines.pct)) {
|
|
84
|
+
throw new Error('Missing or empty coverage from this run');
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Run all three steps with failure propagation. For example, in a POSIX shell or npm script (replace `./app.js` with the real target):
|
|
89
|
+
|
|
90
|
+
```sh
|
|
91
|
+
node ./clean-coverage.mjs && npx mcr -c mcr.config.mjs -- node ./app.js && node ./verify-coverage.mjs
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Here `&&` belongs to the **outer shell**, not a command string passed to MCR. In other CI environments, use equivalent sequential steps that stop on failure. The cleanup, config, and verifier must use the same dedicated output path. Never clear shared output while workers are collecting; clean once in the coordinator before starting them. The verifier rejects missing/invalid/empty data; `onEnd` separately enforces the configured thresholds, and the original test/CLI failure must still fail CI.
|
|
95
|
+
|
|
96
|
+
## Multi-process collection on one filesystem
|
|
97
|
+
|
|
98
|
+
Use shared options with a dedicated `outputDir` and **no `cleanCache: true` on workers**:
|
|
99
|
+
|
|
100
|
+
```js
|
|
101
|
+
// coverage-options.mjs
|
|
102
|
+
export default {
|
|
103
|
+
outputDir: './coverage-reports/shared',
|
|
104
|
+
reports: ['v8', 'console-summary'],
|
|
105
|
+
cleanCache: false
|
|
106
|
+
};
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
1. Coordinator before workers start: `MCR(options).cleanCache()` once.
|
|
110
|
+
2. Each worker: `await MCR(options).add(itsCoverageData)`; do not generate a final report.
|
|
111
|
+
3. Coordinator **after every worker completes its writes**: `await MCR(options).generate()`; require a nonempty result.
|
|
112
|
+
|
|
113
|
+
`add()` persists inputs to the output's `.cache`; generation merges them. `clean` governs old output artifacts, not the worker input collection lifecycle. Default non-debug generation removes cache afterward. Do not let an early worker generate or clear shared cache while other workers are still adding data.
|
|
114
|
+
|
|
115
|
+
## Merge separate jobs/shards with raw exports
|
|
116
|
+
|
|
117
|
+
Each independent job has its own output and exports raw data:
|
|
118
|
+
|
|
119
|
+
```js
|
|
120
|
+
const options = {
|
|
121
|
+
outputDir: './coverage-reports/shard-1', // unique per job
|
|
122
|
+
reports: [
|
|
123
|
+
['raw', { outputDir: 'raw' }],
|
|
124
|
+
'v8',
|
|
125
|
+
'console-summary'
|
|
126
|
+
],
|
|
127
|
+
cleanCache: true
|
|
128
|
+
};
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
The relative raw directory becomes `coverage-reports/shard-1/raw`. Upload/download the **entire** raw directory, including source files. After every required job finishes, merge in a separate output directory:
|
|
132
|
+
|
|
133
|
+
```js
|
|
134
|
+
// merge-coverage.mjs
|
|
135
|
+
import fs from 'node:fs';
|
|
136
|
+
import path from 'node:path';
|
|
137
|
+
import { MCR } from 'monocart-coverage-reports';
|
|
138
|
+
|
|
139
|
+
const inputDir = [
|
|
140
|
+
'./downloaded/shard-1/raw',
|
|
141
|
+
'./downloaded/shard-2/raw'
|
|
142
|
+
];
|
|
143
|
+
// Check all expected shards BEFORE generation can clean old output.
|
|
144
|
+
for (const dir of inputDir) {
|
|
145
|
+
if (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory()) {
|
|
146
|
+
throw new Error(`Missing coverage shard: ${dir}`);
|
|
147
|
+
}
|
|
148
|
+
const coverageFiles = fs.readdirSync(dir).filter((name) =>
|
|
149
|
+
name.startsWith('coverage-') && name.endsWith('.json'));
|
|
150
|
+
let hasData = false;
|
|
151
|
+
for (const name of coverageFiles) {
|
|
152
|
+
const coverage = JSON.parse(fs.readFileSync(path.join(dir, name), 'utf8'));
|
|
153
|
+
if (coverage.type === 'v8' && Array.isArray(coverage.data)) {
|
|
154
|
+
hasData ||= coverage.data.length > 0;
|
|
155
|
+
for (const entry of coverage.data) {
|
|
156
|
+
const sourceFile = path.join(dir, `source-${entry.id}.json`);
|
|
157
|
+
const source = JSON.parse(fs.readFileSync(sourceFile, 'utf8'));
|
|
158
|
+
if (source.id !== entry.id || typeof source.source !== 'string') {
|
|
159
|
+
throw new Error(`Invalid raw source: ${sourceFile}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
} else if (coverage.type === 'istanbul' && coverage.data &&
|
|
163
|
+
typeof coverage.data === 'object' && !Array.isArray(coverage.data)) {
|
|
164
|
+
hasData ||= Object.keys(coverage.data).length > 0;
|
|
165
|
+
} else {
|
|
166
|
+
throw new Error(`Invalid raw coverage: ${dir}/${name}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (!hasData) throw new Error(`Empty coverage shard: ${dir}`);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const report = MCR({
|
|
173
|
+
inputDir,
|
|
174
|
+
outputDir: './coverage-reports/merged',
|
|
175
|
+
reports: ['v8', 'lcovonly', 'console-summary'],
|
|
176
|
+
cleanCache: true
|
|
177
|
+
});
|
|
178
|
+
const results = await report.generate();
|
|
179
|
+
if (!results || !results.files.length) throw new Error('No merged coverage generated');
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
CLI merge syntax (does **not** perform the preflight above; prefer the validated script in CI):
|
|
183
|
+
|
|
184
|
+
```sh
|
|
185
|
+
npx mcr merge --inputDir "./downloaded/shard-1/raw,./downloaded/shard-2/raw" --outputDir ./coverage-reports/merged -r v8,lcovonly,console-summary
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
- Derive the expected shard list from the CI matrix, not only the directories that happened to download. The script rejects missing/empty shards, malformed coverage, and missing/invalid V8 source files; a successful merge alone does not prove all shards contributed.
|
|
189
|
+
- For independently built artifacts, record and compare source revision/build identifiers and shard IDs before merging; directory checks alone cannot prove the builds match.
|
|
190
|
+
- Keep output separate from inputs; default cleaning must not remove downloaded artifacts. Apply the same path normalization/source revision across jobs.
|
|
191
|
+
- HTML, `v8-json`, LCOV, and `json-summary` are not substitutes for MCR raw input. Do not average percentages.
|
|
192
|
+
- Do not assume arbitrary V8 and Istanbul datasets can be mixed in one run. Prefer consistent raw formats or verify the installed release's mixed-format handling with a targeted fixture.
|
|
193
|
+
- Keep raw artifacts until merge validation passes, then apply the host's retention/security policy. Raw exports are not affected by final `outputFilter`.
|
|
194
|
+
|
|
195
|
+
## CI checklist
|
|
196
|
+
|
|
197
|
+
- Pin a supported Node runtime and install from the existing lockfile.
|
|
198
|
+
- Build the exact coverage target with maps, run tests, then generate/merge only when inputs are flushed.
|
|
199
|
+
- Upload coverage artifacts on failed tests too, using the CI platform's failure-safe artifact step. Do not mask exit codes with unconditional success or `continue-on-error`.
|
|
200
|
+
- Check source scope and nonempty metrics before gating. Supply `all` when coverage must account for files never imported.
|
|
201
|
+
- Publish `coverage-summary.md` to the job summary using the host CI's supported file append mechanism; upload LCOV/Codecov with explicit file paths.
|
|
202
|
+
- Never include tokens in generated HTML/config examples. Do not publicly publish source-containing reports without approval.
|
|
203
|
+
|
|
204
|
+
## Regression snapshots
|
|
205
|
+
|
|
206
|
+
The public `getSnapshot(results)` and `diffSnapshot(old, next, options)` helpers compare coverage results, not raw data merges:
|
|
207
|
+
|
|
208
|
+
```js
|
|
209
|
+
import { getSnapshot, diffSnapshot } from 'monocart-coverage-reports';
|
|
210
|
+
const next = getSnapshot(results);
|
|
211
|
+
const diff = diffSnapshot(previousSnapshot, next, {
|
|
212
|
+
skipEqual: true,
|
|
213
|
+
showSummary: true,
|
|
214
|
+
metrics: ['lines', 'branches']
|
|
215
|
+
});
|
|
216
|
+
if (diff.change) console.log(diff.message);
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Here `results` is a validated generation result and `previousSnapshot` is a loaded baseline. Inspect differences; do not overwrite baselines simply to make tests pass. Identical percentages alone do not guarantee identical mapped source ranges.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Repository navigation and maintenance
|
|
2
|
+
|
|
3
|
+
This is a map of project source files, **not** a JavaScript sourcemap specification. For coverage sourcemaps read [filtering-and-sourcemaps.md](filtering-and-sourcemaps.md).
|
|
4
|
+
|
|
5
|
+
## Installed-package authority
|
|
6
|
+
|
|
7
|
+
From the host application's root:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
node -p "require.resolve('monocart-coverage-reports/package.json')"
|
|
11
|
+
node -p "require.resolve('monocart-coverage-reports')"
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Resolve the manifest's `types` relative to its package directory (current path: `lib/index.d.ts`). Read the installed declarations and `lib/default/options.js` before inventing an API. `README.md`, `README.zh-Hans.md`, and `migrate-to-3.md` describe integration/version behavior. File inspection inside `lib/` does not make those files public package exports. Do not import arbitrary internals into a host application.
|
|
15
|
+
|
|
16
|
+
Current exports: main API, `/register` source-capture preload, `/converter` and `/util` named exports, `/package.json`, and `/skills/*` file resolution. Use the high-level API unless a task explicitly requires lower-level conversion.
|
|
17
|
+
|
|
18
|
+
## Checkout navigation
|
|
19
|
+
|
|
20
|
+
Paths below are relative to the repository root and are generally **not shipped in npm** except `lib/`. When working in a source checkout, read its root `AGENTS.md` first for shared development rules and command side effects. That file is checkout-only; do not require it when using the installed skill.
|
|
21
|
+
|
|
22
|
+
| Task | Read first | Related validation / examples |
|
|
23
|
+
| --- | --- | --- |
|
|
24
|
+
| Public factory, config, cache lifecycle | `lib/index.js`, `lib/index.d.ts`, `lib/default/options.js` | `test/unit/config.test.js`, `test/unit/esm.test.js` |
|
|
25
|
+
| CLI execution, test targets, signals | `lib/cli.js` | `test/unit/cli-test.test.js`, `test/unit/cli-signal.test.js`, `test/specs/node.test.js` |
|
|
26
|
+
| Input reading/merge/report dispatch | `lib/generate.js` | `test/test-merge.js`, `test/test-merge-v8.js`, `test/test-merge-istanbul.js` |
|
|
27
|
+
| Source capture/import hooks | `lib/register/register.js`, `lib/register/hooks.js` | `test/unit/register.test.js`, `test/unit/source-map-comments.test.js` |
|
|
28
|
+
| CDP/WebSocket collection | `lib/client/cdp-client.js`, `lib/client/coverage-client.js`, `lib/client/ws-session.js` | `test/test-client.js`, `test/unit/ws-session.test.js` |
|
|
29
|
+
| Node capture workflows | `test/test-node-env.js`, `test/test-node-api.js`, `test/test-node-ins.js` | `test/test-node-cdp.js`, `test/test-node-vm.js` |
|
|
30
|
+
| Browser data shapes | `test/test-v8.js`, `test/test-puppeteer.js`, `test/test-css.js` | `test/test-istanbul.js` |
|
|
31
|
+
| Conversion and sourcemaps | `lib/converter/converter.js`, `lib/converter/collect-source-maps.js`, `lib/converter/find-original-range.js` | `test/test-esbuild.js`, `test/test-rollup.js`, `test/test-swc.js` |
|
|
32
|
+
| AST metrics/ignore/untested sources | `lib/converter/ast.js`, `lib/converter/ast-visitor.js`, `lib/converter/ignore.js`, `lib/converter/untested.js` | `test/test-v8.js`, `test/test-sections.js` |
|
|
33
|
+
| Filters and normalized paths | `lib/utils/util.js`, `lib/utils/source-path.js`, `lib/generate.js` | `test/unit/output-filter.test.js`, `test/unit/source-path.test.js` |
|
|
34
|
+
| Native V8/Istanbul generation | `lib/v8/v8.js`, `lib/istanbul/istanbul.js`, `lib/reports/` | `test/test-v8-and-istanbul.js`, custom reporter examples under `test/` |
|
|
35
|
+
| Snapshots | `lib/utils/snapshot.js` | `test/check-snapshot.js`, `test/snapshot/` |
|
|
36
|
+
| HTML assets and report UI | `lib/assets.js`, `lib/default/template.html`, `src/app/`, `src/vendor/`, `vite.config.mjs` | `npm run dev`, `npm run build`, `npm run test-runtime` |
|
|
37
|
+
| Runtime compatibility / upgrade | `migrate-to-3.md`, `scripts/test-runtime.js` | `test/unit/node-version.test.js` |
|
|
38
|
+
|
|
39
|
+
## Development validation
|
|
40
|
+
|
|
41
|
+
Read current `package.json` scripts before running them. Typical commands from a checkout with dependencies installed:
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
npm run test-unit
|
|
45
|
+
npm run test-types
|
|
46
|
+
npm run test-runtime
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Unit tests run directly with `node:test`, independently of the MCR CLI and coverage pipeline. For a focused test: `node --test test/unit/config.test.js`. Run `npm run test-unit-coverage` separately to collect coverage through `mcr test`; reports are written to `.temp/coverage-unit/`. For focused coverage: `node ./lib/cli.js test -c test/mcr.config.unit.js test/unit/config.test.js`. Browser/integration scripts may require downloaded browsers, built fixtures, local servers, and more time; inspect the relevant script before running it. `npm run build` invokes `postbuild` and builds test fixtures. `npm test` also runs integration/report generation and documentation generation; it is not a lightweight unit-only check.
|
|
50
|
+
|
|
51
|
+
A fresh checkout needs `npm run build` to generate `lib/packages/` before tests that import these bundles. Rebuild after changing UI, template, or vendor-entry source.
|
|
52
|
+
|
|
53
|
+
Avoid unrelated generated changes. `npm run lint` currently includes `--fix`; inspect its scope before invoking it. Use `npx --no-install eslint src/ test/unit/` for the usual scope without fixes, and explicit paths for other changed source. Do not hand-edit generated `lib/packages/*`, `dist/`, `docs/`, or `test/mock/*/dist/`; use the build/generation workflow. `lib/assets.js` is handwritten runtime source, not generated output. Snapshot baseline changes must be intentional and reviewed, never a way to hide a defect.
|
|
54
|
+
|
|
55
|
+
Do not use `npm run eol` for validation: it removes the index and runs a hard reset. `npm run test:snap` overwrites baselines. `npm run publish` prepares a release through `npm version`, including its build hook and commit/tag creation; obtain explicit approval before release preparation or external writes.
|
|
56
|
+
|
|
57
|
+
When changing public behavior, align implementation, `lib/index.d.ts`, default options, English/Chinese docs, migration notes where applicable, and focused tests. This skill supports MCR 3.x only. Validate the installed package separately when release compatibility matters; do not infer support for other major versions from these recipes.
|
|
58
|
+
|
|
59
|
+
For changes to this skill, verify relative Markdown links, public resolution of `SKILL.md`, npm pack inclusion of **all** references, and any executable examples affected by the API change.
|
package/lib/index.mjs
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import MCR from './index.js';
|
|
2
|
-
export default MCR;
|
|
3
|
-
export const CoverageReport = MCR.CoverageReport;
|
|
4
|
-
export const getSnapshot = MCR.getSnapshot;
|
|
5
|
-
export const diffSnapshot = MCR.diffSnapshot;
|
|
6
|
-
|
|
7
|
-
export const WSSession = MCR.WSSession;
|
|
8
|
-
export const CDPClient = MCR.CDPClient;
|
|
9
|
-
export const Util = MCR.Util;
|
package/lib/register/hooks.mjs
DELETED