多远程
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')
)
在此示例中,myFirefoxBrowser
实例将在myChromeBrowser
实例单击#send
按钮后开始等待消息。
多远程使控制多个浏览器变得容易且方便,无论您是想让它们并行执行相同操作,还是想让它们协调执行不同的操作。
通过浏览器对象使用字符串访问浏览器实例
除了通过其全局变量(例如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.$(...)