Chrome DevTools 作为自动化协议
在过去几年中,许多新的测试框架不断涌现,它们提供了不同的功能,但也存在一定的局限性。虽然像Selenium这样的工具通常被认为速度慢且不稳定,而其他工具如Cypress.io或Puppeteer则被吹捧为测试领域的未来。实际上,所有工具都有其自身的用例,具有不同级别的支持,并且基于完全不同的架构。比较它们是毫无意义的,因为这最终相当于在比较苹果和橙子。在较大的测试套件中,使用所有这些工具都可能发生不稳定性和竞争条件,因此我们可以肯定地说,到目前为止,没有任何工具(包括 WebdriverIO)找到了解决世界/(domin|autom)ation/
问题的最终方案。
从 WebdriverIO v9 开始,此博文中宣布的功能已弃用。
归根结底,自动化浏览器的方法主要有两种。一种是使用称为WebDriver的官方 W3C 网络标准,另一种是如今一些浏览器公开的原生浏览器接口。WebDriver 协议是事实上的标准自动化技术,它不仅允许您自动化所有桌面浏览器,还可以对包括移动设备、桌面应用程序甚至智能电视在内的任意用户代理运行自动化。如果您不使用 WebDriver,您的自动化框架很可能使用原生浏览器接口来运行其自动化操作。虽然在过去每个浏览器都有自己的(通常未记录的)协议,但如今许多浏览器,包括 Chrome、Edge 以及很快的 Firefox,都配备了一个与称为Chrome DevTools 协议的协议非常接近的统一接口。虽然 WebDriver 提供了真正的跨浏览器支持,并允许您使用像Sauce Labs这样的供应商在云端大规模运行测试,但原生浏览器接口通常允许更多自动化功能,例如侦听和交互网络或 DOM 事件,而通常仅限于单个浏览器。
随着 WebdriverIO v5.13 的发布,我们现在引入了新的选项,允许您为测试指定自动化协议并利用两全其美的优势。这样,您现在可以决定是使用 WebDriver 还是 Chrome DevTools(通过 Puppeteer)运行测试。对于您的测试来说,实际上没有任何变化,只是自动化使用了不同的技术。我们创建了一个新的 NPM 包,我们称之为devtools
,它实现了所有 WebDriver 命令,但使用 Puppeteer 执行它们。这是一种新型插件,它甚至允许您构建自己的基于 WebDriver 的自动化包,以使用 WebdriverIO 自动化任意设备。新的选项称为automationProtocol
,它期望一个字符串,默认设置为"webdriver"
,以便使用 WebdriverIO 自身的webdriver
绑定运行自动化。但是,如果您通过以下方式安装新的devtools
包:
$ npm install --save-dev devtools webdriverio
并在选项中设置automationProtocol: 'devtools'
,所有自动化都将通过 Chrome DevTools(更具体地说,是通过 Puppeteer)进行,同时使用相同的 WebdriverIO 命令接口
const { remote } = require('webdriverio')
let client;
(async function () {
client = await remote({
automationProtocol: 'devtools', // CHANGE PROTOCOL HERE
capabilities: { browserName: 'chrome' } // or `browserName: 'firefox'`
})
await client.url('https://webdriverio.node.org.cn')
console.log(await client.getTitle())
await client.deleteSession()
})().catch(async (e) => {
console.error(e.stack)
await client.deleteSession()
})
这对于本地测试尤其有用,因为您不再需要下载浏览器驱动程序,而这通常会导致关于在哪里下载以及如何运行它们的困惑。除此之外,测试的运行速度也会快得多,因为 WebdriverIO 直接连接到浏览器。
如前所述,您现在可以利用使用 WebDriver 大规模运行真正的跨浏览器测试的优势,以及在一个工具中利用 DevTools 的所有其他自动化功能。也就是说,鉴于在会话期间无法切换协议,您可能希望有一组需要 Puppeteer 参与的测试,同时还有一组在云中跨浏览器运行的测试。
为了在测试中访问 Puppeteer,我们引入了一个名为getPuppeteer()
的命令,它返回 Puppeteer 框架的browser 类
。从那里,您可以访问 Puppeteer 接口及其所有其他类。请注意,这些接口提供的命令仅基于 Promise,并且 WebdriverIO 不会像您使用 WDIO 测试运行器那样包装它们。在这种情况下,我们建议在call
命令中手动包装所有 Puppeteer 命令调用,以确保在继续执行其他命令之前所有 Promise 都已解决。例如,以下脚本显示了如何在 WDIO 测试运行器世界中使用 Puppeteer 通过devtools
自动化协议使用 WebdriverIO
describe('my e2e tests', () => {
// ...
it('replaces the WebdriverIO logo with the Puppeteer logo', () => {
browser.url('https://webdriverio.node.org.cn')
/**
* run Puppeteer code with promises to intercept network requests
* and replace the WebdriverIO logo in the docs with the Puppeteer logo
*/
browser.call(async () => {
const puppeteerBrowser = browser.getPuppeteer()
const page = (await puppeteerBrowser.pages())[0]
await page.setRequestInterception(true)
page.on('request', interceptedRequest => {
if (interceptedRequest.url().endsWith('webdriverio.png')) {
return interceptedRequest.continue({
url: 'https://user-images.githubusercontent.com/10379601/29446482-04f7036a-841f-11e7-9872-91d1fc2ea683.png'
})
}
interceptedRequest.continue()
})
})
// continue with sync WebdriverIO commands
browser.refresh()
browser.pause(2000)
})
// ...
})
我们还确保您可以将devtools
自动化协议与 WDIO 测试运行器服务(如@wdio/devtools-service
)一起使用,以使体验尽可能无缝。您可以在 WebdriverIO 的示例目录中找到在独立模式下运行的完整脚本示例。
我们建议仅在您的功能测试需要 WebDriver 未提供的某种自动化功能时才在 devtools 协议上运行测试。在本地运行测试时切换到devtools
也是有意义的,因为测试执行速度会快得多。如果您遵循我们的最佳实践,您应该根据环境(例如本地测试与针对 Sauce Labs 或在您的网格中运行测试)拆分您的 wdio 配置文件。您现在可以拥有一个配置,该配置定义了一组需要某些 Puppeteer 交互的测试
// wdio.devtools.conf.js
const { config } = require('./wdio.conf.js')
exports.config = Object.assign(config, {
/**
* set automation protocol to devtools
*/
automationProtocol: 'devtools',
/**
* define a set of tests that require Puppeteer involvement
*/
specs: [
'tests/e2e/devtools/**'
],
/**
* run tests only on Firefox and Chrome in headless mode
*/
capabilities: [{
browserName: 'chrome',
'goog:chromeOptions': {
headless: true
}
}, {
browserName: 'firefox',
'moz:firefoxOptions': {
headless: true
}
}]
// other specific options ...
})
使用新的automationProtocol
选项,我们已将项目扩展到 WebDriver 之外的自动化技术。使用这两种方法都有优点和缺点,并且通过此功能,我们允许您在一个工具中使用这两种方法。devtools 包
仍在开发中,我们将在未来几周内完成其所有功能。如果您对此有任何反馈、错误或意见,请通过Twitter或我们的社区Discord服务器与我们联系。
谢谢!