WebdriverIO v7 Released

It's the time of the year where the WebdriverIO project is releasing a new major update. It’s almost become a tradition for us to rewrite the complete code base to further grow the project. When we announced the v5 update, we moved from a multi-repository setup to a mono-repo. This time, the rewrite of the code base is just as important and impactful, but comes with almost no implications for the end user. As more and more contributors have joined the project, we've noticed that using pure JavaScript can be helpful to keep the entry barrier for contributions low, but that it ultimately decreases the quality of contributions overall. With the growing size of the code in the project, keeping up with all the different types that were thrown around was becoming more difficult for us as core contributors. Since we already had a lot of TypeScript fans among us, we decided to move to TypeScript quickly after meeting at the OpenJS Collaborator Summit.

Our hope is that by moving to TypeScript, fewer bugs will be introduced during continued development on the framework. It will help improve the quality of code contributions and the speed of development of certain features. It also brings more confidence in new versions that we ship to the user.

This major update will largely only impact TypeScript users as we have updated types in all places and changed the way we distribute them. As part of the rewrite, we upgraded to Cucumber v7, which also moved its codebase to TypeScript. Because of that we had to update some of the Cucumber hooks to ensure they come with proper type safety. In the following we go into every major change and will describe how you can upgrade to v7.

Drop Node v10 Support#

We've dropped support for Node v10, which was moved into a maintenance LTS phase by the Node.js team in May 2020. While this version still receives important security updates until April 2021, we recommend updating your Node.js version to v14 or higher.

To update Node.js, it is important to know how it was installed in the first place. If you are in a Docker environment, you can just upgrade the base image like:

- FROM mhart/alpine-node:10
+ FROM mhart/alpine-node:14

We recommend using NVM (Node Version Manager) to install and manage Node.js versions. You can find a detailed description on how to install NVM and update Node in their project readme.

TypeScript Rewrite#

We have rewritten the complete code base and almost touched all files to add type safety and to fix a lot of bugs on the way. This was a true community effort and would have taken much longer if we didn’t have so many people helping with code contributions. Thank you all for that ❤️! Before, WebdriverIO auto-generated all type definitions, which caused the creation of a lot of duplicate types and inconsistency. With this overhaul, all types are directly taken from the code itself and centralised in a single new helper package called @wdio/types. If you have been using TypeScript, you will now have much better type support for various commands and the configuration file.

There are two significant changes how this TypeScript rewrite will impact you. While in v6 you would set @wdio/sync in your types of your tsconfig.json, this will now change to be webdriverio/sync. Similar for running WebdriverIO asynchronously. Instead of just defining webdriverio in your types you now need to set webdriverio/async:

// tsconfig.json
"types": [
"node",
- "@wdio/sync",
+ "webdriverio/sync",
"@wdio/mocha-framework"
],

or

// tsconfig.json
"types": [
"node",
- "webdriverio",
+ "webdriverio/async",
"@wdio/mocha-framework"
],

Lastly, if you define custom commands, you need to provide their types slightly different now:

// define custom commands in v6
declare namespace WebdriverIO {
// adding command to `browser`
interface Browser {
browserCustomCommand: (arg: number) => void
}
}

this now has to be:

declare global {
namespace WebdriverIO {
interface Browser {
browserCustomCommand: (arg: number) => void
}
}
}

You can read more about WebdriverIO TypeScript integration in our docs.

Cucumber v7 Update#

The folks working on Cucumber have done a tremendous job moving their code base to TypeScript, which has made our lives tremendously easier. The new Cucumber integration required us to update the parameters within our Cucumber hooks.

If you have been using Cucumber, all you need to do to update to v7 is to update your Cucumber imports to their new package:

- const { Given, When, Then } = require('cucumber')
+ const { Given, When, Then } = require('@cucumber/cucumber')

Improved Google Lighthouse Integration#

Since v6 WebdriverIO can run on the WebDriver protocol for true cross browser automation, but also automate specific browsers using browser APIs such as Chrome DevTools. This allows for interesting integrations into tools that allow broader testing capabilities such as Google Lighthouse. With the @wdio/devtools-service, WebdriverIO users were able to access these capabilities using Google Lighthouse to run performance tests. In this release, we’ve also updated Google Lighthouse to the latest version to enable new performance metrics such as Cumulative Layout Shifts or First Input Delay.

While in v6 performance tests were automatically run on a mobile environment, we have decided to change this and make the default behavior more obvious. Therefore, if you run performance tests in v7, there aren't any changes to the environment where you run your tests. We still recommend emulating a mobile device to more accurately capture the user experience of users most impacted by bad application performance. To do so, you can run the following commands:

browser.emulateDevice('iPhone X')
browser.enablePerformanceAudits({
networkThrottling: 'Regular 3G',
cpuThrottling: 4,
cacheEnabled: false,
formFactor: 'mobile'
})

The formFactor property has been added with the update to Google Lighthouse v7, which determines how performance metrics are scored and if mobile-only audits are skipped.

New PWA Check Command#

In addition, we have deepened our integration to the tool and added audits for capturing the quality of your progressive web apps (PWA). These applications are built with modern web APIs to deliver enhanced capabilities, reliability, and installability while reaching anyone, anywhere, on any device with a single codebase. To test if your application fulfills the PWA requirements we have introduced a checkPWA command that runs a variety of audits, validating the set up of your app:

const result = browser.checkPWA()
expect(result.passed).toBe(true)

We will continue to add more integrations into tools like Google Lighthouse to provide more testing capabilities, e.g. accessibility, best practices and SEO.

Auto Compiling#

In v7 of WebdriverIO we made using compiler tools like Babel or TypeScript a lot easier. The testrunner can now automatically compile the config if it finds the necessary packages in your modules. Usually these had to be defined in your framework options like so:

mochaOpts: {
ui: 'bdd',
require: ['@babel/register'],
// ...
},

These settings need to be removed now as WebdriverIO automatically includes them. Read more about how to set up Babel or TypeScript in our docs.

Stricter Protocol Compliance#

The WebDriver protocol has been upgraded to a W3C recommended standard since 2018. A lot of cloud vendors and tools have been able to update their implementation making all artifacts of the JSONWireProtocol obsolete. The WebdriverIO projects wants to support this transition by adding additional checks to its capability configuration to ensure users don't accidentally send a mixture of both protocols resulting in an unexpected behavior. With the new version your session request will automatically fail if you send incompatible capabilities along, e.g.:

capabilities: {
browserName: 'Chrome',
platform: 'Windows 10', // invalid JSONWire Protocol capability
'goog:chromeOptions': { ... }
}

Test Coverage Reporting#

The @wdio/devtools-service now offers to capture the code coverage of your JavaScript application files. This can help you to identify whether you should write more e2e tests or not. To enable the feature you have to enable it by setting the coverageReporter option for the service:

// wdio.conf.js
services: [
['devtools' {
coverageReporter: {
enable: true,
type: 'html',
logDir: __dirname + '/coverage'
}
}]
]

You can also assert the code coverage within your tests using the new getCoverageReport command, e.g.:

const coverage = browser.getCoverageReport()
expect(coverage.lines.total).toBeAbove(0.9)
expect(coverage.statements.total).toBeAbove(0.9)
expect(coverage.functions.total).toBeAbove(0.9)
expect(coverage.branches.total).toBeAbove(0.9)

New Docs#

As you might already have seen, we have updated our docs to give this new release a brand new face. We've upgraded our Docusaurus setup to v2 and gave the whole design a new touch. Big shout out to Anton Meier for helping us out and making our robot on the front page so lively.

That's it! We hope you enjoy the new version and update your framework soon-ish to get all these new features, type safety and bug fixes for your projects. If you have any questions don't hesitate to start a conversation on the discussions page or join our growing support chat that has already reached 6.7k active members.

New Network Primitives (Beta)

The WebdriverIO team continues its efforts to provide more functionality to its automation interface by shipping new network primitives to its API. With the latest v6.3. update you can now easily mock web resources in your test and define custom responses that allow you to drastically reduce testing time as you can now better test individual scenarios. With that WebdriverIO catches up with other popular testing tools like Puppeteer, Playwright or Cypress and even simplifies mocking further.

Replacing a REST API request from a browser can now be as simple as follows:

const mock = browser.mock('https://todo-backend-express-knex.herokuapp.com/')
mock.respond([{
title: 'Injected (non) completed Todo',
order: null,
completed: false
}, {
title: 'Injected completed Todo',
order: null,
completed: true
}])
browser.url('https://todobackend.com/client/index.html?https://todo-backend-express-knex.herokuapp.com/')
$('#todo-list li').waitForExist()
console.log($$('#todo-list li').map(el => el.getText()))
// outputs: "[ 'Injected (non) completed Todo', 'Injected completed Todo' ]"

In addition to that you can als modify JavaScript of CSS files as well as abort requests or modify responses dynamically based on the original reponse. You can find more information on all features in the Mocks and Spies section of the docs.

Throttling#

Aside mocking the new version also ships with another network command that allows to modify the network throughput of the browser allowing to test under different network condition, e.g. Regular 3G or even Offline mode:

// throttle to Regular 3G
browser.throttle('Regular 3G')
// disable network completely
browser.throttle('Offline')
// set custom network throughput
browser.throttle({
'offline': false,
'downloadThroughput': 200 * 1024 / 8,
'uploadThroughput': 200 * 1024 / 8,
'latency': 20
})

This can open up interesting use case where you want to ensure that your progressive web app (PWA) stores all essential resources for offline users to use the application.

Support#

This feature uses Chrome DevTools capabilities to enable such behavior. Therefor it can only be supported where such an interface is available which is Chrome, Firefox Nightly and Chromium Edge right now. The Firefox team at Mozilla is working hard to ship this into the stable build of Firefox, therefor support for it can be expected soon.

On top of that the folks at Sauce Labs working on various of WebDriver extensions that even allow this functionality to be support in the cloud. More updates on this will follow soon.

Implementation#

With this feature WebdriverIO now always incorperates Puppeteer as second automation driver allowing these extra features whenever possible. Moving forward the team is looking into more opportunities to enable Chrome DevTools features into the built in API.

Please let us know what you think! We are expecting some bugs here and there but will make sure to fix them immediately. While we are pretty confident with the current interface design it might be still possible that some tweaks will be applied to make it even more user friendly.

Give us feedback!#

We are releasing this as beta feature and hope that you can help us identify weaknesses in the implementation and support. Please give it a try and create an issue if things are unclear or just don't work. We hope with the help of the community and you we are able to ship this as stable within the next months!

WebdriverIO Open Office Hours

Contributing to a big Open Source project can be hard. Especially if the codebase is large and requires a lot of context to understand what certain changes do. Then there is the possibility that tools or infrastructure is being used that are unkown. Nevertheless the project depends on your contributions and help to identify bugs and fix them. How can we overcome this hurdle?

At last weeks OpenJS Foundation Collaborator Summit the WebdriverIO team announced to introduce Open Office Hours that allow everyone to schedule individual 1:1 pairing sessions with the WebdriverIO contributors. This allows you to get started contributing to WebdriverIO easily with the help of people that know the code base well. We only ask you to pick a task you would like to work on up-front so that the pairing partner can be prepared for the session to provide better guidance. This is a free opportunity for you to not only give back to the WebdriverIO community but also get to know the team behind the project.

Currently we offer 4 slots a week from: every Wednesday 10am - 12am (CEST / GMT+2) for our European friends as well as: 11am - 13am (PDT / GMT -7) for people living on the west side of this hemisphere. You can book an appointment at any time on:

calendly.com/webdriverio/open-office-hours

All sessions will be held over Zoom or Google Hangouts but alternative platforms are possible, please let us know in the comment section. Also please note that this is not a way to get individual consulting for your own projects. The time is to be used to work on WebdriverIO related bugs or features. For support questions we still ask you to use our Gitter Support Channel.

We are looking forward to meet you all online and hope to find more collaborators helping us to push the project forward!