-
-
Notifications
You must be signed in to change notification settings - Fork 742
New puppeteer plugin to dump code coverage #1504
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
const Container = require("../container"); | ||
const recorder = require("../recorder"); | ||
dvillarama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const event = require("../event"); | ||
dvillarama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const fs = require("fs"); | ||
dvillarama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const path = require("path"); | ||
dvillarama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const { clearString } = require("../utils"); | ||
dvillarama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const debug = require("debug")("codeceptjs:plugin:puppeteerCoverage"); | ||
dvillarama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
const defaultConfig = { | ||
coverageDir: "output/coverage", | ||
dvillarama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
uniqueFileName: true | ||
dvillarama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}; | ||
|
||
const supportedHelpers = ["Puppeteer"]; | ||
dvillarama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* Builds the filename based on the test title | ||
*/ | ||
function buildFileName(test, uniqueFileName) { | ||
let fileName = clearString(test.title); | ||
|
||
// This prevent data driven to be included in the failed screenshot file name | ||
if (fileName.indexOf("{") !== -1) { | ||
dvillarama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
fileName = fileName.substr(0, fileName.indexOf("{") - 3).trim(); | ||
dvillarama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
if (test.ctx && test.ctx.test && test.ctx.test.type === "hook") { | ||
dvillarama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
fileName = clearString(`${test.title}_${test.ctx.test.title}`); | ||
} | ||
|
||
if (uniqueFileName) { | ||
const uuid = | ||
test.uuid || | ||
test.ctx.test.uuid || | ||
Math.floor(new Date().getTime() / 1000); | ||
fileName = `${fileName.substring(0, 10)}_${uuid}.coverage.json`; | ||
} else { | ||
fileName = `${fileName}.coverage.json`; | ||
} | ||
|
||
return fileName; | ||
} | ||
|
||
/** | ||
* Dumps puppeteers code coverage after every test. | ||
* | ||
* ##### Configuration | ||
* | ||
* Configuration can either be taken from a corresponding helper (deprecated) or a from plugin config (recommended). | ||
* | ||
* ```js | ||
* "plugins": { | ||
* "puppeteerCoverage": { | ||
* "enabled": true | ||
* } | ||
* } | ||
* ``` | ||
* | ||
* Possible config options: | ||
* | ||
* * `outputDir`: directory to dump coverage files | ||
* * `uniqueFileName`: generate a unique filename by adding uuid | ||
* | ||
* Notes: | ||
* First of all, YMMV! | ||
* To work, you need the client javascript code to be NOT uglified. They need to be built in "development" mode. | ||
* And the end of your tests, you'll get a directory full of coverage per test run. Now what? | ||
* You'll need to convert the coverage code to something istanbul can read. Good news is someone wrote the code | ||
* for you (see puppeteer-to-istanbul link below). Then using istanbul you need to combine the converted | ||
dvillarama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* coverage and create a report. Good luck! | ||
* | ||
* Links: | ||
* * https://github.com/GoogleChrome/puppeteer/blob/v1.12.2/docs/api.md#class-coverage | ||
* * https://github.com/istanbuljs/puppeteer-to-istanbul | ||
* * https://github.com/gotwarlost/istanbul | ||
*/ | ||
module.exports = function(config) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing space before function parentheses space-before-function-paren |
||
const helpers = Container.helpers(); | ||
let coverageRunning = false; | ||
let helper; | ||
|
||
for (const helperName of supportedHelpers) { | ||
if (Object.keys(helpers).indexOf(helperName) > -1) { | ||
helper = helpers[helperName]; | ||
} | ||
} | ||
|
||
if (!helper) { | ||
console.error("Coverage is only supported in Puppeteer"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Strings must use singlequote quotes |
||
return; // no helpers for screenshot | ||
} | ||
|
||
const options = Object.assign(defaultConfig, helper.options, config); | ||
|
||
event.dispatcher.on(event.all.before, async suite => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Expected parentheses around arrow function argument having a body with curly braces arrow-parens |
||
debug("*** Collecting coverage for tests ****"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Strings must use singlequote quotes |
||
}); | ||
|
||
/** | ||
* Hack! we're going to try to "start" coverage before each step because this is | ||
* when the browser is already up and is ready to start coverage. | ||
*/ | ||
event.dispatcher.on(event.step.before, async step => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Expected parentheses around arrow function argument having a body with curly braces arrow-parens |
||
recorder.add("starting coverage", async () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Strings must use singlequote quotes |
||
try { | ||
if (!coverageRunning) { | ||
debug("--> starting coverage <--"); | ||
dvillarama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
coverageRunning = true; | ||
await helper.page.coverage.startJSCoverage(); | ||
} | ||
} catch (err) { | ||
console.error(err); | ||
} | ||
}, true); | ||
}); | ||
|
||
/** | ||
* Save puppeteer coverage data after every test run | ||
*/ | ||
event.dispatcher.on(event.test.after, async test => { | ||
dvillarama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
recorder.add("saving coverage", async () => { | ||
dvillarama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
try { | ||
if (coverageRunning) { | ||
debug("--> stopping coverage <--"); | ||
dvillarama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
coverageRunning = false; | ||
const coverage = await helper.page.coverage.stopJSCoverage(); | ||
|
||
const coverageDir = path.resolve(process.cwd(), options.coverageDir); | ||
fs.mkdirSync(coverageDir, {recursive: true}); | ||
dvillarama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
const coveragePath = path.resolve(coverageDir, buildFileName(test, options.uniqueFileName)); | ||
debug(`writing ${coveragePath}`); | ||
fs.writeFileSync(coveragePath, JSON.stringify(coverage)); | ||
} | ||
} catch (err) { | ||
console.error(err); | ||
} | ||
}, true); | ||
}); | ||
}; |
Uh oh!
There was an error while loading. Please reload this page.