use std::sync::Arc;
use std::time::Duration;
use tokio::sync::RwLock;
use tracing::debug;
use viewpoint_cdp::CdpConnection;
use crate::context::trace::TracingState;
use crate::context::{binding, routing, ContextOptions, DEFAULT_TEST_ID_ATTRIBUTE};
use crate::error::ContextError;
use super::{BrowserContext, ContextEventManager};
impl BrowserContext {
pub(crate) fn new(connection: Arc<CdpConnection>, context_id: String) -> Self {
debug!(context_id = %context_id, "Created BrowserContext");
let route_registry = Arc::new(routing::ContextRouteRegistry::new(
connection.clone(),
context_id.clone(),
));
let binding_registry = Arc::new(binding::ContextBindingRegistry::new());
let ctx = Self {
connection: connection.clone(),
context_id: context_id.clone(),
closed: false,
owned: true, pages: Arc::new(RwLock::new(Vec::new())),
default_timeout: Duration::from_secs(30),
default_navigation_timeout: Duration::from_secs(30),
options: ContextOptions::default(),
weberror_handler: Arc::new(RwLock::new(None)),
event_manager: Arc::new(ContextEventManager::new()),
route_registry,
binding_registry,
init_scripts: Arc::new(RwLock::new(Vec::new())),
test_id_attribute: Arc::new(RwLock::new(DEFAULT_TEST_ID_ATTRIBUTE.to_string())),
har_recorder: Arc::new(RwLock::new(None)),
tracing_state: Arc::new(RwLock::new(TracingState::default())),
};
ctx.start_weberror_listener();
ctx
}
pub(crate) fn with_options(
connection: Arc<CdpConnection>,
context_id: String,
options: ContextOptions,
) -> Self {
debug!(context_id = %context_id, "Created BrowserContext with options");
let route_registry = Arc::new(routing::ContextRouteRegistry::new(
connection.clone(),
context_id.clone(),
));
let binding_registry = Arc::new(binding::ContextBindingRegistry::new());
let ctx = Self {
connection: connection.clone(),
context_id: context_id.clone(),
closed: false,
owned: true, pages: Arc::new(RwLock::new(Vec::new())),
default_timeout: options.default_timeout.unwrap_or(Duration::from_secs(30)),
default_navigation_timeout: options
.default_navigation_timeout
.unwrap_or(Duration::from_secs(30)),
options,
weberror_handler: Arc::new(RwLock::new(None)),
event_manager: Arc::new(ContextEventManager::new()),
route_registry,
binding_registry,
init_scripts: Arc::new(RwLock::new(Vec::new())),
test_id_attribute: Arc::new(RwLock::new(DEFAULT_TEST_ID_ATTRIBUTE.to_string())),
har_recorder: Arc::new(RwLock::new(None)),
tracing_state: Arc::new(RwLock::new(TracingState::default())),
};
ctx.start_weberror_listener();
ctx
}
pub(crate) fn from_existing(connection: Arc<CdpConnection>, context_id: String) -> Self {
let is_default = context_id.is_empty();
debug!(context_id = %context_id, is_default = is_default, "Wrapping existing BrowserContext");
let route_registry = Arc::new(routing::ContextRouteRegistry::new(
connection.clone(),
context_id.clone(),
));
let binding_registry = Arc::new(binding::ContextBindingRegistry::new());
let ctx = Self {
connection: connection.clone(),
context_id: context_id.clone(),
closed: false,
owned: false, pages: Arc::new(RwLock::new(Vec::new())),
default_timeout: Duration::from_secs(30),
default_navigation_timeout: Duration::from_secs(30),
options: ContextOptions::default(),
weberror_handler: Arc::new(RwLock::new(None)),
event_manager: Arc::new(ContextEventManager::new()),
route_registry,
binding_registry,
init_scripts: Arc::new(RwLock::new(Vec::new())),
test_id_attribute: Arc::new(RwLock::new(DEFAULT_TEST_ID_ATTRIBUTE.to_string())),
har_recorder: Arc::new(RwLock::new(None)),
tracing_state: Arc::new(RwLock::new(TracingState::default())),
};
ctx.start_weberror_listener();
ctx
}
pub(crate) async fn apply_options(&self) -> Result<(), ContextError> {
if let Some(ref geo) = self.options.geolocation {
self.set_geolocation(geo.latitude, geo.longitude)
.accuracy(geo.accuracy)
.await?;
}
if !self.options.permissions.is_empty() {
self.grant_permissions(self.options.permissions.clone())
.await?;
}
if !self.options.extra_http_headers.is_empty() {
self.set_extra_http_headers(self.options.extra_http_headers.clone())
.await?;
}
if self.options.offline {
self.set_offline(true).await?;
}
Ok(())
}
}