跳至主要内容

WebdriverIO v8 发布

·阅读时长 10 分钟

虽然花费的时间比预期长了一些,但 WebdriverIO 团队很高兴地宣布我们终于在今天发布了v8!🎉 🎉 🎉

与几乎所有最近的主要更新一样,我们再次不得不修改项目的每个文件。这次我们新版本的主要目标是最终从 CommonJS 迁移到 ESM,这使我们能够继续进行重要的依赖项更新并避免安全问题。此外,我们清理了一些技术债务,例如,删除了与同步命令执行相关的所有代码(该代码已于去年弃用),以及实现了新的 Action API 接口,并简化了 WebdriverIO 使用测试运行器处理全局对象的方式。

在这篇博文中,我们将介绍每个重要的更改,并解释您需要执行哪些操作才能升级到v8。剧透警告:在大多数情况下,无需更新您的测试😉

放弃 Node.js v12、v13 和 v14 支持

我们已放弃对 Node v12 和 v14 的支持,后者在 2021 年 10 月被 Node.js 团队移至维护 LTS 阶段。虽然从技术上讲可以继续使用 Node.js v14,但我们没有看到您不直接更新到 Node.js v16 或理想情况下 v18 的理由。

要更新 Node.js,了解它最初是如何安装的非常重要。如果您处于 Docker 环境中,您只需像这样升级基础镜像:

- FROM mhart/alpine-node:14
+ FROM mhart/alpine-node:18

我们建议使用NVM(Node 版本管理器)来安装和管理 Node.js 版本。您可以在其项目自述文件中找到有关如何安装 NVM 和更新 Node 的详细说明。

从 CommonJS 迁移到 ESM

向新的模块系统的迁移是与本次发布相关的最大工作量。它要求我们更新所有模块导入,从Jest迁移到Vitest作为单元测试框架,并重写代码库中的各个部分。虽然这影响了每个文件,但它“应该”对您来说是不可识别的。如果您的项目仍然使用 CommonJS,WebdriverIO 将正常工作,因为这两个模块系统都继续受支持。当使用webdriverdevtoolswebdriverio作为模块时,情况也是如此。

如果您一直只使用 Babel 来在测试中使用import语句,则可以删除该集成,因为 ESM 现在原生支持它。如果您想继续使用 CommonJS 和require,那也可以,无需进行任何更改即可更新到v8

浏览器中用于单元和组件测试的新运行器

如果说我们对本次发布真正感到兴奋的一个功能,那就是新的浏览器运行器🙌在过去的一年中,我编写并测试了许多 Web 组件,并且一直对它们针对JSDOM而不是实际浏览器进行测试感到沮丧。JSDOM 是 Node.js 中许多 Web API 的重新实现,并且是简单测试的绝佳工具,但它不能替代浏览器中的实际 DOM 实现。特别是将 JSDOM 用于组件测试与在浏览器中运行测试相比具有各种缺点

此外,通过 WebdriverIO 运行组件测试允许无缝地使用 WebdriverIO API,并通过WebDriver 协议实现与组件的真实用户交互。与通过 JavaScript 发出交互相比,这使得这些交互更加真实。它还对流行的实用程序框架(例如Testing Library)提供了一流的支持,并允许交替使用这两个 API。查看如何使用 Testing Library 进行渲染和获取元素,同时使用 WebdriverIO 与组件进行交互

vue.test.ts
import { $, expect } from '@wdio/globals'
import { render } from '@testing-library/vue'
import Component from './components/Component.vue'

describe('Vue Component Testing', () => {
it('increments value on click', async () => {
// The render method returns a collection of utilities to query your component.
const { getByText } = render(Component)

// getByText returns the first matching node for the provided text, and
// throws an error if no elements match or if more than one match is found.
getByText('Times clicked: 0')

const button = await $(getByText('increment'))

// Dispatch a native click event to our button element.
await button.click()
await button.click()

getByText('Times clicked: 2') // assert with Testing Library
await expect($('p=Times clicked: 2')).toExist() // assert with WebdriverIO
})
})

新的浏览器运行器允许您在浏览器中而不是在 Node.js 中加载和执行测试。这使您可以访问所有 Web API 以渲染 Web 组件或运行前端模块的单元测试。在幕后,它使用Vite加载所有依赖项并使集成变得无缝。

如果您一直使用Karma在浏览器中运行单元测试,则可以切换到 WebdriverIO,它提供相同的功能,但对其他服务和报告程序提供更好的支持和集成。似乎 Karma 项目现在维护得不多,并且存在未解决的安全漏洞

新的 Action 接口

多年来,喜欢使用 WebDriver 的actions API在其应用程序上运行更复杂交互的用户必须了解许多有关该命令的详细信息才能构建正确的有效负载。使用 WebdriverIO 的v8,我们现在提供了一个新的接口,使执行各种操作变得更加容易。

使用两个新的浏览器命令:actionactions,现在运行正确的操作(例如,向浏览器发送键盘事件)变得更加简单且类型安全

await browser.action('key')
.down('f').up('f')
.down('o').up('o')
.down('o').up('o')
.perform()

WebdriverIO API中阅读有关新 Action 接口的更多信息。

WebDriver BiDi 支持

与其他工具相比使用 WebdriverIO 的一个有力论据是,它基于WebDriver 协议,该协议是用于自动化浏览器的 Web 标准。它保证能够在用户使用的浏览器中运行测试,而不是浏览器引擎,这在功能和安全方面可能与之大不相同。W3C 工作组一直在开发该协议的新版本,该版本将启用更好的自检功能和新的自动化原语。

通过此版本,用户可以在浏览器中提供这些新的协议功能时开始访问它们。随着时间的推移,更多命令将在后台迁移到新的协议,而接口保持不变。我们都对该协议将提供的新的功能和机会感到非常兴奋,例如,在运行测试时侦听日志事件,例如:

await browser.send({
method: 'session.subscribe',
params: { events: ['log.entryAdded'] }
})

/**
* returns:
* {
* "method":"log.entryAdded",
* "params":{
* "type":"console",
* "method":"log",
* "realm":null,
* "args":[
* {
* "type":"string",
* "value":"Hello Bidi"
* }
* ],
* "level":"info",
* "text":"Hello Bidi",
* "timestamp":1657282076037
* }
* }
*/
browser.on('message', (data) => console.log('received %s', data))

/**
* trigger listener
*/
await browser.execute(() => console.log("Hello Bidi"))

我们正在跟踪和支持所有浏览器供应商的开发,以确保新功能按预期工作,并且可以通过精简的用户界面使用。有关此主题的更多信息,请查看我在浏览器自动化的演变上的演讲。

可选全局变量

使用 WebdriverIO 测试运行器时,它通常会将browser对象或$$$命令注册到全局作用域,因为在编写测试时通常会经常使用它们。但是,将对象附加到全局作用域不被视为最佳实践,并且当其他模块决定执行相同的操作时可能会导致副作用。因此,使用v8,现在由用户决定他们是否希望继续将这些对象和方法附加到全局作用域,或者更喜欢通过以下方式直接导入它们:

import { browser, $, $$, expect } from '@wdio/globals'

一个名为injectGlobals(默认值:true)的新配置属性处理测试运行器是否修改全局作用域。如果您的设置使用全局对象可以正常工作,则无需进行任何更改即可更新到v8。但是,我们建议直接导入 WebdriverIO 相关的接口,以确保不会发生任何副作用。

注意:如果您使用的是 TypeScript,则需要更新tsconfig.json以反映对 WebdriverIO 类型位置所做的更改。这些现在是@wdio/globals包的一部分

{
"compilerOptions": {
"types": [
"node",
- "webdriverio/async"
+ "@wdio/globals/types"
]
}
}

其他

除了这些主要更新之外,团队还花费时间改进文档,并引入了围绕 WebdriverIO 对象(如 browserelementmock)的新 API 文档。此外,我们移除了 browser 对象中的 config 属性。如果您之前一直使用它来访问 WDIO 配置中的数据,我们建议您将其替换为 options,例如:

- browser.config.hostname
+ browser.options.hostname

此外,我们修复了相对 spec 或 exclude 路径的行为。在 v8 之前,specsexclude--spec 中的每个路径始终被视为相对于用户的当前工作目录。这种行为令人困惑,尤其是在 wdio.conf.js 不在项目根目录时。此问题现已修复,因此 specsexclude 路径将始终被视为相对于配置文件,而 --spec 参数则相对于当前工作目录。

最后,我们不得不移除对 tsconfig-paths 的支持,因为我们还没有找到在 ESM 上下文中使其工作的方法。我们认为这种集成本来使用就不多,而且现在 TypeScript 本身就原生支持了很多功能。如果您认为我们的假设错误,并且希望看到它再次得到支持,请告诉我们。

接下来是什么?

WebdriverIO 团队对这次发布感到非常兴奋,因为它为我们腾出时间开始开发一些我们放在 路线图 上的新酷功能。几个月来,我们一直在秘密开发一个 VS Code 扩展,它可以使测试的编写和调试变得更加容易。除此之外,还有很多工作要做,以及探索的机会来使这个项目变得更好。我们欢迎并支持所有愿意加入我们的人。

最后,我要感谢所有支持该项目的人。不仅包括通过 Open CollectiveTidelift 提供资金支持的人,还包括所有贡献代码、想法、报告问题或在我们的 支持聊天 中提供帮助的人,无论他们偶尔提供帮助还是定期提供帮助。如果没有社区的贡献,这个项目将无法发展。除了许多替代项目之外,WebdriverIO 没有资金支持,也没有任何公司利益驱动,并且始终保持 100% 的社区治理。资金短缺或对资本收益的需求都不会对这个项目产生影响。从 10 多年前开始就是这样,未来很多年也将继续保持这种状态。因此,我们一直在寻找有兴趣帮助我们改进项目的人。如果您还没有加入,请参加我们的 公开办公时间,并考虑回馈项目。

我期待着未来更多年和更多伟大的功能。感谢您的阅读!

欢迎!我如何帮助您?

WebdriverIO AI Copilot