如何使用 python selenium RemoteWebDriver 从 Chrome DevTools Protocol (cdp) 收集性能指标?

问题描述 投票:0回答:1

我有一组现有的前端自动化测试,它们在 python 中运行并使用 pytest。我想添加一个自动化测试,当针对基于 chromium 的浏览器运行时,收集性能指标。

假设

browser
RemoteWebdriver
的自定义包装器,并且我无法在这些测试中创建
Chrome
驱动程序。

import pytest

@pytest.mark.chrome_only
def test_lighthouse_performance(browser):
    session = browser.bidi_connection()
    # What do I do now?

seleniumHQ的示例提到了aysnc

,但这与我当前的测试框架不兼容,并且这些方法在
RemoteWebdriver
类中不存在。

此外,没有任何关于使用

bidi_connection()

 方法作为远程网络驱动程序的文档。 bidi_api 文档页面同样没有帮助。
    

python selenium-webdriver selenium-chromedriver ui-automation
1个回答
0
投票
我最终弄清楚了这一点,但这是大量的试验和错误,因为 CDP 文档在 selenium 的 python 方面不是很用户友好。

这个答案将分解我用于获取可行解决方案的资源、我从中提取的代码示例,并以封装该解决方案的带注释的代码片段结束。

  • 文档

    • Chrome 开发者工具协议 (CDP)
    • Selenium 双向功能
    • Pyest 三重奏插件:
    • pytest-trio
  • 有用的代码资源

    • Python 远程网络驱动程序
    • Python CDP 实现
    • CDP 的 Puppeteer TypeScript 实现
  • 代码片段

    import pytest # These imports are not strictly necessary, but they help with # autocompletion/typing in VSCode import selenium.webdriver.remote.webdriver as RemoteWebdriver from selenium.webdriver.common.bidi.cdp import CdpSession import selenium.webdriver.common.devtools.v113 as v113Devtools # The devtools is versioned, you can find the latest version here: https://github.com/SeleniumHQ/selenium/tree/trunk/common/devtools/chromium import trio # Selenium uses trio instead of asyncio @pytest.mark.trio # pytest requires this to run the test with trio async def test_cdp(browser: RemoteWebdriver): # See imports above for typing page = SomePageObject( browser ) # This is a page object I made up, you can use your own (or not) async with browser.bidi_connection() as connection: session: CdpSession = connection.session devtools: v113Devtools = connection.devtools data = {"traceEvents": []} trace_config = ( devtools.tracing.TraceConfig() ) # See documentation links for info on this class # Report events is the default transfer mode, but I'm including it here for clarity # There is also a "ReturnAsStream" mode, but unpacking the stream handler it returns # is beyond the scope of this example (and I don't know how to do it yet) await session.execute( devtools.tracing.start( transfer_mode="ReportEvents", trace_config=trace_config ) ) # it's important to start the tracing and THEN navigate to the page page.navigate() session.execute( devtools.tracing.end() ) # This is the only way to stop the tracing and start the event processing async for dc_event in session.listen( devtools.tracing.DataCollected, devtools.tracing.TracingComplete ): # The DataCollected event is sent for each batch of events, and the TracingComplete event is sent when the tracing is done if type(dc_event) == devtools.tracing.DataCollected: data[ "traceEvents" ] += ( dc_event.value ) # Collect the events and do whatever you want with them if type(dc_event) == devtools.tracing.TracingComplete: break # This is how you stop the event loop # Do whatever you want with the data at this point
    
    
  • 注意事项

© www.soinside.com 2019 - 2024. All rights reserved.