feat: add --download-path option (#536)

* feat: add --download-path option

Adds a `--download-path` flag (and `AGENT_BROWSER_DOWNLOAD_PATH` env / `downloadPath` config key) to set a default download directory for browser downloads.

Without this, Playwright stores downloads in a temp directory that is deleted when the browser closes. The new option passes through to Playwright's `downloadsPath` on `launch()` and `launchPersistentContext()`.

Fixes #507

* improvements

* fixes

* fixes
This commit is contained in:
Chris Tate
2026-02-24 07:22:55 -06:00
committed by GitHub
parent 2fe7394dbe
commit 77f2caa1bc
12 changed files with 109 additions and 2 deletions
+29
View File
@@ -34,6 +34,7 @@ pub struct Config {
pub headers: Option<String>,
pub annotate: Option<bool>,
pub color_scheme: Option<String>,
pub download_path: Option<String>,
}
impl Config {
@@ -68,6 +69,7 @@ impl Config {
headers: other.headers.or(self.headers),
annotate: other.annotate.or(self.annotate),
color_scheme: other.color_scheme.or(self.color_scheme),
download_path: other.download_path.or(self.download_path),
}
}
}
@@ -132,6 +134,7 @@ fn extract_config_path(args: &[String]) -> Option<Option<String>> {
"--device",
"--session-name",
"--color-scheme",
"--download-path",
];
let mut i = 0;
while i < args.len() {
@@ -203,6 +206,7 @@ pub struct Flags {
pub session_name: Option<String>,
pub annotate: bool,
pub color_scheme: Option<String>,
pub download_path: Option<String>,
// Track which launch-time options were explicitly passed via CLI
// (as opposed to being set only via environment variables)
@@ -216,6 +220,7 @@ pub struct Flags {
pub cli_proxy_bypass: bool,
pub cli_allow_file_access: bool,
pub cli_annotate: bool,
pub cli_download_path: bool,
}
pub fn parse_flags(args: &[String]) -> Flags {
@@ -285,6 +290,8 @@ pub fn parse_flags(args: &[String]) -> Flags {
|| config.annotate.unwrap_or(false),
color_scheme: env::var("AGENT_BROWSER_COLOR_SCHEME").ok()
.or(config.color_scheme),
download_path: env::var("AGENT_BROWSER_DOWNLOAD_PATH").ok()
.or(config.download_path),
cli_executable_path: false,
cli_extensions: false,
cli_profile: false,
@@ -295,6 +302,7 @@ pub fn parse_flags(args: &[String]) -> Flags {
cli_proxy_bypass: false,
cli_allow_file_access: false,
cli_annotate: false,
cli_download_path: false,
};
let mut i = 0;
@@ -440,6 +448,13 @@ pub fn parse_flags(args: &[String]) -> Flags {
i += 1;
}
}
"--download-path" => {
if let Some(s) = args.get(i + 1) {
flags.download_path = Some(s.clone());
flags.cli_download_path = true;
i += 1;
}
}
"--config" => {
// Already handled by load_config(); skip the value
i += 1;
@@ -484,6 +499,7 @@ pub fn clean_args(args: &[String]) -> Vec<String> {
"--device",
"--session-name",
"--color-scheme",
"--download-path",
"--config",
];
@@ -674,6 +690,19 @@ mod tests {
assert!(!flags.cli_annotate);
}
#[test]
fn test_cli_download_path_tracking() {
let flags = parse_flags(&args("--download-path /tmp/dl snapshot"));
assert!(flags.cli_download_path);
assert_eq!(flags.download_path, Some("/tmp/dl".to_string()));
}
#[test]
fn test_cli_download_path_not_set_without_flag() {
let flags = parse_flags(&args("snapshot"));
assert!(!flags.cli_download_path);
}
#[test]
fn test_cli_multiple_flags_tracking() {
let flags = parse_flags(&args(