Expect
Під час написання тестів часто потрібно перевіряти, чи відповідають значення певним умовам. expect
надає вам доступ до ряду "матчерів", які дозволяють перевіряти різні речі на об'єктах browser
, element
або mock
.
Параметри за замовчуванням
Ці параметри за замовчуванням пов'язані з опціями waitforTimeout
та waitforInterval
, встановленими в конфігурації.
Встановлюйте наведені нижче параметри лише якщо ви хочете чекати певні проміжки часу для ваших тверджень.
{
wait: 2000, // мс для очікування успішного виконання очікування
interval: 100, // інтервал між спробами
}
Якщо ви хочете встановити різні таймаути та інтервали, встановіть ці параметри так:
// wdio.conf.js
import { setOptions } from 'expect-webdriverio'
export const config = {
// ...
before () {
setOptions({ wait: 5000 })
},
// ...
}
Параметри матчера
Кожен матчер може приймати кілька параметрів, які дозволяють модифікувати твердження:
Параметри команди
Назва | Тип | Деталі |
---|---|---|
wait | number | час в мс для очікування успішного виконання очікування. За замовчуванням: 3000 |
interval | number | інтервал між спробами. За замовчуванням: 100 |
beforeAssertion | function | функція, яка буде викликана перед виконанням твердження |
afterAssertion | function | функція, яка буде викликана після виконання твердження і містить результати твердження |
message | string | повідомлення користувача, яке додається перед помилкою твердження |
Параметри рядка
Ці параметри можна застосувати додатково до параметрів команди, коли перевіряються рядки.
Назва | Тип | Деталі |
---|---|---|
ignoreCase | boolean | застосувати toLowerCase для фактичного та очікуваного значень |
trim | boolean | застосувати trim для фактичного значення |
replace | Replacer | Replacer[] | замінити частини фактичного значення, які відповідають рядку/RegExp. Замінник може бути рядком або функцією. |
containing | boolean | очікувати, що фактичне значення містить очікуване значення, інакше строга рівність. |
asString | boolean | може бути корисним для примусового перетворення значення властивості в рядок |
atStart | boolean | очікувати, що фактичне значення починається з очікуваного значення |
atEnd | boolean | очікувати, що фактичне значення закінчується очікуваним значенням |
atIndex | number | очікувати, що фактичне значення має очікуване значення за вказаним індексом |
Параметри числа
Ці параметри можна застосувати додатково до параметрів команди, коли перевіряються числа.
Назва | Тип | Деталі |
---|---|---|
eq | number | дорівнює |
lte | number | менше або дорівнює |
gte | number | більше або дорівнює |
Обробка HTML-сутностей
HTML-сутність - це фрагмент тексту ("рядок"), який починається з амперсанда (&
) і закінчується крапкою з комою (;
). Сутності часто використовуються для відображення зарезервованих символів (які інакше інтерпретуються як HTML-код) та невидимих символів (таких як нерозривні пробіли, наприклад,
).
Щоб знайти або взаємодіяти з таким елементом, використовуйте Unicode-еквівалент сутності. Наприклад:
<div data="Some Value">Some Text</div>
const myElem = await $('div[data="Some\u00a0Value"]')
await expect(myElem).toHaveAttribute('data', 'div[Some\u00a0Value')
await expect(myElem).toHaveText('Some\u00a0Text')
Ви можете знайти всі Unicode-посилання в HTML-специфікації.
Примітка: Unicode нечутливий до регістру, тому обидва варіанти \u00a0
та \u00A0
працюватимуть. Щоб знайти елемент в інспекторі браузера, видаліть u
з Unicode, наприклад: div[data="Some\00a0Value"]
Матчери для браузера
toHaveUrl
Перевіряє, чи знаходиться браузер на певній сторінці.
Використання
await browser.url('https://webdriver.io/')
await expect(browser).toHaveUrl('https://webdriver.io')
Використання
await browser.url('https://webdriver.io/')
await expect(browser).toHaveUrl(expect.stringContaining('webdriver'))
toHaveTitle
Перевіряє, чи має веб-сайт певний заголовок.
Використання
await browser.url('https://webdriver.io/')
await expect(browser).toHaveTitle('WebdriverIO · Next-gen browser and mobile automation test framework for Node.js')
await expect(browser).toHaveTitle(expect.stringContaining('WebdriverIO'))
toHaveClipboardText
Перевіряє, чи має браузер певний текст, збережений у буфері обміну.
Використання
import { Key } from 'webdriverio'
await browser.keys([Key.Ctrl, 'a'])
await browser.keys([Key.Ctrl, 'c'])
await expect(browser).toHaveClipboardText('some clipboard text')
await expect(browser).toHaveClipboardText(expect.stringContaining('clipboard text'))
Матчери для елементів
toBeDisplayed
Викликає isDisplayed
для вказаного елемента.
Використання
const elem = await $('#someElem')
await expect(elem).toBeDisplayed()
toExist
Викликає isExisting
для вказаного елемента.
Використання
const elem = await $('#someElem')
await expect(elem).toExist()
toBePresent
Те саме, що і toExist
.
Використання
const elem = await $('#someElem')
await expect(elem).toBePresent()
toBeExisting
Те саме, що і toExist
.
Використання
const elem = await $('#someElem')
await expect(elem).toBeExisting()
toBeFocused
Перевіряє, чи має елемент фокус. Це твердження працює тільки в веб-контексті.
Використання
const elem = await $('#someElem')
await expect(elem).toBeFocused()
toHaveAttribute
Перевіряє, чи має елемент певний атрибут з певним значенням.
Використання
const myInput = await $('input')
await expect(myInput).toHaveAttribute('class', 'form-control')
await expect(myInput).toHaveAttribute('class', expect.stringContaining('control'))
toHaveAttr
Те саме, що і toHaveAttribute
.
Використання
const myInput = await $('input')
await expect(myInput).toHaveAttr('class', 'form-control')
await expect(myInput).toHaveAttr('class', expect.stringContaining('control'))
toHaveElementClass
Перевіряє, чи має елемент певний клас. Також може бути викликаний з масивом як параметром, коли елемент може мати кілька класів.
Використання
const myInput = await $('input')
await expect(myInput).toHaveElementClass('form-control', { message: 'Not a form control!' })
await expect(myInput).toHaveElementClass(['form-control' , 'w-full'], { message: 'not full width' })
await expect(myInput).toHaveElementClass(expect.stringContaining('form'), { message: 'Not a form control!' })
toHaveElementProperty
Перевіряє, чи має елемент певну властивість.
Використання
const elem = await $('#elem')
await expect(elem).toHaveElementProperty('height', 23)
await expect(elem).not.toHaveElementProperty('height', 0)
toHaveValue
Перевіряє, чи має елемент введення певне значення.
Використання
const myInput = await $('input')
await expect(myInput).toHaveValue('admin-user', { ignoreCase: true })
await expect(myInput).toHaveValue(expect.stringContaining('user'), { ignoreCase: true })
toBeClickable
Перевіряє, чи можна натиснути на елемент, викликаючи isClickable
для елемента.
Використання
const elem = await $('#elem')
await expect(elem).toBeClickable()
toBeDisabled
Перевіряє, чи вимкнено елемент, викликаючи isEnabled
для елемента.
Використання
const elem = await $('#elem')
await expect(elem).toBeDisabled()
// те саме, що
await expect(elem).not.toBeEnabled()
toBeEnabled
Перевіряє, чи ввімкнено елемент, викликаючи isEnabled
для елемента.
Використання
const elem = await $('#elem')
await expect(elem).toBeEnabled()
// те саме, що
await expect(elem).not.toBeDisabled()
toBeSelected
Перевіряє, чи вибрано елемент, викликаючи isSelected
для елемента.
Використання
const elem = await $('#elem')
await expect(elem).toBeSelected()
toBeChecked
Те саме, що і toBeSelected
.
Використання
const elem = await $('#elem')
await expect(elem).toBeChecked()
toHaveComputedLabel
Перевіряє, чи має елемент певну обчислену WAI-ARIA мітку. Також може бути викликаний з масивом як параметром у випадку, коли елемент може мати різні мітки.
Використання
await browser.url('https://webdriver.io/')
const elem = await $('a[href="https://github.com/webdriverio/webdriverio"]')
await expect(elem).toHaveComputedLabel('GitHub repository')
await expect(elem).toHaveComputedLabel(expect.stringContaining('repository'))
Використання
await browser.url('https://webdriver.io/')
const elem = await $('a[href="https://github.com/webdriverio/webdriverio"]')
await expect(elem).toHaveComputedLabel(['GitHub repository', 'Private repository'])
await expect(elem).toHaveComputedLabel([expect.stringContaining('GitHub'), expect.stringContaining('Private')])
toHaveComputedRole
Перевіряє, чи має елемент певну обчислену WAI-ARIA роль. Також може бути викликаний з масивом як параметром у випадку, коли елемент може мати різні ролі.
Використання
await browser.url('https://webdriver.io/')
const elem = await $('[aria-label="Skip to main content"]')
await expect(elem).toHaveComputedRole('region')
await expect(elem).toHaveComputedRole(expect.stringContaining('ion'))
Використання
await browser.url('https://webdriver.io/')
const elem = await $('[aria-label="Skip to main content"]')
await expect(elem).toHaveComputedRole(['region', 'section'])
await expect(elem).toHaveComputedRole([expect.stringContaining('reg'), expect.stringContaining('sec')])
toHaveHref
Перевіряє, чи має елемент посилання певний цільовий URL.
Використання
const link = await $('a')
await expect(link).toHaveHref('https://webdriver.io')
await expect(link).toHaveHref(expect.stringContaining('webdriver.io'))
toHaveLink
Те саме, що і toHaveHref
.
Використання
const link = await $('a')
await expect(link).toHaveLink('https://webdriver.io')
await expect(link).toHaveLink(expect.stringContaining('webdriver.io'))
toHaveId
Перевіряє, чи має елемент певний атрибут id
.
Використання
const elem = await $('#elem')
await expect(elem).toHaveId('elem')
toHaveText
Перевіряє, чи має елемент певний текст. Також може бути викликаний з масивом як параметром у випадку, коли елемент може мати різні тексти.
Використання
await browser.url('https://webdriver.io/')
const elem = await $('.container')
await expect(elem).toHaveText('Next-gen browser and mobile automation test framework for Node.js')
await expect(elem).toHaveText(expect.stringContaining('test framework for Node.js'))
await expect(elem).toHaveText(['Next-gen browser and mobile automation test framework for Node.js', 'Get Started'])
await expect(elem).toHaveText([expect.stringContaining('test framework for Node.js'), expect.stringContaining('Started')])
У випадку, якщо в div є список елементів:
<ul>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>
Ви можете перевірити їх, використовуючи масив:
const elem = await $$('ul > li')
await expect(elem).toHaveText(['Coffee', 'Tea', 'Milk'])
toHaveHTML
Перевіряє, чи має елемент певний HTML. Також може бути викликаний з масивом як параметром у випадку, коли елемент може мати різні HTML.
Використання
await browser.url('https://webdriver.io/')
const elem = await $('.hero__subtitle')
await expect(elem).toHaveHTML('<p class="hero__subtitle">Next-gen browser and mobile automation test framework for Node.js</p>')
await expect(elem).toHaveHTML(expect.stringContaining('Next-gen browser and mobile automation test framework for Node.js'))
await expect(elem).toHaveHTML('Next-gen browser and mobile automation test framework for Node.js', { includeSelectorTag: false })
Використання
await browser.url('https://webdriver.io/')
const elem = await $('.hero__subtitle')
await expect(elem).toHaveHTML(['Next-gen browser and mobile automation test framework for Node.js', 'Get Started'], { includeSelectorTag: false })
await expect(elem).toHaveHTML([expect.stringContaining('automation test framework for Node.js'), expect.stringContaining('Started')], { includeSelectorTag: false })
toBeDisplayedInViewport
Перевіряє, чи знаходиться елемент у видимій частині вікна, викликаючи isDisplayedInViewport
для елемента.
Використання
const elem = await $('#elem')
await expect(elem).toBeDisplayedInViewport()
toHaveChildren
Перевіряє кількість дочірніх елементів елемента, викликаючи команду element.$('./*')
.
Використання
const list = await $('ul')
await expect(list).toHaveChildren() // список має принаймні один елемент
// те саме, що
await expect(list).toHaveChildren({ gte: 1 })
await expect(list).toHaveChildren(3) // список має 3 елементи
// те саме, що
await expect(list).toHaveChildren({ eq: 3 })
toHaveWidth
Перевіряє, чи має елемент певну ширину.
Використання
await browser.url('http://github.com')
const logo = await $('.octicon-mark-github')
await expect(logo).toHaveWidth(32)
toHaveHeight
Перевіряє, чи має елемент певну висоту.
Використання
await browser.url('http://github.com')
const logo = await $('.octicon-mark-github')
await expect(logo).toHaveHeight(32)
toHaveSize
Перевіряє, чи має елемент певний розмір.
Використання
await browser.url('http://github.com')
const logo = await $('.octicon-mark-github')
await expect(logo).toHaveSize({ width: 32, height: 32 })
toBeElementsArrayOfSize
Перевіряє кількість отриманих елементів, використовуючи команду $$
.
Примітка: Цей матчер оновить переданий масив останніми елементами, якщо твердження пройде. Однак, якщо ви перепризначили змінну, вам потрібно буде отримати елементи знову.
Використання
const listItems = await $$('ul>li')
await expect(listItems).toBeElementsArrayOfSize(5) // 5 елементів у списку
await expect(listItems).toBeElementsArrayOfSize({ lte: 10 })
// те саме, що
assert.ok(listItems.length <= 10)
Матчери для мережі
toBeRequested
Перевіряє, що мок був викликаний
Використання
const mock = browser.mock('**/api/todo*')
await expect(mock).toBeRequested()
toBeRequestedTimes
Перевіряє, що мок був викликаний очікувану кількість разів
Використання
const mock = browser.mock('**/api/todo*')
await expect(mock).toBeRequestedTimes(2) // await expect(mock).toBeRequestedTimes({ eq: 2 })
await expect(mock).toBeRequestedTimes({ gte: 5, lte: 10 }) // запит викликаний принаймні 5 разів, але менше ніж 11
toBeRequestedWith
Перевіряє, що мок був викликаний відповідно до очікуваних параметрів.
Більшість опцій підтримує часткові матчери expect/jasmine, такі як expect.objectContaining
Використання
const mock = browser.mock('**/api/todo*', { method: 'POST' })
await expect(mock).toBeRequestedWith({
url: 'http://localhost:8080/api/todo', // [опціонально] string | function | custom matcher
method: 'POST', // [опціонально] string | array
statusCode: 200, // [опціонально] number | array
requestHeaders: { Authorization: 'foo' }, // [опціонально] object | function | custom matcher
responseHeaders: { Authorization: 'bar' }, // [опціонально] object | function | custom matcher
postData: { title: 'foo', description: 'bar' }, // [опціонально] object | function | custom matcher
response: { success: true }, // [опціонально] object | function | custom matcher
})
await expect(mock).toBeRequestedWith({
url: expect.stringMatching(/.*\/api\/.*/i),
method: ['POST', 'PUT'], // або POST, або PUT
statusCode: [401, 403], // або 401, або 403
requestHeaders: headers => headers.Authorization.startsWith('Bearer '),
postData: expect.objectContaining({ released: true, title: expect.stringContaining('foobar') }),
response: r => Array.isArray(r) && r.data.items.length === 20
})
Матчер для знімків (snapshots)
WebdriverIO підтримує базові тести з використанням знімків, а також тести DOM-знімків.
toMatchSnapshot
Перевіряє, чи відповідає будь-який довільний об'єкт певному значенню. Якщо ви передаєте WebdriverIO.Element
, він автоматично зробить знімок стану outerHTML
.
Використання
// знімок довільних об'єктів (тут не потрібно "await")
expect({ foo: 'bar' }).toMatchSnapshot()
// знімок `outerHTML` WebdriverIO.Element (DOM-знімок, потрібно "await")
await expect($('elem')).toMatchSnapshot()
// знімок результату команди елемента
await expect($('elem').getCSSProperty('background-color')).toMatchSnapshot()
toMatchInlineSnapshot
Аналогічно, ви можете використовувати toMatchInlineSnapshot()
для зберігання знімка прямо в тестовому файлі. Наприклад:
await expect($('img')).toMatchInlineSnapshot()
Замість створення файлу знімка, WebdriverIO модифікує тестовий файл безпосередньо, щоб оновити знімок як рядок:
await expect($('img')).toMatchInlineSnapshot(`"<img src="/public/apple-touch-icon-precomposed.png">"`)
Матчери для візуальних знімків
Наступні матчери реалізовані як частина плагіна @wdio/visual-service
і доступні лише тоді, коли налаштовано сервіс. Переконайтеся, що ви правильно виконали інструкції з налаштування.
toMatchElementSnapshot
Перевіряє, чи вказаний елемент відповідає знімку в базовій лінії.
Використання
await expect($('.hero__title-logo')).toMatchElementSnapshot('wdioLogo', 0, {
// options
})
Очікуваний результат за замовчуванням 0
, тому ви можете написати те ж твердження як:
await expect($('.hero__title-logo')).toMatchElementSnapshot('wdioLogo', {
// options
})
або взагалі не передавати жодних опцій:
await expect($('.hero__title-logo')).toMatchElementSnapshot()
toMatchScreenSnapshot
Перевіряє, чи поточний екран відповідає знімку в базовій лінії.
Використання
await expect(browser).toMatchScreenSnapshot('partialPage', 0, {
// options
})
Очікуваний результат за замовчуванням 0
, тому ви можете написати те ж твердження як:
await expect(browser).toMatchScreenSnapshot('partialPage', {
// options
})
або взагалі не передавати жодних опцій:
await expect(browser).toMatchScreenSnapshot('partialPage')
toMatchFullPageSnapshot
Перевіряє, чи знімок всієї сторінки відповідає знімку в базовій лінії.
Використання
await expect(browser).toMatchFullPageSnapshot('fullPage', 0, {
// options
})
Очікуваний результат за замовчуванням 0
, тому ви можете написати те ж твердження як:
await expect(browser).toMatchFullPageSnapshot('fullPage', {
// options
})
або взагалі не передавати жодних опцій:
await expect(browser).toMatchFullPageSnapshot('fullPage')
toMatchTabbablePageSnapshot
Перевіряє, чи знімок всієї сторінки, включаючи позначки вкладок, відповідає знімку в базовій лінії.
Використання
await expect(browser).toMatchTabbablePageSnapshot('tabbable', 0, {
// options
})
Очікуваний результат за замовчуванням 0
, тому ви можете написати те ж твердження як:
await expect(browser).toMatchTabbablePageSnapshot('tabbable', {
// options
})
або взагалі не передавати жодних опцій:
await expect(browser).toMatchTabbablePageSnapshot('tabbable')
Використання регулярних виразів
Ви також можете безпосередньо використовувати регулярні вирази для всіх матчерів, які виконують порівняння тексту.
Використання
await browser.url('https://webdriver.io/')
const elem = await $('.container')
await expect(elem).toHaveText(/node\.js/i)
await expect(elem).toHaveText([/node\.js/i, 'Get Started'])
await expect(browser).toHaveTitle(/webdriverio/i)
await expect(browser).toHaveUrl(/webdriver\.io/)
await expect(elem).toHaveElementClass(/Container/i)
Матчери за замовчуванням
Окрім матчерів expect-webdriverio
, ви можете використовувати вбудовані твердження Jest expect або expect/expectAsync для Jasmine.
Асиметричні матчери
WebdriverIO підтримує використання асиметричних матчерів скрізь, де ви порівнюєте текстові значення, наприклад:
await expect(browser).toHaveTitle(expect.stringContaining('some title'))
або
await expect(browser).toHaveTitle(expect.not.stringContaining('some title'))
TypeScript
Якщо ви використовуєте WDIO Testrunner, все буде налаштовано автоматично. Просто дотримуйтесь інструкції з налаштування з документації. Однак, якщо ви запускаєте WebdriverIO з іншим тестраннером або в простому скрипті Node.js, вам потрібно додати expect-webdriverio
до types
в tsconfig.json
.
"expect-webdriverio"
для всіх, крім користувачів Jasmine/Jest."expect-webdriverio/jasmine"
для Jasmine"expect-webdriverio/jest"
для Jest
JavaScript (VSCode)
Для роботи автозаповнення в звичайному js необхідно створити jsconfig.json
в корені проекту і посилатися на визначення типів.
{
"include": [
"**/*.js",
"**/*.json",
"node_modules/expect-webdriverio"
]
}
Додавання власних матчерів
Подібно до того, як expect-webdriverio
розширює матчери Jasmine/Jest, можна додавати власні матчери.
- Для Jasmine див. документацію custom matchers
- Для всіх інших див. документацію Jest's expect.extend
Власні матчери слід додавати в хук before
wdio
// wdio.conf.js
{
async before () {
const { addCustomMatchers } = await import('./myMatchers')
addCustomMatchers()
}
}
// myMatchers.js - Jest example
export function addCustomMatchers () {
if (global.expect.expect !== undefined) { // Temporary workaround. See https://github.com/webdriverio/expect-webdriverio/issues/835
global.expect = global.expect.expect;
}
expect.extend({
myMatcher (actual, expected) {
return { pass: actual === expected, message: () => 'some message' }
}
})
}