night_fury_core/
selector.rs1#[derive(Debug, Clone)]
3#[non_exhaustive]
4pub enum Selector {
5 Ref(usize),
7 Css(String),
9 Text(String),
11 Role { role: String, name: Option<String> },
16}
17
18impl Selector {
19 pub fn role_to_css(&self) -> Option<String> {
23 match self {
24 Selector::Role { role, name } => {
25 let mut css = format!("[role=\"{}\"]", css_escape_attr(role));
26 if let Some(n) = name {
27 let escaped = css_escape_attr(n);
28 css.push_str(&format!("[aria-label=\"{escaped}\"]"));
29 }
30 Some(css)
31 }
32 _ => None,
33 }
34 }
35}
36
37fn css_escape_attr(s: &str) -> String {
39 s.replace('\\', "\\\\").replace('"', "\\\"")
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45
46 #[test]
47 fn test_selector_debug() {
48 assert_eq!(format!("{:?}", Selector::Ref(3)), "Ref(3)");
49 assert_eq!(
50 format!("{:?}", Selector::Css("#submit".into())),
51 "Css(\"#submit\")"
52 );
53 assert_eq!(
54 format!("{:?}", Selector::Text("Sign in".into())),
55 "Text(\"Sign in\")"
56 );
57 }
58
59 #[test]
60 fn test_selector_clone() {
61 let a = Selector::Css(".btn".into());
62 let b = a.clone();
63 assert_eq!(format!("{:?}", a), format!("{:?}", b));
64 }
65
66 #[test]
67 fn test_role_to_css_with_name() {
68 let sel = Selector::Role {
69 role: "button".into(),
70 name: Some("Submit".into()),
71 };
72 assert_eq!(
73 sel.role_to_css().unwrap(),
74 "[role=\"button\"][aria-label=\"Submit\"]"
75 );
76 }
77
78 #[test]
79 fn test_role_to_css_without_name() {
80 let sel = Selector::Role {
81 role: "link".into(),
82 name: None,
83 };
84 assert_eq!(sel.role_to_css().unwrap(), "[role=\"link\"]");
85 }
86
87 #[test]
88 fn test_role_to_css_escapes_quotes() {
89 let sel = Selector::Role {
90 role: "button".into(),
91 name: Some("Say \"hello\"".into()),
92 };
93 assert_eq!(
94 sel.role_to_css().unwrap(),
95 "[role=\"button\"][aria-label=\"Say \\\"hello\\\"\"]"
96 );
97 }
98
99 #[test]
100 fn test_role_to_css_returns_none_for_other_variants() {
101 assert!(Selector::Css("div".into()).role_to_css().is_none());
102 assert!(Selector::Text("hi".into()).role_to_css().is_none());
103 assert!(Selector::Ref(0).role_to_css().is_none());
104 }
105
106 #[test]
107 fn test_role_debug() {
108 let sel = Selector::Role {
109 role: "button".into(),
110 name: Some("OK".into()),
111 };
112 let dbg = format!("{:?}", sel);
113 assert!(dbg.contains("Role"));
114 assert!(dbg.contains("button"));
115 assert!(dbg.contains("OK"));
116 }
117}