Skip to main content

playwright_cdp/
types.rs

1//! Shared value types used across the public API.
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5use std::collections::HashMap;
6
7/// Default action timeout in milliseconds (matches Playwright's default).
8pub const DEFAULT_TIMEOUT_MS: f64 = 30_000.0;
9
10/// A viewport size.
11#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
12pub struct Viewport {
13    pub width: u32,
14    pub height: u32,
15}
16
17impl Viewport {
18    pub fn new(width: u32, height: u32) -> Self {
19        Self { width, height }
20    }
21}
22
23/// A point in viewport coordinates.
24#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
25pub struct Position {
26    pub x: f64,
27    pub y: f64,
28}
29
30/// Mouse button for click/hover actions.
31///
32/// Note: the discriminant values are an ordering, **not** the CDP `buttons`
33/// bitmask. Use [`MouseButton::bitmask`] for the `Input.dispatchMouseEvent`
34/// `buttons` field.
35#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
36#[repr(u8)]
37pub enum MouseButton {
38    #[default]
39    Left = 0,
40    Middle = 1,
41    Right = 2,
42    Back = 3,
43    Forward = 4,
44}
45
46impl MouseButton {
47    pub fn as_str(&self) -> &'static str {
48        match self {
49            MouseButton::Left => "left",
50            MouseButton::Middle => "middle",
51            MouseButton::Right => "right",
52            MouseButton::Back => "back",
53            MouseButton::Forward => "forward",
54        }
55    }
56
57    /// CDP `Input.dispatchMouseEvent` `buttons` bitmask for this button:
58    /// Left=1, Right=2, Middle=4, Back=8, Forward=16.
59    pub fn bitmask(&self) -> u8 {
60        match self {
61            MouseButton::Left => 1,
62            MouseButton::Right => 2,
63            MouseButton::Middle => 4,
64            MouseButton::Back => 8,
65            MouseButton::Forward => 16,
66        }
67    }
68}
69
70/// A rectangle in viewport coordinates (element bounds).
71#[derive(Debug, Clone, Copy, Default, PartialEq)]
72pub struct BoundingBox {
73    pub x: f64,
74    pub y: f64,
75    pub width: f64,
76    pub height: f64,
77}
78
79/// A clip rectangle for screenshots.
80#[derive(Debug, Clone, Copy, Default, PartialEq)]
81pub struct ScreenshotClip {
82    pub x: f64,
83    pub y: f64,
84    pub width: f64,
85    pub height: f64,
86}
87
88/// Keyboard modifiers for actions.
89#[derive(Debug, Clone, Copy, PartialEq, Eq)]
90pub enum KeyboardModifier {
91    Alt,
92    Control,
93    ControlOrMeta,
94    Meta,
95    Shift,
96}
97
98/// Proxy server configuration.
99#[derive(Debug, Clone, Default)]
100pub struct ProxySettings {
101    pub server: String,
102    pub bypass: Option<String>,
103    pub username: Option<String>,
104    pub password: Option<String>,
105}
106
107/// An ARIA role, used by `get_by_role`.
108///
109/// Mirrors Playwright's `AriaRole` set.
110#[derive(Debug, Clone, Copy, PartialEq, Eq)]
111pub enum AriaRole {
112    Alert,
113    Alertdialog,
114    Application,
115    Article,
116    Banner,
117    Blockquote,
118    Button,
119    Caption,
120    Cell,
121    Checkbox,
122    Code,
123    Columnheader,
124    Combobox,
125    Complementary,
126    Contentinfo,
127    Definition,
128    Deletion,
129    Dialog,
130    Directory,
131    Document,
132    Embed,
133    Figure,
134    Footer,
135    Form,
136    Generic,
137    Grid,
138    Gridcell,
139    Group,
140    Heading,
141    Img,
142    Image,
143    Insertion,
144    Link,
145    List,
146    Listbox,
147    Listitem,
148    Log,
149    Main,
150    Marquee,
151    Math,
152    Menu,
153    Menubar,
154    Menuitem,
155    Menuitemcheckbox,
156    Menuitemradio,
157    Meter,
158    Navigation,
159    None,
160    Note,
161    Option,
162    Paragraph,
163    Presentation,
164    Progressbar,
165    Radio,
166    Radiogroup,
167    Region,
168    Row,
169    Rowgroup,
170    Rowheader,
171    Scrollbar,
172    Search,
173    Searchbox,
174    Separator,
175    Slider,
176    Spinbutton,
177    Status,
178    Strong,
179    Subscript,
180    Superscript,
181    Switch,
182    Tab,
183    Table,
184    Tablist,
185    Tabpanel,
186    Term,
187    Textbox,
188    Time,
189    Timer,
190    Toolbar,
191    Tooltip,
192    Tree,
193    Treegrid,
194    Treeitem,
195}
196
197impl AriaRole {
198    pub fn as_str(&self) -> &'static str {
199        use AriaRole::*;
200        match self {
201            Alert => "alert",
202            Alertdialog => "alertdialog",
203            Application => "application",
204            Article => "article",
205            Banner => "banner",
206            Blockquote => "blockquote",
207            Button => "button",
208            Caption => "caption",
209            Cell => "cell",
210            Checkbox => "checkbox",
211            Code => "code",
212            Columnheader => "columnheader",
213            Combobox => "combobox",
214            Complementary => "complementary",
215            Contentinfo => "contentinfo",
216            Definition => "definition",
217            Deletion => "deletion",
218            Dialog => "dialog",
219            Directory => "directory",
220            Document => "document",
221            Embed => "embed",
222            Figure => "figure",
223            Footer => "footer",
224            Form => "form",
225            Generic => "generic",
226            Grid => "grid",
227            Gridcell => "gridcell",
228            Group => "group",
229            Heading => "heading",
230            Img => "img",
231            Image => "image",
232            Insertion => "insertion",
233            Link => "link",
234            List => "list",
235            Listbox => "listbox",
236            Listitem => "listitem",
237            Log => "log",
238            Main => "main",
239            Marquee => "marquee",
240            Math => "math",
241            Menu => "menu",
242            Menubar => "menubar",
243            Menuitem => "menuitem",
244            Menuitemcheckbox => "menuitemcheckbox",
245            Menuitemradio => "menuitemradio",
246            Meter => "meter",
247            Navigation => "navigation",
248            None => "none",
249            Note => "note",
250            Option => "option",
251            Paragraph => "paragraph",
252            Presentation => "presentation",
253            Progressbar => "progressbar",
254            Radio => "radio",
255            Radiogroup => "radiogroup",
256            Region => "region",
257            Row => "row",
258            Rowgroup => "rowgroup",
259            Rowheader => "rowheader",
260            Scrollbar => "scrollbar",
261            Search => "search",
262            Searchbox => "searchbox",
263            Separator => "separator",
264            Slider => "slider",
265            Spinbutton => "spinbutton",
266            Status => "status",
267            Strong => "strong",
268            Subscript => "subscript",
269            Superscript => "superscript",
270            Switch => "switch",
271            Tab => "tab",
272            Table => "table",
273            Tablist => "tablist",
274            Tabpanel => "tabpanel",
275            Term => "term",
276            Textbox => "textbox",
277            Time => "time",
278            Timer => "timer",
279            Toolbar => "toolbar",
280            Tooltip => "tooltip",
281            Tree => "tree",
282            Treegrid => "treegrid",
283            Treeitem => "treeitem",
284        }
285    }
286}
287
288/// Screenshot image format.
289#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
290pub enum ScreenshotType {
291    #[default]
292    Png,
293    Jpeg,
294    Webp,
295}
296
297/// A cookie, shaped for `add_cookies` / `cookies`.
298#[derive(Debug, Clone, Serialize, Deserialize)]
299pub struct Cookie {
300    pub name: String,
301    pub value: String,
302    /// Either `url` or `domain`+`path` must be supplied.
303    #[serde(skip_serializing_if = "Option::is_none")]
304    pub url: Option<String>,
305    #[serde(skip_serializing_if = "Option::is_none")]
306    pub domain: Option<String>,
307    #[serde(skip_serializing_if = "Option::is_none")]
308    pub path: Option<String>,
309    #[serde(skip_serializing_if = "Option::is_none")]
310    pub expires: Option<f64>,
311    #[serde(skip_serializing_if = "Option::is_none")]
312    pub http_only: Option<bool>,
313    #[serde(skip_serializing_if = "Option::is_none")]
314    pub secure: Option<bool>,
315    #[serde(skip_serializing_if = "Option::is_none")]
316    pub same_site: Option<String>,
317}
318
319/// A name/value pair, e.g. a single localStorage entry.
320#[derive(Debug, Clone, Serialize, Deserialize)]
321pub struct NameValue {
322    pub name: String,
323    pub value: String,
324}
325
326/// localStorage entries grouped by origin.
327#[derive(Debug, Clone, Serialize, Deserialize)]
328#[allow(non_snake_case)]
329pub struct OriginStorage {
330    pub origin: String,
331    // Named to match the JS/Playwright `localStorage` key.
332    pub localStorage: Vec<NameValue>,
333}
334
335/// A serializable snapshot of a context's storage: cookies plus per-origin
336/// localStorage. Mirrors Playwright's `storageState` shape. Cookies stay as
337/// `serde_json::Value` (the raw CDP/`Storage` cookie objects) so they can be
338/// fed straight back to `set_storage_state`.
339#[derive(Debug, Clone, Serialize, Deserialize)]
340pub struct StorageState {
341    pub cookies: Vec<Value>,
342    pub origins: Vec<OriginStorage>,
343}
344
345/// Extra HTTP headers map.
346pub type Headers = HashMap<String, String>;
347
348/// A console message captured from the page.
349#[derive(Debug, Clone)]
350pub struct ConsoleMessage {
351    pub text: String,
352    pub r#type: String,
353}
354
355impl ConsoleMessage {
356    pub fn text(&self) -> &str {
357        &self.text
358    }
359    pub fn r#type(&self) -> &str {
360        &self.r#type
361    }
362}