WebdriverIO v5 Released
We are pleased to announce that a new major version of WebdriverIO has finally been released! I never thought that it would take this long (it's been over a year), but we can finally say that the new version of WebdriverIO is ready for use (and better than ever). There has been over 800 commits, from over 34 different contributors; and I am truly grateful to everyone who participated in this collective effort. With that being said...
🎉 🎉 🎉 Time to celebrate! 🎉 🎉 🎉
When I began to practically rewrite this project from scratch one year ago, I knew there would be problems here and there. However, I was confident that the WebdriverIO community in the support channels would work collectively to help each other out; and I'm proud to say, I was right!
The Goal
Looking into the history of the project, it is humbling to see how much it has been grown within just a few years. From a handful of downloads a day, to now almost 50k; as well as the knowledge that big companies are relying on this tool to ship their software on daily basis, it became obvious that the next big feature had to be sustainability. The first step was made by joining the JS.Foundation at of 2017.
Proud to announce that @webdriverio is joining @the_jsf to continue to grow as project and community 🎉 👏 https://t.co/N58Iv5oC9r
— WebdriverIO (@webdriverio) 13. September 2017
The next step was to implement a technical infrastructure that would allow the project to grow. By reviewing other successful open source projects such as e.g. Jest or Babel, we adapted a monolithic project structure to simplify the process of contributing to WebdriverIO.
We wanted to start this effort completely community driven, and began to gather feedback from everyone who was using WebdriverIO on daily basis. We created a Discord Server in order to discuss architectural changes, and to organize the work of porting the packages into the new tech stack that was Lerna.
New Package Structure
As we moved to a monolithic system we scoped all WebdriverIO packages into the @wdio
NPM organization. This would make it simpler to onboard contributors to release new package versions, and better clarifies which packages are "officially" maintained by the organization or are 3rd party community packages.
If you have been using wdio-mocha-framework
or wdio-spec-reporter
in your project please update the packages to use the ones built for v5: @wdio/mocha-framework
or @wdio/spec-reporter
. Going forward the version number of all packages are now pinned to each other; meaning that you should always have the same versions for all "official" WebdriverIO packages that you use.
We Did Some Spring Cleaning
When people proposed new commands to the API, we contributors became more and more hesitant to introduce them. There were a vast number of existing commands; and many of these requested commands provided very little difference from existing commands. This was beginning to become a maintenance nightmare.
Starting with v5 we created a "base" WebdriverIO package called webdriver
. It contains the bare logic to make a HTTP request to a WebDriver endpoint; and includes all of the commands from various specifications (including the WebDriver spec as well as Appium's Mobile JSONWire protocol) defined in a simple to maintain JSON object.
As part of that effort we've renamed many of the commands in order to align them closer to the pattern that has been used in the protocol. The base WebDriver client now also returns the value
property of all protocol command responses, so that we were able to get rid of a lot of redundancy (e.g. title
is now called with getTitle
).
Additionally, we have seen significant confusion regarding the WebdriverIO API, and the fact that it sometimes took selectors as a first argument, and sometimes not. This was causing various problems e.g. building a consistent and useful TypeScript definition for it. In the new version we got rid of selectors as command parameters, and enforced the difference between commands only accessible from the browser/client instance, and those from the element instance. In order to click on an element, you must now first fetch it, and then call the click command on that instance, e.g.
browser.click('#elem') // throws 'browser.click is not a function'
const elem = $('#elem')
elem.click() // clicks successfully on the element
// or
$('#elem').click()
elem.url('https://webdriver.io') // throws because the url command is scoped on the browser object