Take a Drive with WebdriverIO and Mocha

Take a Drive with WebdriverIO and Mocha

Automate My Commute

  • The car to drive
  • How to drive the car
  • The directions to take
  • The speed limits to follow
  • How to take turns safely
  • Handling traffic delays

Photo Credit: https://flic.kr/p/GvVU5

Terminology

  • Selenium
  • Browsers & Drivers
  • WebdriverIO
  • Mocha
  • Assertions
  • before/beforeEach/afterEach/after
  • Promises

The Car to Drive

Browsers & Drivers

Car = Browser

We can choose any model we prefer: 
Chrome, IE, Safari, Firefox...

Photo Credit: https://flic.kr/p/dtWtC5

WebdriverIO Config

capabilities: [{
  // options: firefox, chrome, internet explorer, phantomjs ...
  browserName: 'chrome',
  version: '27.0',
  platform: 'XP',
  chromeOptions: {
    args: [
      'use-fake-device-for-media-stream',
      'use-fake-ui-for-media-stream'
    ]
  }
}]

WebdriverIO Config

capabilities: [{
    browserName: 'chrome'
  }, {
    browserName: 'firefox',
    specs: [
      'test/ffOnly/*'
    ]
  },{
    browserName: 'phantomjs',
    exclude: [
      'test/spec/alert.js'
    ]
}]

How to Drive the Car

Selenium

The Robot

Drives the car

WebDriver driver = new HtmlUnitDriver();

// And now use this to visit Google
driver.get("http://www.google.com");

// Find the text input element by its name
WebElement element = driver
    .findElement(By.name("q"));

// Enter something to search for
element.sendKeys("Cheese!");

// Now submit the form.
element.submit();

Reads the Dashboard

// Check the title of the page
System.out.println("Page title is: "
    + driver.getTitle());

Photo Credit: https://flic.kr/p/5LpzsN

Local

npm install -g selenium-standalone
selenium-standalone install
selenium-standalone start
webdriverio.remote({
  host: 'hub.browserstack.com',
  port: 80,
  user: 'username',
  key: 'hunter2'
}).init();

Remote

The Directions to Take

WebdriverIO

The Translator

Drives the car

client
    .url('http://cssdevconf.com')
    .click('#myButton')
    .setValue('.input', 'test123')

Reads the Dashboard

client
  .getCssProperty('#someElement', 'width')
  .then(function(width) {
      console.log(width);
      // outputs the following:
      // {
      //     property: 'width',
      //     value: '100px',
      //     parsed: {
      //         type: 'number',
      //         string: '100px',
      //         unit: 'px',
      //         value: 100
      //     }
      // }
  });

Other Robots - Chimpjs

Feature: Search the Web

  As a human
  I want to search the web
  So I can find information

  Scenario: Search for Xolv.io
    Given I have visited Google
    When I search for "Xolv.io"
    Then I see "Xolv.io"
this.When(/^I go to my projects$/, function(done) {
  this.browser.url(process.env.ROOT_URL + 'projects')
  .waitForVisible('.projects-list')
  .call(done);
});

Write the test case

Define the step

The Speed Limits

Assertions, Mocha & Chai

The Limits

Asserting the Speed

car
  .getSpeed()
  .then(function(speed){
    expect(speed).to.equal(20);
  })

Photo Credit: https://flic.kr/p/6r2Q4C

Other Styles

mySpeed.should.equal(20);
assert.equal(mySpeed, 20);

Asserting the Page

client
  .url('https://github.com/')
  .getElementSize('.header-logo-wordmark', function(err, result) {
    expect(result.height).to.equal(26);
    expect(result.width).to.equal(89);
  })
  .getTitle(function(err, title) {
    expect(title).to.equal('GitHub · Where software is built');
  })
  .getCssProperty('a[href="/plans"]', 'color', function(err, result){
    expect(result.value).to.equal('rgba(64,120,192,1)');
  })

Turning Safely

Mocha before/after hooks

Drive to Work

describe('car driving to work', function() { 
  it('should turn left at 32nd', function() {
    slowDown();
    turnWheel(360deg);
    expect(direction).to.equal('north');
    speedUp();
  });
  it('should turn right at 41st', function() {
    slowDown();
    turnWheel(-360deg);
    expect(direction).to.equal('east');
    speedUp();
  });
  it('should turn left at 53rd', function() {
    slowDown();
    turnWheel(360deg);
    expect(direction).to.equal('north');
    speedUp();
  });
});

Before & After Each

describe('car driving to work', function() {  
  beforeEach(function() {
    slowDown();
  });

  it('should turn left at 32nd', function() {
    turnWheel(360deg);
    expect(direction).to.equal('north');
  });
  it('should turn right at 41st', function() {
    turnWheel(-360deg);
    expect(direction).to.equal('east');
  });
  it('should turn left at 53rd', function() {
    turnWheel(360deg);
    expect(direction).to.equal('north');
  });

  afterEach(function() {
    speedUp();
  });
})

Before & After

describe('car driving to work', function() {  
  before(function() {
    startCar();
  });

  beforeEach(function() {
    slowDown();
  });

  it('should turn left at 32nd', function() {
    turnWheel(360deg);
    expect(direction).to.equal('north');
  });

  afterEach(function() {
    speedUp();
  });

  after(function() {
    turnCarOff();
  });
})

Handling Traffic

JavaScript Promises

Waiting for the Unknown

it('should turn left at 32nd', function () {
  car.turnWheel(360deg);

  expect(car.direction).to.equal('north');

  return car;
});

Photo Credit: https://flic.kr/p/2br6Ww

expect(car.direction).to.equal('north');

car.turnWheel(360deg);

Executes as:

Using .then

it('should turn left at 32nd', function () {  
  car
    .turnWheel(360deg)
    .then(function(){ 
      expect(car.direction).to.equal('north');
    });   

  return car;
});
it('should turn left at 32nd', function () {  
  car
    .turnWheel(360deg)
    .getDirection().should.eventually.equal('north');

  return car;
});

Alternate (chai-as-promised)

Finishing Up

  • Browsers are the car to drive. They’re driven using installed Selenium browser drivers.
  • Selenium is the robot that knows how to drive the car.
  • WebdriverIO provides the directions to take to Selenium, in a language that’s easy for us to write in.
  • Assertions help validate the speed limits are followed. Chai is a common assertion library used.
  • Hooks such as before/after help reduce code duplication, making it easier to take turns safely
  • Promises help with handling delays due to congestion along the way

Take a Drive with WebdriverIO and Mocha

By Kevin Lamping

Take a Drive with WebdriverIO and Mocha

A simple analogy that will cover the following functional testing terms and how they all work together: Selenium Browsers & Drivers WebdriverIO Mocha Assertions before/beforeEach/afterEach/after Promises

  • 1,141
Loading comments...

More from Kevin Lamping