async def main(): logger.info('Connecting to browser: %s', sys.argv[1]) async with open_cdp_connection(sys.argv[1]) as conn: logger.info('Listing targets') targets = await conn.execute(target.get_targets()) target_id = targets[0].target_id logger.info('Attaching to target id=%s', target_id) session = await conn.open_session(target_id) logger.info('Setting device emulation') await session.execute( emulation.set_device_metrics_override(width=800, height=600, device_scale_factor=1, mobile=False)) logger.info('Enabling page events') await session.execute(page.enable()) logger.info('Navigating to %s', sys.argv[2]) await session.execute(page.navigate(url=sys.argv[2])) logger.info('Waiting for navigation to finish…') event = await session.wait_for(page.LoadEventFired) logger.info('Making a screenshot') img_data = await session.execute(page.capture_screenshot(format='png')) screenshot_file = await trio.open_file('test.png', 'wb') async with screenshot_file: await screenshot_file.write(b64decode(img_data))
async def test_connection_browser_error(nursery): ''' If the browser sends an error with a valid command ID, then that error should be raised at the point where the command was executed. Compare to ``test_connection_invalid_json()``, where the error is raised on the reader task since there is no way to associate it with a specific commmand. ''' async def handler(request): # It's tricky to catch exceptions from the server, so exceptions # are logged instead. try: ws = await request.accept() command = json.loads(await ws.get_message()) logging.info('Server received: %r', command) response = { 'id': command['id'], 'error': { 'code': -32000, 'message': 'This is a browser error', 'data': 'This is additional data' } } logging.info('Server sending reponse: %r', response) await ws.send_message(json.dumps(response)) except Exception: logging.exception('Server exception') server = await start_server(nursery, handler) async with open_cdp_connection(server) as conn: with pytest.raises(BrowserError) as exc_info: targets = await conn.execute(target.get_targets()) assert exc_info.value.code == -32000
async def main(i): # Open connection async with open_cdp_connection(uri_pwa) as conn: logger.info('Connecting') targets = await conn.execute(target.get_targets()) # Filter the targets to find the PWA one targets = list(filter(findPWA, targets)) logger.info(targets[0]) target_id = targets[0].target_id logger.info('Attaching to target id=%s', target_id) session = await conn.open_session(target_id) final_data = [] def addData(data): final_data += data outfile_path = trio.Path(name + '_' + str(i) + '.json') async with await outfile_path.open('a+') as outfile: logger.info('Tracing...') # write things to file to be readable as a json await outfile.write('[') # data = '[' await generateTrace(session, outfile, final_data) logger.info('Tracing n° {} ended'.format(i)) await outfile.write(',\n'.join(final_data)) await outfile.write("]")
async def test_connection_execute(nursery): ''' Open a connection and execute a command on it. ''' async def handler(request): # It's tricky to catch exceptions from the server, so exceptions are # logged instead. try: ws = await request.accept() command = json.loads(await ws.get_message()) logging.info('Server received: %r', command) assert command['method'] == 'Target.getTargets' response = { 'id': command['id'], 'result': { 'targetInfos': [{ 'targetId': 'target1', 'type': 'tab', 'title': 'New Tab', 'url': 'about:newtab', 'attached': False, }], } } logging.info('Server sending: %r', response) await ws.send_message(json.dumps(response)) except Exception: logging.exception('Server exception') server = await start_server(nursery, handler) async with open_cdp_connection(server) as conn: targets = await conn.execute(target.get_targets()) assert len(targets) == 1 assert isinstance(targets[0], target.TargetInfo)
async def main(): logger.info('Connecting to browser: %s', sys.argv[1]) async with open_cdp_connection(sys.argv[1]) as conn: logger.info('Listing targets') targets = await conn.execute(target.get_targets()) for t in targets: if (t.type == 'page' and not t.url.startswith('devtools://') and not t.attached): target_id = t.target_id break logger.info('Attaching to target id=%s', target_id) session = await conn.open_session(target_id) logger.info('Navigating to %s', sys.argv[2]) await session.execute(page.enable()) async with session.wait_for(page.LoadEventFired): await session.execute(page.navigate(sys.argv[2])) logger.info('Extracting page title') root_node = await session.execute(dom.get_document()) title_node_id = await session.execute( dom.query_selector(root_node.node_id, 'title')) html = await session.execute(dom.get_outer_html(title_node_id)) print(html)
async def test_session_execute(nursery): ''' Open a session and execute a command on it. ''' async def handler(request): # It's tricky to catch exceptions from the server, so exceptions are # logged instead. try: ws = await request.accept() # Handle "attachToTarget" command. command = json.loads(await ws.get_message()) assert command['method'] == 'Target.attachToTarget' assert command['params']['targetId'] == 'target1' logging.info('Server received: %r', command) response = { 'id': command['id'], 'result': { 'sessionId': 'session1', } } logging.info('Server sending: %r', response) await ws.send_message(json.dumps(response)) # Handle "querySelector" command. command = json.loads(await ws.get_message()) assert command['method'] == 'DOM.querySelector' assert command['sessionId'] == 'session1' assert command['params']['nodeId'] == 0 assert command['params']['selector'] == 'p.foo' logging.info('Server received: %r', command) response = { 'id': command['id'], 'sessionId': command['sessionId'], 'result': { 'nodeId': 1, } } logging.info('Server sending: %r', response) await ws.send_message(json.dumps(response)) except Exception: logging.exception('Server exception') server = await start_server(nursery, handler) async with open_cdp_connection(server) as conn: session = await conn.open_session(target.TargetID('target1')) assert session.session_id == 'session1' node_id = await session.execute( dom.query_selector(dom.NodeId(0),'p.foo')) assert node_id == 1
async def main(): cdp_uri = sys.argv[1] async with open_cdp_connection(cdp_uri) as conn: logger.info('Connecting') targets = await conn.execute(target.get_targets()) target_id = targets[0].target_id # First page logger.info('Attaching to target id=%s', target_id) session = await conn.open_session(target_id) logger.info('Started heap snapshot') outfile_path = trio.Path('%s.heapsnapshot' % datetime.today().isoformat()) async with await outfile_path.open('a') as outfile: logger.info('Started writing heap snapshot') await _take_heap_snapshot(session, outfile, report_progress=True)
async def merge_pages_in(ethox_doc, ws_addr, reduction_code): async with open_cdp_connection(ws_addr) as conn: logger.info('Listing targets') targets = await conn.execute(target.get_targets()) target_id = targets[0].target_id logger.info('Attaching to target id=%s', target_id) session = await conn.open_session(target_id) logger.info('Setting device emulation') await session.execute( emulation.set_device_metrics_override(width=800, height=600, device_scale_factor=1, mobile=False)) logger.info('Enabling page events') await session.execute(page.enable()) logger.info('Starting to crawl documentation') contents = {} for doc_page in glob.iglob(os.path.join(ethox_doc, '**', '*.html'), recursive=True): (target_item, main_contents) = await convert_page(session, doc_page, reduction_code) contents[target_item] = main_contents await convert_page(session, os.path.join(ethox_doc, 'index.html'), reduction_code) root_id = (await session.execute(dom.get_document())).node_id body_id = await session.execute(dom.query_selector(root_id, 'body')) footer_id = await session.execute(dom.query_selector( root_id, 'footer')) main_id = await session.execute(dom.query_selector(root_id, '#main')) for (_, contents) in contents.items(): cloned_id = await session.execute( dom.copy_to(main_id, body_id, footer_id)) await session.execute(dom.set_outer_html(cloned_id, contents)) await print_page(session, 'cargo_doc.pdf')
async def main(): logger.info('Connecting to browser: %s', sys.argv[1]) async with open_cdp_connection(sys.argv[1]) as conn: logger.info('Listing targets') targets = await conn.execute(target.get_targets()) target_id = targets[0].target_id logger.info('Attaching to target id=%s', target_id) session = await conn.open_session(target_id) logger.info('Navigating to %s', sys.argv[2]) await session.execute(page.enable()) await session.execute(page.navigate(sys.argv[2])) event = await session.wait_for(page.LoadEventFired) logger.info('Extracting page title') root_node = await session.execute(dom.get_document()) title_node_id = await session.execute( dom.query_selector(root_node.node_id, 'title')) html = await session.execute(dom.get_outer_html(title_node_id)) print(html)
async def test_connection_invalid_json(): ''' If the server sends invalid JSON, that exception is raised on the reader task, which crashes the entire connection. Therefore, the entire test needs to be wrapped in try/except. ''' with pytest.raises(BrowserError) as exc_info: async with trio.open_nursery() as nursery: async def handler(request): # It's tricky to catch exceptions from the server, so exceptions # are logged instead. try: ws = await request.accept() command = json.loads(await ws.get_message()) logging.info('Server received: %r', command) logging.info('Server sending bogus reponse') await ws.send_message('bogus') except Exception: logging.exception('Server exception') server = await start_server(nursery, handler) async with open_cdp_connection(server) as conn: targets = await conn.execute(target.get_targets()) assert exc_info.value.code == -32700 # JSON parse error
async def test_listen_for_events(nursery): ''' The server sends 2 different events. The client is listening for a specific type of event and therefore only sees the 2nd one. ''' async def handler(request): # It's tricky to catch exceptions from the server, so exceptions are # logged instead. try: ws = await request.accept() # Send event 1 event = { 'method': 'Page.loadEventFired', 'params': {'timestamp': 1}, } logging.info('Server sending: %r', event) await ws.send_message(json.dumps(event)) # Send event 2 event = { 'method': 'Page.loadEventFired', 'params': {'timestamp': 2}, } logging.info('Server sending: %r', event) await ws.send_message(json.dumps(event)) except Exception: logging.exception('Server exception') server = await start_server(nursery, handler) async with open_cdp_connection(server) as conn: n = 1 async for event in conn.listen(page.LoadEventFired): assert isinstance(event, page.LoadEventFired) assert event.timestamp == n if n == 2: break n += 1
async def test_wait_for_event(nursery): ''' The server sends 2 different events. The client is listening for a specific type of event and therefore only sees the 2nd one. ''' async def handler(request): # It's tricky to catch exceptions from the server, so exceptions are # logged instead. try: ws = await request.accept() # Send event 1 event = { 'method': 'Page.domContentEventFired', 'params': {'timestamp': 1}, } logging.info('Server sending: %r', event) await ws.send_message(json.dumps(event)) # Send event 2 event = { 'method': 'Page.loadEventFired', 'params': {'timestamp': 2}, } logging.info('Server sending: %r', event) await ws.send_message(json.dumps(event)) except Exception: logging.exception('Server exception') server = await start_server(nursery, handler) async with open_cdp_connection(server) as conn: async with conn.wait_for(page.LoadEventFired) as event: # In real code we would do something here to trigger a load event, # e.g. clicking a link. pass assert isinstance(event.value, page.LoadEventFired) assert event.value.timestamp == 2