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(
139 &self,
140 options: impl Into<Option<StartJSCoverageOptions>>,
141 ) -> Result<()> {
142 let options = options.into();
143 self.page.coverage_start_js(options).await
144 }
145
146 /// Stops JavaScript coverage collection and returns the entries.
147 ///
148 /// # Errors
149 ///
150 /// Returns error if coverage was not started or if the RPC call fails.
151 ///
152 /// See: <https://playwright.dev/docs/api/class-coverage#coverage-stop-js-coverage>
153 pub async fn stop_js_coverage(&self) -> Result<Vec<JSCoverageEntry>> {
154 self.page.coverage_stop_js().await
155 }
156
157 /// Starts collecting CSS coverage.
158 ///
159 /// # Errors
160 ///
161 /// Returns error if coverage is already started, if the browser is not
162 /// Chromium, or if the RPC call fails.
163 ///
164 /// See: <https://playwright.dev/docs/api/class-coverage#coverage-start-css-coverage>
165 pub async fn start_css_coverage(
166 &self,
167 options: impl Into<Option<StartCSSCoverageOptions>>,
168 ) -> Result<()> {
169 let options = options.into();
170 self.page.coverage_start_css(options).await
171 }
172
173 /// Stops CSS coverage collection and returns the entries.
174 ///
175 /// # Errors
176 ///
177 /// Returns error if coverage was not started or if the RPC call fails.
178 ///
179 /// See: <https://playwright.dev/docs/api/class-coverage#coverage-stop-css-coverage>
180 pub async fn stop_css_coverage(&self) -> Result<Vec<CSSCoverageEntry>> {
181 self.page.coverage_stop_css().await
182 }
183}