tablo_test/protocol/
controls.rs1use super::dom::{Attrs, Element, attr_value, elements, open_tags, strip_text};
5
6#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct DisabledAction {
9 pub name: String,
11 pub reason: String,
13}
14
15pub fn confirms_first(html: &str, action: &str) -> Option<bool> {
18 open_tags(html)
19 .into_iter()
20 .find(|(tag, attrs, _)| {
21 tag == "button" && attr_value(attrs, "formaction").as_deref() == Some(action)
22 })
23 .map(|(_, attrs, _)| attr_value(&attrs, "type").as_deref() == Some("button"))
24}
25
26fn posting_button(html: &str, url: &str) -> Option<Element> {
29 let posts_to = |attrs: &Attrs, name: &str| {
30 attr_value(attrs, name).is_some_and(|posted| posted.split('?').next() == Some(url))
31 };
32 elements(html, "button")
33 .into_iter()
34 .find(|(_, attrs, _)| posts_to(attrs, "formaction"))
35 .or_else(|| {
36 elements(html, "form")
37 .into_iter()
38 .find(|(_, attrs, _)| posts_to(attrs, "action"))
39 .and_then(|(_, _, inner)| elements(&inner, "button").into_iter().next())
40 })
41}
42
43pub fn action_label(html: &str, url: &str) -> Option<String> {
45 posting_button(html, url).map(|(_, _, inner)| strip_text(&inner))
46}
47
48pub fn action_tooltip(html: &str, url: &str) -> Option<String> {
51 posting_button(html, url).and_then(|(_, attrs, _)| attr_value(&attrs, "title"))
52}
53
54pub fn action_badge(html: &str, url: &str) -> Option<String> {
57 let (_, _, inner) = posting_button(html, url)?;
58 elements(&inner, "span")
59 .into_iter()
60 .find(|(_, attrs, _)| attr_value(attrs, "data-action-badge").is_some())
61 .map(|(_, _, count)| strip_text(&count))
62}
63
64pub fn selects_matching(html: &str) -> bool {
66 open_tags(html).iter().any(|(tag, attrs, _)| {
67 tag == "button" && attr_value(attrs, "data-select-matching").is_some()
68 })
69}
70
71pub fn disabled_actions(html: &str) -> Vec<DisabledAction> {
74 open_tags(html)
75 .into_iter()
76 .filter_map(|(_, attrs, _)| {
77 Some(DisabledAction {
78 name: attr_value(&attrs, "data-disabled-action")?,
79 reason: attr_value(&attrs, "title").unwrap_or_default(),
80 })
81 })
82 .collect()
83}