When you're writing tests, you often need to check that values meet certain conditions. expect
gives you access to a number of "matchers" that let you validate different things on the browser
, an element
or mock
object.
These default options below are connected to the waitforTimeout
and waitforInterval
options set in the config.
Only set the options below if you want to wait for specific timeouts for your assertions.
{
wait: 2000, // ms to wait for expectation to succeed
interval: 100, // interval between attempts
}
If you like to pick different timeouts and intervals, set these options like this:
// wdio.conf.js
import { setOptions } from 'expect-webdriverio'
export const config = {
// ...
before () {
setOptions({ wait: 5000 })
},
// ...
}
Every matcher can take several options that allows you to modify the assertion:
Name | Type | Details |
---|---|---|
wait |
number | time in ms to wait for expectation to succeed. Default: 3000 |
interval |
number | interval between attempts. Default: 100 |
message |
string | user message to prepend before assertion error |
This options can be applied in addition to the command options when strings are being asserted.
Name | Type | Details |
---|---|---|
ignoreCase |
boolean | apply toLowerCase to both actual and expected values |
trim |
boolean | apply trim to actual value |
containing |
boolean | expect actual value to contain expected value, otherwise strict equal. |
asString |
boolean | might be helpful to force converting property value to string |
This options can be applied in addition to the command options when numbers are being asserted.
Name | Type | Details |
---|---|---|
eq |
number | equals |
lte |
number | less then equals |
gte |
number | greater than or equals |
Checks if browser is on a specific page.
await browser.url('https://webdriver.io/')
await expect(browser).toHaveUrl('https://webdriver.io')
Checks if browser is on a page URL that contains a value.
await browser.url('https://webdriver.io/')
await expect(browser).toHaveUrlContaining('webdriver')
Checks if website has a specific title.
await browser.url('https://webdriver.io/')
await expect(browser).toHaveTitle('WebdriverIO · Next-gen browser and mobile automation test framework for Node.js')
Checks if website has a specific title that contains a value.
await browser.url('https://webdriver.io/')
await expect(browser).toHaveTitleContaining('WebdriverIO')
Calls isDisplayed
on given element.
const elem = await $('#someElem')
await expect(elem).toBeDisplayed()
Calls isExisting
on given element.
const elem = await $('#someElem')
await expect(elem).toExist()
Same as toExist
.
const elem = await $('#someElem')
await expect(elem).toBePresent()
Same as toExist
.
const elem = await $('#someElem')
await expect(elem).toBeExisting()
Checks if element has focus. This assertion only works in a web context.
const elem = await $('#someElem')
await expect(elem).toBeFocused()
Checks if an element has a certain attribute with a specific value.
const myInput = await $('input')
await expect(myInput).toHaveAttribute('class', 'form-control')
Same as toHaveAttribute
.
const myInput = await $('input')
await expect(myInput).toHaveAttr('class', 'form-control')
Checks if an element has a certain attribute that contains a value.
const myInput = await $('input')
await expect(myInput).toHaveAttributeContaining('class', 'form')
Same as toHaveAttributeContaining
.
const myInput = await $('input')
await expect(myInput).toHaveAttrContaining('class', 'form')
Checks if an element has a certain class name.
const myInput = await $('input')
await expect(myInput).toHaveElementClass('form-control', { message: 'Not a form control!', })
Checks if an element has a certain class name that contains provided value.
const myInput = await $('input')
await expect(myInput).toHaveElementClassContaining('form')
Checks if an element has a certain property.
const elem = await $('#elem')
await expect(elem).toHaveElementProperty('height', 23)
await expect(elem).not.toHaveElementProperty('height', 0)
Checks if an input element has a certain value.
const myInput = await $('input')
await expect(myInput).toHaveValue('user', { ignoreCase: true })
Checks if an input element contains a certain value.
const myInput = await $('input')
await expect(myInput).toHaveValueContaining('us')
Checks if an element can be clicked by calling isClickable
on the element.
const elem = await $('#elem')
await expect(elem).toBeClickable()
Checks if an element is disabled by calling isEnabled
on the element.
const elem = await $('#elem')
await expect(elem).toBeDisabled()
// same as
await expect(elem).not.toBeEnabled()
Checks if an element is enabled by calling isEnabled
on the element.
const elem = await $('#elem')
await expect(elem).toBeEnabled()
// same as
await expect(elem).not.toBeDisabled()
Checks if an element is enabled by calling isSelected
on the element.
const elem = await $('#elem')
await expect(elem).toBeSelected()
Same as toBeSelected
.
const elem = await $('#elem')
await expect(elem).toBeChecked()
Checks if link element has a specific link target.
const link = await $('a')
await expect(link).toHaveHref('https://webdriver.io')
Same as toHaveHref
.
const link = await $('a')
await expect(link).toHaveLink('https://webdriver.io')
Checks if link element contains a specific link target.
const link = await $('a')
await expect(link).toHaveHrefContaining('webdriver.io')
Same as toHaveHrefContaining
.
const link = await $('a')
await expect(link).toHaveLinkContaining('webdriver.io')
Checks if element has a specific id
attribute.
const elem = await $('#elem')
await expect(elem).toHaveId('elem')
Checks if element has a specific text. Can also be called with an array as parameter in the case where the element can have different texts.
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(['Next-gen browser and mobile automation test framework for Node.js', 'Get Started'])
Checks if element contains a specific text. Can also be called with an array as parameter in the case where the element can have different texts.
await browser.url('https://webdriver.io/')
const elem = await $('.container')
await expect(elem).toHaveTextContaining('browser and mobile automation test framework')
await expect(elem).toHaveTextContaining(['browser and mobile automation test framework', 'Started'])
Checks if an element is within the viewport by calling isDisplayedInViewport
on the element.
const elem = await $('#elem')
await expect(elem).toBeDisplayedInViewport()
Checks amount of the fetched element's children by calling element.$('./*')
command.
const list = await $('ul')
await expect(list).toHaveChildren() // the list has at least one item
// same as
await expect(list).toHaveChildren({ gte: 1 })
await expect(list).toHaveChildren(3) // the list has 3 items
// same as
await expect(list).toHaveChildren({ eq: 3 })
Checks amount of fetched elements using $$
command.
const listItems = await $$('ul>li')
await expect(listItems).toBeElementsArrayOfSize(5) // 5 items in the list
await expect(listItems).toBeElementsArrayOfSize({ lte: 10 })
// same as
assert.ok(listItems.length <= 10)
Checks that mock was called
const mock = browser.mock('**/api/todo*')
await expect(mock).toBeRequested()
Checks that mock was called for the expected amount of times
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 }) // request called at least 5 times but less than 11
Checks that mock was called according to the expected options.
Most of the options supports expect/jasmine partial matchers like expect.objectContaining
const mock = browser.mock('**/api/todo*', { method: 'POST' })
await expect(mock).toBeRequestedWith({
url: 'http://localhost:8080/api/todo', // [optional] string | function | custom matcher
method: 'POST', // [optional] string | array
statusCode: 200, // [optional] number | array
requestHeaders: { Authorization: 'foo' }, // [optional] object | function | custom matcher
responseHeaders: { Authorization: 'bar' }, // [optional] object | function | custom matcher
postData: { title: 'foo', description: 'bar' }, // [optional] object | function | custom matcher
response: { success: true }, // [optional] object | function | custom matcher
})
await expect(mock).toBeRequestedWith({
url: expect.stringMatching(/.*\/api\/.*/i),
method: ['POST', 'PUT'], // either POST or PUT
statusCode: [401, 403], // either 401 or 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
})
You can also directly use regular expressions for all matchers that do text comparison.
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(elem).toHaveTextContaining([/node\.js/i, 'Started'])
await expect(browser).toHaveTitle(/webdriverio/i)
await expect(browser).toHaveUrl(/webdriver\.io/)
await expect(elem).toHaveElementClass(/Container/i)
In addition to the expect-webdriverio
matchers you can use builtin Jest's expect assertions or expect/expectAsync for Jasmine.