@protolabsai/proto 0.23.0 → 0.24.0
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.
- package/README.md +88 -1
- package/bundled/browser-automation/SKILL.md +358 -0
- package/cli.js +6036 -4676
- package/package.json +2 -2
- package/bundled/qc-helper/docs/_meta.ts +0 -30
- package/bundled/qc-helper/docs/common-workflow.md +0 -571
- package/bundled/qc-helper/docs/configuration/_meta.ts +0 -10
- package/bundled/qc-helper/docs/configuration/auth.md +0 -366
- package/bundled/qc-helper/docs/configuration/memory.md +0 -0
- package/bundled/qc-helper/docs/configuration/model-providers.md +0 -542
- package/bundled/qc-helper/docs/configuration/qwen-ignore.md +0 -55
- package/bundled/qc-helper/docs/configuration/settings.md +0 -661
- package/bundled/qc-helper/docs/configuration/themes.md +0 -160
- package/bundled/qc-helper/docs/configuration/trusted-folders.md +0 -61
- package/bundled/qc-helper/docs/extension/_meta.ts +0 -9
- package/bundled/qc-helper/docs/extension/extension-releasing.md +0 -204
- package/bundled/qc-helper/docs/extension/getting-started-extensions.md +0 -299
- package/bundled/qc-helper/docs/extension/introduction.md +0 -331
- package/bundled/qc-helper/docs/features/_meta.ts +0 -20
- package/bundled/qc-helper/docs/features/approval-mode.md +0 -263
- package/bundled/qc-helper/docs/features/arena.md +0 -218
- package/bundled/qc-helper/docs/features/checkpointing.md +0 -77
- package/bundled/qc-helper/docs/features/commands.md +0 -314
- package/bundled/qc-helper/docs/features/export.md +0 -51
- package/bundled/qc-helper/docs/features/followup-suggestions.md +0 -109
- package/bundled/qc-helper/docs/features/headless.md +0 -318
- package/bundled/qc-helper/docs/features/hooks.md +0 -356
- package/bundled/qc-helper/docs/features/language.md +0 -139
- package/bundled/qc-helper/docs/features/lsp.md +0 -453
- package/bundled/qc-helper/docs/features/mcp.md +0 -299
- package/bundled/qc-helper/docs/features/sandbox.md +0 -241
- package/bundled/qc-helper/docs/features/scheduled-tasks.md +0 -139
- package/bundled/qc-helper/docs/features/skills.md +0 -289
- package/bundled/qc-helper/docs/features/sub-agents.md +0 -353
- package/bundled/qc-helper/docs/features/token-caching.md +0 -29
- package/bundled/qc-helper/docs/ide-integration/_meta.ts +0 -4
- package/bundled/qc-helper/docs/ide-integration/ide-companion-spec.md +0 -182
- package/bundled/qc-helper/docs/ide-integration/ide-integration.md +0 -144
- package/bundled/qc-helper/docs/integration-github-action.md +0 -241
- package/bundled/qc-helper/docs/integration-jetbrains.md +0 -81
- package/bundled/qc-helper/docs/integration-vscode.md +0 -39
- package/bundled/qc-helper/docs/integration-zed.md +0 -72
- package/bundled/qc-helper/docs/overview.md +0 -65
- package/bundled/qc-helper/docs/quickstart.md +0 -273
- package/bundled/qc-helper/docs/reference/_meta.ts +0 -4
- package/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +0 -72
- package/bundled/qc-helper/docs/reference/sdk-api.md +0 -524
- package/bundled/qc-helper/docs/support/Uninstall.md +0 -42
- package/bundled/qc-helper/docs/support/_meta.ts +0 -6
- package/bundled/qc-helper/docs/support/tos-privacy.md +0 -112
- package/bundled/qc-helper/docs/support/troubleshooting.md +0 -123
package/README.md
CHANGED
|
@@ -329,8 +329,9 @@ Results are cached at `.proto/repo-map-cache.json` and auto-invalidate on file c
|
|
|
329
329
|
|
|
330
330
|
## Skills
|
|
331
331
|
|
|
332
|
-
proto ships with
|
|
332
|
+
proto ships with 22 bundled skills for agentic workflows:
|
|
333
333
|
|
|
334
|
+
- **browser-automation** — Web browser automation
|
|
334
335
|
- **brainstorming** — Structured ideation
|
|
335
336
|
- **dispatching-parallel-agents** — Fan-out/fan-in subagent patterns
|
|
336
337
|
- **executing-plans** — Step-by-step plan execution
|
|
@@ -350,6 +351,92 @@ proto ships with 21 bundled skills for agentic workflows:
|
|
|
350
351
|
|
|
351
352
|
Use `/skills` to list available skills in a session.
|
|
352
353
|
|
|
354
|
+
### Browser Automation
|
|
355
|
+
|
|
356
|
+
proto includes a native browser automation tool powered by [agent-browser](https://github.com/nickinack/agent-browser). This enables AI agents to interact with websites — navigate, click, fill forms, take screenshots, and extract content.
|
|
357
|
+
|
|
358
|
+
#### Installation
|
|
359
|
+
|
|
360
|
+
```bash
|
|
361
|
+
npm install -g agent-browser
|
|
362
|
+
agent-browser install # Downloads Chrome
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
#### Usage
|
|
366
|
+
|
|
367
|
+
```javascript
|
|
368
|
+
// Open a website
|
|
369
|
+
browser({ action: 'open', url: 'https://example.com' });
|
|
370
|
+
|
|
371
|
+
// Get interactive elements
|
|
372
|
+
browser({ action: 'snapshot', flags: JSON.stringify({ interactive: true }) });
|
|
373
|
+
|
|
374
|
+
// Click an element
|
|
375
|
+
browser({ action: 'click', selector: '@e2' });
|
|
376
|
+
|
|
377
|
+
// Fill a form
|
|
378
|
+
browser({ action: 'fill', selector: '@e1', text: 'user@example.com' });
|
|
379
|
+
|
|
380
|
+
// Take screenshot
|
|
381
|
+
browser({ action: 'screenshot', outputPath: '/path/to/screenshot.png' });
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
#### Key Actions
|
|
385
|
+
|
|
386
|
+
| Action | Description |
|
|
387
|
+
| ------------------------------ | ------------------------------------------ |
|
|
388
|
+
| `open` / `close` | Navigate to URL or close browser |
|
|
389
|
+
| `click` / `dblclick` / `hover` | Element interaction |
|
|
390
|
+
| `fill` / `type` | Form input |
|
|
391
|
+
| `snapshot` | Get accessibility tree with element refs |
|
|
392
|
+
| `screenshot` | Capture page screenshot |
|
|
393
|
+
| `get` / `is` / `find` | Query element properties |
|
|
394
|
+
| `wait` | Wait for elements, network, or URL changes |
|
|
395
|
+
| `batch` | Execute multiple commands in sequence |
|
|
396
|
+
|
|
397
|
+
The browser skill (`/skills` → browser-automation) provides comprehensive documentation for all 38 available actions.
|
|
398
|
+
|
|
399
|
+
## Agent Teams
|
|
400
|
+
|
|
401
|
+
Run multiple coordinated agents that share tasks and communicate directly with each other.
|
|
402
|
+
|
|
403
|
+
```
|
|
404
|
+
/team start my-team lead:coordinator scout:Explore coder:general-purpose
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
This spawns three live agents immediately. Each member runs as an in-process agent and gets two extra tools injected automatically:
|
|
408
|
+
|
|
409
|
+
- **`mailbox_send`** — send a message to a teammate by their agentId
|
|
410
|
+
- **`mailbox_receive`** — drain all unread messages from your inbox
|
|
411
|
+
|
|
412
|
+
Members share the same task list (`task_create`, `task_list`, `task_update`) so any agent can create tasks and others can claim them.
|
|
413
|
+
|
|
414
|
+
### Team commands
|
|
415
|
+
|
|
416
|
+
| Command | Description |
|
|
417
|
+
| -------------------------------------- | ------------------------------------- |
|
|
418
|
+
| `/team start <name> [member:type ...]` | Spawn live agents and start the team |
|
|
419
|
+
| `/team status <name>` | Show live member status |
|
|
420
|
+
| `/team stop <name>` | Kill all agents and release resources |
|
|
421
|
+
| `/team list` | List all teams in the project |
|
|
422
|
+
| `/team delete <name>` | Delete a team config |
|
|
423
|
+
|
|
424
|
+
**Default team** (no members specified): `lead` (coordinator) + `scout` (Explore).
|
|
425
|
+
|
|
426
|
+
Agent IDs follow the pattern `<name>-<index>` (e.g. `lead-0`, `scout-1`). Use these when sending mailbox messages between agents.
|
|
427
|
+
|
|
428
|
+
### Member types
|
|
429
|
+
|
|
430
|
+
| Type | Purpose |
|
|
431
|
+
| ----------------- | ----------------------------------------- |
|
|
432
|
+
| `coordinator` | Orchestrate subtasks across other members |
|
|
433
|
+
| `Explore` | Fast codebase search and analysis |
|
|
434
|
+
| `general-purpose` | Multi-step implementation tasks |
|
|
435
|
+
| `verify` | Review and correctness checking |
|
|
436
|
+
| `plan` | Design plans before implementation |
|
|
437
|
+
|
|
438
|
+
Any user-defined sub-agent from `.proto/agents/` can also be used as a member type.
|
|
439
|
+
|
|
353
440
|
## Commands
|
|
354
441
|
|
|
355
442
|
| Command | Description |
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: browser-automation
|
|
3
|
+
description: Use browser automation to interact with web pages - navigate, click, fill forms, take screenshots, and extract content from websites. Perfect for testing, data collection, and web interactions.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Browser Automation
|
|
7
|
+
|
|
8
|
+
Use the native `browser` tool to automate web browser interactions. This skill enables AI agents to navigate websites, interact with elements, fill forms, and extract information.
|
|
9
|
+
|
|
10
|
+
## Prerequisites
|
|
11
|
+
|
|
12
|
+
**Before using this skill, verify:**
|
|
13
|
+
|
|
14
|
+
1. **agent-browser is installed:**
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
agent-browser --version
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
If not installed:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install -g agent-browser
|
|
24
|
+
agent-browser install # Downloads Chrome
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
2. **Chrome is installed:**
|
|
28
|
+
The browser tool will auto-download Chrome if needed via `agent-browser install`.
|
|
29
|
+
|
|
30
|
+
## Core Workflow
|
|
31
|
+
|
|
32
|
+
### Step 1: Open a Website
|
|
33
|
+
|
|
34
|
+
```javascript
|
|
35
|
+
browser({
|
|
36
|
+
action: 'open',
|
|
37
|
+
url: 'https://example.com',
|
|
38
|
+
headed: false, // true to see browser window
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Step 2: Get Interactive Elements
|
|
43
|
+
|
|
44
|
+
Use `snapshot` to get an accessibility tree with numbered element references:
|
|
45
|
+
|
|
46
|
+
```javascript
|
|
47
|
+
browser({
|
|
48
|
+
action: 'snapshot',
|
|
49
|
+
flags: JSON.stringify({ interactive: true }),
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Output shows elements with refs like:**
|
|
54
|
+
|
|
55
|
+
```text
|
|
56
|
+
[e1] Button: "Submit"
|
|
57
|
+
[e2] Textbox: "Email"
|
|
58
|
+
[e3] Textbox: "Password"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Step 3: Interact with Elements
|
|
62
|
+
|
|
63
|
+
**Click an element:**
|
|
64
|
+
|
|
65
|
+
```javascript
|
|
66
|
+
browser({
|
|
67
|
+
action: 'click',
|
|
68
|
+
selector: '@e2', // or CSS selector like "#submit-btn"
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Fill a form field:**
|
|
73
|
+
|
|
74
|
+
```javascript
|
|
75
|
+
browser({
|
|
76
|
+
action: 'fill',
|
|
77
|
+
selector: '@e2',
|
|
78
|
+
text: 'user@example.com',
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Type with keystroke simulation:**
|
|
83
|
+
|
|
84
|
+
```javascript
|
|
85
|
+
browser({
|
|
86
|
+
action: 'type',
|
|
87
|
+
selector: '@e3',
|
|
88
|
+
text: 'password123',
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Step 4: Take Screenshots
|
|
93
|
+
|
|
94
|
+
**Page screenshot:**
|
|
95
|
+
|
|
96
|
+
```javascript
|
|
97
|
+
browser({
|
|
98
|
+
action: 'screenshot',
|
|
99
|
+
outputPath: '/path/to/screenshot.png',
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Full-page screenshot:**
|
|
104
|
+
|
|
105
|
+
```javascript
|
|
106
|
+
browser({
|
|
107
|
+
action: 'screenshot',
|
|
108
|
+
outputPath: '/path/to/full.png',
|
|
109
|
+
flags: JSON.stringify({ full: true }),
|
|
110
|
+
});
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Selector Types
|
|
114
|
+
|
|
115
|
+
| Type | Example | Use Case |
|
|
116
|
+
| ------------ | ------------------------------- | -------------------- |
|
|
117
|
+
| Element ref | `@e1`, `@e2` | From snapshot output |
|
|
118
|
+
| CSS selector | `#id`, `.class`, `div > button` | Standard web dev |
|
|
119
|
+
| Semantic | `role:button`, `text:"Sign In"` | AI-friendly |
|
|
120
|
+
|
|
121
|
+
## Common Actions Reference
|
|
122
|
+
|
|
123
|
+
### Navigation
|
|
124
|
+
|
|
125
|
+
```javascript
|
|
126
|
+
// Open URL
|
|
127
|
+
browser({ action: 'open', url: 'https://example.com' });
|
|
128
|
+
|
|
129
|
+
// Close browser
|
|
130
|
+
browser({ action: 'close' });
|
|
131
|
+
|
|
132
|
+
// New tab
|
|
133
|
+
browser({ action: 'tab', text: 'new', url: 'https://example.com' });
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Element Interaction
|
|
137
|
+
|
|
138
|
+
```javascript
|
|
139
|
+
// Click
|
|
140
|
+
browser({ action: 'click', selector: '@e1' });
|
|
141
|
+
|
|
142
|
+
// Double-click
|
|
143
|
+
browser({ action: 'dblclick', selector: '@e1' });
|
|
144
|
+
|
|
145
|
+
// Hover
|
|
146
|
+
browser({ action: 'hover', selector: '@e1' });
|
|
147
|
+
|
|
148
|
+
// Fill (clears and types)
|
|
149
|
+
browser({ action: 'fill', selector: '@e2', text: 'value' });
|
|
150
|
+
|
|
151
|
+
// Type (appends)
|
|
152
|
+
browser({ action: 'type', selector: '@e2', text: 'value' });
|
|
153
|
+
|
|
154
|
+
// Press key
|
|
155
|
+
browser({ action: 'press', key: 'Enter' });
|
|
156
|
+
browser({ action: 'press', key: 'Tab' });
|
|
157
|
+
browser({ action: 'press', key: 'Escape' });
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Page Information
|
|
161
|
+
|
|
162
|
+
```javascript
|
|
163
|
+
// Get page title
|
|
164
|
+
browser({ action: 'get', text: 'title' });
|
|
165
|
+
|
|
166
|
+
// Get current URL
|
|
167
|
+
browser({ action: 'get', text: 'url' });
|
|
168
|
+
|
|
169
|
+
// Get element text
|
|
170
|
+
browser({ action: 'get', selector: '@e1', text: 'text' });
|
|
171
|
+
|
|
172
|
+
// Get element attribute
|
|
173
|
+
browser({ action: 'get', selector: '@e1', text: 'attr', attribute: 'href' });
|
|
174
|
+
|
|
175
|
+
// Check if visible
|
|
176
|
+
browser({ action: 'is', text: 'visible', selector: '@e1' });
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Find Elements
|
|
180
|
+
|
|
181
|
+
```javascript
|
|
182
|
+
// Find by role and click
|
|
183
|
+
browser({ action: 'find', selector: 'role button', text: 'click' });
|
|
184
|
+
|
|
185
|
+
// Find by text
|
|
186
|
+
browser({ action: 'find', selector: 'text "Sign In"', text: 'click' });
|
|
187
|
+
|
|
188
|
+
// Find by label
|
|
189
|
+
browser({ action: 'find', selector: 'label "Email"', text: 'fill' });
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Waiting
|
|
193
|
+
|
|
194
|
+
```javascript
|
|
195
|
+
// Wait for URL pattern
|
|
196
|
+
browser({ action: 'wait', text: '**/dashboard' });
|
|
197
|
+
|
|
198
|
+
// Wait for text
|
|
199
|
+
browser({ action: 'wait', text: 'Welcome' });
|
|
200
|
+
|
|
201
|
+
// Wait for network idle
|
|
202
|
+
browser({ action: 'wait', text: 'networkidle' });
|
|
203
|
+
|
|
204
|
+
// Wait for selector
|
|
205
|
+
browser({ action: 'wait', selector: '@e1' });
|
|
206
|
+
|
|
207
|
+
// Wait with timeout (default 25s)
|
|
208
|
+
browser({ action: 'wait', selector: '@e1' });
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Batch Operations
|
|
212
|
+
|
|
213
|
+
Execute multiple commands in sequence:
|
|
214
|
+
|
|
215
|
+
```javascript
|
|
216
|
+
browser({
|
|
217
|
+
action: 'batch',
|
|
218
|
+
commands: [
|
|
219
|
+
'open https://example.com',
|
|
220
|
+
'wait --load networkidle',
|
|
221
|
+
'fill @e1 user@example.com',
|
|
222
|
+
'fill @e2 password',
|
|
223
|
+
'click @e3',
|
|
224
|
+
'wait --url **/dashboard',
|
|
225
|
+
],
|
|
226
|
+
});
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Sessions
|
|
230
|
+
|
|
231
|
+
Sessions persist authentication and state between commands:
|
|
232
|
+
|
|
233
|
+
```javascript
|
|
234
|
+
// Create named session
|
|
235
|
+
browser({
|
|
236
|
+
action: 'open',
|
|
237
|
+
url: 'https://app.example.com',
|
|
238
|
+
session: 'myapp-auth',
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
// Continue in same session
|
|
242
|
+
browser({
|
|
243
|
+
action: 'click',
|
|
244
|
+
selector: '@e1',
|
|
245
|
+
session: 'myapp-auth',
|
|
246
|
+
});
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Advanced Features
|
|
250
|
+
|
|
251
|
+
### Headed Mode (see browser window)
|
|
252
|
+
|
|
253
|
+
```javascript
|
|
254
|
+
browser({
|
|
255
|
+
action: 'open',
|
|
256
|
+
url: 'https://example.com',
|
|
257
|
+
headed: true,
|
|
258
|
+
});
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Network Interception
|
|
262
|
+
|
|
263
|
+
```javascript
|
|
264
|
+
// Block a URL
|
|
265
|
+
browser({
|
|
266
|
+
action: 'network',
|
|
267
|
+
text: 'route',
|
|
268
|
+
selector: 'https://ads.example.com',
|
|
269
|
+
attribute: 'abort', // or mock response
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
// View requests
|
|
273
|
+
browser({ action: 'network', text: 'requests' });
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Cookies & Storage
|
|
277
|
+
|
|
278
|
+
```javascript
|
|
279
|
+
// Get cookies
|
|
280
|
+
browser({ action: 'cookies' });
|
|
281
|
+
|
|
282
|
+
// Get localStorage
|
|
283
|
+
browser({ action: 'storage', text: 'local' });
|
|
284
|
+
|
|
285
|
+
// Set localStorage
|
|
286
|
+
browser({
|
|
287
|
+
action: 'storage',
|
|
288
|
+
text: 'local',
|
|
289
|
+
selector: 'set myKey myValue',
|
|
290
|
+
});
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Clipboard
|
|
294
|
+
|
|
295
|
+
```javascript
|
|
296
|
+
// Read clipboard
|
|
297
|
+
browser({ action: 'clipboard' });
|
|
298
|
+
|
|
299
|
+
// Write to clipboard
|
|
300
|
+
browser({ action: 'clipboard', text: 'write Hello World' });
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
## Best Practices
|
|
304
|
+
|
|
305
|
+
1. **Always start with `snapshot`**: Get the accessibility tree to understand page structure
|
|
306
|
+
|
|
307
|
+
2. **Use element refs from snapshot**: They're more reliable than CSS selectors for AI automation
|
|
308
|
+
|
|
309
|
+
3. **Wait for network idle**: After form submissions or page loads:
|
|
310
|
+
|
|
311
|
+
```javascript
|
|
312
|
+
browser({ action: 'wait', text: 'networkidle' });
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
4. **Use sessions for multi-step flows**: Maintains login state and cookies:
|
|
316
|
+
|
|
317
|
+
```javascript
|
|
318
|
+
browser({ action: 'open', url: 'https://app.com', session: 'app' });
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
5. **Take screenshots for debugging**: When automation fails, screenshot helps debug:
|
|
322
|
+
|
|
323
|
+
```javascript
|
|
324
|
+
browser({ action: 'screenshot', outputPath: '/tmp/debug.png' });
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
6. **Close browser when done**: Free resources:
|
|
328
|
+
```javascript
|
|
329
|
+
browser({ action: 'close' });
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
## Error Handling
|
|
333
|
+
|
|
334
|
+
If agent-browser is not installed, you'll get:
|
|
335
|
+
|
|
336
|
+
```text
|
|
337
|
+
agent-browser is not installed. Please install it with: npm install -g agent-browser
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
**Installation troubleshooting:**
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
# Install Chrome dependency
|
|
344
|
+
agent-browser install --with-deps
|
|
345
|
+
|
|
346
|
+
# Check installation
|
|
347
|
+
which agent-browser
|
|
348
|
+
agent-browser --version
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
## Use Cases
|
|
352
|
+
|
|
353
|
+
- **Web testing**: Automate UI testing workflows
|
|
354
|
+
- **Form filling**: Submit forms programmatically
|
|
355
|
+
- **Data extraction**: Scrape content from websites
|
|
356
|
+
- **Login flows**: Handle authentication
|
|
357
|
+
- **Screenshot capture**: Document web pages
|
|
358
|
+
- **Accessibility testing**: Verify page structure
|