fix: inherit viewport dimensions in recording context (#1208)

* fix: inherit viewport dimensions in recording context

When `record start` creates a new browser context, it now re-applies the
current viewport settings (from `set viewport` or `set device`) so the
recording resolution matches what the user configured instead of falling
back to the default 1280×720.

Closes #1207

* style: apply cargo fmt to e2e test

* chore: remove obvious comments

* chore: remove obvious comments from e2e test

---------

Co-authored-by: hyunjinee <leehj0110@kakao.com>
This commit is contained in:
jin.2
2026-04-13 23:40:26 -05:00
committed by GitHub
co-authored by hyunjinee
parent ddf6d6a2af
commit db29d5fead
2 changed files with 97 additions and 2 deletions
+16 -2
View File
@@ -248,6 +248,9 @@ pub struct DaemonState {
pub engine: String,
/// Default timeout for wait operations, from AGENT_BROWSER_DEFAULT_TIMEOUT env var.
pub default_timeout_ms: u64,
/// Last viewport settings (width, height, deviceScaleFactor, mobile),
/// re-applied to new contexts (e.g., recording).
pub viewport: Option<(i32, i32, f64, bool)>,
}
impl DaemonState {
@@ -301,6 +304,7 @@ impl DaemonState {
.ok()
.and_then(|s| s.parse::<u64>().ok())
.unwrap_or(30_000),
viewport: None,
}
}
@@ -3605,7 +3609,7 @@ async fn handle_tab_close(cmd: &Value, state: &mut DaemonState) -> Result<Value,
mgr.tab_close(index).await
}
async fn handle_viewport(cmd: &Value, state: &DaemonState) -> Result<Value, String> {
async fn handle_viewport(cmd: &Value, state: &mut DaemonState) -> Result<Value, String> {
let mgr = state.browser.as_ref().ok_or("Browser not launched")?;
let width = cmd.get("width").and_then(|v| v.as_i64()).unwrap_or(1280) as i32;
let height = cmd.get("height").and_then(|v| v.as_i64()).unwrap_or(720) as i32;
@@ -3617,6 +3621,8 @@ async fn handle_viewport(cmd: &Value, state: &DaemonState) -> Result<Value, Stri
mgr.set_viewport(width, height, scale, mobile).await?;
state.viewport = Some((width, height, scale, mobile));
// Update stream server viewport so status messages and screencast use the new dimensions
if let Some(ref server) = state.stream_server {
server.set_viewport(width as u32, height as u32).await;
@@ -3872,6 +3878,8 @@ async fn handle_recording_start(cmd: &Value, state: &mut DaemonState) -> Result<
.and_then(|v| v.as_str())
.filter(|s| !s.is_empty());
let viewport = state.viewport;
let (client, new_session_id) = {
let mgr = state.browser.as_mut().ok_or("Browser not launched")?;
let old_session_id = mgr.active_session_id()?.to_string();
@@ -3985,6 +3993,10 @@ async fn handle_recording_start(cmd: &Value, state: &mut DaemonState) -> Result<
target_type: "page".to_string(),
});
if let Some((w, h, scale, mobile)) = viewport {
let _ = mgr.set_viewport(w, h, scale, mobile).await;
}
// Navigate to URL
if nav_url != "about:blank" {
let _ = mgr
@@ -4661,7 +4673,7 @@ async fn handle_wheel(cmd: &Value, state: &DaemonState) -> Result<Value, String>
Ok(json!({ "scrolled": true, "deltaX": delta_x, "deltaY": delta_y }))
}
async fn handle_device(cmd: &Value, state: &DaemonState) -> Result<Value, String> {
async fn handle_device(cmd: &Value, state: &mut DaemonState) -> Result<Value, String> {
let mgr = state.browser.as_ref().ok_or("Browser not launched")?;
let name = cmd
.get("name")
@@ -4690,6 +4702,8 @@ async fn handle_device(cmd: &Value, state: &DaemonState) -> Result<Value, String
mgr.set_viewport(width, height, scale, mobile).await?;
mgr.set_user_agent(ua).await?;
state.viewport = Some((width, height, scale, mobile));
// Update stream server viewport so status messages and screencast use the new dimensions
if let Some(ref server) = state.stream_server {
server.set_viewport(width as u32, height as u32).await;