SolveitCDP API

Drive the user’s Chrome from a solveit kernel
from fastcore.test import test_eq

solvecdp relies on the solveit-chrome extension being available - let’s check it:

test_eq((await event_get_a('ext-ping')).result, 'pong')

source

JsCDP

def JsCDP(
    wsconn:NoneType=None, debug:bool=False
):

CDP over the solveit-chrome extension: frames relayed via solveit’s /wsx channel

Everything else comes from fastcdp.ext’s ExtCDP: the sessionId↔︎tabId mapping, the lifecycle actions, and new_page/attach_page/pages. JsCDP just supplies the channel, meeting the extension at this solveit’s /wsx relay instead of listening on a local port (a solveit kernel usually runs in a container that the user’s browser can’t reach, so both sides dial out to the relay).

Connect, open a tab, and drive it. goto, eval, and friends are all inherited from fastcdp through the Page proxy:

cdp = await JsCDP.connect()
page = await cdp.new_page()
await page.goto('https://httpbingo.org/forms/post')
await page.eval('document.title')
assert 'httpbingo.org' in await page.eval('document.title')
assert first(await cdp.pages, lambda t: 'httpbingo' in t.get('url',''))

The accessibility tree and form helpers also come straight from fastcdp: find elements with ax_tree/find_id, then fill_text, click, select_option, and click_and_wait.

root = await page.ax_tree()
await page.fill_text(root.find_id('textbox', 'Customer name'), 'Jeremy Howard')
await page.click(root.find_id('radio', 'Large'))
await page.click(root.find_id('checkbox', 'Extra Cheese'))
await page.click_and_wait(root.find_id('button', 'Submit order'))
assert 'Jeremy Howard' in await page.eval('document.body.innerText')

The debugging buffers work too, since every chrome.debugger event is streamed over the channel and dispatched by the inherited machinery:

await page.start_console()
await page.eval(r'console.warn("watch out")')
test_eq(await page.console(r'watch'), ['warning: watch out'])
await page.close()
await cdp.close()

source

cdp_yolo

def cdp_yolo():

Allow all CDP classes in safepyrun