What’s new in WebdriverIO v3?
Some big changes came along with v3
. We’ve rewritten the whole core to an ajax/promise based monad.
Instead of implementing a complex command scheduler or request queues we built the whole library on top
of a monad construct. This allows us to chain commands as we are used to and keep stacktraces sane.
In addition to that we wanted to have 1st level promise support. Therefore we used the Q library
(there are already plans to move to native Promises)
to integrate promises into the monad system. This works astoundingly well. Each command execution represents
a promise. If you chain commands, the command waits until the previous command is resolved. On top of that, the optional
modifier that you can pass to a monad makes the library incredibly flexible and extensible.
Where do I have to change my tests?
Actually, you should be fine with most of your tests. Except all execute commands v3
will support the good old
callbacks, so tests like
1 2 3 4 5 6 7 8 9
| it('should test something', function(done) { client .click('#button') .getValue('#someInput', function(err, value) { expect(err).to.be.undefined; expect(value).to.be.exactly('some value'); }) .call(done); });
|
should still pass after moving to v3
. However, I strongly recommend rewriting tests as you can remove
a lot of obsolete code. Most test frameworks support Promises these days so we should make use of it:
1 2 3 4 5
| it('should test something', function() { return client.click('#button').getValue('#someInput').then(function(value) { expect(value).to.be.exactly('some value'); }); });
|
Looks great doesn’t it? Instead of callbacks, call the then
function if you are interested in the
result of the command. If the command fails for whatever reason, it throws an exception and notifies the
test framework. No unnecessary error checks anymore.
Handling asynchronicity in addCommand
In v2.x
the function parameter used to have a callback that would get called once you were done with
your steps. Here is an example:
1 2 3 4 5 6 7 8 9
| client.addCommand("getUrlAndTitle", function(customVar, cb) { this.url(function(err,urlResult) { this.getTitle(function(err,titleResult) { var specialResult = {url: urlResult.value, title: titleResult}; cb(err,specialResult); console.log(customVar); }) }); });
|
With v3
we switched over to a promised based execution flow. Therefore the callback parameter is gone
and gets replaced by a promise you need to return in that function. Once that promise is resolved the
command queue continues. The example above looks in v3
like this:
1 2 3 4 5 6 7 8
| client.addCommand("getUrlAndTitle", function(customVar) { return this.url().then(function(urlResult) { return this.getTitle().then(function(titleResult) { console.log(customVar); return { url: urlResult.value, title: titleResult }; }); }); });
|
What else?
Here is a list of thing that got introduced with v3
- Finally this release includes Multiremote functionality. It allows you to run multiple instances at
the same time, enabling integration tests of applications that require more than one session.
See more in the multiremote section.
- WebdriverIO now provides its own test runner to run tests in parallel and to help you get your tests up-
and running quickly. It is called
wdio
and takes a config file as parameter. After you’ve defined your
capabilities and test specs in that config file just run the test runner to run test in parallel. See more
in the test runner section.
- Due to the new monad based core, WebdriverIO is now able to chain selectors. This makes querying deeply nested
elements super easy. Checkout the selector section for more information.
- Removed the
waitFor
command as it is basically the same as waitForExist
- Added
debug
command to help you debug your tests. It stops the queue and allows
you to jump into the browser to open dev tools and to check the state of your app. After you are done
with debugging you can jump back into your terminal, press enter and continue running your test.