Skip to content

Latest commit

 

History

History

exercise-4

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

Exercise 4: Adding mocha and chai

When we originally ran the wdio command to generate our config file, we chose mocha as the framework for organizing our tests.

Overview


Success criteria

  1. Learn the main difference between sync modes
  2. Learn how to use mocha to group our tests appropriately.
  3. Install chai and learn to use expect() for assertions.

Instructions

Init the exercise

  1. Change to the correct directory
cd exercise-4
  1. Install dependencies
npm i

Switch to sync mode

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."

Enable sync mode

It makes your code cleaner and more readable!

  1. In wdio.conf.js, ensure that sync is set back to true (the WebDriver default):
sync: true,

Using Mocha

Mocha is already included in your project when you installed wdio. But we do need to update our code to use it.

  1. 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.

  1. 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:

1 passing test with sync mode on

Adding chai

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().

  1. Install chai as a devDependency:
npm i --save-dev chai
  1. 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.

Expect the homepage's h1 text to be correct

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

3 passing tests

If you run the test suite multiple times in succession, you're bound to notice that your tests are running asynchronously and in parallel 🤓

Tests are asynchrous and run in parallel

✅ You've made a lot of progress, great job!


What we learned

  • We learned how to use mocha syntax to group our tests with describe() and it() functions.
  • We learned that setting sync mode to true 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.

Up next

Exercise 5: Practice with selectors and commands