agent_first_http/sdk/fetch/
wait.rs1use crate::shared::error::{Error, ErrorCode};
4
5#[derive(Debug, Clone, Default, PartialEq, Eq)]
7pub enum Wait {
8 #[default]
10 Load,
11 Idle,
13 Selector(String),
18 SelectorVisible(String),
24 Ms(u64),
26}
27
28impl Wait {
29 pub fn parse(s: &str) -> Result<Self, Error> {
30 if s == "load" {
31 Ok(Self::Load)
32 } else if s == "idle" {
33 Ok(Self::Idle)
34 } else if let Some(sel) = s.strip_prefix("selector-visible:") {
35 if sel.is_empty() {
36 Err(Error::new(
37 ErrorCode::InvalidArgument,
38 "--wait selector-visible: requires a non-empty CSS selector",
39 ))
40 } else {
41 Ok(Self::SelectorVisible(sel.to_string()))
42 }
43 } else if let Some(sel) = s.strip_prefix("selector:") {
44 if sel.is_empty() {
45 Err(Error::new(
46 ErrorCode::InvalidArgument,
47 "--wait selector: requires a non-empty CSS selector",
48 ))
49 } else {
50 Ok(Self::Selector(sel.to_string()))
51 }
52 } else if let Some(ms) = s.strip_prefix("ms:") {
53 let n: u64 = ms.parse().map_err(|_| {
54 Error::new(
55 ErrorCode::InvalidArgument,
56 format!("--wait ms: not a u64: {ms:?}"),
57 )
58 })?;
59 Ok(Self::Ms(n))
60 } else {
61 Err(Error::new(
62 ErrorCode::InvalidArgument,
63 format!(
64 "--wait: unknown mode {s:?}; expected \
65 load|idle|selector:<css>|selector-visible:<css>|ms:<n>"
66 ),
67 ))
68 }
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75
76 #[test]
77 fn parses_simple_modes() {
78 assert_eq!(Wait::parse("load").unwrap(), Wait::Load);
79 assert_eq!(Wait::parse("idle").unwrap(), Wait::Idle);
80 assert_eq!(
81 Wait::parse("selector:#root").unwrap(),
82 Wait::Selector("#root".into())
83 );
84 assert_eq!(
85 Wait::parse("selector-visible:#root").unwrap(),
86 Wait::SelectorVisible("#root".into())
87 );
88 assert_eq!(Wait::parse("ms:250").unwrap(), Wait::Ms(250));
89 }
90
91 #[test]
92 fn rejects_empty_selector() {
93 let err = Wait::parse("selector:").err();
94 assert_eq!(err.map(|e| e.error_code), Some(ErrorCode::InvalidArgument));
95 let err = Wait::parse("selector-visible:").err();
96 assert_eq!(err.map(|e| e.error_code), Some(ErrorCode::InvalidArgument));
97 }
98
99 #[test]
100 fn selector_visible_prefix_does_not_collide_with_selector() {
101 let parsed = Wait::parse("selector-visible:.btn").unwrap();
105 assert_eq!(parsed, Wait::SelectorVisible(".btn".into()));
106 }
107
108 #[test]
109 fn rejects_bad_ms() {
110 let err = Wait::parse("ms:nope").err();
111 assert_eq!(err.map(|e| e.error_code), Some(ErrorCode::InvalidArgument));
112 }
113
114 #[test]
115 fn rejects_unknown_mode() {
116 let err = Wait::parse("forever").err();
117 assert_eq!(err.map(|e| e.error_code), Some(ErrorCode::InvalidArgument));
118 }
119}