Metadata-Version: 2.4
Name: solvecdp
Version: 0.0.4
Summary: Lightweight Chrome Debug Protocol (CDP) client for solveit
Author-email: Jeremy Howard <github@jhoward.fastmail.fm>
License: Apache-2.0
Project-URL: Repository, https://github.com/AnswerDotAI/solvecdp
Project-URL: Documentation, https://AnswerDotAI.github.io/solvecdp/
Keywords: nbdev
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: dialoghelper
Requires-Dist: fastcore
Dynamic: license-file

# solvecdp


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

fastcdp provides an async Python client for the [Chrome DevTools
Protocol](https://chromedevtools.github.io/devtools-protocol/) (CDP)
over solveit’s js bridge. It exposes every CDP domain as a Python
attribute with auto-generated signatures and docstrings —
e.g. `await cdp.page.navigate(url=...)`.

It includes event subscription via `cdp.on()`/`cdp.wait_event()`,
navigation helpers (`goto`, `wait_for_selector`, `wait_for`), screenshot
capture, and accessibility tree access. A
[`cdp_search`](https://AnswerDotAI.github.io/solvecdp/core.html#cdp_search)
utility lets you search CDP commands by name or description. For use
inside [safepyrun](https://github.com/AnswerDotAI/safepyrun) sandboxes,
[`cdp_yolo()`](https://AnswerDotAI.github.io/solvecdp/core.html#cdp_yolo)
registers all CDP classes.

## Installation

You must install the [solveit-chrome
extension](https://github.com/AnswerDotAI/solveit-chrome) before using
solvecdp.

Solveit already has solvecdp installed, but if you want to install the
latest you can get it from [pypi](https://pypi.org/project/solvecdp/):

``` sh
$ pip install solvecdp
```

## How to use

``` python
from solvecdp import *
```

### The JsCDP class

Every CDP domain is available as an attribute with auto-generated
signatures. You can search for commands with
[`cdp_search`](https://AnswerDotAI.github.io/solvecdp/core.html#cdp_search):

``` python
cdp_search('screenshot')
```

    "Emulation.setVisibleSize: Resizes the frame/viewport of the page. Note that this does not affect the frame's container\n(e.g. browser window). Can \nHeadlessExperimental.beginFrame: Sends a BeginFrame to the target and returns when the frame was completed. Optionally captures a\nscreenshot from the res\n  evt Overlay.screenshotRequested: Fired when user asks to capture screenshot of some area on the page.\nPage.captureScreenshot: Capture page screenshot."

Create a new page:

``` python
jc = await JsCDP.new()
```

Go to a page:

``` python
await jc.goto('https://httpbin.org/forms/post')
```

Eval js:

``` python
await jc.eval('document.title')
```

    '6. httpbin.org/forms/post'

Or you can `wait_for` any js expression to be truthy, and have it
returned:

``` python
await jc.wait_for('document.title')
```

    '6. httpbin.org/forms/post'

Take a screenshot of the page:

``` python
img = await jc.screenshot()
```

Clean up when done:

``` python
await jc.close()
```

See [`JsCDP`](https://AnswerDotAI.github.io/solvecdp/core.html#jscdp)
docs for full details.

## Filling forms

``` python
page = await JsCDP.new(url='https://httpbin.org/forms/post')
```

For finding elements to interact with, use `ax_tree`:

``` python
root = await page.ax_tree()
print(str(root)[:300])
```

    - **RootWebArea** "6. httpbin.org/forms/post" `focusable=True` `url=https://httpbin.org/forms/post` [#14]
      - **LabelText** "" [#20]
        - **StaticText** "Customer name: " [#62]
          - **InlineTextBox** "Customer name: "
        - **textbox** "Customer name: " `focusable=True` `editable=plaintext` `set

`find` and `find_id` are used to identify elements in the tree:

``` python
nmid = root.find_id('textbox', 'Customer name')
nmid
```

    2

You can use regular CDP methods, or one of the provided shortcuts:

``` python
await page.fill_text(nmid, 'Jeremy Howard')
await page.click(root.find_id('radio', 'Large'))
await page.js_node_run('this.value = "18:30"', root.find_id('InputTime', 'delivery time'));
```

You can use `click` to click a button, or `click_and_wait` to wait for
the next page to load:

``` python
await page.click_and_wait(root.find_id('button', 'Submit order'))
```

``` python
await page.close()
```

To allow LLMs like solveit with safepyrun to access solvecdp, use:

``` python
cdp_yolo()
```

Then use a prompt such as:

> Try using pyrun to create a `page_` JsCDP object, then goto `<url>`,
> fill it out, read it to check it’s filled correctly, then submit it,
> and see what you get back. Don’t use find_id - you can get all the ids
> at once with ax_tree (don’t truncate the result of it). Don’t add
> extra waits etc - solvecdp handles it automatically. IDs can change so
> be sure to use the ax_tree IDs you read.
