feat: add ability to collect JS code coverage at the function level (#9027)

This commit is contained in:
smithc 2022-10-06 17:22:44 -04:00 committed by Randolf Jung
parent 41d0122b94
commit a032583b6c
7 changed files with 61 additions and 15 deletions

View File

@ -14,9 +14,9 @@ class Coverage {
## Parameters
| Parameter | Type | Description |
| --------- | ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| options | [JSCoverageOptions](./puppeteer.jscoverageoptions.md) | <i>(Optional)</i> Set of configurable options for coverage defaults to <code>resetOnNavigation : true, reportAnonymousScripts : false</code> |
| Parameter | Type | Description |
| --------- | ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| options | [JSCoverageOptions](./puppeteer.jscoverageoptions.md) | <i>(Optional)</i> Set of configurable options for coverage defaults to <code>resetOnNavigation : true, reportAnonymousScripts : false,</code> <code>includeRawScriptCoverage : false, useBlockCoverage : true</code> |
**Returns:**

View File

@ -12,15 +12,16 @@ class JSCoverage {
resetOnNavigation?: boolean;
reportAnonymousScripts?: boolean;
includeRawScriptCoverage?: boolean;
useBlockCoverage?: boolean;
}): Promise<void>;
}
```
## Parameters
| Parameter | Type | Description |
| --------- | ------------------------------------------------------------------------------------------------------ | ----------------- |
| options | { resetOnNavigation?: boolean; reportAnonymousScripts?: boolean; includeRawScriptCoverage?: boolean; } | <i>(Optional)</i> |
| Parameter | Type | Description |
| --------- | ---------------------------------------------------------------------------------------------------------------------------------- | ----------------- |
| options | { resetOnNavigation?: boolean; reportAnonymousScripts?: boolean; includeRawScriptCoverage?: boolean; useBlockCoverage?: boolean; } | <i>(Optional)</i> |
**Returns:**

View File

@ -14,8 +14,9 @@ export interface JSCoverageOptions
## Properties
| Property | Modifiers | Type | Description |
| -------------------------------------------------------------------------------------- | --------- | ------- | ------------------------------------------------------------------------------------- |
| [includeRawScriptCoverage?](./puppeteer.jscoverageoptions.includerawscriptcoverage.md) | | boolean | <i>(Optional)</i> Whether the result includes raw V8 script coverage entries. |
| [reportAnonymousScripts?](./puppeteer.jscoverageoptions.reportanonymousscripts.md) | | boolean | <i>(Optional)</i> Whether anonymous scripts generated by the page should be reported. |
| [resetOnNavigation?](./puppeteer.jscoverageoptions.resetonnavigation.md) | | boolean | <i>(Optional)</i> Whether to reset coverage on every navigation. |
| Property | Modifiers | Type | Description |
| -------------------------------------------------------------------------------------- | --------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [includeRawScriptCoverage?](./puppeteer.jscoverageoptions.includerawscriptcoverage.md) | | boolean | <i>(Optional)</i> Whether the result includes raw V8 script coverage entries. |
| [reportAnonymousScripts?](./puppeteer.jscoverageoptions.reportanonymousscripts.md) | | boolean | <i>(Optional)</i> Whether anonymous scripts generated by the page should be reported. |
| [resetOnNavigation?](./puppeteer.jscoverageoptions.resetonnavigation.md) | | boolean | <i>(Optional)</i> Whether to reset coverage on every navigation. |
| [useBlockCoverage?](./puppeteer.jscoverageoptions.useblockcoverage.md) | | boolean | <i>(Optional)</i> Whether to collect coverage information at the block level. If true, coverage will be collected at the block level (this is the default). If false, coverage will be collected at the function level. |

View File

@ -0,0 +1,15 @@
---
sidebar_label: JSCoverageOptions.useBlockCoverage
---
# JSCoverageOptions.useBlockCoverage property
Whether to collect coverage information at the block level. If true, coverage will be collected at the block level (this is the default). If false, coverage will be collected at the function level.
**Signature:**
```typescript
interface JSCoverageOptions {
useBlockCoverage?: boolean;
}
```

View File

@ -74,6 +74,12 @@ export interface JSCoverageOptions {
* Whether the result includes raw V8 script coverage entries.
*/
includeRawScriptCoverage?: boolean;
/**
* Whether to collect coverage information at the block level.
* If true, coverage will be collected at the block level (this is the default).
* If false, coverage will be collected at the function level.
*/
useBlockCoverage?: boolean;
}
/**
@ -135,7 +141,8 @@ export class Coverage {
/**
* @param options - Set of configurable options for coverage defaults to
* `resetOnNavigation : true, reportAnonymousScripts : false`
* `resetOnNavigation : true, reportAnonymousScripts : false,`
* `includeRawScriptCoverage : false, useBlockCoverage : true`
* @returns Promise that resolves when coverage is started.
*
* @remarks
@ -204,6 +211,7 @@ export class JSCoverage {
resetOnNavigation?: boolean;
reportAnonymousScripts?: boolean;
includeRawScriptCoverage?: boolean;
useBlockCoverage?: boolean;
} = {}
): Promise<void> {
assert(!this.#enabled, 'JSCoverage is already enabled');
@ -211,6 +219,7 @@ export class JSCoverage {
resetOnNavigation = true,
reportAnonymousScripts = false,
includeRawScriptCoverage = false,
useBlockCoverage = true,
} = options;
this.#resetOnNavigation = resetOnNavigation;
this.#reportAnonymousScripts = reportAnonymousScripts;
@ -234,7 +243,7 @@ export class JSCoverage {
this.#client.send('Profiler.enable'),
this.#client.send('Profiler.startPreciseCoverage', {
callCount: this.#includeRawScriptCoverage,
detailed: true,
detailed: useBlockCoverage,
}),
this.#client.send('Debugger.enable'),
this.#client.send('Debugger.setSkipAllPauses', {skip: true}),

View File

@ -1,2 +1,2 @@
<script>
function unused(){}console.log('used!');</script>
function unused(){}console.log('used!');if(true===false)console.log('unused!');</script>

View File

@ -108,7 +108,27 @@ describe('Coverage specs', function () {
expect(entry.text.substring(range1.start, range1.end)).toBe('\n');
const range2 = entry.ranges[1]!;
expect(entry.text.substring(range2.start, range2.end)).toBe(
`console.log('used!');`
`console.log('used!');if(true===false)`
);
});
it('should report right ranges for "per function" scope', async () => {
const {page, server} = getTestState();
const coverageOptions = {
useBlockCoverage: false,
};
await page.coverage.startJSCoverage(coverageOptions);
await page.goto(server.PREFIX + '/jscoverage/ranges.html');
const coverage = await page.coverage.stopJSCoverage();
expect(coverage.length).toBe(1);
const entry = coverage[0]!;
expect(entry.ranges.length).toBe(2);
const range1 = entry.ranges[0]!;
expect(entry.text.substring(range1.start, range1.end)).toBe('\n');
const range2 = entry.ranges[1]!;
expect(entry.text.substring(range2.start, range2.end)).toBe(
`console.log('used!');if(true===false)console.log('unused!');`
);
});
it('should report scripts that have no coverage', async () => {