WebdriverIO v8 發布
雖然比預期的時間長了一些,但 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 Version Manager) 來安裝和管理 Node.js 版本。您可以在他們的專案說明檔中找到關於如何安裝 NVM 和更新 Node 的詳細說明。
CommonJS 至 ESM 的轉換
轉換到新的模組系統是與此版本相關的最大一塊工作。這需要我們更新所有的模組匯入,從 Jest 轉換到 Vitest 作為單元測試框架,並重寫程式碼庫中的各個部分。雖然這影響了每個檔案,但對您來說「應該」是無法辨識的。如果您的專案仍然使用 CommonJS,WebdriverIO 仍然可以正常運作,因為這兩種模組系統都將繼續受到支援。當使用 webdriver
、devtools
或 webdriverio
作為模組時也是如此。
如果您一直以來都只為了在測試中使用 import
陳述式而使用 Babel,那麼您可以移除此整合,因為 ESM 現在原生支援此功能。如果您喜歡繼續使用 CommonJS 和 require
,那也沒問題,不需要進行任何變更即可更新到 v8
。
用於瀏覽器中單元和元件測試的新執行器
如果說這個版本中我們真正感到興奮的一項功能,那就是新的瀏覽器執行器 🙌 我在過去一年中撰寫和測試了許多 Web 元件,並且一直對以下事實感到沮喪:它們將針對 JSDOM 而不是實際的瀏覽器進行測試。JSDOM 是許多 Node.js 中 Web API 的重新實作,並且是簡單測試的絕佳工具,但它並不能取代瀏覽器中的實際 DOM 實作。尤其是在使用 JSDOM 進行元件測試時,與在瀏覽器中執行測試相比,存在各種缺點。
此外,透過 WebdriverIO 執行元件測試,可以順暢地使用 WebdriverIO API,並透過 WebDriver 協定,實現與您的元件進行真實的使用者互動。這使得這些互動比透過 JavaScript 發射它們更為真實。它還為熱門的公用程式框架(例如 Testing Library)提供一流的支援,並允許交替使用這兩種 API。查看如何使用 Testing Library 進行渲染和擷取元素,同時使用 WebdriverIO 與元件互動
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 專案最近也沒有太多維護,並且存在未解決的安全漏洞。
新的動作介面
多年來,喜歡使用 WebDriver 的 動作 API 在應用程式上執行更複雜互動的使用者,必須了解有關命令的許多詳細資訊,才能建構正確的酬載。在 WebdriverIO 的 v8
中,我們現在提供新的介面,讓執行各種動作變得更加容易。
有了兩個新的瀏覽器命令:action
和 actions
,現在執行正確的動作(例如,向瀏覽器傳送按鍵事件)更加簡單且類型安全
await browser.action('key')
.down('f').up('f')
.down('o').up('o')
.down('o').up('o')
.perform()
在 WebdriverIO API 中閱讀更多關於新的動作介面的資訊。
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 物件的新 API 文件,例如 browser
、element
和 mock
。此外,我們從 browser
物件中移除了 config
屬性。如果您一直使用它來存取 WDIO 配置中的資料,我們建議將其替換為 options
,例如:
- browser.config.hostname
+ browser.options.hostname
此外,我們修正了相對 spec 或排除路徑的行為。在 v8
之前,specs
、exclude
或 --spec
中的每個路徑都被視為相對於使用者的工作目錄。這種行為令人困惑,特別是當 wdio.conf.js
不在您的專案根目錄時。現在已修正此問題,因此 specs
和 exclude
路徑將始終被視為相對於設定檔,而 --spec
引數則相對於工作目錄。
最後,我們不得不移除對 tsconfig-paths 的支援,因為我們還沒有找到在 ESM 環境中使其運作的方法。我們認為這個整合並沒有被廣泛使用,而且現在 TypeScript 本身已經原生支援很多功能。如果這個假設錯誤,並且您希望看到再次支援它,請告訴我們。
接下來是什麼?
WebdriverIO 團隊對此版本感到非常興奮,因為它可以釋放時間開始開發我們放在路線圖上的一些新酷功能。我們已經秘密開發了幾個月的 VS Code 擴充功能,這使得編寫和偵錯測試變得更加容易。除此之外,總是有很多工作要做和機會去探索,以使這個專案變得更好。我們歡迎並支持每個想加入我們的人。
最後,我要感謝所有支持該專案的人。不僅是透過 Open Collective 或 Tidelift 在財務上做出貢獻的人,還有每個貢獻程式碼、想法、回報問題或在我們的 支援聊天中偶爾或定期支持他人的人。沒有社群的貢獻,這個專案無法發展。除了許多替代專案之外,WebdriverIO 並非由任何企業利益資助或推動,而是 100% 由社群管理。資金不足或需要資本收益不會對這個專案產生影響。自 10 多年前成立以來,情況一直是如此,並且未來許多年都將如此。因此,我們一直在尋找有興趣協助我們開發這個專案的人。如果您還沒有加入,請參加我們的開放辦公時間並考慮回饋專案。
我期待未來更多年和更多精彩的功能。感謝您的閱讀!