1use serde::{Deserialize, Serialize};
4use serde_json::Value;
5use std::collections::HashMap;
6
7pub const DEFAULT_TIMEOUT_MS: f64 = 30_000.0;
9
10#[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#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
25pub struct Position {
26 pub x: f64,
27 pub y: f64,
28}
29
30#[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 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#[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#[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#[derive(Debug, Clone, Copy, PartialEq, Eq)]
90pub enum KeyboardModifier {
91 Alt,
92 Control,
93 ControlOrMeta,
94 Meta,
95 Shift,
96}
97
98#[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#[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#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
290pub enum ScreenshotType {
291 #[default]
292 Png,
293 Jpeg,
294 Webp,
295}
296
297#[derive(Debug, Clone, Serialize, Deserialize)]
299pub struct Cookie {
300 pub name: String,
301 pub value: String,
302 #[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#[derive(Debug, Clone, Serialize, Deserialize)]
321pub struct NameValue {
322 pub name: String,
323 pub value: String,
324}
325
326#[derive(Debug, Clone, Serialize, Deserialize)]
328#[allow(non_snake_case)]
329pub struct OriginStorage {
330 pub origin: String,
331 pub localStorage: Vec<NameValue>,
333}
334
335#[derive(Debug, Clone, Serialize, Deserialize)]
340pub struct StorageState {
341 pub cookies: Vec<Value>,
342 pub origins: Vec<OriginStorage>,
343}
344
345pub type Headers = HashMap<String, String>;
347
348#[derive(Debug, Clone, Default)]
354pub struct ConsoleMessageLocation {
355 pub url: Option<String>,
357 pub line_number: Option<i64>,
359 pub column_number: Option<i64>,
361}
362
363impl ConsoleMessageLocation {
364 pub fn url(&self) -> Option<&str> {
365 self.url.as_deref()
366 }
367 pub fn line_number(&self) -> Option<i64> {
368 self.line_number
369 }
370 pub fn column_number(&self) -> Option<i64> {
371 self.column_number
372 }
373}
374
375#[derive(Debug, Clone)]
377pub struct ConsoleMessage {
378 pub text: String,
379 pub r#type: String,
380 pub location: Option<ConsoleMessageLocation>,
383}
384
385impl ConsoleMessage {
386 pub fn text(&self) -> &str {
387 &self.text
388 }
389 pub fn r#type(&self) -> &str {
390 &self.r#type
391 }
392 pub fn location(&self) -> Option<&ConsoleMessageLocation> {
393 self.location.as_ref()
394 }
395}
396
397#[derive(Debug, Clone, Default)]
403pub struct WebError {
404 pub message: Option<String>,
406 pub stack: Option<String>,
408 pub url: Option<String>,
410 pub line_number: Option<i64>,
412 pub column_number: Option<i64>,
413}
414
415impl WebError {
416 pub fn new() -> Self {
417 Self::default()
418 }
419}
420
421#[derive(Debug, Clone, Default)]
427pub struct SecurityDetails {
428 pub protocol: Option<String>,
430 pub cipher: Option<String>,
432 pub issuer: Option<String>,
434 pub subject_name: Option<String>,
436 pub valid_from: Option<f64>,
438 pub valid_to: Option<f64>,
440}
441
442impl SecurityDetails {
443 pub fn new() -> Self {
444 Self::default()
445 }
446
447 pub fn from_cdp(value: &Value) -> Self {
451 let get = |k: &str| value.get(k).and_then(|v| v.as_str()).map(String::from);
452 Self {
453 protocol: get("protocol"),
454 cipher: get("cipher"),
455 issuer: get("issuer"),
456 subject_name: get("subjectName").or_else(|| get("subject_name")),
457 valid_from: value.get("validFrom").and_then(|v| v.as_f64()),
458 valid_to: value.get("validTo").and_then(|v| v.as_f64()),
459 }
460 }
461}