1#![allow(missing_docs)]
5
6use clap::{Parser, Subcommand, ValueEnum};
7
8#[derive(Debug, Parser)]
10#[command(
11 name = "browser-automation-cli",
12 version,
13 about = "One-shot browser automation CLI (Chrome CDP). NASCE, EXECUTA, FINALIZE, MORRE.",
14 long_about = None,
15 propagate_version = true
16)]
17pub struct Cli {
18 #[command(flatten)]
19 pub globals: GlobalOpts,
20
21 #[command(subcommand)]
22 pub command: Commands,
23}
24
25#[derive(Debug, Clone, Parser)]
26pub struct GlobalOpts {
27 #[arg(long, global = true, env = "BROWSER_AUTOMATION_CLI_JSON")]
28 pub json: bool,
29
30 #[arg(
32 short = 'q',
33 long = "quiet",
34 global = true,
35 env = "BROWSER_AUTOMATION_CLI_QUIET"
36 )]
37 pub quiet: bool,
38
39 #[arg(
41 long = "verbose",
42 global = true,
43 env = "BROWSER_AUTOMATION_CLI_VERBOSE"
44 )]
45 pub verbose: bool,
46
47 #[arg(long = "debug", global = true, env = "BROWSER_AUTOMATION_CLI_DEBUG")]
49 pub debug: bool,
50
51 #[arg(
52 long,
53 global = true,
54 env = "BROWSER_AUTOMATION_CLI_TIMEOUT",
55 default_value_t = 0
56 )]
57 pub timeout: u64,
58
59 #[arg(
61 long,
62 global = true,
63 env = "BROWSER_AUTOMATION_CLI_STEP_TIMEOUT",
64 default_value_t = 0
65 )]
66 pub step_timeout: u64,
67
68 #[arg(long, global = true, env = "BROWSER_AUTOMATION_CLI_HEADED")]
70 pub headed: bool,
71
72 #[arg(long, global = true, env = "BROWSER_AUTOMATION_CLI_ARTIFACTS_DIR")]
73 pub artifacts_dir: Option<std::path::PathBuf>,
74
75 #[arg(long, global = true, env = "BROWSER_AUTOMATION_CLI_LANG")]
76 pub lang: Option<String>,
77
78 #[arg(long, global = true, env = "BROWSER_AUTOMATION_CLI_CAPTURE_CONSOLE")]
79 pub capture_console: bool,
80
81 #[arg(long, global = true, env = "BROWSER_AUTOMATION_CLI_CAPTURE_NETWORK")]
82 pub capture_network: bool,
83
84 #[arg(long, global = true, env = "BROWSER_AUTOMATION_CLI_IGNORE_ROBOTS")]
85 pub ignore_robots: bool,
86
87 #[arg(
88 long,
89 global = true,
90 env = "BROWSER_AUTOMATION_CLI_I_ACCEPT_ROBOTS_RISK"
91 )]
92 pub i_accept_robots_risk: bool,
93
94 #[arg(long, global = true, env = "BROWSER_AUTOMATION_CLI_CATEGORY_MEMORY")]
96 pub category_memory: bool,
97
98 #[arg(
100 long,
101 global = true,
102 env = "BROWSER_AUTOMATION_CLI_CATEGORY_EXTENSIONS"
103 )]
104 pub category_extensions: bool,
105
106 #[arg(
108 long,
109 global = true,
110 env = "BROWSER_AUTOMATION_CLI_CATEGORY_THIRD_PARTY"
111 )]
112 pub category_third_party: bool,
113
114 #[arg(long, global = true, env = "BROWSER_AUTOMATION_CLI_CATEGORY_WEBMCP")]
116 pub category_webmcp: bool,
117
118 #[arg(
120 long,
121 global = true,
122 env = "BROWSER_AUTOMATION_CLI_EXPERIMENTAL_SCREENCAST"
123 )]
124 pub experimental_screencast: bool,
125
126 #[arg(
128 long,
129 global = true,
130 env = "BROWSER_AUTOMATION_CLI_EXPERIMENTAL_VISION"
131 )]
132 pub experimental_vision: bool,
133}
134
135#[derive(Debug, Subcommand)]
136pub enum Commands {
137 Doctor {
139 #[arg(long)]
140 offline: bool,
141 #[arg(long)]
142 quick: bool,
143 #[arg(long)]
144 fix: bool,
145 #[arg(long)]
146 json: bool,
147 },
148 Commands {
150 #[arg(long)]
151 json: bool,
152 },
153 Schema {
155 #[arg(long = "cmd", value_name = "CMD")]
156 cmd: String,
157 },
158 Version,
160 Goto {
162 url: String,
163 #[arg(long)]
165 init_script: Option<String>,
166 #[arg(long)]
168 handle_before_unload: bool,
169 #[arg(long)]
171 navigation_timeout_ms: Option<u64>,
172 },
173 View {
175 #[arg(long)]
176 verbose: bool,
177 #[arg(long)]
178 path: Option<std::path::PathBuf>,
179 },
180 Press {
182 target: String,
183 #[arg(long)]
184 dblclick: bool,
185 #[arg(long)]
187 include_snapshot: bool,
188 },
189 ClickAt {
191 #[arg(long)]
192 x: f64,
193 #[arg(long)]
194 y: f64,
195 #[arg(long)]
196 dblclick: bool,
197 #[arg(long)]
199 include_snapshot: bool,
200 },
201 Write {
203 target: String,
204 value: String,
205 #[arg(long)]
207 include_snapshot: bool,
208 },
209 Keys {
211 key: String,
212 #[arg(long)]
214 include_snapshot: bool,
215 },
216 Type {
218 text: String,
220 #[arg(long)]
222 target: Option<String>,
223 #[arg(long)]
224 clear: bool,
225 #[arg(long)]
227 submit: Option<String>,
228 #[arg(long)]
230 focus_only: bool,
231 },
232 Wait {
234 #[arg(long, default_value_t = 0)]
235 ms: u64,
236 #[arg(long = "text", action = clap::ArgAction::Append)]
238 text: Vec<String>,
239 #[arg(long)]
240 selector: Option<String>,
241 #[arg(long)]
243 state: Option<String>,
244 #[arg(long)]
246 wait_timeout_ms: Option<u64>,
247 #[arg(long)]
249 include_snapshot: bool,
250 },
251 Hover {
253 target: String,
254 #[arg(long)]
256 include_snapshot: bool,
257 },
258 Drag {
260 #[arg(long)]
261 from: String,
262 #[arg(long)]
263 to: String,
264 #[arg(long)]
266 include_snapshot: bool,
267 },
268 FillForm {
270 #[arg(long)]
271 json: String,
272 #[arg(long)]
274 include_snapshot: bool,
275 },
276 Upload {
278 target: String,
279 path: std::path::PathBuf,
280 #[arg(long)]
282 include_snapshot: bool,
283 },
284 Back,
286 Forward,
288 Reload {
290 #[arg(long)]
291 ignore_cache: bool,
292 #[arg(long)]
294 init_script: Option<String>,
295 #[arg(long)]
297 handle_before_unload: bool,
298 },
299 Eval {
301 expression: String,
303 #[arg(long)]
305 args: Option<String>,
306 #[arg(long)]
308 dialog_action: Option<String>,
309 #[arg(long)]
311 file_path: Option<std::path::PathBuf>,
312 },
313 Grab {
315 #[arg(long)]
316 path: Option<std::path::PathBuf>,
317 #[arg(long, value_enum, default_value_t = GrabFormat::Png)]
318 format: GrabFormat,
319 #[arg(long)]
320 full_page: bool,
321 #[arg(long)]
322 quality: Option<i32>,
323 #[arg(long)]
325 element: Option<String>,
326 },
327 Run {
329 #[arg(long)]
330 script: std::path::PathBuf,
331 },
332 Exec {
334 #[arg(trailing_var_arg = true)]
337 args: Vec<String>,
338 },
339 Extract {
341 target: String,
342 #[arg(long)]
343 attr: Option<String>,
344 },
345 Text { target: String },
347 Scroll {
349 #[arg(long)]
351 target: Option<String>,
352 #[arg(long, default_value_t = 0.0)]
353 delta_x: f64,
354 #[arg(long, default_value_t = 0.0)]
355 delta_y: f64,
356 },
357 Cookie {
359 #[command(subcommand)]
360 action: CookieAction,
361 },
362 Attr { target: String, name: String },
364 Assert {
366 #[command(subcommand)]
367 kind: AssertKind,
368 },
369 Console {
371 #[command(subcommand)]
372 action: ConsoleAction,
373 },
374 Net {
376 #[command(subcommand)]
377 action: NetAction,
378 },
379 Page {
381 #[command(subcommand)]
382 action: Option<PageAction>,
383 },
384 Dialog {
386 #[command(subcommand)]
387 action: DialogAction,
388 },
389 Scrape { url: String },
391 Emulate {
393 #[arg(long)]
394 user_agent: Option<String>,
395 #[arg(long)]
396 locale: Option<String>,
397 #[arg(long)]
398 timezone: Option<String>,
399 #[arg(long)]
400 offline: bool,
401 #[arg(long)]
402 latitude: Option<f64>,
403 #[arg(long)]
404 longitude: Option<f64>,
405 #[arg(long)]
406 media: Option<String>,
407 #[arg(long)]
409 network_conditions: Option<String>,
410 #[arg(long)]
412 cpu_throttling_rate: Option<f64>,
413 #[arg(long)]
415 color_scheme: Option<String>,
416 #[arg(long)]
418 extra_headers: Option<String>,
419 #[arg(long)]
421 viewport: Option<String>,
422 },
423 Resize {
425 #[arg(long)]
426 width: i32,
427 #[arg(long)]
428 height: i32,
429 #[arg(long, default_value_t = 1.0)]
430 scale: f64,
431 #[arg(long)]
432 mobile: bool,
433 },
434 Perf {
436 #[command(subcommand)]
437 action: PerfAction,
438 },
439 Lighthouse {
441 url: String,
442 #[arg(long)]
443 out_dir: Option<std::path::PathBuf>,
444 #[arg(long, default_value = "desktop")]
445 device: String,
446 #[arg(long, default_value = "navigation")]
448 mode: String,
449 #[arg(long)]
450 lighthouse_path: Option<std::path::PathBuf>,
451 },
452 Screencast {
454 #[command(subcommand)]
455 action: ScreencastAction,
456 },
457 Heap {
459 #[command(subcommand)]
460 action: HeapAction,
461 },
462 Extension {
464 #[command(subcommand)]
465 action: ExtensionAction,
466 },
467 Devtools3p {
469 #[command(subcommand)]
470 action: Devtools3pAction,
471 },
472 Webmcp {
474 #[command(subcommand)]
475 action: WebmcpAction,
476 },
477 Completions {
479 #[arg(value_enum)]
480 shell: CompletionShell,
481 },
482}
483
484#[derive(Debug, Clone, Subcommand)]
485pub enum PerfAction {
486 Start {
487 #[arg(long)]
488 path: Option<std::path::PathBuf>,
489 #[arg(long)]
490 reload: bool,
491 #[arg(long)]
493 auto_stop: bool,
494 },
495 Stop {
496 #[arg(long)]
497 path: Option<std::path::PathBuf>,
498 },
499 Insight {
500 #[arg(long)]
502 name: Option<String>,
503 #[arg(long)]
505 insight_set_id: Option<String>,
506 #[arg(long)]
508 insight_name: Option<String>,
509 },
510}
511
512#[derive(Debug, Clone, Subcommand)]
513pub enum ScreencastAction {
514 Start {
515 #[arg(long)]
516 path: Option<std::path::PathBuf>,
517 },
518 Stop {
519 #[arg(long)]
521 path: Option<std::path::PathBuf>,
522 },
523}
524
525#[derive(Debug, Clone, Subcommand)]
526pub enum HeapAction {
527 Take {
528 #[arg(long)]
529 path: std::path::PathBuf,
530 },
531 Close {
532 #[arg(long)]
533 path: std::path::PathBuf,
534 },
535 Compare {
536 #[arg(long)]
537 base: std::path::PathBuf,
538 #[arg(long)]
539 current: std::path::PathBuf,
540 #[arg(long)]
542 class_index: Option<u64>,
543 },
544 Summary {
545 #[arg(long)]
546 path: std::path::PathBuf,
547 },
548 Details {
549 #[arg(long)]
550 path: std::path::PathBuf,
551 #[arg(long)]
552 filter_name: Option<String>,
553 #[arg(long)]
554 page_idx: Option<usize>,
555 #[arg(long)]
556 page_size: Option<usize>,
557 },
558 ClassNodes {
559 #[arg(long)]
560 path: std::path::PathBuf,
561 #[arg(long)]
562 id: u64,
563 #[arg(long)]
564 filter_name: Option<String>,
565 #[arg(long)]
566 page_idx: Option<usize>,
567 #[arg(long)]
568 page_size: Option<usize>,
569 },
570 Dominators {
571 #[arg(long)]
572 path: std::path::PathBuf,
573 #[arg(long)]
574 node: u64,
575 },
576 DupStrings {
577 #[arg(long)]
578 path: std::path::PathBuf,
579 #[arg(long)]
580 page_idx: Option<usize>,
581 #[arg(long)]
582 page_size: Option<usize>,
583 },
584 Edges {
585 #[arg(long)]
586 path: std::path::PathBuf,
587 #[arg(long)]
588 node: u64,
589 #[arg(long)]
590 page_idx: Option<usize>,
591 #[arg(long)]
592 page_size: Option<usize>,
593 },
594 Retainers {
595 #[arg(long)]
596 path: std::path::PathBuf,
597 #[arg(long)]
598 node: u64,
599 #[arg(long)]
600 page_idx: Option<usize>,
601 #[arg(long)]
602 page_size: Option<usize>,
603 },
604 Paths {
605 #[arg(long)]
606 path: std::path::PathBuf,
607 #[arg(long)]
608 node: u64,
609 #[arg(long, default_value_t = 8)]
610 max_depth: u64,
611 #[arg(long)]
612 max_nodes: Option<u64>,
613 #[arg(long)]
614 max_siblings: Option<u64>,
615 },
616 ObjectDetails {
618 #[arg(long)]
619 path: std::path::PathBuf,
620 #[arg(long)]
621 node: u64,
622 },
623}
624
625#[derive(Debug, Clone, Subcommand)]
626pub enum ExtensionAction {
627 List,
628 Install {
629 path: std::path::PathBuf,
630 },
631 Reload {
632 id: String,
633 #[arg(long)]
635 path: Option<std::path::PathBuf>,
636 },
637 Trigger {
638 id: String,
639 #[arg(long)]
641 path: Option<std::path::PathBuf>,
642 },
643 Uninstall {
644 id: String,
645 },
646}
647
648#[derive(Debug, Clone, Subcommand)]
649pub enum Devtools3pAction {
650 List {
651 #[arg(long)]
653 url: Option<String>,
654 },
655 Exec {
656 name: String,
657 #[arg(long)]
658 params: Option<String>,
659 #[arg(long)]
660 url: Option<String>,
661 },
662}
663
664#[derive(Debug, Clone, Subcommand)]
665pub enum WebmcpAction {
666 List {
667 #[arg(long)]
668 url: Option<String>,
669 },
670 Exec {
671 name: String,
672 #[arg(long)]
673 input: Option<String>,
674 #[arg(long)]
675 url: Option<String>,
676 },
677}
678
679#[derive(Debug, Clone, Copy, ValueEnum)]
680pub enum CompletionShell {
681 Bash,
682 Zsh,
683 Fish,
684 Elvish,
685 Powershell,
686}
687
688#[derive(Debug, Clone, Subcommand)]
689pub enum PageAction {
690 Info,
692 List,
694 New {
696 #[arg(long)]
697 url: Option<String>,
698 #[arg(long)]
700 background: bool,
701 #[arg(long)]
703 isolated_context: bool,
704 },
705 Select {
707 #[arg(value_name = "INDEX")]
708 index: Option<usize>,
709 #[arg(long = "page-id")]
711 page_id: Option<usize>,
712 #[arg(long, default_value_t = true)]
714 bring_to_front: bool,
715 },
716 Close {
718 #[arg(long)]
719 index: Option<usize>,
720 #[arg(long = "page-id")]
722 page_id: Option<usize>,
723 },
724}
725
726#[derive(Debug, Clone, Subcommand)]
727pub enum CookieAction {
728 List {
730 #[arg(long)]
731 url: Option<String>,
732 },
733 Set {
735 #[arg(long)]
737 json: String,
738 },
739 Clear,
741}
742
743#[derive(Debug, Clone, Copy, ValueEnum, Default)]
744pub enum GrabFormat {
745 #[default]
746 Png,
747 Jpeg,
748 Webp,
749}
750
751#[derive(Debug, Clone, Subcommand)]
752pub enum AssertKind {
753 Url {
754 value: String,
755 #[arg(long)]
756 contains: bool,
757 },
758 Text {
759 value: String,
760 #[arg(long)]
761 target: Option<String>,
762 },
763 Console {
764 #[arg(long, default_value = "error")]
765 level: String,
766 #[arg(long, default_value_t = 0)]
767 max: u64,
768 },
769}
770
771#[derive(Debug, Clone, Subcommand)]
772pub enum ConsoleAction {
773 List {
774 #[arg(long)]
776 page_idx: Option<usize>,
777 #[arg(long)]
779 page_size: Option<usize>,
780 #[arg(long)]
782 types: Option<String>,
783 #[arg(long)]
785 include_preserved: bool,
786 #[arg(long)]
788 service_worker_id: Option<String>,
789 },
790 Get {
791 id: usize,
792 },
793 Clear,
794 Dump {
795 #[arg(long)]
796 path: std::path::PathBuf,
797 },
798}
799
800#[derive(Debug, Clone, Subcommand)]
801pub enum NetAction {
802 List {
803 #[arg(long)]
805 page_idx: Option<usize>,
806 #[arg(long)]
808 page_size: Option<usize>,
809 #[arg(long)]
811 resource_types: Option<String>,
812 #[arg(long)]
814 include_preserved: bool,
815 },
816 Get {
817 id: String,
819 #[arg(long)]
820 request_path: Option<std::path::PathBuf>,
821 #[arg(long)]
822 response_path: Option<std::path::PathBuf>,
823 },
824}
825
826#[derive(Debug, Clone, Subcommand)]
827pub enum DialogAction {
828 Accept {
829 #[arg(long)]
830 text: Option<String>,
831 },
832 Dismiss,
833}