Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add puppeteer-to-c8 script #65

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
42 changes: 37 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,37 @@ Convert coverage from the format outputted by [puppeteer](https://developers.goo

## Usage

### To Output Coverage in Istanbul Format with Puppeteer
### To Output Coverage in Istanbul Format with Puppeteer (using `c8`)

1. install _puppeteer_, `npm i -D puppeteer`.
2. install _puppeteer-to-istanbul_, `npm i -D puppeteer-to-istanbul`.
3. run your code in puppeteer with coverage enabled:

```js
(async () => {
const pti = require('puppeteer-to-istanbul')
const puppeteer = require('puppeteer')
const browser = await puppeteer.launch()
const page = await browser.newPage()

// Enable both JavaScript and CSS coverage
await Promise.all([
page.coverage.startJSCoverage({includeRawScriptCoverage: true}),
page.coverage.startCSSCoverage()
]);
// Navigate to page
await page.goto('https://www.google.com');
// Disable both JavaScript and CSS coverage
const [jsCoverage, cssCoverage] = await Promise.all([
page.coverage.stopJSCoverage(),
page.coverage.stopCSSCoverage(),
]);
pti.writeC8([...jsCoverage, ...cssCoverage], { includeHostname: true , storagePath: process.env.NODE_V8_COVERAGE })
await browser.close()
})()
````

### To Output Coverage in Istanbul Format with Puppeteer (using `nyc`)

1. install _puppeteer_, `npm i -D puppeteer`.
2. install _puppeteer-to-istanbul_, `npm i -D puppeteer-to-istanbul`.
Expand Down Expand Up @@ -36,19 +66,21 @@ Convert coverage from the format outputted by [puppeteer](https://developers.goo
pti.write([...jsCoverage, ...cssCoverage], { includeHostname: true , storagePath: './.nyc_output' })
await browser.close()
})()
```
````

### To Check Istanbul Reports

1. install nyc, `npm i nyc -g`.
2. use nyc's report functionality:
1. install c8 or nyc, `npm i c8 -g` or `npm i nyc -g`.
2. use c8's or nyc's report functionality:

```bash
c8 report --reporter=html
# or
nyc report --reporter=html
```

_puppeteer-to-istanbul_ outputs temporary files in a format that can be
consumed by nyc.
consumed by `nyc` or `c8`.

see [istanbul](https://github.com/istanbuljs/istanbuljs/tree/master/packages/istanbul-reports/lib) for a list of possible reporters.

Expand Down
2 changes: 1 addition & 1 deletion bin/puppeteer-js-runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ async function outputPuppeteerCoverage (input, output) {

// Enable both JavaScript and CSS coverage
await Promise.all([
page.coverage.startJSCoverage(),
page.coverage.startJSCoverage({includeRawScriptCoverage: true}),
page.coverage.startCSSCoverage()
])

Expand Down
5 changes: 5 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
const PuppeteerToIstanbul = require('./lib/puppeteer-to-istanbul')
const PuppeteerToC8 = require('./lib/puppeteer-to-c8')

module.exports = {
write: (puppeteerFormat, options) => {
const pti = PuppeteerToIstanbul(puppeteerFormat, options)
pti.writeIstanbulFormat(options)
},
writeC8: (puppeteerFormat, options) => {
const ptc8 = PuppeteerToC8(puppeteerFormat, options)
ptc8.writeC8Format(options)
}
}
34 changes: 34 additions & 0 deletions lib/puppeteer-to-c8.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const fs = require('fs')
const mkdirp = require('mkdirp')

class PuppeteerToC8 {
constructor (coverageInfo, options = {}) {
this.storagePath = options.storagePath || process.env.NODE_V8_COVERAGE
this.includeHostname = options.hasOwnProperty('includeHostname') ? options.includeHostname : true

if (!(coverageInfo[0]?.rawScriptCoverage)) {
throw new Error('rawScriptCoverage property not found in coverage info. Make sure you have set "includeRawScriptCoverage" to true when calling startJSCoverage().');
}

this.coverageInfo = coverageInfo
this.options = options
}

setCoverageInfo (coverageInfo) {
this.coverageInfo = coverageInfo
}

writeC8Format () {
mkdirp.sync(this.storagePath)

const outFilePath = `${this.storagePath}/out.json`

fs.writeFileSync(outFilePath, JSON.stringify({result: this.coverageInfo.map(ci => ci.rawScriptCoverage)}))
}
}

function genPuppeteerToC8 (coverageInfo, options) {
return new PuppeteerToC8(coverageInfo, options)
}

module.exports = genPuppeteerToC8
2 changes: 1 addition & 1 deletion lib/puppeteer-to-v8.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class PuppeteerToV8 {
let id = 0

return this.coverageInfo.map(coverageItem => {
return {
return coverageItem.rawScriptCoverage || {
scriptId: id++,
url: 'file://' + coverageItem.url,
originalUrl: coverageItem.originalUrl,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"chai": "^4.2.0",
"coveralls": "^3.0.11",
"mocha": "^7.1.1",
"puppeteer": "^2.1.1",
"puppeteer": "^13.2.0",
"rimraf": "^3.0.0",
"standard": "^11.0.0"
},
Expand Down
89 changes: 74 additions & 15 deletions test/fixtures/two-inline.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,90 @@
"ranges": [
{
"start": 0,
"end": 55
"end": 74
},
{
"start": 60,
"end": 66
},
{
"start": 109,
"end": 126
"start": 121,
"end": 140
}
],
"text": "\n function c(num1, num2) {\n return num2 * num1;\n }\n function d(num3) {\n return num3;\n }\n c(4,3);\n "
"text": "\n function c(num1, num2) {\n return num2 * num1;\n }\n function d(num3) {\n return num3;\n }\n c(4,3);\n ",
"rawScriptCoverage": {
"scriptId": "4",
"url": "file:///tmp/puppeteerTemp.html",
"functions": [
{
"functionName": "",
"ranges": [
{
"startOffset": 0,
"endOffset": 140,
"count": 1
}
],
"isBlockCoverage": true
},
{
"functionName": "c",
"ranges": [
{
"startOffset": 7,
"endOffset": 67,
"count": 1
}
],
"isBlockCoverage": true
},
{
"functionName": "d",
"ranges": [
{
"startOffset": 74,
"endOffset": 121,
"count": 0
}
],
"isBlockCoverage": false
}
]
}
},
{
"url": "file:///tmp/puppeteerTemp.html",
"ranges": [
{
"start": 0,
"end": 68
},
{
"start": 73,
"end": 93
"end": 101
}
],
"text": "\n function e(num4, num5, num6) {\n return num4 * num5 - num6;\n }\n e(3,5,6);\n "
"text": "\n function e(num4, num5, num6) {\n return num4 * num5 - num6;\n }\n e(3,5,6);\n ",
"rawScriptCoverage": {
"scriptId": "5",
"url": "file:///tmp/puppeteerTemp.html",
"functions": [
{
"functionName": "",
"ranges": [
{
"startOffset": 0,
"endOffset": 101,
"count": 1
}
],
"isBlockCoverage": true
},
{
"functionName": "e",
"ranges": [
{
"startOffset": 7,
"endOffset": 80,
"count": 1
}
],
"isBlockCoverage": true
}
]
}
}
]
]
40 changes: 40 additions & 0 deletions test/puppeteer-to-c8.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/* globals describe, it */

const should = require('chai').should()
const fs = require('fs')

var PuppeteerToC8 = require('../lib/puppeteer-to-c8')

describe('puppeteer-to-c8', () => {
it('outputs a valid out.json file, to the default location', () => {
const fixture = require('./fixtures/two-inline.json')
const pti = PuppeteerToC8(fixture)
pti.writeC8Format()
const content = fs.readFileSync(`${process.env.NODE_V8_COVERAGE}/out.json`, 'utf8')
const jsonObject = JSON.parse(content)
should.exist(jsonObject)
fs.unlinkSync(`${process.env.NODE_V8_COVERAGE}/out.json`)
})

it('outputs a valid out.json file, in the custom location', () => {
const fixture = require('./fixtures/two-inline.json')
const pti = PuppeteerToC8(fixture, { storagePath: '.nyc_output/custom' })
pti.writeC8Format()
const content = fs.readFileSync('.nyc_output/custom/out.json', 'utf8')
const jsonObject = JSON.parse(content)
should.exist(jsonObject)
fs.unlinkSync('.nyc_output/custom/out.json')
})

it('correctly sets coverage info', () => {
const fixture = require('./fixtures/two-inline.json')
const pti = PuppeteerToC8(fixture)
pti.setCoverageInfo(fixture)
pti.coverageInfo.should.eql(fixture)
})

it('ensures rawScriptCoverage is present', () => {
const fixture = require('./fixtures/http-es6-modules.json')
should.Throw(() => PuppeteerToC8(fixture), 'rawScriptCoverage property not found in coverage info. Make sure you have set "includeRawScriptCoverage" to true when calling startJSCoverage().')
})
})