Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 7 additions & 31 deletions cli/src/native/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,7 @@ impl DaemonState {
.await;
if let Ok(attach) = attach_result {
let _ = mgr.enable_domains_pub(&attach.session_id).await;
mgr.apply_session_settings(&attach.session_id, None).await;

// Install domain filter on new pages
let df = self.domain_filter.read().await;
Expand Down Expand Up @@ -3928,37 +3929,9 @@ async fn handle_recording_start(cmd: &Value, state: &mut DaemonState) -> Result<
let new_session_id = attach_result.session_id.clone();
mgr.enable_domains_pub(&new_session_id).await?;

// Re-apply download behavior to the recording context.
// Without this, downloads in the recording context are silently dropped
// because Browser.setDownloadBehavior at launch only applies to the default context.
if let Some(ref dl_path) = mgr.download_path {
let _ = mgr
.client
.send_command(
"Browser.setDownloadBehavior",
Some(json!({
"behavior": "allow",
"downloadPath": dl_path,
"browserContextId": context_id,
"eventsEnabled": true
})),
None,
)
.await;
}

// Re-apply HTTPS error ignore to the recording context.
// Security.setIgnoreCertificateErrors at launch only applies to the session it was sent on.
if mgr.ignore_https_errors {
let _ = mgr
.client
.send_command(
"Security.setIgnoreCertificateErrors",
Some(json!({ "ignore": true })),
Some(&new_session_id),
)
.await;
}
// Re-apply all session-scoped settings to the recording context.
mgr.apply_session_settings(&new_session_id, Some(&context_id))
.await;

// Transfer cookies to new context
if let Some(ref cr) = cookies_result {
Expand Down Expand Up @@ -5882,6 +5855,9 @@ async fn handle_window_new(cmd: &Value, state: &mut DaemonState) -> Result<Value
)
.await?;

mgr.apply_session_settings(&attach.session_id, Some(&context_id))
.await;

mgr.add_page(super::browser::PageInfo {
target_id: create_result.target_id,
session_id: attach.session_id,
Expand Down
63 changes: 45 additions & 18 deletions cli/src/native/browser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,10 @@ pub struct BrowserManager {
pub download_path: Option<String>,
/// Whether to ignore HTTPS certificate errors, re-applied to new contexts (e.g., recording)
pub ignore_https_errors: bool,
/// Stored user-agent override from launch options, re-applied to new contexts (e.g., recording)
pub user_agent: Option<String>,
/// Stored color-scheme override from launch options, re-applied to new contexts (e.g., recording)
pub color_scheme: Option<String>,
/// Origins visited during this session, used by save_state to collect cross-origin localStorage.
visited_origins: HashSet<String>,
}
Expand Down Expand Up @@ -276,59 +280,75 @@ impl BrowserManager {
default_timeout_ms: 25_000,
download_path: download_path.clone(),
ignore_https_errors,
user_agent: user_agent.clone(),
color_scheme: color_scheme.clone(),
visited_origins: HashSet::new(),
};
manager.discover_and_attach_targets().await?;
manager
};

let session_id = manager.active_session_id()?.to_string();
manager.apply_session_settings(&session_id, None).await;

if ignore_https_errors {
let _ = manager
Ok(manager)
}

/// Apply all session-scoped CDP settings to the given session.
///
/// Called after initial target discovery in `launch()` and after attaching to
/// new sessions (e.g., recording contexts in `handle_recording_start`).
///
/// Any new session-scoped CDP setting should be added here so it is
/// automatically applied to every new session/context.
///
/// `browser_context_id` is required for settings like `Browser.setDownloadBehavior`
/// that are scoped to a browser context rather than a session.
pub async fn apply_session_settings(&self, session_id: &str, browser_context_id: Option<&str>) {
if self.ignore_https_errors {
let _ = self
.client
.send_command(
"Security.setIgnoreCertificateErrors",
Some(json!({ "ignore": true })),
Some(&session_id),
Some(session_id),
)
.await;
}

if let Some(ref ua) = user_agent {
let _ = manager
if let Some(ref ua) = self.user_agent {
let _ = self
.client
.send_command(
"Emulation.setUserAgentOverride",
Some(json!({ "userAgent": ua })),
Some(&session_id),
Some(session_id),
)
.await;
}

if let Some(ref scheme) = color_scheme {
let _ = manager
if let Some(ref scheme) = self.color_scheme {
let _ = self
.client
.send_command(
"Emulation.setEmulatedMedia",
Some(json!({ "features": [{ "name": "prefers-color-scheme", "value": scheme }] })),
Some(&session_id),
Some(session_id),
)
.await;
}

if let Some(ref path) = download_path {
let _ = manager
if let Some(ref path) = self.download_path {
let mut params = json!({ "behavior": "allow", "downloadPath": path });
if let Some(ctx_id) = browser_context_id {
params["browserContextId"] = json!(ctx_id);
params["eventsEnabled"] = json!(true);
}
let _ = self
.client
.send_command(
"Browser.setDownloadBehavior",
Some(json!({ "behavior": "allow", "downloadPath": path })),
None,
)
.send_command("Browser.setDownloadBehavior", Some(params), None)
.await;
}

Ok(manager)
}

pub async fn connect_cdp(url: &str) -> Result<Self, String> {
Expand Down Expand Up @@ -364,6 +384,8 @@ impl BrowserManager {
default_timeout_ms: 25_000,
download_path: None,
ignore_https_errors: false,
user_agent: None,
color_scheme: None,
visited_origins: HashSet::new(),
};

Expand Down Expand Up @@ -810,6 +832,8 @@ impl BrowserManager {
});
self.active_page_index = 0;
self.enable_domains(&attach_result.session_id).await?;
self.apply_session_settings(&attach_result.session_id, None)
.await;

Ok(())
}
Expand Down Expand Up @@ -873,6 +897,7 @@ impl BrowserManager {
.await?;

self.enable_domains(&attach.session_id).await?;
self.apply_session_settings(&attach.session_id, None).await;

let index = self.pages.len();
self.pages.push(PageInfo {
Expand Down Expand Up @@ -1369,6 +1394,8 @@ async fn initialize_lightpanda_manager(
default_timeout_ms: 25_000,
download_path: None,
ignore_https_errors: false,
user_agent: None,
color_scheme: None,
visited_origins: HashSet::new(),
};

Expand Down
Loading