End-to-End Test Automation with Selenium and Cucumber

4 min read

End-to-end testing is a technique in software development lifecycle used to ascertain that the flow of an application is as expected. It is a way of testing user experience by simulating scenarios of interaction with the different features of the application and identifying system variations to ensure that the data integrity is maintained across board.

We will be using selenium-webdriver as the web automation framework to execute tests against different browsers, while cucumber while be used as the tool for writing the test scenarios in Gherkins (plain English language for running automated tests). So, let's do a quick walk-through on how to setup and run a basic automated end-to-end tests with Selenium and Cucumber in a NodeJS environment.

PROJECT SETUP

Create a project directory and open it on commandline, run npm init -y to initialise your NodeJS project. Then proceed to install the following NPM packages.

$ npm install selenium-webdriver cucumber chromedriver expect -D

Say the root directory is named e2e. So, you should expect your package.json file to look like this

{
  "name": "e2e",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "e2e-test": "cucumber-js e2e"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "chromedriver": "80.0.1",
    "cucumber": "6.0.5",
    "expect": "24.9.0",
    "geckodriver": "1.19.1",
    "selenium-webdriver": "4.0.0-alpha.5"
  }
}

chromedirver and geckodriver are the browser dependencies for chrome and firefox respectively. expect is an ascersion library from jest. Note that selenium-webdriver is not limited to running on only the browsers above.
Now create directories and files that conforms to the tree below

e2e
├── features
│   ├── step_definitions
│   │   ├── page.js
│   │
│   ├── support
│   │   ├── world.js
│   │   ├── hooks.js
│   │
│   ├── page.feature

Fill up the files accordingly

e2e/features/support/world.js

const seleniumWebdriver = require('selenium-webdriver');
const {setWorldConstructor, setDefaultTimeout} = require('cucumber');

class CustomWorld {
  constructor() {

    this.driver = new seleniumWebdriver
      .Builder()
      .forBrowser('chrome')
      .build();
  }
}

setDefaultTimeout(60000);
setWorldConstructor(CustomWorld);

e2e/features/support/hooks.js

const {Before, After} = require('cucumber');

Before(function() {
  return this.driver.manage().window().maximize();
});

After(function() {
  return this.driver.quit();
});

e2e/features/page.feature

Feature: Google Search
  As an internet user
  I want to be able to search for a word on Google

  Scenario: When using Google Search to find the meaning of a word
    Given I visit google search homepage
    When I search Google for a word
    Then I should see some results

e2e/features/step_definitions/page.js

const {Given, When, Then} = require('cucumber');
const {By, Key, until} = require('selenium-webdriver');
const expect = require('expect');

Given('I visit google search homepage', function() {
  // Launch the specified browser (in world.js) and navigate to google homepage
  this.driver.get('https://www.google.com');
});

When('I search Google for a word', async function() {
  const driver = this.driver;
  const currentUrl = await driver.getCurrentUrl();
  // Validate that the current page is correct
  expect(currentUrl).toEqual('https://www.google.com/')
  // Locate the input field and enter your search word. Then simulate an enter action
  await driver.findElement(By.name('q')).sendKeys('what is test automation', Key.ENTER);
});

Then('I should see some results', async function() {
  const driver = this.driver;
  // Wait for the results to be loaded in the DOM
  await driver.wait(until.elementsLocated(By.css('div.g')), 5000);
  // Get an array of the results
  const results = await driver.findElements(By.css('div.g'));
  // Validate that results are populated to the DOM
  expect(results.length).not.toEqual(0);
});

Below are images showing the selector for input (q) and results (g) respectively

input-field
search-results

NOTE: The file structure and testing methods adopted here may not be efficient when testing a very large application. Below are useful articles I have written in this regard;

PART ONE: How to use Cucumber and Selenium WebDriver effectively for BDD test automation

PART TWO: How to use Cucumber and Selenium WebDriver effectively for BDD test automation

Readup how to generate test reports

📅 22-02-2020