code-puppy 0.0.177__py3-none-any.whl → 0.0.179__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.
- code_puppy/agents/agent_golang_reviewer.py +61 -0
- code_puppy/agents/base_agent.py +8 -11
- code_puppy/main.py +2 -0
- code_puppy/tui/app.py +2 -0
- {code_puppy-0.0.177.dist-info → code_puppy-0.0.179.dist-info}/METADATA +1 -1
- {code_puppy-0.0.177.dist-info → code_puppy-0.0.179.dist-info}/RECORD +10 -16
- code_puppy/tools/browser_control.py +0 -293
- code_puppy/tools/browser_interactions.py +0 -552
- code_puppy/tools/browser_locators.py +0 -642
- code_puppy/tools/browser_navigation.py +0 -251
- code_puppy/tools/browser_screenshot.py +0 -278
- code_puppy/tools/browser_scripts.py +0 -472
- code_puppy/tools/browser_workflows.py +0 -223
- {code_puppy-0.0.177.data → code_puppy-0.0.179.data}/data/code_puppy/models.json +0 -0
- {code_puppy-0.0.177.dist-info → code_puppy-0.0.179.dist-info}/WHEEL +0 -0
- {code_puppy-0.0.177.dist-info → code_puppy-0.0.179.dist-info}/entry_points.txt +0 -0
- {code_puppy-0.0.177.dist-info → code_puppy-0.0.179.dist-info}/licenses/LICENSE +0 -0
@@ -1,552 +0,0 @@
|
|
1
|
-
"""Browser element interaction tools for clicking, typing, and form manipulation."""
|
2
|
-
|
3
|
-
from typing import Any, Dict, List, Optional
|
4
|
-
|
5
|
-
from pydantic_ai import RunContext
|
6
|
-
|
7
|
-
from code_puppy.messaging import emit_info
|
8
|
-
from code_puppy.tools.common import generate_group_id
|
9
|
-
|
10
|
-
from .camoufox_manager import get_camoufox_manager
|
11
|
-
|
12
|
-
|
13
|
-
async def click_element(
|
14
|
-
selector: str,
|
15
|
-
timeout: int = 10000,
|
16
|
-
force: bool = False,
|
17
|
-
button: str = "left",
|
18
|
-
modifiers: Optional[List[str]] = None,
|
19
|
-
) -> Dict[str, Any]:
|
20
|
-
"""Click on an element."""
|
21
|
-
group_id = generate_group_id("browser_click", selector[:100])
|
22
|
-
emit_info(
|
23
|
-
f"[bold white on blue] BROWSER CLICK [/bold white on blue] 🖱️ selector='{selector}' button={button}",
|
24
|
-
message_group=group_id,
|
25
|
-
)
|
26
|
-
try:
|
27
|
-
browser_manager = get_camoufox_manager()
|
28
|
-
page = await browser_manager.get_current_page()
|
29
|
-
|
30
|
-
if not page:
|
31
|
-
return {"success": False, "error": "No active browser page available"}
|
32
|
-
|
33
|
-
# Find element
|
34
|
-
element = page.locator(selector)
|
35
|
-
|
36
|
-
# Wait for element to be visible and enabled
|
37
|
-
await element.wait_for(state="visible", timeout=timeout)
|
38
|
-
|
39
|
-
# Click options
|
40
|
-
click_options = {
|
41
|
-
"force": force,
|
42
|
-
"button": button,
|
43
|
-
"timeout": timeout,
|
44
|
-
}
|
45
|
-
|
46
|
-
if modifiers:
|
47
|
-
click_options["modifiers"] = modifiers
|
48
|
-
|
49
|
-
await element.click(**click_options)
|
50
|
-
|
51
|
-
emit_info(f"[green]Clicked element: {selector}[/green]", message_group=group_id)
|
52
|
-
|
53
|
-
return {"success": True, "selector": selector, "action": f"{button}_click"}
|
54
|
-
|
55
|
-
except Exception as e:
|
56
|
-
emit_info(f"[red]Click failed: {str(e)}[/red]", message_group=group_id)
|
57
|
-
return {"success": False, "error": str(e), "selector": selector}
|
58
|
-
|
59
|
-
|
60
|
-
async def double_click_element(
|
61
|
-
selector: str,
|
62
|
-
timeout: int = 10000,
|
63
|
-
force: bool = False,
|
64
|
-
) -> Dict[str, Any]:
|
65
|
-
"""Double-click on an element."""
|
66
|
-
group_id = generate_group_id("browser_double_click", selector[:100])
|
67
|
-
emit_info(
|
68
|
-
f"[bold white on blue] BROWSER DOUBLE CLICK [/bold white on blue] 🖱️🖱️ selector='{selector}'",
|
69
|
-
message_group=group_id,
|
70
|
-
)
|
71
|
-
try:
|
72
|
-
browser_manager = get_camoufox_manager()
|
73
|
-
page = await browser_manager.get_current_page()
|
74
|
-
|
75
|
-
if not page:
|
76
|
-
return {"success": False, "error": "No active browser page available"}
|
77
|
-
|
78
|
-
element = page.locator(selector)
|
79
|
-
await element.wait_for(state="visible", timeout=timeout)
|
80
|
-
await element.dblclick(force=force, timeout=timeout)
|
81
|
-
|
82
|
-
emit_info(
|
83
|
-
f"[green]Double-clicked element: {selector}[/green]", message_group=group_id
|
84
|
-
)
|
85
|
-
|
86
|
-
return {"success": True, "selector": selector, "action": "double_click"}
|
87
|
-
|
88
|
-
except Exception as e:
|
89
|
-
return {"success": False, "error": str(e), "selector": selector}
|
90
|
-
|
91
|
-
|
92
|
-
async def hover_element(
|
93
|
-
selector: str,
|
94
|
-
timeout: int = 10000,
|
95
|
-
force: bool = False,
|
96
|
-
) -> Dict[str, Any]:
|
97
|
-
"""Hover over an element."""
|
98
|
-
group_id = generate_group_id("browser_hover", selector[:100])
|
99
|
-
emit_info(
|
100
|
-
f"[bold white on blue] BROWSER HOVER [/bold white on blue] 👆 selector='{selector}'",
|
101
|
-
message_group=group_id,
|
102
|
-
)
|
103
|
-
try:
|
104
|
-
browser_manager = get_camoufox_manager()
|
105
|
-
page = await browser_manager.get_current_page()
|
106
|
-
|
107
|
-
if not page:
|
108
|
-
return {"success": False, "error": "No active browser page available"}
|
109
|
-
|
110
|
-
element = page.locator(selector)
|
111
|
-
await element.wait_for(state="visible", timeout=timeout)
|
112
|
-
await element.hover(force=force, timeout=timeout)
|
113
|
-
|
114
|
-
emit_info(
|
115
|
-
f"[green]Hovered over element: {selector}[/green]", message_group=group_id
|
116
|
-
)
|
117
|
-
|
118
|
-
return {"success": True, "selector": selector, "action": "hover"}
|
119
|
-
|
120
|
-
except Exception as e:
|
121
|
-
return {"success": False, "error": str(e), "selector": selector}
|
122
|
-
|
123
|
-
|
124
|
-
async def set_element_text(
|
125
|
-
selector: str,
|
126
|
-
text: str,
|
127
|
-
clear_first: bool = True,
|
128
|
-
timeout: int = 10000,
|
129
|
-
) -> Dict[str, Any]:
|
130
|
-
"""Set text in an input element."""
|
131
|
-
group_id = generate_group_id("browser_set_text", f"{selector[:50]}_{text[:30]}")
|
132
|
-
emit_info(
|
133
|
-
f"[bold white on blue] BROWSER SET TEXT [/bold white on blue] ✏️ selector='{selector}' text='{text[:50]}{'...' if len(text) > 50 else ''}'",
|
134
|
-
message_group=group_id,
|
135
|
-
)
|
136
|
-
try:
|
137
|
-
browser_manager = get_camoufox_manager()
|
138
|
-
page = await browser_manager.get_current_page()
|
139
|
-
|
140
|
-
if not page:
|
141
|
-
return {"success": False, "error": "No active browser page available"}
|
142
|
-
|
143
|
-
element = page.locator(selector)
|
144
|
-
await element.wait_for(state="visible", timeout=timeout)
|
145
|
-
|
146
|
-
if clear_first:
|
147
|
-
await element.clear(timeout=timeout)
|
148
|
-
|
149
|
-
await element.fill(text, timeout=timeout)
|
150
|
-
|
151
|
-
emit_info(
|
152
|
-
f"[green]Set text in element: {selector}[/green]", message_group=group_id
|
153
|
-
)
|
154
|
-
|
155
|
-
return {
|
156
|
-
"success": True,
|
157
|
-
"selector": selector,
|
158
|
-
"text": text,
|
159
|
-
"action": "set_text",
|
160
|
-
}
|
161
|
-
|
162
|
-
except Exception as e:
|
163
|
-
emit_info(f"[red]Set text failed: {str(e)}[/red]", message_group=group_id)
|
164
|
-
return {"success": False, "error": str(e), "selector": selector, "text": text}
|
165
|
-
|
166
|
-
|
167
|
-
async def get_element_text(
|
168
|
-
selector: str,
|
169
|
-
timeout: int = 10000,
|
170
|
-
) -> Dict[str, Any]:
|
171
|
-
"""Get text content from an element."""
|
172
|
-
group_id = generate_group_id("browser_get_text", selector[:100])
|
173
|
-
emit_info(
|
174
|
-
f"[bold white on blue] BROWSER GET TEXT [/bold white on blue] 📝 selector='{selector}'",
|
175
|
-
message_group=group_id,
|
176
|
-
)
|
177
|
-
try:
|
178
|
-
browser_manager = get_camoufox_manager()
|
179
|
-
page = await browser_manager.get_current_page()
|
180
|
-
|
181
|
-
if not page:
|
182
|
-
return {"success": False, "error": "No active browser page available"}
|
183
|
-
|
184
|
-
element = page.locator(selector)
|
185
|
-
await element.wait_for(state="visible", timeout=timeout)
|
186
|
-
|
187
|
-
text = await element.text_content()
|
188
|
-
|
189
|
-
return {"success": True, "selector": selector, "text": text}
|
190
|
-
|
191
|
-
except Exception as e:
|
192
|
-
return {"success": False, "error": str(e), "selector": selector}
|
193
|
-
|
194
|
-
|
195
|
-
async def get_element_value(
|
196
|
-
selector: str,
|
197
|
-
timeout: int = 10000,
|
198
|
-
) -> Dict[str, Any]:
|
199
|
-
"""Get value from an input element."""
|
200
|
-
group_id = generate_group_id("browser_get_value", selector[:100])
|
201
|
-
emit_info(
|
202
|
-
f"[bold white on blue] BROWSER GET VALUE [/bold white on blue] 📎 selector='{selector}'",
|
203
|
-
message_group=group_id,
|
204
|
-
)
|
205
|
-
try:
|
206
|
-
browser_manager = get_camoufox_manager()
|
207
|
-
page = await browser_manager.get_current_page()
|
208
|
-
|
209
|
-
if not page:
|
210
|
-
return {"success": False, "error": "No active browser page available"}
|
211
|
-
|
212
|
-
element = page.locator(selector)
|
213
|
-
await element.wait_for(state="visible", timeout=timeout)
|
214
|
-
|
215
|
-
value = await element.input_value()
|
216
|
-
|
217
|
-
return {"success": True, "selector": selector, "value": value}
|
218
|
-
|
219
|
-
except Exception as e:
|
220
|
-
return {"success": False, "error": str(e), "selector": selector}
|
221
|
-
|
222
|
-
|
223
|
-
async def select_option(
|
224
|
-
selector: str,
|
225
|
-
value: Optional[str] = None,
|
226
|
-
label: Optional[str] = None,
|
227
|
-
index: Optional[int] = None,
|
228
|
-
timeout: int = 10000,
|
229
|
-
) -> Dict[str, Any]:
|
230
|
-
"""Select an option in a dropdown/select element."""
|
231
|
-
option_desc = value or label or str(index) if index is not None else "unknown"
|
232
|
-
group_id = generate_group_id(
|
233
|
-
"browser_select_option", f"{selector[:50]}_{option_desc}"
|
234
|
-
)
|
235
|
-
emit_info(
|
236
|
-
f"[bold white on blue] BROWSER SELECT OPTION [/bold white on blue] 📄 selector='{selector}' option='{option_desc}'",
|
237
|
-
message_group=group_id,
|
238
|
-
)
|
239
|
-
try:
|
240
|
-
browser_manager = get_camoufox_manager()
|
241
|
-
page = await browser_manager.get_current_page()
|
242
|
-
|
243
|
-
if not page:
|
244
|
-
return {"success": False, "error": "No active browser page available"}
|
245
|
-
|
246
|
-
element = page.locator(selector)
|
247
|
-
await element.wait_for(state="visible", timeout=timeout)
|
248
|
-
|
249
|
-
if value is not None:
|
250
|
-
await element.select_option(value=value, timeout=timeout)
|
251
|
-
selection = value
|
252
|
-
elif label is not None:
|
253
|
-
await element.select_option(label=label, timeout=timeout)
|
254
|
-
selection = label
|
255
|
-
elif index is not None:
|
256
|
-
await element.select_option(index=index, timeout=timeout)
|
257
|
-
selection = str(index)
|
258
|
-
else:
|
259
|
-
return {
|
260
|
-
"success": False,
|
261
|
-
"error": "Must specify value, label, or index",
|
262
|
-
"selector": selector,
|
263
|
-
}
|
264
|
-
|
265
|
-
emit_info(
|
266
|
-
f"[green]Selected option in {selector}: {selection}[/green]",
|
267
|
-
message_group=group_id,
|
268
|
-
)
|
269
|
-
|
270
|
-
return {"success": True, "selector": selector, "selection": selection}
|
271
|
-
|
272
|
-
except Exception as e:
|
273
|
-
return {"success": False, "error": str(e), "selector": selector}
|
274
|
-
|
275
|
-
|
276
|
-
async def check_element(
|
277
|
-
selector: str,
|
278
|
-
timeout: int = 10000,
|
279
|
-
) -> Dict[str, Any]:
|
280
|
-
"""Check a checkbox or radio button."""
|
281
|
-
group_id = generate_group_id("browser_check", selector[:100])
|
282
|
-
emit_info(
|
283
|
-
f"[bold white on blue] BROWSER CHECK [/bold white on blue] ☑️ selector='{selector}'",
|
284
|
-
message_group=group_id,
|
285
|
-
)
|
286
|
-
try:
|
287
|
-
browser_manager = get_camoufox_manager()
|
288
|
-
page = await browser_manager.get_current_page()
|
289
|
-
|
290
|
-
if not page:
|
291
|
-
return {"success": False, "error": "No active browser page available"}
|
292
|
-
|
293
|
-
element = page.locator(selector)
|
294
|
-
await element.wait_for(state="visible", timeout=timeout)
|
295
|
-
await element.check(timeout=timeout)
|
296
|
-
|
297
|
-
emit_info(f"[green]Checked element: {selector}[/green]", message_group=group_id)
|
298
|
-
|
299
|
-
return {"success": True, "selector": selector, "action": "check"}
|
300
|
-
|
301
|
-
except Exception as e:
|
302
|
-
return {"success": False, "error": str(e), "selector": selector}
|
303
|
-
|
304
|
-
|
305
|
-
async def uncheck_element(
|
306
|
-
selector: str,
|
307
|
-
timeout: int = 10000,
|
308
|
-
) -> Dict[str, Any]:
|
309
|
-
"""Uncheck a checkbox."""
|
310
|
-
group_id = generate_group_id("browser_uncheck", selector[:100])
|
311
|
-
emit_info(
|
312
|
-
f"[bold white on blue] BROWSER UNCHECK [/bold white on blue] ☐️ selector='{selector}'",
|
313
|
-
message_group=group_id,
|
314
|
-
)
|
315
|
-
try:
|
316
|
-
browser_manager = get_camoufox_manager()
|
317
|
-
page = await browser_manager.get_current_page()
|
318
|
-
|
319
|
-
if not page:
|
320
|
-
return {"success": False, "error": "No active browser page available"}
|
321
|
-
|
322
|
-
element = page.locator(selector)
|
323
|
-
await element.wait_for(state="visible", timeout=timeout)
|
324
|
-
await element.uncheck(timeout=timeout)
|
325
|
-
|
326
|
-
emit_info(
|
327
|
-
f"[green]Unchecked element: {selector}[/green]", message_group=group_id
|
328
|
-
)
|
329
|
-
|
330
|
-
return {"success": True, "selector": selector, "action": "uncheck"}
|
331
|
-
|
332
|
-
except Exception as e:
|
333
|
-
return {"success": False, "error": str(e), "selector": selector}
|
334
|
-
|
335
|
-
|
336
|
-
# Tool registration functions
|
337
|
-
def register_click_element(agent):
|
338
|
-
"""Register the click element tool."""
|
339
|
-
|
340
|
-
@agent.tool
|
341
|
-
async def browser_click(
|
342
|
-
context: RunContext,
|
343
|
-
selector: str,
|
344
|
-
timeout: int = 10000,
|
345
|
-
force: bool = False,
|
346
|
-
button: str = "left",
|
347
|
-
modifiers: Optional[List[str]] = None,
|
348
|
-
) -> Dict[str, Any]:
|
349
|
-
"""
|
350
|
-
Click on an element in the browser.
|
351
|
-
|
352
|
-
Args:
|
353
|
-
selector: CSS or XPath selector for the element
|
354
|
-
timeout: Timeout in milliseconds to wait for element
|
355
|
-
force: Skip actionability checks and force the click
|
356
|
-
button: Mouse button to click (left, right, middle)
|
357
|
-
modifiers: Modifier keys to hold (Alt, Control, Meta, Shift)
|
358
|
-
|
359
|
-
Returns:
|
360
|
-
Dict with click results
|
361
|
-
"""
|
362
|
-
return await click_element(selector, timeout, force, button, modifiers)
|
363
|
-
|
364
|
-
|
365
|
-
def register_double_click_element(agent):
|
366
|
-
"""Register the double-click element tool."""
|
367
|
-
|
368
|
-
@agent.tool
|
369
|
-
async def browser_double_click(
|
370
|
-
context: RunContext,
|
371
|
-
selector: str,
|
372
|
-
timeout: int = 10000,
|
373
|
-
force: bool = False,
|
374
|
-
) -> Dict[str, Any]:
|
375
|
-
"""
|
376
|
-
Double-click on an element in the browser.
|
377
|
-
|
378
|
-
Args:
|
379
|
-
selector: CSS or XPath selector for the element
|
380
|
-
timeout: Timeout in milliseconds to wait for element
|
381
|
-
force: Skip actionability checks and force the double-click
|
382
|
-
|
383
|
-
Returns:
|
384
|
-
Dict with double-click results
|
385
|
-
"""
|
386
|
-
return await double_click_element(selector, timeout, force)
|
387
|
-
|
388
|
-
|
389
|
-
def register_hover_element(agent):
|
390
|
-
"""Register the hover element tool."""
|
391
|
-
|
392
|
-
@agent.tool
|
393
|
-
async def browser_hover(
|
394
|
-
context: RunContext,
|
395
|
-
selector: str,
|
396
|
-
timeout: int = 10000,
|
397
|
-
force: bool = False,
|
398
|
-
) -> Dict[str, Any]:
|
399
|
-
"""
|
400
|
-
Hover over an element in the browser.
|
401
|
-
|
402
|
-
Args:
|
403
|
-
selector: CSS or XPath selector for the element
|
404
|
-
timeout: Timeout in milliseconds to wait for element
|
405
|
-
force: Skip actionability checks and force the hover
|
406
|
-
|
407
|
-
Returns:
|
408
|
-
Dict with hover results
|
409
|
-
"""
|
410
|
-
return await hover_element(selector, timeout, force)
|
411
|
-
|
412
|
-
|
413
|
-
def register_set_element_text(agent):
|
414
|
-
"""Register the set element text tool."""
|
415
|
-
|
416
|
-
@agent.tool
|
417
|
-
async def browser_set_text(
|
418
|
-
context: RunContext,
|
419
|
-
selector: str,
|
420
|
-
text: str,
|
421
|
-
clear_first: bool = True,
|
422
|
-
timeout: int = 10000,
|
423
|
-
) -> Dict[str, Any]:
|
424
|
-
"""
|
425
|
-
Set text in an input element.
|
426
|
-
|
427
|
-
Args:
|
428
|
-
selector: CSS or XPath selector for the input element
|
429
|
-
text: Text to enter
|
430
|
-
clear_first: Whether to clear existing text first
|
431
|
-
timeout: Timeout in milliseconds to wait for element
|
432
|
-
|
433
|
-
Returns:
|
434
|
-
Dict with text input results
|
435
|
-
"""
|
436
|
-
return await set_element_text(selector, text, clear_first, timeout)
|
437
|
-
|
438
|
-
|
439
|
-
def register_get_element_text(agent):
|
440
|
-
"""Register the get element text tool."""
|
441
|
-
|
442
|
-
@agent.tool
|
443
|
-
async def browser_get_text(
|
444
|
-
context: RunContext,
|
445
|
-
selector: str,
|
446
|
-
timeout: int = 10000,
|
447
|
-
) -> Dict[str, Any]:
|
448
|
-
"""
|
449
|
-
Get text content from an element.
|
450
|
-
|
451
|
-
Args:
|
452
|
-
selector: CSS or XPath selector for the element
|
453
|
-
timeout: Timeout in milliseconds to wait for element
|
454
|
-
|
455
|
-
Returns:
|
456
|
-
Dict with element text content
|
457
|
-
"""
|
458
|
-
return await get_element_text(selector, timeout)
|
459
|
-
|
460
|
-
|
461
|
-
def register_get_element_value(agent):
|
462
|
-
"""Register the get element value tool."""
|
463
|
-
|
464
|
-
@agent.tool
|
465
|
-
async def browser_get_value(
|
466
|
-
context: RunContext,
|
467
|
-
selector: str,
|
468
|
-
timeout: int = 10000,
|
469
|
-
) -> Dict[str, Any]:
|
470
|
-
"""
|
471
|
-
Get value from an input element.
|
472
|
-
|
473
|
-
Args:
|
474
|
-
selector: CSS or XPath selector for the input element
|
475
|
-
timeout: Timeout in milliseconds to wait for element
|
476
|
-
|
477
|
-
Returns:
|
478
|
-
Dict with element value
|
479
|
-
"""
|
480
|
-
return await get_element_value(selector, timeout)
|
481
|
-
|
482
|
-
|
483
|
-
def register_select_option(agent):
|
484
|
-
"""Register the select option tool."""
|
485
|
-
|
486
|
-
@agent.tool
|
487
|
-
async def browser_select_option(
|
488
|
-
context: RunContext,
|
489
|
-
selector: str,
|
490
|
-
value: Optional[str] = None,
|
491
|
-
label: Optional[str] = None,
|
492
|
-
index: Optional[int] = None,
|
493
|
-
timeout: int = 10000,
|
494
|
-
) -> Dict[str, Any]:
|
495
|
-
"""
|
496
|
-
Select an option in a dropdown/select element.
|
497
|
-
|
498
|
-
Args:
|
499
|
-
selector: CSS or XPath selector for the select element
|
500
|
-
value: Option value to select
|
501
|
-
label: Option label text to select
|
502
|
-
index: Option index to select (0-based)
|
503
|
-
timeout: Timeout in milliseconds to wait for element
|
504
|
-
|
505
|
-
Returns:
|
506
|
-
Dict with selection results
|
507
|
-
"""
|
508
|
-
return await select_option(selector, value, label, index, timeout)
|
509
|
-
|
510
|
-
|
511
|
-
def register_browser_check(agent):
|
512
|
-
"""Register checkbox/radio button check tool."""
|
513
|
-
|
514
|
-
@agent.tool
|
515
|
-
async def browser_check(
|
516
|
-
context: RunContext,
|
517
|
-
selector: str,
|
518
|
-
timeout: int = 10000,
|
519
|
-
) -> Dict[str, Any]:
|
520
|
-
"""
|
521
|
-
Check a checkbox or radio button.
|
522
|
-
|
523
|
-
Args:
|
524
|
-
selector: CSS or XPath selector for the checkbox/radio
|
525
|
-
timeout: Timeout in milliseconds to wait for element
|
526
|
-
|
527
|
-
Returns:
|
528
|
-
Dict with check results
|
529
|
-
"""
|
530
|
-
return await check_element(selector, timeout)
|
531
|
-
|
532
|
-
|
533
|
-
def register_browser_uncheck(agent):
|
534
|
-
"""Register checkbox uncheck tool."""
|
535
|
-
|
536
|
-
@agent.tool
|
537
|
-
async def browser_uncheck(
|
538
|
-
context: RunContext,
|
539
|
-
selector: str,
|
540
|
-
timeout: int = 10000,
|
541
|
-
) -> Dict[str, Any]:
|
542
|
-
"""
|
543
|
-
Uncheck a checkbox.
|
544
|
-
|
545
|
-
Args:
|
546
|
-
selector: CSS or XPath selector for the checkbox
|
547
|
-
timeout: Timeout in milliseconds to wait for element
|
548
|
-
|
549
|
-
Returns:
|
550
|
-
Dict with uncheck results
|
551
|
-
"""
|
552
|
-
return await uncheck_element(selector, timeout)
|