dominator_testing/
barrier_testing.rs1use crate::DominatorTestingError;
2use std::fmt::{Debug, Formatter};
3use std::time::Duration;
4use web_sys::NodeList;
5
6pub enum Condition {
7 AtLeastCount(u32),
8 AtMostCount(u32),
9 Fn(Box<dyn Fn(NodeList) -> bool>),
10}
11
12impl Debug for Condition {
13 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
14 match self {
15 Condition::AtLeastCount(count) => write!(f, "AtLeastCount({})", count),
16 Condition::AtMostCount(count) => write!(f, "AtMostCount({})", count),
17 Condition::Fn(_) => write!(f, "Fn"),
18 }
19 }
20}
21
22pub async fn wait_for_query_selector_all_condition(
34 query: &str,
35 condition: Condition,
36 timeout: Duration,
37) -> Result<(), DominatorTestingError> {
38 barrier(
39 move || {
40 let elements = web_sys::window()
41 .unwrap()
42 .document()
43 .unwrap()
44 .query_selector_all(query)
45 .unwrap();
46
47 match &condition {
48 Condition::AtLeastCount(count) => elements.length() >= *count,
49 Condition::AtMostCount(count) => elements.length() <= *count,
50 Condition::Fn(fn_) => fn_(elements),
51 }
52 },
53 timeout,
54 format!("query: {query}"),
55 )
56 .await
57}
58
59pub async fn barrier(
62 mut expr: impl FnMut() -> bool,
63 timeout: Duration,
64 label: impl ToString,
65) -> Result<(), DominatorTestingError> {
66 let started_at = web_time::Instant::now();
67
68 loop {
69 crate::async_yield().await;
70
71 if expr() {
72 break Ok(());
73 }
74
75 if started_at.elapsed() > timeout {
76 break Err(DominatorTestingError::BarrierTimeOut(label.to_string()));
77 }
78 }
79}