#[cfg(test)]
mod tests {
use crate::integ as h;
use std::time::Duration;
use xa11y::*;
const NO_MATCH: &str = r#"button[name="xa11y-no-such-element-3f9a"]"#;
const SHORT_TIMEOUT_CEILING: Duration = Duration::from_secs(4);
#[test]
#[ignore]
fn error_element_on_no_match_is_selector_not_matched() {
let app = h::app_root();
match app.locator(NO_MATCH).element() {
Err(Error::SelectorNotMatched { .. }) => {}
Err(e) => panic!("expected SelectorNotMatched, got: {e}"),
Ok(_) => panic!("expected SelectorNotMatched, but the selector matched"),
}
}
#[test]
#[ignore]
fn error_no_match_exists_false_count_zero() {
let app = h::app_root();
let exists = app
.locator(NO_MATCH)
.exists()
.expect("exists() should not error on a selector miss");
assert!(
!exists,
"exists() should be false for a never-matching selector"
);
let count = app
.locator(NO_MATCH)
.count()
.expect("count() should not error on a selector miss");
assert_eq!(
count, 0,
"count() should be 0 for a never-matching selector"
);
}
#[test]
#[ignore]
fn error_invalid_selector_propagates_through_exists() {
let app = h::app_root();
match app.locator("$$$invalid!!!").exists() {
Err(Error::InvalidSelector { .. }) => {}
Err(e) => panic!("expected InvalidSelector, got: {e}"),
Ok(v) => panic!("expected InvalidSelector, got Ok({v})"),
}
}
#[test]
#[ignore]
fn error_wait_attached_times_out() {
let app = h::app_root();
let start = std::time::Instant::now();
match app
.locator(NO_MATCH)
.wait_attached(Duration::from_millis(500))
{
Err(err @ Error::Timeout { .. }) => {
let Error::Timeout { elapsed, .. } = &err else {
unreachable!()
};
assert!(
*elapsed >= Duration::from_millis(500),
"Timeout::elapsed should cover the full wait, got {elapsed:?}"
);
let d = err
.diagnosis()
.expect("wait timeout must carry a diagnosis");
assert_eq!(d.condition.as_deref(), Some("attached"));
assert_eq!(d.selector.as_deref(), Some(NO_MATCH));
assert_eq!(d.last_observed.as_deref(), Some("selector never matched"));
assert!(
d.scope.is_some(),
"a never-matched wait should include a bounded scope snapshot"
);
}
Err(e) => panic!("expected Timeout, got: {e}"),
Ok(_) => panic!("expected Timeout, but the selector matched"),
}
assert!(
start.elapsed() < SHORT_TIMEOUT_CEILING,
"wait_attached(500ms) took {:?} — the explicit short timeout was not honoured",
start.elapsed()
);
}
#[test]
#[ignore]
fn error_wait_detached_times_out_for_persistent_element() {
let app = h::app_root();
match app
.locator(r#"[name*="Submit"]"#)
.wait_detached(Duration::from_millis(500))
{
Err(Error::Timeout { .. }) => {}
Err(e) => panic!("expected Timeout, got: {e}"),
Ok(()) => panic!("expected Timeout, but Submit detached"),
}
}
#[test]
#[ignore]
fn error_action_auto_wait_times_out() {
let app = h::app_root();
let start = std::time::Instant::now();
let result = app
.locator(NO_MATCH)
.with_timeout(Duration::from_millis(500))
.press();
assert!(
matches!(result, Err(Error::Timeout { .. })),
"press() on a never-matching selector should be Timeout, got: {result:?}"
);
assert!(
start.elapsed() < SHORT_TIMEOUT_CEILING,
"press() with a 500ms auto-wait took {:?}",
start.elapsed()
);
}
#[test]
#[ignore]
fn error_unknown_action_is_action_not_supported() {
let app = h::app_root();
let submit = h::named(&app, "Submit");
let result = h::try_act(&submit, "frobnicate");
assert!(
matches!(result, Err(Error::ActionNotSupported { .. })),
"unknown action name should be ActionNotSupported, got: {result:?}"
);
}
#[test]
#[ignore]
fn error_select_text_inverted_range_is_invalid_action_data() {
let app = h::app_root();
let result = app.locator(r#"[name*="Submit"]"#).select_text(5, 2);
assert!(
matches!(result, Err(Error::InvalidActionData { .. })),
"select_text(5, 2) should be InvalidActionData, got: {result:?}"
);
}
#[test]
#[ignore]
fn error_set_numeric_value_nan_via_locator_is_invalid_action_data() {
let app = h::app_root();
let start = std::time::Instant::now();
let result = app.locator("slider").set_numeric_value(f64::NAN);
assert!(
matches!(result, Err(Error::InvalidActionData { .. })),
"set_numeric_value(NaN) should be InvalidActionData, got: {result:?}"
);
assert!(
start.elapsed() < SHORT_TIMEOUT_CEILING,
"NaN validation should fail fast, took {:?}",
start.elapsed()
);
}
}