Skip to content

Commit df2ba5a

Browse files
committed
feat(coverage): expose raw v8 coverage
1 parent 8abf35c commit df2ba5a

File tree

9 files changed

+150
-250
lines changed

9 files changed

+150
-250
lines changed

docs/api.md

Lines changed: 68 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@
2121
- [class: Selectors](#class-selectors)
2222
- [class: TimeoutError](#class-timeouterror)
2323
- [class: Accessibility](#class-accessibility)
24-
- [class: Coverage](#class-coverage)
2524
- [class: Worker](#class-worker)
2625
- [class: BrowserServer](#class-browserserver)
2726
- [class: BrowserType](#class-browsertype)
2827
- [class: ChromiumBrowser](#class-chromiumbrowser)
28+
- [class: ChromiumCoverage](#class-chromiumcoverage)
2929
- [class: ChromiumSession](#class-chromiumsession)
3030
- [class: ChromiumTarget](#class-chromiumtarget)
3131
- [class: FirefoxBrowser](#class-firefoxbrowser)
@@ -796,9 +796,9 @@ Get the browser context that the page belongs to.
796796

797797
#### page.coverage
798798

799-
- returns: <[Coverage]>
799+
- returns: <?[any]>
800800

801-
> **NOTE** Code coverage is currently only supported in Chromium.
801+
Browser-specific Coverage implementation, only available for Chromium atm. See [ChromiumCoverage](#class-chromiumcoverage) for more details.
802802

803803
#### page.dblclick(selector[, options])
804804
- `selector` <[string]> A selector to search for element to double click. If there are multiple elements satisfying the selector, the first will be double clicked.
@@ -3246,78 +3246,6 @@ function findFocusedNode(node) {
32463246
}
32473247
```
32483248

3249-
### class: Coverage
3250-
3251-
Coverage gathers information about parts of JavaScript and CSS that were used by the page.
3252-
3253-
An example of using JavaScript and CSS coverage to get percentage of initially
3254-
executed code:
3255-
3256-
```js
3257-
// Enable both JavaScript and CSS coverage
3258-
await Promise.all([
3259-
page.coverage.startJSCoverage(),
3260-
page.coverage.startCSSCoverage()
3261-
]);
3262-
// Navigate to page
3263-
await page.goto('https://example.com');
3264-
// Disable both JavaScript and CSS coverage
3265-
const [jsCoverage, cssCoverage] = await Promise.all([
3266-
page.coverage.stopJSCoverage(),
3267-
page.coverage.stopCSSCoverage(),
3268-
]);
3269-
let totalBytes = 0;
3270-
let usedBytes = 0;
3271-
const coverage = [...jsCoverage, ...cssCoverage];
3272-
for (const entry of coverage) {
3273-
totalBytes += entry.text.length;
3274-
for (const range of entry.ranges)
3275-
usedBytes += range.end - range.start - 1;
3276-
}
3277-
console.log(`Bytes used: ${usedBytes / totalBytes * 100}%`);
3278-
```
3279-
3280-
<!-- GEN:toc -->
3281-
- [coverage.startCSSCoverage([options])](#coveragestartcsscoverageoptions)
3282-
- [coverage.startJSCoverage([options])](#coveragestartjscoverageoptions)
3283-
- [coverage.stopCSSCoverage()](#coveragestopcsscoverage)
3284-
- [coverage.stopJSCoverage()](#coveragestopjscoverage)
3285-
<!-- GEN:stop -->
3286-
3287-
#### coverage.startCSSCoverage([options])
3288-
- `options` <[Object]> Set of configurable options for coverage
3289-
- `resetOnNavigation` <[boolean]> Whether to reset coverage on every navigation. Defaults to `true`.
3290-
- returns: <[Promise]> Promise that resolves when coverage is started
3291-
3292-
#### coverage.startJSCoverage([options])
3293-
- `options` <[Object]> Set of configurable options for coverage
3294-
- `resetOnNavigation` <[boolean]> Whether to reset coverage on every navigation. Defaults to `true`.
3295-
- `reportAnonymousScripts` <[boolean]> Whether anonymous scripts generated by the page should be reported. Defaults to `false`.
3296-
- returns: <[Promise]> Promise that resolves when coverage is started
3297-
3298-
> **NOTE** Anonymous scripts are ones that don't have an associated url. These are scripts that are dynamically created on the page using `eval` or `new Function`. If `reportAnonymousScripts` is set to `true`, anonymous scripts will have `__playwright_evaluation_script__` as their URL.
3299-
3300-
#### coverage.stopCSSCoverage()
3301-
- returns: <[Promise]<[Array]<[Object]>>> Promise that resolves to the array of coverage reports for all stylesheets
3302-
- `url` <[string]> StyleSheet URL
3303-
- `text` <[string]> StyleSheet content
3304-
- `ranges` <[Array]<[Object]>> StyleSheet ranges that were used. Ranges are sorted and non-overlapping.
3305-
- `start` <[number]> A start offset in text, inclusive
3306-
- `end` <[number]> An end offset in text, exclusive
3307-
3308-
> **NOTE** CSS Coverage doesn't include dynamically injected style tags without sourceURLs.
3309-
3310-
#### coverage.stopJSCoverage()
3311-
- returns: <[Promise]<[Array]<[Object]>>> Promise that resolves to the array of coverage reports for all scripts
3312-
- `url` <[string]> Script URL
3313-
- `text` <[string]> Script content
3314-
- `ranges` <[Array]<[Object]>> Script ranges that were executed. Ranges are sorted and non-overlapping.
3315-
- `start` <[number]> A start offset in text, inclusive
3316-
- `end` <[number]> An end offset in text, exclusive
3317-
3318-
> **NOTE** JavaScript Coverage doesn't include anonymous scripts by default. However, scripts with sourceURLs are
3319-
reported.
3320-
33213249
### class: Worker
33223250

33233251
The Worker class represents a [WebWorker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API).
@@ -3672,6 +3600,71 @@ await page.evaluate(() => window.open('https://www.example.com/'));
36723600
const newWindowTarget = await browser.chromium.waitForTarget(target => target.url() === 'https://www.example.com/');
36733601
```
36743602

3603+
### class: ChromiumCoverage
3604+
3605+
Coverage gathers information about parts of JavaScript and CSS that were used by the page.
3606+
3607+
An example of using JavaScript coverage to produce Istambul report for page load:
3608+
3609+
```js
3610+
const { chromium } = require('.');
3611+
const v8toIstanbul = require('v8-to-istanbul');
3612+
3613+
(async() => {
3614+
const browser = await chromium.launch();
3615+
const page = await browser.newPage();
3616+
await page.coverage.startJSCoverage();
3617+
await page.goto('https://chromium.org');
3618+
const coverage = await page.coverage.stopJSCoverage();
3619+
for (const entry of coverage) {
3620+
const converter = new v8toIstanbul('', 0, { source: entry.source });
3621+
await converter.load();
3622+
converter.applyCoverage(entry.functions);
3623+
console.log(JSON.stringify(converter.toIstanbul()));
3624+
}
3625+
await browser.close();
3626+
})();
3627+
```
3628+
3629+
<!-- GEN:toc -->
3630+
- [chromiumCoverage.startCSSCoverage([options])](#chromiumcoveragestartcsscoverageoptions)
3631+
- [chromiumCoverage.startJSCoverage([options])](#chromiumcoveragestartjscoverageoptions)
3632+
- [chromiumCoverage.stopCSSCoverage()](#chromiumcoveragestopcsscoverage)
3633+
- [chromiumCoverage.stopJSCoverage()](#chromiumcoveragestopjscoverage)
3634+
<!-- GEN:stop -->
3635+
3636+
#### chromiumCoverage.startCSSCoverage([options])
3637+
- `options` <[Object]> Set of configurable options for coverage
3638+
- `resetOnNavigation` <[boolean]> Whether to reset coverage on every navigation. Defaults to `true`.
3639+
- returns: <[Promise]> Promise that resolves when coverage is started
3640+
3641+
#### chromiumCoverage.startJSCoverage([options])
3642+
- `options` <[Object]> Set of configurable options for coverage
3643+
- `resetOnNavigation` <[boolean]> Whether to reset coverage on every navigation. Defaults to `true`.
3644+
- `reportAnonymousScripts` <[boolean]> Whether anonymous scripts generated by the page should be reported. Defaults to `false`.
3645+
- returns: <[Promise]> Promise that resolves when coverage is started
3646+
3647+
> **NOTE** Anonymous scripts are ones that don't have an associated url. These are scripts that are dynamically created on the page using `eval` or `new Function`. If `reportAnonymousScripts` is set to `true`, anonymous scripts will have `__playwright_evaluation_script__` as their URL.
3648+
3649+
#### chromiumCoverage.stopCSSCoverage()
3650+
- returns: <[Promise]<[Array]<[Object]>>> Promise that resolves to the array of coverage reports for all stylesheets
3651+
- `url` <[string]> StyleSheet URL
3652+
- `source` <[string]> StyleSheet content
3653+
- `ranges` <[Array]<[Object]>> StyleSheet ranges that were used. Ranges are sorted and non-overlapping.
3654+
- `start` <[number]> A start offset in text, inclusive
3655+
- `end` <[number]> An end offset in text, exclusive
3656+
3657+
> **NOTE** CSS Coverage doesn't include dynamically injected style tags without sourceURLs.
3658+
3659+
#### chromiumCoverage.stopJSCoverage()
3660+
- returns: <[Promise]<[Array]<[Object]>>> Promise that resolves to the array of coverage reports for all scripts
3661+
- `url` <[string]> Script URL
3662+
- `source` <[string]> Script content
3663+
- `functions` <[Array]<[Object]>> V8-specific coverage format.
3664+
3665+
> **NOTE** JavaScript Coverage doesn't include anonymous scripts by default. However, scripts with sourceURLs are
3666+
reported.
3667+
36753668
### class: ChromiumSession
36763669

36773670
* extends: [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter)

src/api.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@ export { Frame } from './frames';
2525
export { Keyboard, Mouse } from './input';
2626
export { JSHandle } from './javascript';
2727
export { Request, Response } from './network';
28-
export { Coverage, FileChooser, Page, Worker } from './page';
28+
export { FileChooser, Page, Worker } from './page';
2929
export { Selectors } from './selectors';
3030

3131
export { CRBrowser as ChromiumBrowser } from './chromium/crBrowser';
32+
export { CRCoverage as ChromiumCoverage } from './chromium/crCoverage';
3233
export { CRSession as ChromiumSession } from './chromium/crConnection';
3334
export { CRTarget as ChromiumTarget } from './chromium/crTarget';
3435

0 commit comments

Comments
 (0)