from fastcore.test import test_eqSolveitCDP API
solvecdp relies on the solveit-chrome extension being available - let’s check it:
test_eq((await event_get_a('ext-ping')).result, 'pong')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()