Пользовательские Команды
Если вы хотите расширить экземпляр browser своим собственным набором команд, метод браузера addCommand поможет вам в этом. Вы можете написать свою команду асинхронно, как и в ваших спецификациях.
Параметры
Имя команды
Имя, которое определяет команду и будет прикреплено к области видимости браузера или элемента.
Тип: String
Пользовательская функция
Функция, которая выполняется при вызове команды. Область видимости this - это либо WebdriverIO.Browser, либо WebdriverIO.Element, в зависимости от того, прикрепляется ли команда к области видимости браузера или элемента.
Тип: Function
Опции
Объект с опциями конфигурации, изменяющими поведение пользовательской команды
Целевая область
Флаг для определения, прикреплять ли команду к области видимости браузера или элемента. Если установлено значение true, команда будет командой элемента.
Имя опции: attachToElement
Тип: Boolean
По умолчанию: false
Отключение implicitWait
Флаг для определения, нужно ли неявно ожидать существования элемента перед вызовом пользовательской команды.
Имя опции: disableElementImplicitWait
Тип: Boolean
По умолчанию: false
Примеры
Этот пример показывает, как добавить новую команду, которая возвращает текущий URL и заголовок как один результат. Область видимости (this) - это объект WebdriverIO.Browser.
browser.addCommand('getUrlAndTitle', async function (customVar) {
// `this` относится к области видимости `browser`
return {
url: await this.getUrl(),
title: await this.getTitle(),
customVar: customVar
}
})
Кроме того, вы можете расширить экземпляр элемента своим собственным набором команд, передав true в качестве последнего аргумента. Область видимости (this) в этом случае - объект WebdriverIO.Element.
browser.addCommand("waitAndClick", async function () {
// `this` - это возвращаемое значение $(selector)
await this.waitForDisplayed()
await this.click()
}, { attachToElement: true })
По умолчанию пользовательские команды элементов ожидают существования элемента перед вызовом пользовательской команды. Хотя в большинстве случаев это желательно, если нет, это можно отключить с помощью disableImplicitWait:
browser.addCommand("waitAndClick", async function () {
// `this` - это возвращаемое значение $(selector)
await this.waitForExists()
await this.click()
}, { attachToElement: true, disableElementImplicitWait: true })
Пользовательские команды дают вам возможность объединить определенную последовательность часто используемых команд в один вызов. Вы можете определить пользовательские команды в любой момент вашего набора тестов; просто убедитесь, что команда определена до ее первого использования. (Хук before в вашем wdio.conf.js - хорошее место для их создания.)
После определения вы можете использовать их следующим образом:
it('should use my custom command', async () => {
await browser.url('http://www.github.com')
const result = await browser.getUrlAndTitle('foobar')
assert.strictEqual(result.url, 'https://github.com/')
assert.strictEqual(result.title, 'GitHub · Where software is built')
assert.strictEqual(result.customVar, 'foobar')
})
Примечание: Если вы регистрируете пользовательскую команду в области видимости browser, команда не будет доступна для элементов. Аналогично, если вы регистрируете команду в области видимости элемента, она не будет доступна в области видимости browser:
browser.addCommand("myCustomBrowserCommand", () => { return 1 })
const elem = await $('body')
console.log(typeof browser.myCustomBrowserCommand) // выводит "function"
console.log(typeof elem.myCustomBrowserCommand()) // выводит "undefined"
browser.addCommand("myCustomElementCommand", () => { return 1 }, { attachToElement: true })
const elem2 = await $('body')
console.log(typeof browser.myCustomElementCommand) // выводит "undefined"
console.log(await elem2.myCustomElementCommand('foobar')) // выводит "1"
const elem3 = await $('body')
elem3.addCommand("myCustomElementCommand2", () => { return 2 })
console.log(typeof browser.myCustomElementCommand2) // выводит "undefined"
console.log(await elem3.myCustomElementCommand2('foobar')) // выводит "2"
Примечание: Если вам нужно цепочкой связывать пользовательскую команду, команда должна заканчиваться символом $,
browser.addCommand("user$", (locator) => { return ele })
browser.addCommand("user$", (locator) => { return ele }, { attachToElement: true })
await browser.user$('foo').user$('bar').click()
Будьте осторожны, чтобы не перегружать область видимости browser слишком большим количеством пользовательских команд.
Мы рекомендуем определять пользовательскую логику в объектах страниц, чтобы они были привязаны к конкретной странице.
Multiremote
addCommand работает аналогично для multiremote, за исключением того, что новая команда будет распространяться на дочерние экземпляры. Вы должны быть осторожны при использовании объекта this, так как multiremote browser и его дочерние экземпляры имеют разные this.
Этот пример показывает, как добавить новую команду для multiremote.
import { multiRemoteBrowser } from '@wdio/globals'
multiRemoteBrowser.addCommand('getUrlAndTitle', async function (this: WebdriverIO.MultiRemoteBrowser, customVar: any) {
// `this` относится к:
// - MultiRemoteBrowser области для браузера
// - Browser области для экземпляров
return {
url: await this.getUrl(),
title: await this.getTitle(),
customVar: customVar
}
})
multiRemoteBrowser.getUrlAndTitle()
/*
{
url: [ 'https://webdriver.io/', 'https://webdriver.io/' ],
title: [
'WebdriverIO · Next-gen browser and mobile automation test framework for Node.js | WebdriverIO',
'WebdriverIO · Next-gen browser and mobile automation test framework for Node.js | WebdriverIO'
],
customVar: undefined
}
*/
multiRemoteBrowser.getInstance('browserA').getUrlAndTitle()
/*
{
url: 'https://webdriver.io/',
title: 'WebdriverIO · Next-gen browser and mobile automation test framework for Node.js | WebdriverIO',
customVar: undefined
}
*/
Расширение определений типов
С TypeScript легко расширять интерфейсы WebdriverIO. Добавьте типы к вашим пользовательским командам следующим образом:
-
Создайте файл определения типов (например,
./src/types/wdio.d.ts) -
a. Если вы используете файл определения типов в стиле модуля (используя import/export и
declare global WebdriverIOв файле определения типов), убедитесь, что путь к файлу включен в свойствоincludeвtsconfig.json.b. Если вы используете файлы определения типов в окружающем стиле (без import/export в файлах определения типов и
declare namespace WebdriverIOдля пользовательских команд), убедитесь, чтоtsconfig.jsonне содержит разделinclude, так как это приведет к тому, что все файлы определения типов, не перечисленные в разделеinclude, не будут распознаны TypeScript.
- Модули (используя import/export)
- Окружающие определения типов (без include в tsconfig)
{
"compilerOptions": { ... },
"include": [
"./test/**/*.ts",
"./src/types/**/*.ts"
]
}
{
"compilerOptions": { ... }
}
- Добавьте определения для ваших команд в соответствии с режимом выполнения.
- Модули (используя import/export)
- Окружающие определения типов
declare global {
namespace WebdriverIO {
interface Browser {
browserCustomCommand: (arg: any) => Promise<void>
}
interface MultiRemoteBrowser {
browserCustomCommand: (arg: any) => Promise<void>
}
interface Element {
elementCustomCommand: (arg: any) => Promise<number>
}
}
}
declare namespace WebdriverIO {
interface Browser {
browserCustomCommand: (arg: any) => Promise<void>
}
interface MultiRemoteBrowser {
browserCustomCommand: (arg: any) => Promise<void>
}
interface Element {
elementCustomCommand: (arg: any) => Promise<number>
}
}