Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

monocart-coverage-reports

Package Overview
Dependencies
Maintainers
1
Versions
89
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

monocart-coverage-reports - npm Package Compare versions

Comparing version 2.7.6 to 2.7.7

21

lib/cli.js

@@ -24,21 +24,8 @@ #!/usr/bin/env node

const isFeatureSupported = (nv) => {
const initNodeOptions = async (cliOptions) => {
// module register added in Node.js: v20.6.0
const [major, minor] = nv.split('.').map((s) => parseInt(s));
if (major < 20) {
return false;
}
if (major > 20) {
return true;
}
if (minor < 6) {
return false;
}
return true;
};
const initNodeOptions = async (cliOptions) => {
const nv = process.versions.node;
if (!isFeatureSupported(nv)) {
Util.logInfo(EC.yellow(`The current Node.js version "${nv}" does NOT support "module.register", it requires "20.6.0" or higher.`));
if (Util.cmpVersion(nv, '20.6.0') < 0) {
Util.logInfo(`The current Node.js version "${nv}" does NOT support "module.register", it requires "20.6.0" or higher.`);
return;

@@ -45,0 +32,0 @@ }

80

lib/client/coverage-client.js

@@ -134,16 +134,19 @@ const Util = require('../utils/util.js');

const jsCoverage = profileResponse.result;
const jsCoverage = [];
// console.log('coverageList', coverageList);
if (profileResponse && profileResponse.result) {
profileResponse.result.forEach((entry) => {
// anonymous url
entry.url = entry.url || '';
// add source
const source = this.scriptSources.get(entry.scriptId);
if (!source) {
Util.logDebug(`Not found js source: ${entry.url}`);
}
entry.source = source || '';
jsCoverage.push(entry);
});
}
jsCoverage.forEach((entry) => {
// anonymous url
entry.url = entry.url || '';
// add source
const source = this.scriptSources.get(entry.scriptId);
if (!source) {
Util.logDebug(`Not found js source: ${entry.url}`);
}
entry.source = source || '';
});
this.scriptSources.clear();

@@ -243,2 +246,5 @@ this.enabledJS = false;

async stopCoverage() {
if (!this.session) {
return;
}
const [jsCoverage, cssCoverage] = await Promise.all([

@@ -248,3 +254,11 @@ this.stopJSCoverage(),

]);
return [... jsCoverage, ... cssCoverage];
// could be undefined
let coverageList = [];
if (jsCoverage) {
coverageList = coverageList.concat(jsCoverage);
}
if (cssCoverage) {
coverageList = coverageList.concat(cssCoverage);
}
return coverageList;
}

@@ -255,8 +269,14 @@

async writeCoverage() {
// // enable and start v8 coverage
if (!this.session) {
return;
}
await this.session.send('Runtime.enable');
// write the coverage started by NODE_V8_COVERAGE to disk on demand
// write the coverage started by NODE_V8_COVERAGE to disk on demand
const res = await this.session.send('Runtime.evaluate', {
expression: 'new Promise(resolve=>{ require("v8").takeCoverage(); resolve(process.env.NODE_V8_COVERAGE); })',
expression: `new Promise((resolve) => {
require("v8").takeCoverage();
resolve(process.env.NODE_V8_COVERAGE);
})`,
includeCommandLineAPI: true,

@@ -269,5 +289,29 @@ returnByValue: true,

return res.result.value;
return res && res.result && res.result.value;
}
// get istanbul coverage data
async getIstanbulCoverage(coverageKey = '__coverage__') {
if (!this.session) {
return;
}
await this.session.send('Runtime.enable');
// both browser and Node.js
const res = await this.session.send('Runtime.evaluate', {
expression: `new Promise((resolve) => {
const globalTarget = typeof window !== 'undefined' ? window : global;
resolve(globalTarget['${coverageKey}']);
})`,
includeCommandLineAPI: true,
returnByValue: true,
awaitPromise: true
});
await this.session.send('Runtime.disable');
return res && res.result && res.result.value;
}
// =================================================================================================

@@ -278,6 +322,4 @@ async close() {

}
await this.session.detach();
this.session = null;
}

@@ -284,0 +326,0 @@ }

@@ -122,3 +122,3 @@ declare namespace MCR {

[string] | [string, {
type?: "v8" | "istanbul" | "both";
type?: "v8" | "istanbul" | "both" | string;
[key: string]: any;

@@ -196,3 +196,3 @@ }];

lines: {
[key: string]: number | string
[key: string]: number | string;
};

@@ -292,3 +292,3 @@ }

[pattern: string]: "js" | "css" | boolean;
} | ((filePath: string) => "js" | "css" | boolean)
} | ((filePath: string) => "js" | "css" | boolean);
};

@@ -326,2 +326,3 @@

[key: string]: any;
}

@@ -448,4 +449,8 @@

/** write the coverage started by NODE_V8_COVERAGE to disk on demand, returns v8 coverage dir */
writeCoverage: () => Promise<string>
writeCoverage: () => Promise<string>;
/** get istanbul coverage data
* @param coverageKey defaults to `__coverage__`
*/
getIstanbulCoverage: (coverageKey?: string) => Promise<any>;
}

@@ -457,3 +462,3 @@

on: (type: string, handler: (e: any) => void) => void;
detach: () => Promise<void>
detach: () => Promise<void>;
}

@@ -466,3 +471,3 @@

on: (type: string, handler: (e: any) => void) => void;
detach: () => Promise<void>
detach: () => Promise<void>;
}

@@ -482,3 +487,3 @@

/** target filter, defaults to first page */
target?: (targets) => any;
target?: (targets: any) => any;
/** websocket options */

@@ -485,0 +490,0 @@ ws?: any;

@@ -445,2 +445,14 @@ const fs = require('fs');

cmpVersion: (v1, v2) => {
const [major1, minor1, patch1] = `${v1}`.split('.').map((s) => parseInt(s));
const [major2, minor2, patch2] = `${v2}`.split('.').map((s) => parseInt(s));
if (major1 === major2) {
if (minor1 === minor2) {
return Util.toNum(patch1) - Util.toNum(patch2);
}
return Util.toNum(minor1) - Util.toNum(minor2);
}
return Util.toNum(major1) - Util.toNum(major2);
},
// ==========================================================================================

@@ -447,0 +459,0 @@

{
"name": "monocart-coverage-reports",
"version": "2.7.6",
"version": "2.7.7",
"description": "A code coverage tool to generate native V8 reports or Istanbul reports.",

@@ -27,3 +27,3 @@ "main": "./lib/index.js",

"scripts": {
"build-test": "node ./scripts/build-test.js",
"build-test": "node ./test/build/build-test.js",
"build": "sf lint && sf b -p && npm run build-test",

@@ -37,3 +37,3 @@ "test-node-env": "cross-env NODE_V8_COVERAGE=.temp/v8-coverage-env node ./test/test-node-env.js && node ./test/generate-report.js",

"test-node-fgc": "node ./test/test-node-fgc.js",
"test-node": "npm run test-node-env && npm run test-node-api && npm run test-node-ins && npm run test-node-cdp && npm run test-node-vm && npm run test-node-koa",
"test-node": "node ./test/test.js --node",
"test-istanbul": "node ./test/test-istanbul.js",

@@ -48,3 +48,3 @@ "test-v8": "node ./test/test-v8.js",

"test-v8-and-istanbul": "node ./test/test-v8-and-istanbul.js",
"test-browser": "npm run test-istanbul && npm run test-v8 && npm run test-puppeteer && npm run test-anonymous && npm run test-css && npm run test-minify && npm run test-esbuild && npm run test-rollup && npm run test-v8-and-istanbul",
"test-browser": "node ./test/test.js --browser",
"test-cli": "npx mcr node ./test/specs/node.test.js -c test/mcr.config.cli.js",

@@ -56,4 +56,3 @@ "test-tsx": "npx mcr tsx ./test/specs/tsx.test.ts -c test/mcr.config.tsx.js",

"test-client": "node ./test/test-client.js",
"test-all": "npm run test-node && npm run test-browser && npm run test-cli && npm run test-tsx && npm run test-merge && node ./scripts/docs.js",
"test-node-14": "npm run test-node && npm run test-v8 && npm run test-anonymous && npm run test-css && npm run test-minify && npm run test-esbuild && npm run test-v8-and-istanbul && npm run test-cli",
"test-all": "node ./test/test.js && node ./scripts/docs.js",
"test": "npx mcr npm run test-all -c test/mcr.config.mcr.js",

@@ -96,3 +95,3 @@ "test:snap": "cross-env TEST_SNAPSHOT=true npm run test",

"minimatch": "^9.0.3",
"stylelint": "^16.2.1",
"stylelint": "^16.3.0",
"stylelint-config-plus": "^1.1.0",

@@ -99,0 +98,0 @@ "supports-color": "^9.4.0",

@@ -19,3 +19,3 @@ # Monocart Coverage Reports

- [Collecting Raw V8 Coverage Data with Puppeteer](#collecting-raw-v8-coverage-data-with-puppeteer)
- [Node.js V8 Coverage Report for Server Side](#nodejs-v8-coverage-report-for-server-side)
- [Collecting V8 Coverage Data from Node.js](#collecting-v8-coverage-data-from-nodejs)
- [Collecting V8 Coverage Data with `CDPClient` API](#collecting-v8-coverage-data-with-cdpclient-api)

@@ -46,2 +46,3 @@ - [V8 Coverage Data API](#v8-coverage-data-api)

- [TestCafe](#testcafe)
- [Selenium Webdriver](#selenium-webdriver)
- [Mocha](#mocha)

@@ -58,26 +59,27 @@ - [tsx](#tsx)

> It's recommended to use [Node.js 20+](https://nodejs.org/).
- [API](#multiprocessing-support)
- API
```js
const MCR = require('monocart-coverage-reports');
const coverageOptions = {
const mcr = MCR({
name: 'My Coverage Report - 2024-02-28',
outputDir: './coverage-reports',
reports: ["v8", "console-details"]
}
const mcr = MCR(coverageOptions);
mcr.cleanCache();
await mcr.add(coverageData1);
await mcr.add(coverageData2);
reports: ["v8", "console-details"],
cleanCache: true
});
await mcr.add(coverageData);
await mcr.generate();
```
Using `import` and load options from [config file](#config-file)
```js
import { CoverageReport } from 'monocart-coverage-reports';
const mcr = new CoverageReport();
await mcr.loadConfig();
```
For more information, see [Multiprocessing Support](#multiprocessing-support)
// Or
// const { CoverageReport } = require('monocart-coverage-reports');
// const mcr = new CoverageReport(coverageOptions);
```
- [CLI](#command-line)
- CLI
```sh
mcr node my-app.js -r v8,console-details
```
For more information, see [Command Line](#command-line)

@@ -115,3 +117,3 @@ ## Options

> Istanbul build-in reports (both V8 and istanbul data):
> Istanbul build-in reports (both V8 and Istanbul data):

@@ -136,3 +138,3 @@ - `clover`

> Other build-in reports (both V8 and istanbul data):
> Other build-in reports (both V8 and Istanbul data):

@@ -171,5 +173,5 @@ - `codecov`

```
- istanbul custom reporter
- Istanbul custom reporter
> example: [./test/custom-istanbul-reporter.js](./test/custom-istanbul-reporter.js), see [istanbul built-in reporters' implementation](https://github.com/istanbuljs/istanbuljs/tree/master/packages/istanbul-reports/lib) for reference.
- v8 custom reporter
- V8 custom reporter
> example: [./test/custom-v8-reporter.js](./test/custom-v8-reporter.js)

@@ -203,7 +205,5 @@

['/absolute/path/to/custom-reporter.js']
]
}
const mcr = MCR(coverageOptions);
mcr.cleanCache();
```

@@ -226,7 +226,8 @@

## Collecting Istanbul Coverage Data
- Instrumenting source code
> Before collecting Istanbul coverage data, It requires your source code is instrumented with Istanbul
- webpack: [babel-plugin-istanbul](https://github.com/istanbuljs/babel-plugin-istanbul), example: [webpack.config-istanbul.js](./test/webpack.config-istanbul.js)
- Before coverage collection: Instrumenting source code with Istanbul
- webpack with babel loader: [babel-plugin-istanbul](https://github.com/istanbuljs/babel-plugin-istanbul), see example: [webpack.config-istanbul.js](./test/build/webpack.config-istanbul.js)
- CLI: [nyc instrument](https://github.com/istanbuljs/nyc/blob/master/docs/instrument.md) or API: [istanbul-lib-instrument](https://github.com/istanbuljs/istanbuljs/blob/main/packages/istanbul-lib-instrument/api.md)
- vite: [vite-plugin-istanbul](https://github.com/ifaxity/vite-plugin-istanbul)
- rollup: [rollup-plugin-istanbul](https://github.com/artberri/rollup-plugin-istanbul)
- vite: [vite-plugin-istanbul](https://github.com/ifaxity/vite-plugin-istanbul)
- swc: [swc-plugin-coverage-instrument](https://github.com/kwonoj/swc-plugin-coverage-instrument)
- Browser

@@ -238,4 +239,4 @@ - Collecting coverage data from `window.__coverage__`, example: [test-istanbul.js](./test/test-istanbul.js)

## Collecting V8 Coverage Data
- Sourcemap for source code: enable `sourcemap` and do not compress/minify:
- [webpack](https://webpack.js.org/configuration/): `devtool: source-map` and `mode: development`, example [webpack.config-v8.js](./test/webpack.config-v8.js)
- Before coverage collection: Enabling `sourcemap` for source code
- [webpack](https://webpack.js.org/configuration/): `devtool: source-map` and `mode: development`, example [webpack.config-v8.js](./test/build/webpack.config-v8.js)
- [rollup](https://rollupjs.org/configuration-options/): `sourcemap: true`

@@ -250,3 +251,3 @@ - [vite](https://vitejs.dev/config/build-options.html): `sourcemap: true` and `minify: false`

- Node.js
- [Node.js V8 Coverage Report for Server Side](#nodejs-v8-coverage-report-for-server-side)
- [Collecting V8 Coverage Data from Node.js](#collecting-v8-coverage-data-from-nodejs)

@@ -277,3 +278,3 @@ - CDP

```
see [./test/test-v8.js](./test/test-v8.js), and [anonymous](./test/test-anonymous.js), [css](./test/test-css.js)
For more examples, see [./test/test-v8.js](./test/test-v8.js), and [anonymous](./test/test-anonymous.js), [css](./test/test-css.js)

@@ -308,5 +309,5 @@ ### Collecting Raw V8 Coverage Data with Puppeteer

```
see example: [./test/test-puppeteer.js](./test/test-puppeteer.js)
Example: [./test/test-puppeteer.js](./test/test-puppeteer.js)
### Node.js V8 Coverage Report for Server Side
### Collecting V8 Coverage Data from Node.js
Possible solutions:

@@ -345,3 +346,3 @@ - [NODE_V8_COVERAGE](https://nodejs.org/docs/latest/api/cli.html#node_v8_coveragedir)=`dir`

### Collecting V8 Coverage Data with `CDPClient` API
- Work with node debugger `--inspect=9229`
- Work with node debugger port `--inspect=9229`
```js

@@ -388,8 +389,42 @@ const MCR = require('monocart-coverage-reports');

```
- Work with [Selenium Webdriver](https://www.selenium.dev/documentation/webdriver/) WebSocket (Chrome/Edge Browser)
```js
const { Builder, Browser } = require('selenium-webdriver');
const MCR = require('monocart-coverage-reports');
const driver = await new Builder().forBrowser(Browser.CHROME).build();
const pageCdpConnection = await driver.createCDPConnection('page');
const session = new MCR.WSSession(pageCdpConnection._wsConnection);
const client = await MCR.CDPClient({
session
})
```
- `CDPClient` available APIs
```js
/** start js coverage */
startJSCoverage: () => Promise<void>;
/** stop and return js coverage */
stopJSCoverage: () => Promise<V8CoverageEntry[]>;
/** start css coverage */
startCSSCoverage: () => Promise<void>;
/** stop and return css coverage */
stopCSSCoverage: () => Promise<V8CoverageEntry[]>;
/** start both js and css coverage */
startCoverage: () => Promise<void>;
/** stop and return both js and css coverage */
stopCoverage: () => Promise<V8CoverageEntry[]>;
/** write the coverage started by NODE_V8_COVERAGE to disk on demand, returns v8 coverage dir */
writeCoverage: () => Promise<string>;
/** get istanbul coverage data */
getIstanbulCoverage: (coverageKey?: string) => Promise<any>;
```
### V8 Coverage Data API
- [V8 coverage report](https://v8.dev/blog/javascript-code-coverage) - Native support for JavaScript code coverage to V8. (Chromium only)
- [JavaScript code coverage in V8](https://v8.dev/blog/javascript-code-coverage)
- [Playwright Coverage Class](https://playwright.dev/docs/api/class-coverage)
- [Puppeteer Coverage class](https://pptr.dev/api/puppeteer.coverage)
- [DevTools Protocol for Coverage](https://chromedevtools.github.io/devtools-protocol/tot/Profiler/#method-startPreciseCoverage) see devtools-protocol [ScriptCoverage](https://chromedevtools.github.io/devtools-protocol/tot/Profiler/#type-ScriptCoverage) and [v8-coverage](https://github.com/bcoe/v8-coverage)
- [Puppeteer Coverage Class](https://pptr.dev/api/puppeteer.coverage)
- [DevTools Protocol for Coverage](https://chromedevtools.github.io/devtools-protocol/tot/Profiler/#method-startPreciseCoverage) see [ScriptCoverage](https://chromedevtools.github.io/devtools-protocol/tot/Profiler/#type-ScriptCoverage) and [v8-coverage](https://github.com/bcoe/v8-coverage)
```js

@@ -405,3 +440,2 @@ // Coverage data for a source range.

}
// Coverage data for a JavaScript function.

@@ -423,3 +457,2 @@ /**

}
// Coverage data for a JavaScript script.

@@ -434,3 +467,2 @@ export interface ScriptCoverage {

}
export type V8CoverageData = ScriptCoverage[];

@@ -441,22 +473,22 @@ ```

When V8 coverage data collected, it actually contains the data of all entry files, for example:
```
dist/main.js
dist/vendor.js
dist/something-else.js
```
- *dist/main.js*
- *dist/vendor.js*
- *dist/something-else.js*
We can use `entryFilter` to filter the entry files. For example, we should remove `vendor.js` and `something-else.js` if they are not in our coverage scope.
```
dist/main.js
```
- *dist/main.js*
When inline or linked sourcemap exists to the entry file, the source files will be extracted from the sourcemap for the entry file, and the entry file will be removed if `logging` is not `debug`.
```
> src/index.js
> src/components/app.js
> node_modules/dependency/dist/dependency.js
```
- *src/index.js*
- *src/components/app.js*
- *node_modules/dependency/dist/dependency.js*
We can use `sourceFilter` to filter the source files. For example, we should remove `dependency.js` if it is not in our coverage scope.
```
> src/index.js
> src/components/app.js
```
- *src/index.js*
- *src/components/app.js*
For example:

@@ -621,3 +653,2 @@ ```js

const mcr = MCR(coverageOptions);
// do not clean cache in the stage
await mcr.add(coverageData1);

@@ -631,3 +662,2 @@ ```

const mcr = MCR(coverageOptions);
// do not clean cache in the stage
await mcr.add(coverageData2);

@@ -642,3 +672,2 @@ ```

const mcr = MCR(coverageOptions);
// do not clean cache before generating reports
await mcr.generate();

@@ -653,3 +682,3 @@ ```

npm i monocart-coverage-reports -g
mcr node ./test/specs/node.test.js -r v8,console-summary --lcov
mcr node ./test/specs/node.test.js -r v8,console-details --lcov
```

@@ -660,3 +689,3 @@

npm i monocart-coverage-reports
npx mcr node ./test/specs/node.test.js -r v8,console-summary --lcov
npx mcr node ./test/specs/node.test.js -r v8,console-details --lcov
```

@@ -718,2 +747,3 @@

First, using the `raw` report to export the original coverage data to the specified directory.
For example, we have `raw` coverage data from unit tests:
```js

@@ -726,11 +756,14 @@ const coverageOptions = {

// relative path will be "./coverage-reports/unit/raw"
// defaults to raw
outputDir: "raw"
}],
['v8'],
['console-summary']
['console-details']
]
};
```
Then, after all the tests are completed, generate a merged report with option `inputDir`:
We also have `raw` coverage data from e2e tests, which is output to `./coverage-reports/e2e/raw`.
After all the tests are completed, generate a merged report with option `inputDir`:
```js
// merge-coverage.js
const fs = require('fs');

@@ -759,2 +792,6 @@ const { CoverageReport } = require('monocart-coverage-reports');

// Unify the file path for the same files
// For example, the file index.js has different paths:
// unit: unit-dist/src/index.js
// e2e: e2e-dist/src/index.js
// return filePath.replace("unit-dist/", "").replace("e2e-dist/", "")
return filePath;

@@ -770,8 +807,8 @@ },

// remove the raw files if it useless
inputDir.forEach((p) => {
fs.rmSync(p, {
recursive: true,
force: true
});
});
// inputDir.forEach((p) => {
// fs.rmSync(p, {
// recursive: true,
// force: true
// });
// });
}

@@ -793,3 +830,3 @@ };

How `MCR` Works:
- 1, Trying to fix the middle position if not found the exact mapping for the position. However, for non-JS code, such as Vue template, JSX, etc., it might be hard to find a perfect solution.
- 1, Trying to fix the middle original position with string comparison and [`diff-sequences`](https://github.com/jestjs/jest/tree/main/packages/diff-sequences). However, for non-JS code, such as Vue template, JSX, etc., it might be hard to find a perfect solution.
- 2, Finding all functions, statements and branches by parsing the source code [AST](https://github.com/acornjs/acorn). However, there's a small issue, which is the V8 cannot provide effective branch coverage information for `AssignmentPattern`.

@@ -826,3 +863,3 @@

['v8'],
['console-summary']
['console-details']
]

@@ -850,2 +887,3 @@ };

### [Playwright](https://github.com/microsoft/playwright)
- [playwright-coverage](https://github.com/cenfun/playwright-coverage) - A Example for Playwright Coverage Reports
- [monocart-reporter](https://github.com/cenfun/monocart-reporter) - A Playwright custom reporter, supports generating [Code Coverage Report](https://github.com/cenfun/monocart-reporter?#code-coverage-report)

@@ -862,2 +900,3 @@ - Coverage for component testing:

- [jest-monocart-coverage](https://github.com/cenfun/jest-monocart-coverage) - A Jest custom reporter for coverage reports
- [jest-puppeteer-coverage](https://github.com/cenfun/jest-puppeteer-coverage) - A Jest Puppeteer Coverage Example
- Example for Jest (unit) + Puppeteer (e2e) + Codecov: [maplibre-gl-js](https://github.com/maplibre/maplibre-gl-js)

@@ -884,2 +923,5 @@

### [Selenium Webdriver](https://github.com/seleniumhq/selenium)
- [selenium-webdriver-coverage](https://github.com/cenfun/selenium-webdriver-coverage) - Selenium Webdriver V8 Coverage Example
### [Mocha](https://github.com/mochajs/mocha)

@@ -886,0 +928,0 @@ ```sh

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc