Timeouts
Each command in WebdriverIO is an asynchronous operation. A request is fired to the Selenium server (or a cloud service like Sauce Labs), and its response contains the result once the action has completed or failed.
Therefore, time is a crucial component in the whole testing process. When a certain action depends on the state of a different action, you need to make sure that they get executed in the right order. Timeouts play an important role when dealing with these issues.
WebDriver Timeouts
Session Script Timeout
A session has an associated session script timeout that specifies a time to wait for asynchronous scripts to run. Unless stated otherwise, it is 30 seconds. You can set this timeout like so:
await browser.setTimeout({ 'script': 60000 })
await browser.executeAsync((done) => {
console.log('this should not fail')
setTimeout(done, 59000)
})
Session Page Load Timeout
A session has an associated session page load timeout that specifies a time to wait for the page loading to complete. Unless stated otherwise, it is 300,000 milliseconds.
You can set this timeout like so:
await browser.setTimeout({ 'pageLoad': 10000 })
The
pageLoad
keyword is a part of the official WebDriver specification, but might not be supported for your browser (the previous name ispage load
).
Session Implicit Wait Timeout
A session has an associated session implicit wait timeout. This specifies the time to wait for the implicit element location strategy when locating elements using the findElement
or findElements
commands ($
or $$
, respectively, when running WebdriverIO with or without the WDIO testrunner). Unless stated otherwise, it is 0 milliseconds.
You can set this timeout via:
await browser.setTimeout({ 'implicit': 5000 })
WebdriverIO related timeouts
WaitFor*
timeout
WebdriverIO provides multiple commands to wait on elements to reach a certain state (e.g. enabled, visible, existing). These commands take a selector argument and a timeout number, which determines how long the instance should wait for that element to reach the state. The waitforTimeout
option allows you to set the global timeout for all waitFor*
commands, so you don't need to set the same timeout over and over again. (Note the lowercase f
!)
// wdio.conf.js
export const config = {
// ...
waitforTimeout: 5000,
// ...
}
In your tests, you now can do this:
const myElem = await $('#myElem')
await myElem.waitForDisplayed()
// you can also overwrite the default timeout if needed
await myElem.waitForDisplayed({ timeout: 10000 })
Framework related timeouts
The testing framework you’re using with WebdriverIO has to deal with timeouts, especially since everything is asynchronous. It ensures that the test process doesn't get stuck if something goes wrong.
By default, the timeout is 10 seconds, which means that a single test should not take longer than that.
A single test in Mocha looks like:
it('should login into the application', () => {
await browser.url('/login')
const form = await $('form')
const username = await $('#username')
const password = await $('#password')
await username.setValue('userXY')
await password.setValue('******')
await form.submit()
expect(await browser.getTitle()).to.be.equal('Admin Area')
})
In Cucumber, the timeout applies to a single step definition. However, if you want to increase the timeout because your test takes longer than the default value, you need to set it in the framework options.
- Mocha
- Jasmine
- Cucumber
// wdio.conf.js
export const config = {
// ...
framework: 'mocha',
mochaOpts: {
timeout: 20000
},
// ...
}
// wdio.conf.js
export const config = {
// ...
framework: 'jasmine',
jasmineOpts: {
defaultTimeoutInterval: 20000
},
// ...
}
// wdio.conf.js
export const config = {
// ...
framework: 'cucumber',
cucumberOpts: {
timeout: 20000
},
// ...
}