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