feat(coverage): option for raw V8 script coverage (#6454)

This commit is contained in:
Yosuke Kurami 2021-09-16 03:54:24 +09:00 committed by GitHub
parent caa2b732fe
commit cb4470a6d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 66 additions and 6 deletions

View File

@ -45,6 +45,17 @@ export interface CoverageEntry {
ranges: Array<{ start: number; end: number }>;
}
/**
* The CoverageEntry class for JavaScript
* @public
*/
export interface JSCoverageEntry extends CoverageEntry {
/**
* Raw V8 script coverage entry.
*/
rawScriptCoverage?: Protocol.Profiler.ScriptCoverage;
}
/**
* Set of configurable options for JS coverage.
* @public
@ -58,6 +69,10 @@ export interface JSCoverageOptions {
* Whether anonymous scripts generated by the page should be reported.
*/
reportAnonymousScripts?: boolean;
/**
* Whether the result includes raw V8 script coverage entries.
*/
includeRawScriptCoverage?: boolean;
}
/**
@ -145,7 +160,7 @@ export class Coverage {
* JavaScript Coverage doesn't include anonymous scripts by default.
* However, scripts with sourceURLs are reported.
*/
async stopJSCoverage(): Promise<CoverageEntry[]> {
async stopJSCoverage(): Promise<JSCoverageEntry[]> {
return await this._jsCoverage.stop();
}
@ -181,6 +196,7 @@ export class JSCoverage {
_eventListeners: PuppeteerEventListener[] = [];
_resetOnNavigation = false;
_reportAnonymousScripts = false;
_includeRawScriptCoverage = false;
constructor(client: CDPSession) {
this._client = client;
@ -190,13 +206,18 @@ export class JSCoverage {
options: {
resetOnNavigation?: boolean;
reportAnonymousScripts?: boolean;
includeRawScriptCoverage?: boolean;
} = {}
): Promise<void> {
assert(!this._enabled, 'JSCoverage is already enabled');
const { resetOnNavigation = true, reportAnonymousScripts = false } =
options;
const {
resetOnNavigation = true,
reportAnonymousScripts = false,
includeRawScriptCoverage = false,
} = options;
this._resetOnNavigation = resetOnNavigation;
this._reportAnonymousScripts = reportAnonymousScripts;
this._includeRawScriptCoverage = includeRawScriptCoverage;
this._enabled = true;
this._scriptURLs.clear();
this._scriptSources.clear();
@ -215,7 +236,7 @@ export class JSCoverage {
await Promise.all([
this._client.send('Profiler.enable'),
this._client.send('Profiler.startPreciseCoverage', {
callCount: false,
callCount: this._includeRawScriptCoverage,
detailed: true,
}),
this._client.send('Debugger.enable'),
@ -248,7 +269,7 @@ export class JSCoverage {
}
}
async stop(): Promise<CoverageEntry[]> {
async stop(): Promise<JSCoverageEntry[]> {
assert(this._enabled, 'JSCoverage is not enabled');
this._enabled = false;
@ -278,7 +299,11 @@ export class JSCoverage {
const flattenRanges = [];
for (const func of entry.functions) flattenRanges.push(...func.ranges);
const ranges = convertToDisjointRanges(flattenRanges);
coverage.push({ url, ranges, text });
if (!this._includeRawScriptCoverage) {
coverage.push({ url, ranges, text });
} else {
coverage.push({ url, ranges, text, rawScriptCoverage: entry });
}
}
return coverage;
}

View File

@ -157,6 +157,41 @@ describe('Coverage specs', function () {
expect(coverage.length).toBe(0);
});
});
describe('includeRawScriptCoverage', function () {
it('should not include rawScriptCoverage field when disabled', async () => {
const { page, server } = getTestState();
await page.coverage.startJSCoverage();
await page.goto(server.PREFIX + '/jscoverage/simple.html', {
waitUntil: 'networkidle0',
});
const coverage = await page.coverage.stopJSCoverage();
expect(coverage.length).toBe(1);
expect(coverage[0].rawScriptCoverage).toBeUndefined();
});
it('should include rawScriptCoverage field when enabled', async () => {
const { page, server } = getTestState();
await page.coverage.startJSCoverage({
includeRawScriptCoverage: true,
});
await page.goto(server.PREFIX + '/jscoverage/simple.html', {
waitUntil: 'networkidle0',
});
const coverage = await page.coverage.stopJSCoverage();
expect(coverage.length).toBe(1);
expect(coverage[0].rawScriptCoverage).toBeTruthy();
});
});
// @see https://crbug.com/990945
xit('should not hang when there is a debugger statement', async () => {
const { page, server } = getTestState();
await page.coverage.startJSCoverage();
await page.goto(server.EMPTY_PAGE);
await page.evaluate(() => {
debugger; // eslint-disable-line no-debugger
});
await page.coverage.stopJSCoverage();
});
});
describeChromeOnly('CSSCoverage', function () {