feat(coverage): option for raw V8 script coverage (#6454)
This commit is contained in:
parent
caa2b732fe
commit
cb4470a6d9
@ -45,6 +45,17 @@ export interface CoverageEntry {
|
|||||||
ranges: Array<{ start: number; end: number }>;
|
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.
|
* Set of configurable options for JS coverage.
|
||||||
* @public
|
* @public
|
||||||
@ -58,6 +69,10 @@ export interface JSCoverageOptions {
|
|||||||
* Whether anonymous scripts generated by the page should be reported.
|
* Whether anonymous scripts generated by the page should be reported.
|
||||||
*/
|
*/
|
||||||
reportAnonymousScripts?: boolean;
|
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.
|
* JavaScript Coverage doesn't include anonymous scripts by default.
|
||||||
* However, scripts with sourceURLs are reported.
|
* However, scripts with sourceURLs are reported.
|
||||||
*/
|
*/
|
||||||
async stopJSCoverage(): Promise<CoverageEntry[]> {
|
async stopJSCoverage(): Promise<JSCoverageEntry[]> {
|
||||||
return await this._jsCoverage.stop();
|
return await this._jsCoverage.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,6 +196,7 @@ export class JSCoverage {
|
|||||||
_eventListeners: PuppeteerEventListener[] = [];
|
_eventListeners: PuppeteerEventListener[] = [];
|
||||||
_resetOnNavigation = false;
|
_resetOnNavigation = false;
|
||||||
_reportAnonymousScripts = false;
|
_reportAnonymousScripts = false;
|
||||||
|
_includeRawScriptCoverage = false;
|
||||||
|
|
||||||
constructor(client: CDPSession) {
|
constructor(client: CDPSession) {
|
||||||
this._client = client;
|
this._client = client;
|
||||||
@ -190,13 +206,18 @@ export class JSCoverage {
|
|||||||
options: {
|
options: {
|
||||||
resetOnNavigation?: boolean;
|
resetOnNavigation?: boolean;
|
||||||
reportAnonymousScripts?: boolean;
|
reportAnonymousScripts?: boolean;
|
||||||
|
includeRawScriptCoverage?: boolean;
|
||||||
} = {}
|
} = {}
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
assert(!this._enabled, 'JSCoverage is already enabled');
|
assert(!this._enabled, 'JSCoverage is already enabled');
|
||||||
const { resetOnNavigation = true, reportAnonymousScripts = false } =
|
const {
|
||||||
options;
|
resetOnNavigation = true,
|
||||||
|
reportAnonymousScripts = false,
|
||||||
|
includeRawScriptCoverage = false,
|
||||||
|
} = options;
|
||||||
this._resetOnNavigation = resetOnNavigation;
|
this._resetOnNavigation = resetOnNavigation;
|
||||||
this._reportAnonymousScripts = reportAnonymousScripts;
|
this._reportAnonymousScripts = reportAnonymousScripts;
|
||||||
|
this._includeRawScriptCoverage = includeRawScriptCoverage;
|
||||||
this._enabled = true;
|
this._enabled = true;
|
||||||
this._scriptURLs.clear();
|
this._scriptURLs.clear();
|
||||||
this._scriptSources.clear();
|
this._scriptSources.clear();
|
||||||
@ -215,7 +236,7 @@ export class JSCoverage {
|
|||||||
await Promise.all([
|
await Promise.all([
|
||||||
this._client.send('Profiler.enable'),
|
this._client.send('Profiler.enable'),
|
||||||
this._client.send('Profiler.startPreciseCoverage', {
|
this._client.send('Profiler.startPreciseCoverage', {
|
||||||
callCount: false,
|
callCount: this._includeRawScriptCoverage,
|
||||||
detailed: true,
|
detailed: true,
|
||||||
}),
|
}),
|
||||||
this._client.send('Debugger.enable'),
|
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');
|
assert(this._enabled, 'JSCoverage is not enabled');
|
||||||
this._enabled = false;
|
this._enabled = false;
|
||||||
|
|
||||||
@ -278,7 +299,11 @@ export class JSCoverage {
|
|||||||
const flattenRanges = [];
|
const flattenRanges = [];
|
||||||
for (const func of entry.functions) flattenRanges.push(...func.ranges);
|
for (const func of entry.functions) flattenRanges.push(...func.ranges);
|
||||||
const ranges = convertToDisjointRanges(flattenRanges);
|
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;
|
return coverage;
|
||||||
}
|
}
|
||||||
|
@ -157,6 +157,41 @@ describe('Coverage specs', function () {
|
|||||||
expect(coverage.length).toBe(0);
|
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 () {
|
describeChromeOnly('CSSCoverage', function () {
|
||||||
|
Loading…
Reference in New Issue
Block a user