多重遠端控制
WebdriverIO 允許您在單一測試中執行多個自動化工作階段。當您測試需要多個使用者的功能時(例如,聊天或 WebRTC 應用程式),這會非常方便。
您可以使用單一的 多重遠端控制 實例,同時控制所有瀏覽器,而不需要建立多個遠端實例,然後在每個實例上執行像 newSession
或 url
之類的通用指令。
若要執行此操作,只需使用 multiremote()
函式,並傳入一個物件,其中名稱為鍵,而值為 capabilities
。透過為每個功能指定名稱,您可以在單一實例上執行指令時,輕鬆選取和存取該單一實例。
多重遠端控制 並非 設計用於平行執行所有測試。它旨在協助協調多個瀏覽器和/或行動裝置,以進行特殊的整合測試(例如,聊天應用程式)。
所有多重遠端控制實例都會傳回結果陣列。第一個結果代表功能物件中定義的第一個功能,第二個結果代表第二個功能,依此類推。
使用獨立模式
以下範例說明如何在獨立模式中建立多重遠端控制實例
import { multiremote } from 'webdriverio'
(async () => {
const browser = await multiremote({
myChromeBrowser: {
capabilities: {
browserName: 'chrome'
}
},
myFirefoxBrowser: {
capabilities: {
browserName: 'firefox'
}
}
})
// open url with both browser at the same time
await browser.url('http://json.org')
// call commands at the same time
const title = await browser.getTitle()
expect(title).toEqual(['JSON', 'JSON'])
// click on an element at the same time
const elem = await browser.$('#someElem')
await elem.click()
// only click with one browser (Firefox)
await elem.getInstance('myFirefoxBrowser').click()
})()
使用 WDIO 測試執行器
若要在 WDIO 測試執行器中使用多重遠端控制,只需在 wdio.conf.js
中將 capabilities
物件定義為以瀏覽器名稱為鍵的物件(而不是功能清單)即可。
export const config = {
// ...
capabilities: {
myChromeBrowser: {
capabilities: {
browserName: 'chrome'
}
},
myFirefoxBrowser: {
capabilities: {
browserName: 'firefox'
}
}
}
// ...
}
這將會使用 Chrome 和 Firefox 建立兩個 WebDriver 工作階段。除了 Chrome 和 Firefox,您也可以使用 Appium 啟動兩個行動裝置,或啟動一個行動裝置和一個瀏覽器。
您也可以將瀏覽器功能物件放在陣列中,以平行執行多重遠端控制。請務必在每個瀏覽器中加入 capabilities
欄位,因為這是我們區分每個模式的方式。
export const config = {
// ...
capabilities: [{
myChromeBrowser0: {
capabilities: {
browserName: 'chrome'
}
},
myFirefoxBrowser0: {
capabilities: {
browserName: 'firefox'
}
}
}, {
myChromeBrowser1: {
capabilities: {
browserName: 'chrome'
}
},
myFirefoxBrowser1: {
capabilities: {
browserName: 'firefox'
}
}
}]
// ...
}
您甚至可以將其中一個雲端服務後端與本機 Webdriver/Appium 或 Selenium 獨立實例一起啟動。如果您在瀏覽器功能中指定 bstack:options
(Browserstack)、sauce:options
(SauceLabs)或 tb:options
(TestingBot),WebdriverIO 會自動偵測雲端後端功能。
export const config = {
// ...
user: process.env.BROWSERSTACK_USERNAME,
key: process.env.BROWSERSTACK_ACCESS_KEY,
capabilities: {
myChromeBrowser: {
capabilities: {
browserName: 'chrome'
}
},
myBrowserStackFirefoxBrowser: {
capabilities: {
browserName: 'firefox',
'bstack:options': {
// ...
}
}
}
},
services: [
['browserstack', 'selenium-standalone']
],
// ...
}
這裡可以使用任何類型的作業系統/瀏覽器組合(包括行動和桌面瀏覽器)。您的測試透過 browser
變數呼叫的所有指令都會在每個實例中平行執行。這有助於簡化您的整合測試,並加快其執行速度。
例如,如果您開啟 URL
browser.url('https://socketio-chat-h9jt.herokuapp.com/')
每個指令的結果都會是一個物件,其中瀏覽器名稱為鍵,而指令結果為值,如下所示
// wdio testrunner example
await browser.url('https://www.whatismybrowser.com')
const elem = await $('.string-major')
const result = await elem.getText()
console.log(result[0]) // returns: 'Chrome 40 on Mac OS X (Yosemite)'
console.log(result[1]) // returns: 'Firefox 35 on Mac OS X (Yosemite)'
請注意,每個指令都是依序執行。這表示當所有瀏覽器都執行指令後,指令才會完成。這很有幫助,因為它會讓瀏覽器動作保持同步,讓您更容易了解目前正在發生的事情。
有時候,必須在每個瀏覽器中執行不同的動作,才能測試某些內容。例如,如果我們要測試聊天應用程式,就必須有一個瀏覽器傳送簡訊,而另一個瀏覽器則等待接收訊息,然後對其執行判斷提示。
使用 WDIO 測試執行器時,它會將瀏覽器名稱及其對應的實例註冊到全域範圍
const myChromeBrowser = browser.getInstance('myChromeBrowser')
await myChromeBrowser.$('#message').setValue('Hi, I am Chrome')
await myChromeBrowser.$('#send').click()
// wait until messages arrive
await $('.messages').waitForExist()
// check if one of the messages contain the Chrome message
assert.true(
(
await $$('.messages').map((m) => m.getText())
).includes('Hi, I am Chrome')
)
在此範例中,一旦 myChromeBrowser
實例點擊 #send
按鈕,myFirefoxBrowser
實例就會開始等待訊息。
無論您是想要讓多個瀏覽器平行執行相同的動作,還是協同執行不同的動作,多重遠端控制都能讓您輕鬆方便地控制多個瀏覽器。
使用瀏覽器物件透過字串存取瀏覽器實例
除了透過其全域變數(例如 myChromeBrowser
、myFirefoxBrowser
)存取瀏覽器實例之外,您也可以透過 browser
物件存取它們,例如 browser["myChromeBrowser"]
或 browser["myFirefoxBrowser"]
。您可以使用 browser.instances
取得所有實例的清單。當撰寫可以在任一瀏覽器中執行的可重複使用測試步驟時,這特別有用,例如:
wdio.conf.js
capabilities: {
userA: {
capabilities: {
browserName: 'chrome'
}
},
userB: {
capabilities: {
browserName: 'chrome'
}
}
}
Cucumber 檔案
When User A types a message into the chat
步驟定義檔案
When(/^User (.) types a message into the chat/, async (userId) => {
await browser.getInstance(`user${userId}`).$('#message').setValue('Hi, I am Chrome')
await browser.getInstance(`user${userId}`).$('#send').click()
})
擴充 TypeScript 類型
如果您使用 TypeScript,而且想要直接從多重遠端控制物件存取驅動程式實例,您也可以擴充多重遠端控制類型來執行此操作。例如,假設有以下功能
export const config: WebdriverIO.MultiremoteConfig = {
// ...
capabilities: {
myAppiumDriver: {
// ...
},
myChromeDriver: {
// ...
}
}
// ...
}
您可以透過新增自訂驅動程式名稱來擴充多重遠端控制實例,例如:
declare namespace WebdriverIO {
interface MultiRemoteBrowser {
myAppiumDriver: WebdriverIO.Browser
myChromeDriver: WebdriverIO.Browser
}
}
現在您可以直接透過例如以下方式存取驅動程式:
multiremotebrowser.myAppiumDriver.$$(...)
multiremotebrowser.myChromeDriver.$(...)