browser-control-and-automation-cli 0.1.1.dev3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- browser_cli/__init__.py +7 -0
- browser_cli/actions/__init__.py +5 -0
- browser_cli/actions/cli_specs.py +868 -0
- browser_cli/agent_scope/__init__.py +14 -0
- browser_cli/automation/__init__.py +11 -0
- browser_cli/automation/api/__init__.py +5 -0
- browser_cli/automation/api/server.py +321 -0
- browser_cli/automation/hooks.py +42 -0
- browser_cli/automation/loader.py +134 -0
- browser_cli/automation/models.py +127 -0
- browser_cli/automation/persistence/__init__.py +5 -0
- browser_cli/automation/persistence/store.py +682 -0
- browser_cli/automation/projections.py +279 -0
- browser_cli/automation/publisher.py +153 -0
- browser_cli/automation/scheduler/__init__.py +5 -0
- browser_cli/automation/scheduler/schedule.py +113 -0
- browser_cli/automation/service/__init__.py +8 -0
- browser_cli/automation/service/__main__.py +64 -0
- browser_cli/automation/service/client.py +232 -0
- browser_cli/automation/service/runtime.py +388 -0
- browser_cli/automation/toml.py +35 -0
- browser_cli/automation/web/__init__.py +5 -0
- browser_cli/automation/web/assets.py +377 -0
- browser_cli/browser/__init__.py +1 -0
- browser_cli/browser/models.py +44 -0
- browser_cli/browser/network_capture.py +392 -0
- browser_cli/browser/service.py +1519 -0
- browser_cli/browser/session.py +158 -0
- browser_cli/browser/snapshot.py +35 -0
- browser_cli/browser/stealth.py +450 -0
- browser_cli/cli/__init__.py +1 -0
- browser_cli/cli/error_hints.py +26 -0
- browser_cli/cli/main.py +298 -0
- browser_cli/commands/__init__.py +1 -0
- browser_cli/commands/action.py +25 -0
- browser_cli/commands/automation.py +304 -0
- browser_cli/commands/doctor.py +336 -0
- browser_cli/commands/install_skills.py +138 -0
- browser_cli/commands/paths.py +31 -0
- browser_cli/commands/read.py +33 -0
- browser_cli/commands/reload.py +51 -0
- browser_cli/commands/status.py +444 -0
- browser_cli/commands/task.py +71 -0
- browser_cli/constants.py +97 -0
- browser_cli/daemon/__init__.py +1 -0
- browser_cli/daemon/__main__.py +34 -0
- browser_cli/daemon/app.py +941 -0
- browser_cli/daemon/browser_service.py +998 -0
- browser_cli/daemon/client.py +280 -0
- browser_cli/daemon/models.py +63 -0
- browser_cli/daemon/runtime_presentation.py +167 -0
- browser_cli/daemon/server.py +103 -0
- browser_cli/daemon/state.py +15 -0
- browser_cli/daemon/transport.py +77 -0
- browser_cli/drivers/__init__.py +6 -0
- browser_cli/drivers/_extension/__init__.py +1 -0
- browser_cli/drivers/_extension/artifact_actions.py +154 -0
- browser_cli/drivers/_extension/dialog_actions.py +35 -0
- browser_cli/drivers/_extension/input_actions.py +63 -0
- browser_cli/drivers/_extension/locator_actions.py +100 -0
- browser_cli/drivers/_extension/observe_actions.py +285 -0
- browser_cli/drivers/_extension/page_actions.py +210 -0
- browser_cli/drivers/_extension/state_actions.py +134 -0
- browser_cli/drivers/base.py +391 -0
- browser_cli/drivers/extension_driver.py +33 -0
- browser_cli/drivers/models.py +21 -0
- browser_cli/drivers/playwright_driver.py +499 -0
- browser_cli/error_codes.py +27 -0
- browser_cli/errors.py +146 -0
- browser_cli/exit_codes.py +9 -0
- browser_cli/extension/__init__.py +32 -0
- browser_cli/extension/protocol.py +222 -0
- browser_cli/extension/session.py +393 -0
- browser_cli/network.py +147 -0
- browser_cli/outputs/__init__.py +1 -0
- browser_cli/outputs/json.py +10 -0
- browser_cli/outputs/render.py +7 -0
- browser_cli/packaged_skills/__init__.py +1 -0
- browser_cli/packaged_skills/browser-cli-converge/SKILL.md +62 -0
- browser_cli/packaged_skills/browser-cli-delivery/SKILL.md +61 -0
- browser_cli/packaged_skills/browser-cli-explore/SKILL.md +77 -0
- browser_cli/profiles/__init__.py +1 -0
- browser_cli/profiles/discovery.py +185 -0
- browser_cli/refs/__init__.py +17 -0
- browser_cli/refs/generator.py +386 -0
- browser_cli/refs/models.py +127 -0
- browser_cli/refs/registry.py +51 -0
- browser_cli/refs/resolver.py +214 -0
- browser_cli/tabs/__init__.py +5 -0
- browser_cli/tabs/registry.py +283 -0
- browser_cli/task_runtime/__init__.py +31 -0
- browser_cli/task_runtime/client.py +107 -0
- browser_cli/task_runtime/entrypoint.py +110 -0
- browser_cli/task_runtime/errors.py +17 -0
- browser_cli/task_runtime/flow.py +171 -0
- browser_cli/task_runtime/models.py +97 -0
- browser_cli/task_runtime/read.py +71 -0
- browser_cli/task_runtime/templates.py +58 -0
- browser_control_and_automation_cli-0.1.1.dev3.dist-info/METADATA +340 -0
- browser_control_and_automation_cli-0.1.1.dev3.dist-info/RECORD +104 -0
- browser_control_and_automation_cli-0.1.1.dev3.dist-info/WHEEL +5 -0
- browser_control_and_automation_cli-0.1.1.dev3.dist-info/entry_points.txt +2 -0
- browser_control_and_automation_cli-0.1.1.dev3.dist-info/licenses/LICENSE +21 -0
- browser_control_and_automation_cli-0.1.1.dev3.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,868 @@
|
|
|
1
|
+
"""CLI metadata for daemon-backed actions."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from argparse import ArgumentParser, Namespace
|
|
7
|
+
from collections.abc import Callable
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
RequestBuilder = Callable[[Namespace], dict[str, Any]]
|
|
12
|
+
ArgumentBuilder = Callable[[ArgumentParser], None]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass(slots=True, frozen=True)
|
|
16
|
+
class ActionSpec:
|
|
17
|
+
name: str
|
|
18
|
+
help: str
|
|
19
|
+
description: str
|
|
20
|
+
add_arguments: ArgumentBuilder
|
|
21
|
+
build_request: RequestBuilder
|
|
22
|
+
start_if_needed: bool = True
|
|
23
|
+
cli_name: str | None = None
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def get_action_specs() -> list[ActionSpec]:
|
|
27
|
+
return [
|
|
28
|
+
ActionSpec(
|
|
29
|
+
"open",
|
|
30
|
+
"Open a URL in a new tab.",
|
|
31
|
+
"Create a new tab and navigate to URL.",
|
|
32
|
+
_add_open_arguments,
|
|
33
|
+
_default_request,
|
|
34
|
+
),
|
|
35
|
+
ActionSpec(
|
|
36
|
+
"search",
|
|
37
|
+
"Search the web in a new tab.",
|
|
38
|
+
"Open a search results page in a new tab.",
|
|
39
|
+
_add_search_arguments,
|
|
40
|
+
_default_request,
|
|
41
|
+
),
|
|
42
|
+
ActionSpec(
|
|
43
|
+
"info",
|
|
44
|
+
"Show the current page info.",
|
|
45
|
+
"Return the current active tab metadata.",
|
|
46
|
+
_no_arguments,
|
|
47
|
+
_default_request,
|
|
48
|
+
),
|
|
49
|
+
ActionSpec(
|
|
50
|
+
"html",
|
|
51
|
+
"Capture rendered DOM HTML.",
|
|
52
|
+
"Return rendered DOM HTML for the active tab.",
|
|
53
|
+
_no_arguments,
|
|
54
|
+
_default_request,
|
|
55
|
+
),
|
|
56
|
+
ActionSpec(
|
|
57
|
+
"snapshot",
|
|
58
|
+
"Capture a bridgic-style snapshot.",
|
|
59
|
+
"Return the accessibility-style snapshot tree for the active tab.",
|
|
60
|
+
_add_snapshot_arguments,
|
|
61
|
+
_default_request,
|
|
62
|
+
),
|
|
63
|
+
ActionSpec(
|
|
64
|
+
"reload",
|
|
65
|
+
"Reload the current page.",
|
|
66
|
+
"Reload the current active tab.",
|
|
67
|
+
_no_arguments,
|
|
68
|
+
_default_request,
|
|
69
|
+
True,
|
|
70
|
+
"page-reload",
|
|
71
|
+
),
|
|
72
|
+
ActionSpec(
|
|
73
|
+
"back",
|
|
74
|
+
"Go back in history.",
|
|
75
|
+
"Navigate back in the current active tab history.",
|
|
76
|
+
_no_arguments,
|
|
77
|
+
_default_request,
|
|
78
|
+
),
|
|
79
|
+
ActionSpec(
|
|
80
|
+
"forward",
|
|
81
|
+
"Go forward in history.",
|
|
82
|
+
"Navigate forward in the current active tab history.",
|
|
83
|
+
_no_arguments,
|
|
84
|
+
_default_request,
|
|
85
|
+
),
|
|
86
|
+
ActionSpec(
|
|
87
|
+
"tabs",
|
|
88
|
+
"List visible tabs.",
|
|
89
|
+
"List tabs visible to the current agent domain.",
|
|
90
|
+
_no_arguments,
|
|
91
|
+
_default_request,
|
|
92
|
+
),
|
|
93
|
+
ActionSpec(
|
|
94
|
+
"new-tab",
|
|
95
|
+
"Create a new tab.",
|
|
96
|
+
"Open a new blank tab or navigate to URL.",
|
|
97
|
+
_add_optional_url_arguments,
|
|
98
|
+
_default_request,
|
|
99
|
+
),
|
|
100
|
+
ActionSpec(
|
|
101
|
+
"switch-tab",
|
|
102
|
+
"Switch the active tab.",
|
|
103
|
+
"Switch to a visible tab by page id.",
|
|
104
|
+
_add_page_id_arguments,
|
|
105
|
+
_default_request,
|
|
106
|
+
),
|
|
107
|
+
ActionSpec(
|
|
108
|
+
"close-tab",
|
|
109
|
+
"Close a tab.",
|
|
110
|
+
"Close the active tab or a visible tab by page id.",
|
|
111
|
+
_add_optional_page_id_arguments,
|
|
112
|
+
_default_request,
|
|
113
|
+
),
|
|
114
|
+
ActionSpec(
|
|
115
|
+
"close",
|
|
116
|
+
"Close the active tab.",
|
|
117
|
+
"Close the current active tab in this agent domain.",
|
|
118
|
+
_no_arguments,
|
|
119
|
+
_default_request,
|
|
120
|
+
),
|
|
121
|
+
ActionSpec(
|
|
122
|
+
"click",
|
|
123
|
+
"Click an element ref.",
|
|
124
|
+
"Click an element by ref.",
|
|
125
|
+
_add_ref_arguments,
|
|
126
|
+
_default_request,
|
|
127
|
+
),
|
|
128
|
+
ActionSpec(
|
|
129
|
+
"double-click",
|
|
130
|
+
"Double-click an element ref.",
|
|
131
|
+
"Double-click an element by ref.",
|
|
132
|
+
_add_ref_arguments,
|
|
133
|
+
_default_request,
|
|
134
|
+
),
|
|
135
|
+
ActionSpec(
|
|
136
|
+
"hover",
|
|
137
|
+
"Hover an element ref.",
|
|
138
|
+
"Hover over an element by ref.",
|
|
139
|
+
_add_ref_arguments,
|
|
140
|
+
_default_request,
|
|
141
|
+
),
|
|
142
|
+
ActionSpec(
|
|
143
|
+
"focus",
|
|
144
|
+
"Focus an element ref.",
|
|
145
|
+
"Focus an element by ref.",
|
|
146
|
+
_add_ref_arguments,
|
|
147
|
+
_default_request,
|
|
148
|
+
),
|
|
149
|
+
ActionSpec(
|
|
150
|
+
"fill",
|
|
151
|
+
"Fill an input element by ref.",
|
|
152
|
+
"Fill an input-like element by ref.",
|
|
153
|
+
_add_fill_arguments,
|
|
154
|
+
_default_request,
|
|
155
|
+
),
|
|
156
|
+
ActionSpec(
|
|
157
|
+
"fill-form",
|
|
158
|
+
"Fill multiple refs from JSON.",
|
|
159
|
+
"Fill multiple form fields from a JSON array.",
|
|
160
|
+
_add_fill_form_arguments,
|
|
161
|
+
_fill_form_request,
|
|
162
|
+
),
|
|
163
|
+
ActionSpec(
|
|
164
|
+
"select",
|
|
165
|
+
"Select an option by text.",
|
|
166
|
+
"Select an option from a dropdown ref.",
|
|
167
|
+
_add_select_arguments,
|
|
168
|
+
_default_request,
|
|
169
|
+
),
|
|
170
|
+
ActionSpec(
|
|
171
|
+
"options",
|
|
172
|
+
"List dropdown options.",
|
|
173
|
+
"List all options from a dropdown ref.",
|
|
174
|
+
_add_ref_arguments,
|
|
175
|
+
_default_request,
|
|
176
|
+
),
|
|
177
|
+
ActionSpec(
|
|
178
|
+
"check",
|
|
179
|
+
"Check a checkbox or radio.",
|
|
180
|
+
"Check an element by ref.",
|
|
181
|
+
_add_ref_arguments,
|
|
182
|
+
_default_request,
|
|
183
|
+
),
|
|
184
|
+
ActionSpec(
|
|
185
|
+
"uncheck",
|
|
186
|
+
"Uncheck a checkbox.",
|
|
187
|
+
"Uncheck an element by ref.",
|
|
188
|
+
_add_ref_arguments,
|
|
189
|
+
_default_request,
|
|
190
|
+
),
|
|
191
|
+
ActionSpec(
|
|
192
|
+
"scroll-to",
|
|
193
|
+
"Scroll to an element ref.",
|
|
194
|
+
"Scroll the active page so the ref is visible.",
|
|
195
|
+
_add_ref_arguments,
|
|
196
|
+
_default_request,
|
|
197
|
+
),
|
|
198
|
+
ActionSpec(
|
|
199
|
+
"drag",
|
|
200
|
+
"Drag between two refs.",
|
|
201
|
+
"Drag from one ref to another.",
|
|
202
|
+
_add_drag_arguments,
|
|
203
|
+
_default_request,
|
|
204
|
+
),
|
|
205
|
+
ActionSpec(
|
|
206
|
+
"upload",
|
|
207
|
+
"Upload a file to an input ref.",
|
|
208
|
+
"Set input files on a file input ref.",
|
|
209
|
+
_add_upload_arguments,
|
|
210
|
+
_default_request,
|
|
211
|
+
),
|
|
212
|
+
ActionSpec(
|
|
213
|
+
"type",
|
|
214
|
+
"Type text into the focused element.",
|
|
215
|
+
"Type text into the currently focused element.",
|
|
216
|
+
_add_type_arguments,
|
|
217
|
+
_default_request,
|
|
218
|
+
),
|
|
219
|
+
ActionSpec(
|
|
220
|
+
"press",
|
|
221
|
+
"Press a keyboard key.",
|
|
222
|
+
"Press a key or key combination.",
|
|
223
|
+
_add_key_arguments,
|
|
224
|
+
_default_request,
|
|
225
|
+
),
|
|
226
|
+
ActionSpec(
|
|
227
|
+
"key-down",
|
|
228
|
+
"Press and hold a key.",
|
|
229
|
+
"Press and hold a keyboard key.",
|
|
230
|
+
_add_key_arguments,
|
|
231
|
+
_default_request,
|
|
232
|
+
),
|
|
233
|
+
ActionSpec(
|
|
234
|
+
"key-up",
|
|
235
|
+
"Release a key.",
|
|
236
|
+
"Release a held keyboard key.",
|
|
237
|
+
_add_key_arguments,
|
|
238
|
+
_default_request,
|
|
239
|
+
),
|
|
240
|
+
ActionSpec(
|
|
241
|
+
"scroll",
|
|
242
|
+
"Scroll the page.",
|
|
243
|
+
"Scroll the current page using mouse wheel deltas.",
|
|
244
|
+
_add_scroll_arguments,
|
|
245
|
+
_default_request,
|
|
246
|
+
),
|
|
247
|
+
ActionSpec(
|
|
248
|
+
"mouse-click",
|
|
249
|
+
"Click at viewport coordinates.",
|
|
250
|
+
"Click the mouse at viewport coordinates.",
|
|
251
|
+
_add_mouse_click_arguments,
|
|
252
|
+
_default_request,
|
|
253
|
+
),
|
|
254
|
+
ActionSpec(
|
|
255
|
+
"mouse-move",
|
|
256
|
+
"Move the mouse.",
|
|
257
|
+
"Move the mouse to viewport coordinates.",
|
|
258
|
+
_add_mouse_move_arguments,
|
|
259
|
+
_default_request,
|
|
260
|
+
),
|
|
261
|
+
ActionSpec(
|
|
262
|
+
"mouse-drag",
|
|
263
|
+
"Drag the mouse.",
|
|
264
|
+
"Drag the mouse between viewport coordinates.",
|
|
265
|
+
_add_mouse_drag_arguments,
|
|
266
|
+
_default_request,
|
|
267
|
+
),
|
|
268
|
+
ActionSpec(
|
|
269
|
+
"mouse-down",
|
|
270
|
+
"Hold a mouse button.",
|
|
271
|
+
"Press and hold a mouse button.",
|
|
272
|
+
_add_mouse_button_arguments,
|
|
273
|
+
_default_request,
|
|
274
|
+
),
|
|
275
|
+
ActionSpec(
|
|
276
|
+
"mouse-up",
|
|
277
|
+
"Release a mouse button.",
|
|
278
|
+
"Release a mouse button.",
|
|
279
|
+
_add_mouse_button_arguments,
|
|
280
|
+
_default_request,
|
|
281
|
+
),
|
|
282
|
+
ActionSpec(
|
|
283
|
+
"eval",
|
|
284
|
+
"Evaluate JavaScript.",
|
|
285
|
+
"Evaluate JavaScript in the page context.",
|
|
286
|
+
_add_eval_arguments,
|
|
287
|
+
_default_request,
|
|
288
|
+
),
|
|
289
|
+
ActionSpec(
|
|
290
|
+
"eval-on",
|
|
291
|
+
"Evaluate JavaScript on a ref.",
|
|
292
|
+
"Evaluate JavaScript on an element ref.",
|
|
293
|
+
_add_eval_on_arguments,
|
|
294
|
+
_default_request,
|
|
295
|
+
),
|
|
296
|
+
ActionSpec(
|
|
297
|
+
"wait",
|
|
298
|
+
"Wait for time or text.",
|
|
299
|
+
"Wait for time or for text to appear/disappear.",
|
|
300
|
+
_add_wait_arguments,
|
|
301
|
+
_default_request,
|
|
302
|
+
),
|
|
303
|
+
ActionSpec(
|
|
304
|
+
"wait-network",
|
|
305
|
+
"Wait for network idle.",
|
|
306
|
+
"Wait until the page network is idle.",
|
|
307
|
+
_add_wait_network_arguments,
|
|
308
|
+
_default_request,
|
|
309
|
+
),
|
|
310
|
+
ActionSpec(
|
|
311
|
+
"screenshot",
|
|
312
|
+
"Save a screenshot.",
|
|
313
|
+
"Save a screenshot to path.",
|
|
314
|
+
_add_screenshot_arguments,
|
|
315
|
+
_default_request,
|
|
316
|
+
),
|
|
317
|
+
ActionSpec(
|
|
318
|
+
"pdf",
|
|
319
|
+
"Save a PDF.",
|
|
320
|
+
"Save the current page as a PDF.",
|
|
321
|
+
_add_path_arguments,
|
|
322
|
+
_default_request,
|
|
323
|
+
),
|
|
324
|
+
ActionSpec(
|
|
325
|
+
"console-start",
|
|
326
|
+
"Start console capture.",
|
|
327
|
+
"Start capturing browser console messages.",
|
|
328
|
+
_no_arguments,
|
|
329
|
+
_default_request,
|
|
330
|
+
),
|
|
331
|
+
ActionSpec(
|
|
332
|
+
"console",
|
|
333
|
+
"Read console messages.",
|
|
334
|
+
"Read captured console messages.",
|
|
335
|
+
_add_console_arguments,
|
|
336
|
+
_default_request,
|
|
337
|
+
),
|
|
338
|
+
ActionSpec(
|
|
339
|
+
"console-stop",
|
|
340
|
+
"Stop console capture.",
|
|
341
|
+
"Stop capturing browser console messages.",
|
|
342
|
+
_no_arguments,
|
|
343
|
+
_default_request,
|
|
344
|
+
),
|
|
345
|
+
ActionSpec(
|
|
346
|
+
"network-wait",
|
|
347
|
+
"Wait for a matching network response.",
|
|
348
|
+
"Wait for the first matching completed network record.",
|
|
349
|
+
_add_network_wait_arguments,
|
|
350
|
+
_default_request,
|
|
351
|
+
),
|
|
352
|
+
ActionSpec(
|
|
353
|
+
"network-start",
|
|
354
|
+
"Start network capture.",
|
|
355
|
+
"Start capturing completed network records.",
|
|
356
|
+
_no_arguments,
|
|
357
|
+
_default_request,
|
|
358
|
+
),
|
|
359
|
+
ActionSpec(
|
|
360
|
+
"network",
|
|
361
|
+
"Read network records.",
|
|
362
|
+
"Read captured completed network records.",
|
|
363
|
+
_add_network_arguments,
|
|
364
|
+
_default_request,
|
|
365
|
+
),
|
|
366
|
+
ActionSpec(
|
|
367
|
+
"network-stop",
|
|
368
|
+
"Stop network capture.",
|
|
369
|
+
"Stop capturing completed network records.",
|
|
370
|
+
_no_arguments,
|
|
371
|
+
_default_request,
|
|
372
|
+
),
|
|
373
|
+
ActionSpec(
|
|
374
|
+
"dialog-setup",
|
|
375
|
+
"Configure automatic dialog handling.",
|
|
376
|
+
"Automatically accept or dismiss future dialogs for the active tab.",
|
|
377
|
+
_add_dialog_setup_arguments,
|
|
378
|
+
_default_request,
|
|
379
|
+
),
|
|
380
|
+
ActionSpec(
|
|
381
|
+
"dialog",
|
|
382
|
+
"Configure one-time dialog handling.",
|
|
383
|
+
"Handle the next dialog shown by the active tab.",
|
|
384
|
+
_add_dialog_arguments,
|
|
385
|
+
_default_request,
|
|
386
|
+
),
|
|
387
|
+
ActionSpec(
|
|
388
|
+
"dialog-remove",
|
|
389
|
+
"Remove automatic dialog handling.",
|
|
390
|
+
"Remove the persistent dialog handler for the active tab.",
|
|
391
|
+
_no_arguments,
|
|
392
|
+
_default_request,
|
|
393
|
+
),
|
|
394
|
+
ActionSpec(
|
|
395
|
+
"cookies",
|
|
396
|
+
"List cookies.",
|
|
397
|
+
"List cookies visible to the shared browser context.",
|
|
398
|
+
_add_cookie_filter_arguments,
|
|
399
|
+
_default_request,
|
|
400
|
+
),
|
|
401
|
+
ActionSpec(
|
|
402
|
+
"cookie-set",
|
|
403
|
+
"Set a cookie.",
|
|
404
|
+
"Set a cookie on the shared browser context.",
|
|
405
|
+
_add_cookie_set_arguments,
|
|
406
|
+
_default_request,
|
|
407
|
+
),
|
|
408
|
+
ActionSpec(
|
|
409
|
+
"cookies-clear",
|
|
410
|
+
"Clear cookies.",
|
|
411
|
+
"Clear cookies with optional filters.",
|
|
412
|
+
_add_cookie_filter_arguments,
|
|
413
|
+
_default_request,
|
|
414
|
+
),
|
|
415
|
+
ActionSpec(
|
|
416
|
+
"storage-save",
|
|
417
|
+
"Save storage state.",
|
|
418
|
+
"Save cookies and localStorage to a JSON file.",
|
|
419
|
+
_add_optional_path_arguments,
|
|
420
|
+
_default_request,
|
|
421
|
+
),
|
|
422
|
+
ActionSpec(
|
|
423
|
+
"storage-load",
|
|
424
|
+
"Load storage state.",
|
|
425
|
+
"Restore cookies and localStorage from a JSON file.",
|
|
426
|
+
_add_path_arguments,
|
|
427
|
+
_default_request,
|
|
428
|
+
),
|
|
429
|
+
ActionSpec(
|
|
430
|
+
"verify-text",
|
|
431
|
+
"Verify text is visible.",
|
|
432
|
+
"Verify text is visible on the current page.",
|
|
433
|
+
_add_verify_text_arguments,
|
|
434
|
+
_default_request,
|
|
435
|
+
),
|
|
436
|
+
ActionSpec(
|
|
437
|
+
"verify-visible",
|
|
438
|
+
"Verify role/name is visible.",
|
|
439
|
+
"Verify a role/name locator is visible.",
|
|
440
|
+
_add_verify_visible_arguments,
|
|
441
|
+
_default_request,
|
|
442
|
+
),
|
|
443
|
+
ActionSpec(
|
|
444
|
+
"verify-url",
|
|
445
|
+
"Verify the current URL.",
|
|
446
|
+
"Verify the current URL against an expected value.",
|
|
447
|
+
_add_verify_expected_arguments,
|
|
448
|
+
_rename_expected_request,
|
|
449
|
+
),
|
|
450
|
+
ActionSpec(
|
|
451
|
+
"verify-title",
|
|
452
|
+
"Verify the current title.",
|
|
453
|
+
"Verify the current page title.",
|
|
454
|
+
_add_verify_expected_arguments,
|
|
455
|
+
_rename_expected_request,
|
|
456
|
+
),
|
|
457
|
+
ActionSpec(
|
|
458
|
+
"verify-state",
|
|
459
|
+
"Verify ref state.",
|
|
460
|
+
"Verify state for an element ref.",
|
|
461
|
+
_add_verify_state_arguments,
|
|
462
|
+
_default_request,
|
|
463
|
+
),
|
|
464
|
+
ActionSpec(
|
|
465
|
+
"verify-value",
|
|
466
|
+
"Verify ref value.",
|
|
467
|
+
"Verify input value for an element ref.",
|
|
468
|
+
_add_verify_value_arguments,
|
|
469
|
+
_default_request,
|
|
470
|
+
),
|
|
471
|
+
ActionSpec(
|
|
472
|
+
"trace-start",
|
|
473
|
+
"Start browser tracing.",
|
|
474
|
+
"Start Playwright tracing on the shared browser context.",
|
|
475
|
+
_add_trace_start_arguments,
|
|
476
|
+
_default_request,
|
|
477
|
+
),
|
|
478
|
+
ActionSpec(
|
|
479
|
+
"trace-chunk",
|
|
480
|
+
"Add a trace chunk.",
|
|
481
|
+
"Add a named trace chunk marker to the active trace.",
|
|
482
|
+
_add_trace_chunk_arguments,
|
|
483
|
+
_default_request,
|
|
484
|
+
),
|
|
485
|
+
ActionSpec(
|
|
486
|
+
"trace-stop",
|
|
487
|
+
"Stop browser tracing.",
|
|
488
|
+
"Stop tracing and save a trace archive.",
|
|
489
|
+
_add_optional_path_arguments,
|
|
490
|
+
_default_request,
|
|
491
|
+
),
|
|
492
|
+
ActionSpec(
|
|
493
|
+
"video-start",
|
|
494
|
+
"Start page video capture.",
|
|
495
|
+
"Mark the active tab video capture session as started.",
|
|
496
|
+
_add_video_start_arguments,
|
|
497
|
+
_default_request,
|
|
498
|
+
),
|
|
499
|
+
ActionSpec(
|
|
500
|
+
"video-stop",
|
|
501
|
+
"Stop page video capture.",
|
|
502
|
+
"Stop the active tab video capture session and choose an output path.",
|
|
503
|
+
_add_optional_path_arguments,
|
|
504
|
+
_default_request,
|
|
505
|
+
),
|
|
506
|
+
ActionSpec(
|
|
507
|
+
"resize",
|
|
508
|
+
"Resize the active viewport.",
|
|
509
|
+
"Resize the active tab viewport to WIDTH x HEIGHT.",
|
|
510
|
+
_add_resize_arguments,
|
|
511
|
+
_default_request,
|
|
512
|
+
),
|
|
513
|
+
ActionSpec(
|
|
514
|
+
"stop",
|
|
515
|
+
"Stop the daemon.",
|
|
516
|
+
"Stop the browser daemon and the shared browser instance.",
|
|
517
|
+
_no_arguments,
|
|
518
|
+
_default_request,
|
|
519
|
+
False,
|
|
520
|
+
),
|
|
521
|
+
]
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
def _no_arguments(_parser: ArgumentParser) -> None:
|
|
525
|
+
return
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
def _add_open_arguments(parser: ArgumentParser) -> None:
|
|
529
|
+
parser.add_argument("url", help="Target URL.")
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
def _add_optional_url_arguments(parser: ArgumentParser) -> None:
|
|
533
|
+
parser.add_argument("url", nargs="?", help="Optional target URL.")
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
def _add_search_arguments(parser: ArgumentParser) -> None:
|
|
537
|
+
parser.add_argument("query", help="Search query.")
|
|
538
|
+
parser.add_argument(
|
|
539
|
+
"--engine",
|
|
540
|
+
default="duckduckgo",
|
|
541
|
+
choices=["duckduckgo", "google", "bing"],
|
|
542
|
+
help="Search engine to use.",
|
|
543
|
+
)
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
def _add_snapshot_arguments(parser: ArgumentParser) -> None:
|
|
547
|
+
parser.add_argument(
|
|
548
|
+
"-i",
|
|
549
|
+
"--interactive",
|
|
550
|
+
action="store_true",
|
|
551
|
+
help="Only keep interactive elements in the snapshot.",
|
|
552
|
+
)
|
|
553
|
+
parser.add_argument(
|
|
554
|
+
"-F",
|
|
555
|
+
"--no-full-page",
|
|
556
|
+
action="store_false",
|
|
557
|
+
dest="full_page",
|
|
558
|
+
default=True,
|
|
559
|
+
help="Limit the snapshot to the current viewport.",
|
|
560
|
+
)
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
def _add_page_id_arguments(parser: ArgumentParser) -> None:
|
|
564
|
+
parser.add_argument("page_id", help="Visible page id, for example page_0001.")
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
def _add_optional_page_id_arguments(parser: ArgumentParser) -> None:
|
|
568
|
+
parser.add_argument(
|
|
569
|
+
"page_id", nargs="?", help="Optional page id. Defaults to the current active tab."
|
|
570
|
+
)
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
def _add_ref_arguments(parser: ArgumentParser) -> None:
|
|
574
|
+
parser.add_argument("ref", help="Element ref from the latest snapshot.")
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
def _add_fill_arguments(parser: ArgumentParser) -> None:
|
|
578
|
+
parser.add_argument("ref", help="Element ref from the latest snapshot.")
|
|
579
|
+
parser.add_argument("text", help="Text to fill.")
|
|
580
|
+
parser.add_argument("--submit", action="store_true", help="Press Enter after filling.")
|
|
581
|
+
|
|
582
|
+
|
|
583
|
+
def _add_fill_form_arguments(parser: ArgumentParser) -> None:
|
|
584
|
+
parser.add_argument(
|
|
585
|
+
"--fields",
|
|
586
|
+
required=True,
|
|
587
|
+
help='JSON array like \'[{"ref":"abcd1234","text":"hello"}]\'',
|
|
588
|
+
)
|
|
589
|
+
parser.add_argument(
|
|
590
|
+
"--submit", action="store_true", help="Press Enter after all fields are filled."
|
|
591
|
+
)
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
def _add_select_arguments(parser: ArgumentParser) -> None:
|
|
595
|
+
parser.add_argument("ref", help="Dropdown ref.")
|
|
596
|
+
parser.add_argument("text", help="Option text.")
|
|
597
|
+
|
|
598
|
+
|
|
599
|
+
def _add_drag_arguments(parser: ArgumentParser) -> None:
|
|
600
|
+
parser.add_argument("start_ref", help="Start ref.")
|
|
601
|
+
parser.add_argument("end_ref", help="End ref.")
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
def _add_upload_arguments(parser: ArgumentParser) -> None:
|
|
605
|
+
parser.add_argument("ref", help="File input ref.")
|
|
606
|
+
parser.add_argument("path", help="File path to upload.")
|
|
607
|
+
|
|
608
|
+
|
|
609
|
+
def _add_type_arguments(parser: ArgumentParser) -> None:
|
|
610
|
+
parser.add_argument("text", help="Text to type.")
|
|
611
|
+
parser.add_argument("--submit", action="store_true", help="Press Enter after typing.")
|
|
612
|
+
|
|
613
|
+
|
|
614
|
+
def _add_key_arguments(parser: ArgumentParser) -> None:
|
|
615
|
+
parser.add_argument("key", help='Key or key combination like "Enter" or "Control+A".')
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
def _add_scroll_arguments(parser: ArgumentParser) -> None:
|
|
619
|
+
parser.add_argument("--dx", type=int, default=0, help="Horizontal wheel delta.")
|
|
620
|
+
parser.add_argument("--dy", type=int, default=700, help="Vertical wheel delta.")
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
def _add_mouse_click_arguments(parser: ArgumentParser) -> None:
|
|
624
|
+
parser.add_argument("x", type=int, help="Viewport X coordinate.")
|
|
625
|
+
parser.add_argument("y", type=int, help="Viewport Y coordinate.")
|
|
626
|
+
parser.add_argument(
|
|
627
|
+
"--button", default="left", choices=["left", "right", "middle"], help="Mouse button."
|
|
628
|
+
)
|
|
629
|
+
parser.add_argument("--count", type=int, default=1, help="Number of clicks.")
|
|
630
|
+
|
|
631
|
+
|
|
632
|
+
def _add_mouse_move_arguments(parser: ArgumentParser) -> None:
|
|
633
|
+
parser.add_argument("x", type=int, help="Viewport X coordinate.")
|
|
634
|
+
parser.add_argument("y", type=int, help="Viewport Y coordinate.")
|
|
635
|
+
|
|
636
|
+
|
|
637
|
+
def _add_mouse_drag_arguments(parser: ArgumentParser) -> None:
|
|
638
|
+
parser.add_argument("x1", type=int, help="Start X coordinate.")
|
|
639
|
+
parser.add_argument("y1", type=int, help="Start Y coordinate.")
|
|
640
|
+
parser.add_argument("x2", type=int, help="End X coordinate.")
|
|
641
|
+
parser.add_argument("y2", type=int, help="End Y coordinate.")
|
|
642
|
+
|
|
643
|
+
|
|
644
|
+
def _add_mouse_button_arguments(parser: ArgumentParser) -> None:
|
|
645
|
+
parser.add_argument(
|
|
646
|
+
"--button", default="left", choices=["left", "right", "middle"], help="Mouse button."
|
|
647
|
+
)
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
def _add_eval_arguments(parser: ArgumentParser) -> None:
|
|
651
|
+
parser.add_argument("code", help='Arrow function JavaScript like "() => document.title".')
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
def _add_eval_on_arguments(parser: ArgumentParser) -> None:
|
|
655
|
+
parser.add_argument("ref", help="Element ref from the latest snapshot.")
|
|
656
|
+
parser.add_argument("code", help='Arrow function JavaScript like "(el) => el.textContent".')
|
|
657
|
+
|
|
658
|
+
|
|
659
|
+
def _add_wait_arguments(parser: ArgumentParser) -> None:
|
|
660
|
+
parser.add_argument(
|
|
661
|
+
"seconds", nargs="?", type=float, help="Seconds to wait when not waiting for text."
|
|
662
|
+
)
|
|
663
|
+
parser.add_argument("--text", help="Visible text to wait for.")
|
|
664
|
+
parser.add_argument(
|
|
665
|
+
"--gone", action="store_true", help="Wait for the text to disappear instead of appear."
|
|
666
|
+
)
|
|
667
|
+
parser.add_argument("--exact", action="store_true", help="Use exact text matching.")
|
|
668
|
+
|
|
669
|
+
|
|
670
|
+
def _add_wait_network_arguments(parser: ArgumentParser) -> None:
|
|
671
|
+
parser.add_argument("--timeout", type=float, default=30.0, help="Maximum wait time in seconds.")
|
|
672
|
+
|
|
673
|
+
|
|
674
|
+
def _add_screenshot_arguments(parser: ArgumentParser) -> None:
|
|
675
|
+
parser.add_argument("path", help="Output path.")
|
|
676
|
+
parser.add_argument("--full-page", action="store_true", help="Capture the full page.")
|
|
677
|
+
|
|
678
|
+
|
|
679
|
+
def _add_path_arguments(parser: ArgumentParser) -> None:
|
|
680
|
+
parser.add_argument("path", help="Path.")
|
|
681
|
+
|
|
682
|
+
|
|
683
|
+
def _add_optional_path_arguments(parser: ArgumentParser) -> None:
|
|
684
|
+
parser.add_argument("path", nargs="?", help="Optional path.")
|
|
685
|
+
|
|
686
|
+
|
|
687
|
+
def _add_dialog_setup_arguments(parser: ArgumentParser) -> None:
|
|
688
|
+
parser.add_argument(
|
|
689
|
+
"--action",
|
|
690
|
+
choices=["accept", "dismiss"],
|
|
691
|
+
default="accept",
|
|
692
|
+
help="Default action to take on future dialogs.",
|
|
693
|
+
)
|
|
694
|
+
parser.add_argument(
|
|
695
|
+
"--text",
|
|
696
|
+
help="Optional prompt text used when automatically accepting prompt dialogs.",
|
|
697
|
+
)
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
def _add_dialog_arguments(parser: ArgumentParser) -> None:
|
|
701
|
+
parser.add_argument(
|
|
702
|
+
"--dismiss",
|
|
703
|
+
action="store_true",
|
|
704
|
+
help="Dismiss the next dialog instead of accepting it.",
|
|
705
|
+
)
|
|
706
|
+
parser.add_argument(
|
|
707
|
+
"--text",
|
|
708
|
+
help="Optional prompt text used when accepting the next prompt dialog.",
|
|
709
|
+
)
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
def _add_console_arguments(parser: ArgumentParser) -> None:
|
|
713
|
+
parser.add_argument(
|
|
714
|
+
"--type",
|
|
715
|
+
dest="message_type",
|
|
716
|
+
choices=["log", "debug", "info", "error", "warning", "dir", "trace"],
|
|
717
|
+
help="Optional message type filter.",
|
|
718
|
+
)
|
|
719
|
+
parser.add_argument(
|
|
720
|
+
"--no-clear", action="store_true", help="Keep buffered messages after reading."
|
|
721
|
+
)
|
|
722
|
+
|
|
723
|
+
|
|
724
|
+
def _add_network_filter_arguments(parser: ArgumentParser) -> None:
|
|
725
|
+
parser.add_argument(
|
|
726
|
+
"--url-contains", help="Only match records whose URL contains this substring."
|
|
727
|
+
)
|
|
728
|
+
parser.add_argument("--url-regex", help="Only match records whose URL matches this regex.")
|
|
729
|
+
parser.add_argument("--method", help="Only match a specific HTTP method like GET or POST.")
|
|
730
|
+
parser.add_argument("--status", type=int, help="Only match a specific response status code.")
|
|
731
|
+
parser.add_argument("--resource-type", help="Only match a specific browser resource type.")
|
|
732
|
+
parser.add_argument(
|
|
733
|
+
"--mime-contains", help="Only match records whose MIME type contains this substring."
|
|
734
|
+
)
|
|
735
|
+
parser.add_argument(
|
|
736
|
+
"--include-static", action="store_true", help="Include images, scripts, and stylesheets."
|
|
737
|
+
)
|
|
738
|
+
|
|
739
|
+
|
|
740
|
+
def _add_network_wait_arguments(parser: ArgumentParser) -> None:
|
|
741
|
+
_add_network_filter_arguments(parser)
|
|
742
|
+
parser.add_argument(
|
|
743
|
+
"--timeout",
|
|
744
|
+
dest="timeout_seconds",
|
|
745
|
+
type=float,
|
|
746
|
+
default=30.0,
|
|
747
|
+
help="Maximum wait time in seconds.",
|
|
748
|
+
)
|
|
749
|
+
|
|
750
|
+
|
|
751
|
+
def _add_network_arguments(parser: ArgumentParser) -> None:
|
|
752
|
+
_add_network_filter_arguments(parser)
|
|
753
|
+
parser.add_argument(
|
|
754
|
+
"--no-clear", action="store_true", help="Keep buffered records after reading."
|
|
755
|
+
)
|
|
756
|
+
|
|
757
|
+
|
|
758
|
+
def _add_cookie_filter_arguments(parser: ArgumentParser) -> None:
|
|
759
|
+
parser.add_argument("--name", help="Cookie name filter.")
|
|
760
|
+
parser.add_argument("--domain", help="Cookie domain filter.")
|
|
761
|
+
parser.add_argument("--path", help="Cookie path filter.")
|
|
762
|
+
|
|
763
|
+
|
|
764
|
+
def _add_cookie_set_arguments(parser: ArgumentParser) -> None:
|
|
765
|
+
parser.add_argument("name", help="Cookie name.")
|
|
766
|
+
parser.add_argument("value", help="Cookie value.")
|
|
767
|
+
parser.add_argument("--domain", help="Cookie domain. Defaults to the current page host.")
|
|
768
|
+
parser.add_argument("--path", default="/", help="Cookie path.")
|
|
769
|
+
parser.add_argument("--expires", type=float, help="Cookie expiry timestamp.")
|
|
770
|
+
parser.add_argument("--http-only", action="store_true", help="Mark the cookie httpOnly.")
|
|
771
|
+
parser.add_argument("--secure", action="store_true", help="Mark the cookie secure.")
|
|
772
|
+
parser.add_argument("--same-site", choices=["Lax", "Strict", "None"], help="SameSite value.")
|
|
773
|
+
|
|
774
|
+
|
|
775
|
+
def _add_verify_text_arguments(parser: ArgumentParser) -> None:
|
|
776
|
+
parser.add_argument("text", help="Text to verify.")
|
|
777
|
+
parser.add_argument("--exact", action="store_true", help="Use exact text matching.")
|
|
778
|
+
parser.add_argument("--timeout", type=float, default=5.0, help="Timeout in seconds.")
|
|
779
|
+
|
|
780
|
+
|
|
781
|
+
def _add_verify_visible_arguments(parser: ArgumentParser) -> None:
|
|
782
|
+
parser.add_argument("role", help="ARIA role.")
|
|
783
|
+
parser.add_argument("name", help="Accessible name.")
|
|
784
|
+
parser.add_argument("--timeout", type=float, default=5.0, help="Timeout in seconds.")
|
|
785
|
+
|
|
786
|
+
|
|
787
|
+
def _add_verify_expected_arguments(parser: ArgumentParser) -> None:
|
|
788
|
+
parser.add_argument("expected", help="Expected substring or exact value.")
|
|
789
|
+
parser.add_argument("--exact", action="store_true", help="Require exact equality.")
|
|
790
|
+
|
|
791
|
+
|
|
792
|
+
def _add_verify_state_arguments(parser: ArgumentParser) -> None:
|
|
793
|
+
parser.add_argument("ref", help="Element ref.")
|
|
794
|
+
parser.add_argument(
|
|
795
|
+
"state",
|
|
796
|
+
choices=["visible", "hidden", "enabled", "disabled", "checked", "unchecked", "editable"],
|
|
797
|
+
help="State to verify.",
|
|
798
|
+
)
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
def _add_verify_value_arguments(parser: ArgumentParser) -> None:
|
|
802
|
+
parser.add_argument("ref", help="Element ref.")
|
|
803
|
+
parser.add_argument("expected", help="Expected input value.")
|
|
804
|
+
|
|
805
|
+
|
|
806
|
+
def _add_trace_start_arguments(parser: ArgumentParser) -> None:
|
|
807
|
+
parser.add_argument(
|
|
808
|
+
"--no-screenshots",
|
|
809
|
+
action="store_true",
|
|
810
|
+
help="Do not capture screenshots while tracing.",
|
|
811
|
+
)
|
|
812
|
+
parser.add_argument(
|
|
813
|
+
"--no-snapshots",
|
|
814
|
+
action="store_true",
|
|
815
|
+
help="Do not capture DOM snapshots while tracing.",
|
|
816
|
+
)
|
|
817
|
+
parser.add_argument(
|
|
818
|
+
"--sources",
|
|
819
|
+
action="store_true",
|
|
820
|
+
help="Include source files in the trace archive.",
|
|
821
|
+
)
|
|
822
|
+
|
|
823
|
+
|
|
824
|
+
def _add_trace_chunk_arguments(parser: ArgumentParser) -> None:
|
|
825
|
+
parser.add_argument("title", nargs="?", help="Optional chunk title.")
|
|
826
|
+
|
|
827
|
+
|
|
828
|
+
def _add_video_start_arguments(parser: ArgumentParser) -> None:
|
|
829
|
+
parser.add_argument("--width", type=int, help="Requested video width.")
|
|
830
|
+
parser.add_argument("--height", type=int, help="Requested video height.")
|
|
831
|
+
|
|
832
|
+
|
|
833
|
+
def _add_resize_arguments(parser: ArgumentParser) -> None:
|
|
834
|
+
parser.add_argument("width", type=int, help="Viewport width in pixels.")
|
|
835
|
+
parser.add_argument("height", type=int, help="Viewport height in pixels.")
|
|
836
|
+
|
|
837
|
+
|
|
838
|
+
def _default_request(args: Namespace) -> dict[str, Any]:
|
|
839
|
+
ignore = {
|
|
840
|
+
"command",
|
|
841
|
+
"handler",
|
|
842
|
+
"action_name",
|
|
843
|
+
"action_start_if_needed",
|
|
844
|
+
"action_request_builder",
|
|
845
|
+
}
|
|
846
|
+
payload: dict[str, Any] = {}
|
|
847
|
+
for key, value in vars(args).items():
|
|
848
|
+
if key in ignore:
|
|
849
|
+
continue
|
|
850
|
+
if value is None:
|
|
851
|
+
continue
|
|
852
|
+
payload[key] = value
|
|
853
|
+
return payload
|
|
854
|
+
|
|
855
|
+
|
|
856
|
+
def _fill_form_request(args: Namespace) -> dict[str, Any]:
|
|
857
|
+
payload = _default_request(args)
|
|
858
|
+
try:
|
|
859
|
+
payload["fields"] = json.loads(str(args.fields))
|
|
860
|
+
except json.JSONDecodeError as exc:
|
|
861
|
+
raise ValueError(f"Invalid JSON for --fields: {exc}") from exc
|
|
862
|
+
return payload
|
|
863
|
+
|
|
864
|
+
|
|
865
|
+
def _rename_expected_request(args: Namespace) -> dict[str, Any]:
|
|
866
|
+
payload = _default_request(args)
|
|
867
|
+
payload["expected"] = payload.pop("expected")
|
|
868
|
+
return payload
|