1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
//! Event expectation helpers (`expect_request` / `expect_response` /
//! `expect_dialog` / `expect_download` / `expect_file_chooser`).
//!
//! Each helper registers a one-shot subscription on a Tab's CDP event stream
//! and resolves with the first matching event. [`UrlMatcher`] is the shared
//! pattern type used by request/response expectations.
//!
//! ```no_run
//! # async fn ex() -> zendriver::Result<()> {
//! # let browser = zendriver::Browser::builder().launch().await?;
//! # let tab = browser.main_tab();
//! // Pre-register before triggering the action that causes the request.
//! let exp = tab.expect_response("/api/users");
//! tab.find().css("button#load").one().await?.click().await?;
//! let resp = exp.await?;
//! let body = resp.body().await?;
//! # let _ = body;
//! # Ok(()) }
//! ```
pub use crateUrlMatcher;
use ;
use ;
use crate;
/// Subscribe to `method`-shaped events scoped to `session`, decoded via
/// `T`'s [`serde::de::DeserializeOwned`] impl. Backs every `expect_*`
/// subscriber task — riding [`Connection::subscribe_raw_accounted`]
/// (rather than the plain [`SessionHandle::subscribe`]) so a delivery-loss
/// boundary crossed while a wait is in progress is visible instead of
/// silently vanishing.
///
/// [`Connection::subscribe_raw_accounted`]: zendriver_transport::Connection::subscribe_raw_accounted
///
/// Yields `Ok(T)` for every successfully-decoded `method` event on this
/// session. Yields `Err(`[`ZendriverError::EventStreamIncomplete`]`)` on:
///
/// - [`AccountedRawEvent::Disconnected`] / [`AccountedRawEvent::Reconnected`]
/// — the watched stream is gone, so the caller can no longer prove the
/// awaited condition didn't occur just before the boundary.
/// - [`AccountedRawEvent::Lagged`] — this subscriber missed frames it can't
/// recover. There's no way to prove the awaited event wasn't among them,
/// so a "no show" (`Timeout`) would be a possibly-wrong claim. Treated the
/// same as an outright disconnect — mirrors the `IdleLossPolicy::Strict`
/// precedent in `Tab::wait_for_idle_opts`, which makes the identical call
/// for the same reason.
/// - A decode failure on an event that otherwise matches `method` +
/// `session` — the event we were waiting for arrived in a shape we can't
/// parse, which leaves us just as unable to confirm the awaited condition
/// as an outright loss would.
///
/// Events for any other method or session are silently skipped: they were
/// never candidates for the awaited condition, so their absence from the
/// output isn't a loss of anything this caller cares about.
pub + Send + Unpin + use<T>
where
T: DeserializeOwned + Send + 'static,