« Back to article list

Webdriver.io Intro

Table of Contents

Intro

So, lets start at the very beginning and define some terms I may refer to (some of these are based on popular opinion and do not have a concrete definition, so I'll try to define in the most commonly used context):

Types of Testing

Automation Software

So, if you're reading this blog, chance are you have some interest in automation (or you're just very bored).

While this list could span many pages, we'll keep it topical to just the things being discussed here:

So, what do those terms have to do with anything?

Well, while you may be familiar with unit testing (and perhaps even TDD, test driven development), and think of 'integration testing' in the sense that you annotate your unit tests with 'integration' test if it touches the database, and think of 'functional testing' as that manual process of clicking around the product, you may be surprised to find out all 3 parts can be automated to some degree.

Ok ok, I didn't need a glossary or terms that simple, lets get started

Great, you're ready to start scripting some tests - well, maybe not yet.

First you'll need to set up your local environment before you start tinkering with it.

The best guide to use is on the webdriver.io site here: http://webdriver.io/guide.html

As long as you run each command identified there, you should end up with a pretty solid setup to begin writing some more interesting test cases (we'll go over how to fill out a form, something the guide doesn't discuss).

After you're done with the guide, confirm your directory structure resembles this:

├── node_modules/
├── geckodriver
├── package.json
├── selenium-server-standalone-3.0.1.jar
├── test
│   └── specs
│       └── blub.js
├── test.js
└── wdio.conf.js

3 directories, 6 files

More interesting testing

So, after completing the guide, you saw how your browser opened a site on its own, ran the test assertion (in my case, the file blub.js has the 'describe' and 'it' assertion wrappers, you may have named your file differently).

Lets create a new file in the test/specs directory and call it, bmiTest.js.

Run something like (assuming you're in the project root):

touch test/specs/bmiTest.js

to create the initial file.

After that, open it in your favorite text editor and add the following:

var assert = require('assert');

browser.url('https://www.cdc.gov/healthyweight/assessing/bmi/adult_bmi/english_bmi_calculator/bmi_calculator.html');

describe('BMI calculator page', function () {

  it('Should tell me the correct page title for BMI calculations', function () {
    var title = browser.getTitle()
    assert.equal(title, 'Adult BMI Calculator | Healthy Weight | CDC')
  })

  it('Should calculate my BMI when submitting', function () {
    // We can chain these calls, instead of putting 'browser' in front of each
    browser
      .setValue('#feet', '5')
      .setValue('#inches', '10')
      .setValue('#pounds', '150')
      .click('#calc')

    // Here we are selecting the class="bmiNum" nested under the id="normal" element
    var myBmi = browser.getText('#normal .bmiNum')

    assert.equal(myBmi, '21.5')
  })
})

Now, change the browser to chrome if using firefox 53.

This is because of an error in geckodriver with FF 53+:

https://github.com/webdriverio/webdriverio/issues/1999

You can do this by opening the wdio.conf.js file and replacing the 'firefox' word with 'chrome' (line 47, under browserName).

After you save the file, start your selenium server. If running the project local one that the wdio guide had you install, you can use (assuming it isn't already running):

java -jar -Dwebdriver.gecko.driver=./geckodriver selenium-server-standalone-3.0.1.jar

to start it.

Then, you can run your test suite with the following command again:

./node_modules/.bin/wdio wdio.conf.js

You will notice it actually runs both the test files (the one that opens the BMI calculator page, and the one that opens the webdriver.io page for asserting the title is correct).

Assuming neither site is down, you should see results as follows:

./node_modules/.bin/wdio wdio.conf.js

․․․

3 passing (4.50s)


Which means all our tests worked as planned!

The node code breakdown

Cool, automation is easy and fun! Well, it would be more fun if all that code made sense, so lets begin to break it down by adding some inline code comments describing what each thing is doing:

// This is pulling in a package/library intalled from npm
// into this specific script (sometimes called a 'module')
// and assigning it into a variable called 'assert'
var assert = require('assert');

// Where does 'browser' come from?  Well, when you use the wdio test
// runner, it is a variable similar to assert above, that is
// automatically populated with the browser/webdriver configuration
// that we specified manually in the very first test.js file the wdio
// guide had us work on.

// In this case, we call a 'method' or 'function' that is bound to the
// instance of the browser object, and this causes selenium to open
// the browser to that page.
browser.url('https://www.cdc.gov/healthyweight/assessing/bmi/adult_bmi/english_bmi_calculator/bmi_calculator.html');

// So, what the heck is this?  Describe is a function call from the
// mocha test framework (this was set up in the wdio.conf.js file that
// we clicked through).

// The function is taking 2 arguments, a string 'BMI calculator page'
// and another function, often called an 'anonymous
// function' (see how it doesn't have a name next to it?)
describe('BMI calculator page', function () {

  // Similar to 'describe', the 'it' wrapper is almost identical,
  // a function from mocha that takes a string and an anonymous function

  // The general mocha structure is to 'describe' a general test case,
  // then define all the things 'it' should do - each 'it' block then contains
  // different 'assert'ions, which all must be satisfied for the test cases to pass.
  it('Should tell me the correct page title for BMI calculations', function () {
    // Finally, we do something useful, we use the 'browser' variable
    // from up above to request the page title and plop it in a variable.
    var title = browser.getTitle()

    // After we get the page title, we run an 'assert' to confirm
    // it equals what we expect it to equal
    assert.equal(title, 'Adult BMI Calculator | Healthy Weight | CDC')
  })

  // Here, we define another thing 'it' should do
  it('Should calculate my BMI when submitting', function () {
    // We can chain these calls, instead of putting 'browser' in front of each
    browser
      .setValue('#feet', '5')
      .setValue('#inches', '10')
      .setValue('#pounds', '150')
      .click('#calc')

    // Up above, we set some values in various DOM elements (specified
    // by their unique id attribute in the HTML, using a CSS
    // selector), then 'click'ed the submit button.

    // Here we are selecting the class="bmiNum" nested under the id="normal" element
    // and assigning it into a variable to assert against in a moment.
    var myBmi = browser.getText('#normal .bmiNum')

    // Notice that we used a getText call, not a getValue call - getText is for
    // grabbing HTML text, getValue is for getting an input field value.

    // Finally, we confirm the calculation functioned as expected with
    // another assertion and a pre-determined value we know to be correct.
    assert.equal(myBmi, '21.5')
  })
})