use crate::Selector;
#[test]
fn test_and_operator() {
let sel = Selector::from("role:button && name:Submit");
match sel {
Selector::And(v) => {
assert_eq!(v.len(), 2);
assert!(matches!(v[0], Selector::Role { .. }));
assert!(matches!(v[1], Selector::Name(_)));
}
_ => panic!("Expected And selector, got: {sel:?}"),
}
}
#[test]
fn test_or_operator_with_double_pipe() {
let sel = Selector::from("role:button || role:link");
match sel {
Selector::Or(v) => {
assert_eq!(v.len(), 2);
assert!(matches!(v[0], Selector::Role { .. }));
assert!(matches!(v[1], Selector::Role { .. }));
}
_ => panic!("Expected Or selector, got: {sel:?}"),
}
}
#[test]
fn test_or_operator_with_comma() {
let sel = Selector::from("role:button, role:link, role:checkbox");
match sel {
Selector::Or(v) => {
assert_eq!(v.len(), 3);
for item in v {
assert!(matches!(item, Selector::Role { .. }));
}
}
_ => panic!("Expected Or selector, got: {sel:?}"),
}
}
#[test]
fn test_not_operator() {
let sel = Selector::from("!visible:false");
match sel {
Selector::Not(inner) => {
assert!(matches!(*inner, Selector::Visible(false)));
}
_ => panic!("Expected Not selector, got: {sel:?}"),
}
}
#[test]
fn test_parentheses_basic() {
let sel = Selector::from("(role:button && name:Submit)");
match sel {
Selector::And(v) => {
assert_eq!(v.len(), 2);
}
_ => panic!("Expected And selector, got: {sel:?}"),
}
}
#[test]
fn test_complex_parentheses() {
let sel = Selector::from("(role:button && name:Submit) || (role:link && name:Cancel)");
match sel {
Selector::Or(v) => {
assert_eq!(v.len(), 2);
assert!(matches!(v[0], Selector::And(_)));
assert!(matches!(v[1], Selector::And(_)));
}
_ => panic!("Expected Or selector with And children, got: {sel:?}"),
}
}
#[test]
fn test_operator_precedence() {
let sel = Selector::from("role:button || role:link && visible:true");
match sel {
Selector::Or(v) => {
assert_eq!(v.len(), 2);
assert!(matches!(v[0], Selector::Role { .. }));
assert!(matches!(v[1], Selector::And(_)));
}
_ => panic!("Expected Or with And on right side, got: {sel:?}"),
}
}
#[test]
fn test_not_precedence() {
let sel = Selector::from("!role:button && visible:true");
match sel {
Selector::And(v) => {
assert_eq!(v.len(), 2);
assert!(matches!(v[0], Selector::Not(_)));
assert!(matches!(v[1], Selector::Visible(true)));
}
_ => panic!("Expected And with Not on left side, got: {sel:?}"),
}
}
#[test]
fn test_backward_compat_pipe_syntax() {
let sel = Selector::from("role:button|name:Submit");
match sel {
Selector::Role { role, name } => {
assert_eq!(role, "button");
assert_eq!(name, Some("Submit".to_string()));
}
_ => panic!("Expected Role selector with name, got: {sel:?}"),
}
}
#[test]
fn test_backward_compat_pipe_with_role_prefix() {
let sel = Selector::from("button|Submit");
match sel {
Selector::Role { role, name } => {
assert_eq!(role, "button");
assert_eq!(name, Some("Submit".to_string()));
}
_ => panic!("Expected Role selector with name, got: {sel:?}"),
}
}
#[test]
fn test_chain_with_boolean_expression() {
let sel = Selector::from("application:Calculator >> (role:button && name:1)");
match sel {
Selector::Chain(parts) => {
assert_eq!(parts.len(), 2);
assert!(matches!(parts[0], Selector::Role { .. }));
assert!(matches!(parts[1], Selector::And(_)));
}
_ => panic!("Expected Chain with And in second part, got: {sel:?}"),
}
}
#[test]
fn test_complex_nested_expression() {
let sel = Selector::from("((role:button && name:Submit) || role:link) && visible:true");
match sel {
Selector::And(v) => {
assert_eq!(v.len(), 2);
assert!(matches!(v[0], Selector::Or(_)));
assert!(matches!(v[1], Selector::Visible(true)));
}
_ => panic!("Expected complex And expression, got: {sel:?}"),
}
}
#[test]
fn test_whitespace_handling() {
let sel1 = Selector::from("role:button&&name:Submit");
let sel2 = Selector::from("role:button && name:Submit");
let sel3 = Selector::from(" role:button && name:Submit ");
assert!(matches!(sel1, Selector::And(_)));
assert!(matches!(sel2, Selector::And(_)));
assert!(matches!(sel3, Selector::And(_)));
}
#[test]
fn test_invalid_mismatched_parentheses() {
let sel = Selector::from("(role:button && name:Submit");
assert!(matches!(sel, Selector::Invalid(_)));
}
#[test]
fn test_flatten_nested_and() {
let sel = Selector::from("role:button && name:Submit && visible:true");
match sel {
Selector::And(v) => {
assert_eq!(v.len(), 3, "Expected flattened AND with 3 operands");
}
_ => panic!("Expected And selector, got: {sel:?}"),
}
}
#[test]
fn test_flatten_nested_or() {
let sel = Selector::from("role:button || role:link || role:checkbox");
match sel {
Selector::Or(v) => {
assert_eq!(v.len(), 3, "Expected flattened OR with 3 operands");
}
_ => panic!("Expected Or selector, got: {sel:?}"),
}
}
#[test]
fn test_single_selector_without_operators() {
let sel = Selector::from("role:button");
match sel {
Selector::Role { role, name } => {
assert_eq!(role, "button");
assert_eq!(name, None);
}
_ => panic!("Expected simple Role selector, got: {sel:?}"),
}
}
#[test]
fn test_id_selector_not_confused_with_boolean() {
let sel = Selector::from("#submit-button");
match sel {
Selector::Id(id) => {
assert_eq!(id, "submit-button");
}
_ => panic!("Expected Id selector, got: {sel:?}"),
}
}
#[test]
fn test_mixed_selectors() {
let sel = Selector::from("#submit-button && visible:true || text:Submit");
match sel {
Selector::Or(v) => {
assert_eq!(v.len(), 2);
assert!(matches!(v[0], Selector::And(_)));
assert!(matches!(v[1], Selector::Text(_)));
}
_ => panic!("Expected Or with mixed selectors, got: {sel:?}"),
}
}