viewpoint_core/context/page_management/
mod.rs1use tracing::{debug, info, instrument};
4
5use viewpoint_cdp::protocol::target_domain::{GetTargetsParams, GetTargetsResult};
6
7use crate::context::page_factory;
8use crate::error::ContextError;
9use crate::page::Page;
10
11use super::{BrowserContext, PageInfo};
12
13impl BrowserContext {
14 #[instrument(level = "info", skip(self), fields(context_id = %self.context_id))]
20 pub async fn new_page(&self) -> Result<Page, ContextError> {
21 if self.closed {
22 return Err(ContextError::Closed);
23 }
24
25 info!("Creating new page");
26
27 let (create_result, attach_result) =
29 page_factory::create_and_attach_target(&self.connection, &self.context_id).await?;
30
31 let target_id = &create_result.target_id;
32 let session_id = &attach_result.session_id;
33
34 page_factory::enable_page_domains(&self.connection, session_id).await?;
36
37 page_factory::apply_emulation_settings(&self.connection, session_id, &self.options).await?;
39
40 let frame_id = page_factory::get_main_frame_id(&self.connection, session_id).await?;
42
43 page_factory::track_page(
45 &self.pages,
46 create_result.target_id.clone(),
47 attach_result.session_id.clone(),
48 )
49 .await;
50
51 if let Err(e) = self.apply_init_scripts_to_session(session_id).await {
53 debug!("Failed to apply init scripts: {}", e);
54 }
55
56 info!(target_id = %target_id, session_id = %session_id, frame_id = %frame_id, "Page created successfully");
57
58 let test_id_attr = self.test_id_attribute.read().await.clone();
60
61 let http_credentials = page_factory::convert_http_credentials(&self.options);
63
64 let proxy_credentials = page_factory::convert_proxy_credentials(&self.options);
66
67 let page_index = self.next_page_index();
69
70 let page = page_factory::create_page_instance(
72 self.connection.clone(),
73 create_result,
74 attach_result,
75 frame_id,
76 self.context_index,
77 page_index,
78 &self.options,
79 test_id_attr,
80 self.route_registry.clone(),
81 http_credentials,
82 proxy_credentials,
83 )
84 .await;
85
86 if let Err(e) = page.enable_fetch_for_context_routes().await {
89 debug!("Failed to enable Fetch for context routes: {}", e);
90 }
91
92 self.event_manager.emit_page(page.clone_internal()).await;
94
95 Ok(page)
96 }
97
98 pub async fn pages(&self) -> Result<Vec<PageInfo>, ContextError> {
104 if self.closed {
105 return Err(ContextError::Closed);
106 }
107
108 let result: GetTargetsResult = self
109 .connection
110 .send_command("Target.getTargets", Some(GetTargetsParams::default()), None)
111 .await?;
112
113 let pages: Vec<PageInfo> = result
114 .target_infos
115 .into_iter()
116 .filter(|t| {
117 let matches_context = if self.context_id.is_empty() {
120 t.browser_context_id.as_deref().is_none()
122 || t.browser_context_id.as_deref() == Some("")
123 } else {
124 t.browser_context_id.as_deref() == Some(&self.context_id)
126 };
127 matches_context && t.target_type == "page"
128 })
129 .map(|t| PageInfo {
130 target_id: t.target_id,
131 session_id: String::new(), })
133 .collect();
134
135 Ok(pages)
136 }
137}