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.