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
//! Attach to a live session's browser over raw CDP.
//!
//! Behind the **`connect`** cargo feature (off by default) so the control-plane
//! surface stays dependency-light.
//!
//! Playwright has no Rust binding, so there is no port of the TypeScript
//! `BrowserSession` object model — Rust drives the session over the raw CDP
//! endpoint via [`chromiumoxide`], which is why this helper attaches to
//! [`Session::cdp_endpoint`] and not `Session::ws_endpoint` (the latter speaks
//! the Playwright wire protocol, which chromiumoxide does not understand). For a
//! one-call create+connect+seed+probe+retry+release convenience on top of this,
//! see [`crate::Client::launch`].
use Browser;
use HandlerConfig;
use StreamExt;
use JoinHandle;
use crateSolariError;
use crateSession;
/// A browser attached to a Solari session.
///
/// Holds the [`chromiumoxide::Browser`] plus the spawned task pumping its event
/// handler. The handler must keep running for as long as the browser is used —
/// every `browser` call resolves through it. It ends on its own once `browser`
/// is dropped.
/// Attach to `session.cdp_endpoint` and return the connected browser plus its
/// handler task.
///
/// ```no_run
/// # async fn ex(client: &solari_browser::Client) -> Result<(), solari_browser::SolariError> {
/// use solari_browser::CreateSessionOptions;
///
/// let session = client
/// .sessions()
/// .create(CreateSessionOptions::new().stealth(true))
/// .await?;
///
/// let connected = solari_browser::connect(&session).await?;
/// let page = connected
/// .browser
/// .new_page("https://example.com")
/// .await
/// .map_err(|e| solari_browser::SolariError::Connect { message: e.to_string() })?;
/// println!("{:?}", page.url().await.ok());
///
/// connected.disconnect().await;
/// client.sessions().release(&session.id).await?;
/// # Ok(()) }
/// ```
pub async
/// Attach to an explicit CDP endpoint. Useful when you persisted a session's
/// `cdp_endpoint` and no longer hold the [`Session`].
pub async