When we originally ran the wdio
command to generate our config file, we chose mocha
as the framework for organizing our tests.
Overview
- Learn the main difference between
sync
modes - Learn how to use mocha to group our tests appropriately.
- Install
chai
and learn to useexpect()
for assertions.
- Change to the correct directory
cd exercise-4
- Install dependencies
npm i
Back when we first created our wdio.conf.js
file, we set sync
mode to false
so we could reuse some of our test code from previous exercises. It returned a promise with a .then()
which called assert()
to validate the test.
However, WebDriver.io can do a cool trick where we enable sync
mode to true
, and it will handle a lot of the asynchronous nature of browser testing for us, and allow us to write more readable code that looks more synchronous.
You can read more about it in the official documentation, It's all synchronous.
An example from the WebDriver.io docs of code that looks more synchronous, without any promises:
// Notice the lack of return statements and `.then()`?
describe('webdriver.io page', function() {
it('should have the right title', function () {
// Navigate
browser.url('/');
// Get the page's title
var title = browser.getTitle();
// Assert the page title is what we expect it to be
assert.equal(title, 'WebdriverIO - WebDriver bindings for Node.js');
});
});
Important: "All commands now block the execution of the test process until they’ve resolved. No then calls have to be done anymore, we can just assign the direct response of the Selenium server to a variable."
It makes your code cleaner and more readable!
- In
wdio.conf.js
, ensure thatsync
is set back totrue
(the WebDriver default):
sync: true,
Mocha is already included in your project when you installed wdio
. But we do need to update our code to use it.
- We need to change the code from returning a promise (async style), to a handful of separate statements that will execute one after another (sync style).
Open the exercise-4/tests/browser/example.spec.js
test file, and replace it with the following code:
/**
* example.spec.js
*/
var assert = require('assert');
describe('Example using Node\'s assertion library', function () {
describe('page title', function () {
var expectedPageTitle = "Verbo - Simple travel planning";
it('should be "' + expectedPageTitle + '"', function () {
// Navigate to the home page
browser.url('/');
// Get the page title
var pageTitle = browser.getTitle();
// Log the page title (just for fun)
console.log('\n🤖 The page title is: ' + pageTitle);
// Assert the page title is what we expect it to be
assert.equal(pageTitle, expectedPageTitle);
// HINT: Want to see what a failure looks like?
// Uncomment the line below to try the `.notEqual()` syntax!
// assert.notEqual(pageTitle, expectedPageTitle);
// HINT: You can also change the page title in `verbo/public/index.html` to simulate an actual bug in the code, which should also cause your test to fail.
});
});
});
Look Ma, no promises! We're simply using Node's built-in assert
module, and our test runner will tell us if any of our assertions fail.
- Run it
npm run test:browser
You should see the example spec run with 1 passing test, and the page title printed to the console:
Chai enables much more powerful assertions via multiple styles, and for this workshop we'll use expect()
.
Side note: Chai's should()
syntax has some gotchas, as explained in the official docs. This is why we'll use expect()
.
- Install
chai
as adevDependency
:
npm i --save-dev chai
- Create a new file called
example-chai.spec.js
, and paste the following code:
var expect = require('chai').expect;
describe('Example using Chai\'s assertion library', function () {
describe('page title', function () {
var expectedPageTitle = "Verbo - Simple travel planning";
it('should be "' + expectedPageTitle + '"', function () {
// Navigate to the home page
browser.url('/');
// Get the page title
var pageTitle = browser.getTitle();
// Log the page title (just for fun)
console.log('\n🤖 (Chai) The page title is: ' + pageTitle);
// Assert the page title is what we expect it to be
expect(pageTitle).to.equal(expectedPageTitle);
// HINT: Want to see what a failure looks like?
// Uncomment the line below to try the `.not.to.equal()` syntax!
// expect(pageTitle).not.to.equal(expectedPageTitle);
// HINT: You can also change the page title in `verbo/public/index.html` to simulate an actual bug in the code, which should also cause your test to fail.
});
});
});
The above simply changes from the Node.js assert
module to using Chai's, which is much more powerful.
For extra practice, let's add another inner describe()
block within the outermost describe()
block ... you'll then have two "sub-groups" of tests within this example group:
- One for
describe('page title')
- Another for
describe('page h1')
describe('page h1', function () {
var expectedH1Text = "Did you remember to pack your toothbrush?";
it('should be "' + expectedH1Text + '"', function () {
// Navigate to the home page
browser.url('/');
// Get the h1 text
var h1Text = browser.getText('h1');
// Log the h1 text (just for fun)
console.log('\n🤖 (Chai) The h1 text is: ' + h1Text);
// Assert the h1 text is what we expect it to be
expect(h1Text).to.equal(expectedH1Text);
// HINT: Want to see what a failure looks like?
// Uncomment the line below to try the `.not.to.equal()` syntax!
// expect(h1Text).not.to.equal(expectedH1Text);
// HINT: You can also change the h1 text in `verbo/src/components/HomePage/HomePage.jsx` to simulate an actual bug in the code, which should also cause your test to fail.
});
});
Run your test script again, and you'll see another passing test!
npm run test:browser
If you run the test suite multiple times in succession, you're bound to notice that your tests are running asynchronously and in parallel 🤓
✅ You've made a lot of progress, great job!
- We learned how to use mocha syntax to group our tests with
describe()
andit()
functions. - We learned that setting
sync
mode totrue
allows us to write more simple, synchronous-looking code in our tests, and let WebDriver.io abstract away the inherently async behavior of testing with web browsers.