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}