playwright_rs/protocol/coverage.rs
1// Coverage — Chromium-only code coverage collection
2//
3// See: https://playwright.dev/docs/api/class-coverage
4
5use crate::error::Result;
6use crate::protocol::page::Page;
7
8/// Options for `Coverage::start_js_coverage`.
9///
10/// See: <https://playwright.dev/docs/api/class-coverage#coverage-start-js-coverage>
11#[derive(Debug, Default, Clone)]
12#[non_exhaustive]
13pub struct StartJSCoverageOptions {
14 /// Whether to reset coverage on every navigation.
15 ///
16 /// Defaults to `true`.
17 pub reset_on_navigation: Option<bool>,
18
19 /// Whether to report anonymous scripts generated by the page.
20 ///
21 /// Defaults to `false`.
22 pub report_anonymous_scripts: Option<bool>,
23}
24
25/// Options for `Coverage::start_css_coverage`.
26///
27/// See: <https://playwright.dev/docs/api/class-coverage#coverage-start-css-coverage>
28#[derive(Debug, Default, Clone)]
29#[non_exhaustive]
30pub struct StartCSSCoverageOptions {
31 /// Whether to reset coverage on every navigation.
32 ///
33 /// Defaults to `true`.
34 pub reset_on_navigation: Option<bool>,
35}
36
37/// A byte-offset range within a CSS stylesheet.
38///
39/// Used in [`CSSCoverageEntry`].
40#[derive(Debug, Clone, serde::Deserialize)]
41#[non_exhaustive]
42pub struct CoverageRange {
43 /// Start byte offset (inclusive).
44 pub start: usize,
45 /// End byte offset (exclusive).
46 pub end: usize,
47}
48
49/// A byte-offset range with hit count within a JavaScript function.
50///
51/// Used in [`JSFunctionCoverage`].
52#[derive(Debug, Clone, serde::Deserialize)]
53#[non_exhaustive]
54pub struct JSCoverageRange {
55 /// Start byte offset (inclusive).
56 #[serde(rename = "startOffset")]
57 pub start_offset: usize,
58 /// End byte offset (exclusive).
59 #[serde(rename = "endOffset")]
60 pub end_offset: usize,
61 /// Number of times this range was executed.
62 pub count: i64,
63}
64
65/// Per-function coverage data within a [`JSCoverageEntry`].
66#[derive(Debug, Clone, serde::Deserialize)]
67#[non_exhaustive]
68pub struct JSFunctionCoverage {
69 /// The function name (empty string for anonymous functions).
70 #[serde(rename = "functionName")]
71 pub function_name: String,
72 /// Whether this is block-level coverage (true) or function-level (false).
73 #[serde(rename = "isBlockCoverage")]
74 pub is_block_coverage: bool,
75 /// Covered byte-offset ranges within this function.
76 pub ranges: Vec<JSCoverageRange>,
77}
78
79/// A JavaScript coverage entry returned by `Coverage::stop_js_coverage`.
80///
81/// See: <https://playwright.dev/docs/api/class-coverage#coverage-stop-js-coverage>
82#[derive(Debug, Clone, serde::Deserialize)]
83#[non_exhaustive]
84pub struct JSCoverageEntry {
85 /// The URL of the script.
86 pub url: String,
87 /// The V8 script ID.
88 #[serde(rename = "scriptId")]
89 pub script_id: String,
90 /// The script source text.
91 pub source: Option<String>,
92 /// Per-function coverage data.
93 pub functions: Vec<JSFunctionCoverage>,
94}
95
96/// A CSS coverage entry returned by `Coverage::stop_css_coverage`.
97///
98/// See: <https://playwright.dev/docs/api/class-coverage#coverage-stop-css-coverage>
99#[derive(Debug, Clone, serde::Deserialize)]
100#[non_exhaustive]
101pub struct CSSCoverageEntry {
102 /// The URL of the stylesheet.
103 pub url: String,
104 /// The stylesheet source text.
105 pub text: Option<String>,
106 /// Byte-offset ranges of used CSS rules.
107 pub ranges: Vec<CoverageRange>,
108}
109
110/// Provides JavaScript and CSS code coverage collection (Chromium only).
111///
112/// Access via [`Page::coverage`].
113///
114/// Coverage collection is only supported in Chromium. Calling these methods on
115/// Firefox or WebKit will return an error.
116///
117/// See: <https://playwright.dev/docs/api/class-coverage>
118#[derive(Clone)]
119pub struct Coverage {
120 page: Page,
121}
122
123impl Coverage {
124 pub(crate) fn new(page: Page) -> Self {
125 Self { page }
126 }
127
128 /// Starts collecting JavaScript coverage.
129 ///
130 /// Must be called before navigating to the page(s) you want to measure.
131 ///
132 /// # Errors
133 ///
134 /// Returns error if coverage is already started, if the browser is not
135 /// Chromium, or if the RPC call fails.
136 ///
137 /// See: <https://playwright.dev/docs/api/class-coverage#coverage-start-js-coverage>
138 pub async fn start_js_coverage(&self, options: Option<StartJSCoverageOptions>) -> Result<()> {
139 self.page.coverage_start_js(options).await
140 }
141
142 /// Stops JavaScript coverage collection and returns the entries.
143 ///
144 /// # Errors
145 ///
146 /// Returns error if coverage was not started or if the RPC call fails.
147 ///
148 /// See: <https://playwright.dev/docs/api/class-coverage#coverage-stop-js-coverage>
149 pub async fn stop_js_coverage(&self) -> Result<Vec<JSCoverageEntry>> {
150 self.page.coverage_stop_js().await
151 }
152
153 /// Starts collecting CSS coverage.
154 ///
155 /// # Errors
156 ///
157 /// Returns error if coverage is already started, if the browser is not
158 /// Chromium, or if the RPC call fails.
159 ///
160 /// See: <https://playwright.dev/docs/api/class-coverage#coverage-start-css-coverage>
161 pub async fn start_css_coverage(&self, options: Option<StartCSSCoverageOptions>) -> Result<()> {
162 self.page.coverage_start_css(options).await
163 }
164
165 /// Stops CSS coverage collection and returns the entries.
166 ///
167 /// # Errors
168 ///
169 /// Returns error if coverage was not started or if the RPC call fails.
170 ///
171 /// See: <https://playwright.dev/docs/api/class-coverage#coverage-stop-css-coverage>
172 pub async fn stop_css_coverage(&self) -> Result<Vec<CSSCoverageEntry>> {
173 self.page.coverage_stop_css().await
174 }
175}