(node: &Value, selector: &ElementSelector)
| 104 | } |
| 105 | |
| 106 | fn element_matches(node: &Value, selector: &ElementSelector) -> bool { |
| 107 | if let Some(element_type) = &selector.element_type { |
| 108 | let node_type = string_field(node, "type").or_else(|| string_field(node, "role")); |
| 109 | if !node_type |
| 110 | .as_deref() |
| 111 | .map(|value| value.eq_ignore_ascii_case(element_type)) |
| 112 | .unwrap_or(false) |
| 113 | { |
| 114 | return false; |
| 115 | } |
| 116 | } |
| 117 | if let Some(id) = &selector.id { |
| 118 | return [ |
| 119 | "AXUniqueId", |
| 120 | "AXIdentifier", |
| 121 | "id", |
| 122 | "identifier", |
| 123 | "inspectorId", |
| 124 | ] |
| 125 | .iter() |
| 126 | .filter_map(|key| string_field(node, key)) |
| 127 | .any(|value| value == *id); |
| 128 | } |
| 129 | if let Some(label) = &selector.label { |
| 130 | return ["AXLabel", "label", "title", "name"] |
| 131 | .iter() |
| 132 | .filter_map(|key| string_field(node, key)) |
| 133 | .any(|value| value == *label); |
| 134 | } |
| 135 | if let Some(expected_value) = &selector.value { |
| 136 | return ["AXValue", "value"] |
| 137 | .iter() |
| 138 | .filter_map(|key| string_field(node, key)) |
| 139 | .any(|value| value == *expected_value); |
| 140 | } |
| 141 | true |
| 142 | } |
| 143 | |
| 144 | fn string_field(node: &Value, key: &str) -> Option<String> { |
| 145 | node.get(key)?.as_str().map(str::to_owned) |
no test coverage detected