Mind Dump, Tech And Life Blog
written by Ivan Alenko
published under license Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)copy! share!
posted at 11. Jul '19
last updated at 11. May '21

Howto Write Rock Solid Tests for React in Webdriver.io

This howto provides information and examples how to implement steps for Webdriver.io for a React application.

I like my end-to-end tests in Cucumber. But testing a React application has it’s specifics. The code is for an older version Webdriver 4, but with small changes it will work for version 5.

Rerender

A component (a node in DOM) can be rerendered any time. Don’t assign references and use finders everywhere. Don’t worry, it’s fast.

Usually there aren’t any problems with rerenders as webdriver can recover and find it again. But well, not always - there are some API methods which will say elements is stale and throw “referenced element is no longer available”.

BAD

const form = $('.my-form');
form.$('#name').setValue('blah');
form.$('.my-form__submit').click();

GOOD

$('.my-form #name').setValue('blah');
$('.my-form__submit').click();

or in helper:

const fillAndSubmitUserForm = (formSelector) => {
  $(`${formSelector} #name`).setValue('blah');
  $(`${formSelector}__submit`).click();
}
~~~`

## Wait for Correct Content

Usually the problem is content is not yet rendered in the DOM, but an element with such class name exists, so webdriver finds `<div class="header"></header>`, because model data are not yet loaded and the app uses empty object ({}) to prevent errors on calling method on `null` or `undefined`.

BAD

~~~javascript
expect($('.header')).to.contain('Users');

GOOD

browser.waitUntil(
  () => expect($('.header')).to.contain('Users'),
  undefined,
  'Header "Users" could not be found',
);

or implement loaders in your application and then:

// wait until it doesn't exist
browser.waitForExist('.loader', undefined, true);
expect($('.header')).to.contain('Users');

Conclusion

There are two main issues which will manifest like everywhere. Don’t be afraid to use waitUntil(), the only thing is default message is cryptic, so provide your own. Probably create a helper for this. And don’t save finders to a variable.

Add Comment