Tutorial - Cucumber

A gentle intro

mkdir chimp-tutorial
cd chimp-tutorial
npm install chimp
mkdir features
chimp --watch

Chimp will download any tools it needs and then start watching your files. When it's ready, it will start a Chrome browser for you. Don't close this window as you will use it to see the automation happening.

Create the file ./chimp-tutorial/features/search.feature and paste the following content into it: (note this is not a YAML file it is in Gherkin syntax and not valid YAML)

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"

Save this file and you'll see this output in the console:

[chimp] Watching features with tagged with @dev,@watch,@focus
[chimp] Running...

0 scenarios
0 steps

Next add a @watch tag just above the scenario as you can see below:

@watch
  Scenario: Search for Xolv.io

Save this file again and you'll see this in the console:

[chimp] Running...

Feature: Search the Web

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

  @watch
  Scenario: Search for Xolv.io   # features/search.feature:8
    Given I have visited Google  # features/search.feature:9
    When I search for "Xolv.io"  # features/search.feature:10
    Then I see "Xolv.io"         # features/search.feature:11


1 scenario (1 undefined)
3 steps (3 undefined)

You can implement step definitions for undefined steps with these snippets:

this.Given(/^I have visited Google$/, function () {
  // Write the automation code here
	pending();
});

this.When(/^I search for "([^"]*)"$/, function (arg1) {
  // Write the automation code here
	pending();
});

this.Then(/^I see "([^"]*)"$/, function (arg1) {
  // Write the automation code here
	pending();
});

Cucumber.js has just reported to you that you have not implemented step definitions for your scenario and it provided you with some helpful code snips that you can use. So create the file ./chimp-tutorial/features/support/step_defs.js and copy the code snips into it like this:

module.exports = function() {

  this.Given(/^I have visited Google$/, function () {
    // Write the automation code here
    pending();
  });

  this.When(/^I search for "([^"]*)"$/, function (arg1) {
    // Write the automation code here
    pending();
  });

  this.Then(/^I see "([^"]*)"$/, function (arg1) {
    // Write the automation code here
    pending();
  });
  
}

πŸ“˜

Step Definitions Files are Modules

Note that the steps definitions files must be wrapped with module.exports for Cucumber.js to use them.

Save this file, and now you'll see this in the console:

[chimp] Running...

...

1 scenario (1 pending)
3 steps (1 pending, 2 skipped)

Cucumber.js is now letting you know that 1 scenario is pending. This is because the first step used callback.pending, therefore subsequent steps are skipped.

The next step is to automate the steps one by one and turn every line into cucumber-green!

Edit the Given step in your step definitions file to match the following code:

this.Given(/^I have visited Google$/, function () {
  browser.url('http://google.com');
});

When you save this file, you will see the browser navigate to http://google.com as you instructed it to. You will also see this in the console:

[chimp] Running...

...

1 scenario (1 pending)
3 steps (1 pending, 1 skipped, 1 passed)

Yay! Our first passing step! Let's take a minute to examine what just happened.

You have access to browser, which an instance of WebdriverIO, and you are using the url(docs) method. As you can see in its docs, when the url method is called with a parameter, it commands the browser to navigate to the provided URL.

We have two more steps to automate, so edit the When step your step definitions file to match the following code:

this.When(/^I search for "([^"]*)"$/, function (searchTerm) {
  browser.setValue('input[name="q"]', searchTerm);
  browser.keys(['Enter']);
});

Save. Now you'll see your browser go to http://google.com and it will also search for "Xolv.io". You'll also see this in the console:

[chimp] Running...

...

1 scenario (1 pending)
3 steps (1 pending, 2 passed)

2 steps are passing. You're getting there! Let's take another minute to examine this code:

Notice the searchTerm parameter being passed in to the step. This is because the regex of the When function is extracting anything between quotes defined in the feature file and passing into the parameter of the step definition function. This is how you pass parameters from feature files to the automation layer.

There are also two new methods being used on the browser object. They are setValue (docs) and keys (docs). The first method uses the selector input[name='q'] which targets Google's search box, and the second method sends a sequence of keys. The 'Enter' keyword is a shortcut for sending the equivalent a Unicode character as you can see here.

Let's automate the final step. Modify the Then step in your step definitions file to match the following code:

Save this file and the browser will navigate to Google and perform the search and the console will show the following:

[chimp] Running...

...

1 scenario (1 passed)
3 steps (3 passed)

The whole scenario has passed because all 3 steps passed. Most excellent!

Let's examine the last step. As before, a link parameter is being passed in from the feature, and now the waitForExist (docs) command is being used from WebdriverIO.

This command will wait for the element addressed by the selector to exist before continuing. If the element is not found, this method will timeout.

πŸ“˜

Don't assume elements are ready

When working with the DOM, you need to make sure you wait for elements to exist and not assume they are already on the page.

Hopefully the above tutorial gives you a taste of how Chimp helps you drive development from specifications. This tutorial only scratches the surface of what you can do with Chimp.

You should check out CucumberJS and learn more about the Gherkin syntax. For example, you can use simpler strings with placeholders instead of regular expressions:

this.When('I search for "$string"', function (searchTerm) { ... });

You should check out WebdriverIO's API guide to see all the things you can do with the browser object.

You should also checkout the Jasmine Expect and master them so you can write clean automation steps like this:

this.Then(/^they see the heading "([^"]*)"$/, function(heading) {
  expect(browser.getText('h1')).toEqual(heading);
});

You also have access to a request inside your step definitions. See the request API guide. With this you can automate calls to servers over HTTP and perform tasks such as calling fixtures and setting up test data.

For some more examples of what you can do with Chimp, check out Letterpress which has plenty of examples of automation.



##Learn the Fundamentals of Testing, Specifications and Become a Chimp Ninja!
Checkout our new book where you can learn how to can use Chimp across the Full Stack from CUCUMBER to React, Node.JS, Mocha, Meteor and more.

Quality, Faster. By Sam Hatoum, creator of Chimp.