viewpoint_core/context/page_events/mod.rs
1//! Page event handling for BrowserContext.
2//!
3//! This module provides page and close event handling functionality.
4
5use std::future::Future;
6
7use super::events::{HandlerId, WaitForPageBuilder};
8use super::BrowserContext;
9use crate::error::ContextError;
10use crate::page::Page;
11
12impl BrowserContext {
13 /// Register a handler for new page events.
14 ///
15 /// The handler will be called whenever a new page is created in this context.
16 /// Returns a handler ID that can be used to remove the handler with `off_page`.
17 ///
18 /// # Example
19 ///
20 /// ```ignore
21 /// let handler_id = context.on_page(|page: Page| async move {
22 /// println!("New page created: {}", page.url().await.unwrap_or_default());
23 /// }).await;
24 ///
25 /// // Later, remove the handler
26 /// context.off_page(handler_id).await;
27 /// ```
28 pub async fn on_page<F, Fut>(&self, handler: F) -> HandlerId
29 where
30 F: Fn(Page) -> Fut + Send + Sync + 'static,
31 Fut: Future<Output = ()> + Send + 'static,
32 {
33 self.event_manager.on_page(handler).await
34 }
35
36 /// Remove a page event handler by its ID.
37 ///
38 /// Returns `true` if a handler was removed, `false` if the ID was not found.
39 pub async fn off_page(&self, handler_id: HandlerId) -> bool {
40 self.event_manager.off_page(handler_id).await
41 }
42
43 /// Register a handler for context close events.
44 ///
45 /// The handler will be called when the context is about to close,
46 /// before cleanup begins.
47 ///
48 /// # Example
49 ///
50 /// ```ignore
51 /// let handler_id = context.on_close(|| async {
52 /// println!("Context is closing!");
53 /// }).await;
54 ///
55 /// // Later, remove the handler
56 /// context.off_close(handler_id).await;
57 /// ```
58 pub async fn on_close<F, Fut>(&self, handler: F) -> HandlerId
59 where
60 F: Fn() -> Fut + Send + Sync + 'static,
61 Fut: Future<Output = ()> + Send + 'static,
62 {
63 self.event_manager.on_close(handler).await
64 }
65
66 /// Remove a close event handler by its ID.
67 ///
68 /// Returns `true` if a handler was removed, `false` if the ID was not found.
69 pub async fn off_close(&self, handler_id: HandlerId) -> bool {
70 self.event_manager.off_close(handler_id).await
71 }
72
73 /// Wait for a new page to be created during an action.
74 ///
75 /// This is useful for handling popups or links that open in new tabs.
76 /// The action is executed and the method waits for a new page to be
77 /// created as a result.
78 ///
79 /// # Example
80 ///
81 /// ```ignore
82 /// let popup = context.wait_for_page(|| async {
83 /// page.locator("a[target=_blank]").click().await?;
84 /// Ok(())
85 /// }).await?;
86 ///
87 /// // Now work with the popup page
88 /// popup.goto("https://example.com").goto().await?;
89 /// ```
90 ///
91 /// # Errors
92 ///
93 /// Returns an error if:
94 /// - The action fails
95 /// - No page is created within the timeout (30 seconds)
96 pub fn wait_for_page<F, Fut>(
97 &self,
98 action: F,
99 ) -> WaitForPageBuilder<'_, F, Fut>
100 where
101 F: FnOnce() -> Fut,
102 Fut: Future<Output = Result<(), ContextError>>,
103 {
104 WaitForPageBuilder::new(&self.event_manager, action)
105 }
106}