Skip to content

bchinmz/protractor-cucumber

Repository files navigation

Test Angular using CucumberJs

I created this repository to consolidate all my findings on how to perform e2e testing on Angular using CucumberJs. I have practise Scenario based testing for VB.net and C# projects and not willing to let it go just because I have move to Angular project. I read through many articles in order to come out a working solution. I hope this will benefit not only myself and also to other front-end developer out there.

  • Angular - the code to test
  • Protractor - test executor
  • Cucumber - to write test in plain language

Setup

Assuming you already have an existing Angular app

npm install --save-dev protractor-cucumber-framework

npm install --save-dev cucumber

npm install --save-dev chai

npm install --save-dev chai-as-promised

npm install --save-dev @types/cucumber

npm install --save-dev @types/chai

npm install --save-dev @types/chai-as-promised

Config

protractor.conf.js

exports.config = {
  allScriptsTimeout: 11000,

  specs: [
    './e2e/features/**/*.feature'
  ],
  capabilities: {
    'browserName': 'chrome'
  },
  directConnect: true,

  framework: 'custom',  // set to "custom" instead of cucumber.

  frameworkPath: require.resolve('protractor-cucumber-framework'),  // path relative to the current config file
  cucumberOpts: {
    require: ['./e2e/features/**/*.steps.ts'], // loads step definitions
    format: 'json: e2e-output.txt',               // enable console output
  },
  onPrepare() {
    require('ts-node').register({
      project: 'e2e/tsconfig.e2e.json' //enable typescript
    });
  }
};

Feature file

  • based on protractor.conf.js place to store the feature file will be in:
    • e2e\features<filename>.features
    • e2e\features<folder><filename>.features
  • in the feature file, you may write your test in Gherkin
Feature: App page

    Scenario: First scenario
        Given I open app page
        When app page loads
        Then header "Welcome to app!" is displayed

Steps definition

  • based on protractor.conf.js place to store the feature file will be in:
    • e2e\features<filename>.steps.ts
    • e2e\features<folder><filename>.steps.ts
  • in the steps file, you may fill in your steps definition with test setup, test execution and test assertion.
import { Given, Before, When, Then } from 'cucumber';
import { browser, element, by, ExpectedConditions } from 'protractor';
import * as chai from 'chai';
import * as chaiAsPromised from 'chai-as-promised';
import { AppPage } from './app.po';
const expect = chai.use(chaiAsPromised).expect;

let appPage: AppPage = new AppPage();

Given('I open a page', function () {
  return browser.get('/').then(() => {
    element(by.css('h1')).getText()
      .then(text => {
        expect(text).to.have.string("Welcome to app!")
      })
  });
});

Before(() => {
  appPage = new AppPage();
});

Given('I open app page', () => {
  appPage.navigateTo();
});

When('app page loads', () => {
  return browser.wait(ExpectedConditions.visibilityOf(appPage.getTitle()), 5000);
});

Then('header {string} is displayed', (title) => {
  return appPage.getParagraphText()
    .then(text => {
      expect(text).to.have.string(title)
    })
});

Timeout

  • By default, asynchronous hooks and steps timeout after 5000 milliseconds.
  • As the app grew larger and my laptop grew slower, is time to increase the timeout.
  • Timeout can be globally modified. However, for some reason only specific hook or step's timeout work for me.
Before({timeout: 60 * 1000}, function() {
  // Does some slow browser/filesystem/network actions
});

Given(/^a slow step$/, {timeout: 60 * 1000}, function() {
  // Does some slow browser/filesystem/network actions
});

See: https://github.com/cucumber/cucumber-js/blob/master/docs/support_files/timeouts.md

Reference