跳至主要内容

多远程

WebdriverIO 允许您在一个测试中运行多个自动化会话。当您测试需要多个用户的功能(例如,聊天或 WebRTC 应用程序)时,这会变得很方便。

与其创建几个远程实例,您需要在每个实例上执行诸如newSessionurl之类的常用命令,不如简单地创建一个多远程实例并同时控制所有浏览器。

为此,只需使用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:optionsBrowserstack)、sauce:optionsSauceLabs)或tb:optionsTestingBot)中的任何一个,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按钮后开始等待消息。

多远程使控制多个浏览器变得容易且方便,无论您是想让它们并行执行相同操作,还是想让它们协调执行不同的操作。

通过浏览器对象使用字符串访问浏览器实例

除了通过其全局变量(例如myChromeBrowsermyFirefoxBrowser)访问浏览器实例外,您还可以通过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.$(...)

欢迎!我如何帮助您?

WebdriverIO AI Copilot