tablo_test/protocol/
tabs.rs1use super::dom::{attr_value, strip_text, tags_where};
6
7#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct Tab {
10 pub label: String,
12 pub active: bool,
14 pub errored: bool,
16 pub keys: Vec<String>,
18}
19
20pub fn tabs(html: &str) -> Vec<Tab> {
23 tags_where(html, |tag, attrs| {
24 tag == "button" && attr_value(attrs, "role").as_deref() == Some("tab")
25 })
26 .into_iter()
27 .map(|(_, attrs, inner)| {
28 let panel = attr_value(&attrs, "aria-controls").and_then(|id| {
29 tags_where(html, |_, attrs| {
30 attr_value(attrs, "id").as_deref() == Some(id.as_str())
31 })
32 .into_iter()
33 .next()
34 });
35 let shown = panel
36 .as_ref()
37 .is_some_and(|(_, attrs, _)| !attrs.iter().any(|(name, _)| name == "hidden"));
38 let mut keys: Vec<String> = Vec::new();
39 if let Some((_, _, panel)) = &panel {
40 for (_, attrs, _) in tags_where(panel, |_, attrs| attr_value(attrs, "name").is_some()) {
41 let key = attr_value(&attrs, "name").unwrap_or_default();
42 if !keys.contains(&key) {
43 keys.push(key);
44 }
45 }
46 }
47 Tab {
48 label: strip_text(&inner),
49 active: shown && attr_value(&attrs, "aria-selected").as_deref() == Some("true"),
50 errored: attrs.iter().any(|(name, _)| name == "data-tab-error"),
51 keys,
52 }
53 })
54 .collect()
55}