chore: 更新 Cloudflare 及浏览器自动化攻防文章并补发 blog 链接

This commit is contained in:
leeguooooo
2026-03-04 09:39:38 +09:00
parent d32a1d046a
commit c07eb7ee52
16 changed files with 1324 additions and 248 deletions
+25
View File
@@ -197,6 +197,22 @@ pub fn parse_command(args: &[String], flags: &Flags) -> Result<Value, ParseError
});
}
}
if let Some(ref wait_until) = flags.wait_until {
if matches!(
wait_until.as_str(),
"load" | "domcontentloaded" | "networkidle"
) {
nav_cmd["waitUntil"] = json!(wait_until);
} else {
return Err(ParseError::InvalidValue {
message: format!(
"Invalid --wait-until value: {} (expected load, domcontentloaded, or networkidle)",
wait_until
),
usage: "open <url>",
});
}
}
Ok(nav_cmd)
}
"back" => Ok(json!({ "id": id, "action": "back" })),
@@ -2068,6 +2084,7 @@ mod tests {
tab_group: None,
tab_group_plugin_id: None,
risk_mode: None,
wait_until: None,
cli_tab_group: false,
cli_tab_group_plugin_id: false,
}
@@ -2349,6 +2366,14 @@ mod tests {
assert_eq!(cmd["riskMode"], "block");
}
#[test]
fn test_navigate_with_wait_until() {
let mut flags = default_flags();
flags.wait_until = Some("domcontentloaded".to_string());
let cmd = parse_command(&args("open https://example.com"), &flags).unwrap();
assert_eq!(cmd["waitUntil"], "domcontentloaded");
}
#[test]
fn test_navigate_with_multiple_headers() {
let mut flags = default_flags();
+26
View File
@@ -39,6 +39,7 @@ pub struct Config {
pub tab_group: Option<String>,
pub tab_group_plugin_id: Option<String>,
pub risk_mode: Option<String>,
pub wait_until: Option<String>,
}
impl Config {
@@ -76,6 +77,7 @@ impl Config {
tab_group: other.tab_group.or(self.tab_group),
tab_group_plugin_id: other.tab_group_plugin_id.or(self.tab_group_plugin_id),
risk_mode: other.risk_mode.or(self.risk_mode),
wait_until: other.wait_until.or(self.wait_until),
}
}
}
@@ -145,6 +147,7 @@ fn extract_config_path(args: &[String]) -> Option<Option<String>> {
"--tab-group",
"--tab-group-plugin-id",
"--risk-mode",
"--wait-until",
];
let mut i = 0;
while i < args.len() {
@@ -220,6 +223,9 @@ pub struct Flags {
/// How verification/captcha detections are handled on navigation:
/// `off` (disable), `warn` (retry and warn), `block` (fail fast).
pub risk_mode: Option<String>,
/// Navigation wait strategy passed to navigate/open commands:
/// `load`, `domcontentloaded`, or `networkidle`.
pub wait_until: Option<String>,
// Track which launch-time options were explicitly passed via CLI
// (as opposed to being set only via environment variables)
@@ -316,6 +322,7 @@ pub fn parse_flags(args: &[String]) -> Flags {
.ok()
.or(config.risk_mode)
.map(|s| s.to_ascii_lowercase()),
wait_until: config.wait_until.map(|s| s.to_ascii_lowercase()),
cli_executable_path: false,
cli_extensions: false,
cli_state: false,
@@ -509,6 +516,12 @@ pub fn parse_flags(args: &[String]) -> Flags {
i += 1;
}
}
"--wait-until" => {
if let Some(s) = args.get(i + 1) {
flags.wait_until = Some(s.to_ascii_lowercase());
i += 1;
}
}
"--config" => {
// Already handled by load_config(); skip the value
i += 1;
@@ -568,6 +581,7 @@ pub fn clean_args(args: &[String]) -> Vec<String> {
"--tab-group",
"--tab-group-plugin-id",
"--risk-mode",
"--wait-until",
"--config",
];
@@ -918,6 +932,18 @@ mod tests {
assert_eq!(cleaned, vec!["open", "example.com"]);
}
#[test]
fn test_parse_wait_until_flag() {
let flags = parse_flags(&args("--wait-until domcontentloaded open example.com"));
assert_eq!(flags.wait_until.as_deref(), Some("domcontentloaded"));
}
#[test]
fn test_clean_args_removes_wait_until() {
let cleaned = clean_args(&args("--wait-until networkidle open example.com"));
assert_eq!(cleaned, vec!["open", "example.com"]);
}
#[test]
fn test_cli_multiple_flags_tracking() {
let flags = parse_flags(&args(
+8 -3
View File
@@ -874,11 +874,13 @@ Global Options:
--session <name> Use specific session
--headers <json> Set HTTP headers (scoped to this origin)
--risk-mode <mode> Risk handling for verify/captcha pages: off, warn, block
--wait-until <mode> Navigation wait strategy: load, domcontentloaded, networkidle
--headed Show browser window
Examples:
agent-browser open example.com
agent-browser --risk-mode block open example.com
agent-browser --wait-until domcontentloaded open example.com
agent-browser open https://github.com
agent-browser open localhost:3000
agent-browser open api.example.com --headers '{"Authorization": "Bearer token"}'
@@ -2232,19 +2234,21 @@ Examples:
}
"doctor" => {
r##"
agent-browser doctor - Diagnose CDP and tab-group plugin health
agent-browser doctor - Diagnose CDP, sourceURL sanitization, and tab-group plugin health
Usage: agent-browser doctor
Runs a non-destructive health check focused on:
- CDP endpoint reachability (preferred :9333 + common ports)
- DevToolsActivePort discovery from local Chrome profiles
- CDP sourceURL sanitization probe (Runtime.evaluate leakage check)
- Plugin handshake page context suitability (internal page vs http(s))
- Tab-group plugin handshake status (when connected via CDP)
Notes:
- doctor does not accept positional arguments
- If browser is not already connected, doctor will still report CDP probe results
- Plugin handshake requires a live CDP page and the extension to be installed
- Plugin handshake requires CDP mode, a normal http(s) page, and the extension installed
Global Options:
--json Output as JSON
@@ -2483,7 +2487,7 @@ Sessions:
Setup:
install Install browser binaries
install --with-deps Also install system dependencies (Linux)
doctor Diagnose CDP + plugin health
doctor Diagnose CDP + sourceURL + plugin health
Snapshot Options:
-i, --interactive Only interactive elements
@@ -2520,6 +2524,7 @@ Options:
--tab-group <name> Base title for agent tab groups (CDP plugin mode; silent no-op if plugin unavailable)
--tab-group-plugin-id <id> Expected Chrome extension ID for tab-group handshake (or AGENT_BROWSER_TAB_GROUP_PLUGIN_ID)
--risk-mode <mode> Verify/captcha handling: off, warn, block (or AGENT_BROWSER_RISK_MODE)
--wait-until <mode> Navigation wait strategy for open/navigate: load, domcontentloaded, networkidle
--session-name <name> Auto-save/restore session state (defaults to --session)
--content-boundaries Wrap page output in boundary markers (or AGENT_BROWSER_CONTENT_BOUNDARIES)
--max-output <chars> Truncate page output to N chars (or AGENT_BROWSER_MAX_OUTPUT)