top of page

Cucumber Scenario set up in a typescript-driven protractor framework.

  • Writer: khyati sehgal
    khyati sehgal
  • Jun 23, 2020
  • 3 min read

In this blog, I will describe how I have mapped the feature file to step definition and then to page objects in a protractor driven cucumber project.

Background:

The project is based on

  1. Protractor

  2. Typescript

  3. Cucumber – BDD

  4. Page Object Model

Before setting up any project we shall know about the configuration so here is the package json and protractor config which I am using for the reference.

{
  "name": "khyati_blogspot",
  "version": "0.0.1",
  "scripts": {
    "webdriver": "webdriver-manager update --standalone --versions.standalone=2.53.1 && webdriver-manager start --versions.standalone=2.53.1",
    "test": "protractor protractorConf.js"
  },
  "license": "ISC",
  "devDependencies": {
    "@types/chai": "^4.2.11",
    "@types/core-js": "~0.9.34",
    "@types/node": "^6.14.10",
    "aurelia-protractor-plugin": "^1.0.6",
    "chai": "^4.2.0",
    "chai-as-promised": "^7.1.1",
    "concurrently": "2.2.0",
    "cucumber": "^2.3.1",
    "log4js": "^3.0.6",
    "log4js-protractor-appender": "^1.1.2",
    "multiple-cucumber-html-reporter": "^1.16.3",
    "nodemailer": "^6.4.8",
    "path": "^0.12.7",
    "protractor": "5.4.2",
    "protractor-beautiful-reporter": "^1.2.5",
    "protractor-console": "^3.0.0",
    "protractor-cucumber-framework": "^3.1.2",
    "protractor-notify-plugin": "^1.0.0",
    "selenium-webdriver": "^3.0.1",
    "soft-assert": "^0.2.2",
    "ts-node": "5.0.1",
    "typescript": "3.6.4",
    "user-home": "^2.0.0",
    "webdriver-manager": "^12.1.6"
  },
  "dependencies": {
    "cucumber-html-reporter": "^5.2.0",
    "install": "^0.13.0",
    "print-message": "^3.0.1",
    "tslint": "^6.1.2"
  }
}

 

Protractor config

const printMessage = require('print-message');
const report = require('multiple-cucumber-html-reporter');
const fsExtra = require("fs-extra");
const start_date = new Date().toLocaleString();

exports.config = {
    SELENIUM_PROMISE_MANAGER: false,
    directConnect: true,
    specs: ["./e2e/features/*/Sanity.feature"],
    format: 'json:./CucumberReport/cucumberReport.json',
    framework: 'custom',
    frameworkPath: require.resolve('protractor-cucumber-framework'),
    cucumberOpts: {
        strict: true,
        format: 'json:./CucumberReport/cucumberReport.json',
        keepAlive: false,
        require: [
            './e2e/hooks/*.ts',
            './e2e/stepDefinition/*/*.ts',
        ],
         tags: '@tag1'
    },
    beforeLaunch: function () {
        require('ts-node/register')
    },
    onPrepare: async () => {
        await browser.waitForAngularEnabled(false);
        await browser.ignoreSynchronization == true;
        await browser.manage().window().maximize();
        fsExtra.emptyDirSync("./CucumberReport/");
    },
    
    onComplete: async () => {
        report.generate({
            jsonDir: './CucumberReport/',
            reportPath: './CucumberReport',
            metadata: {
                browser: {
                    name: 'chrome',
                    version: '83'
                },
                device: 'Local test machine',
                platform: {
                    name: 'windows',
                    version: '10'
                }
            },

            customData: {
                title: 'Run infomation of the automation',
                pageTitle: 'Automation Report',
                reportName: 'Automation Report',
                pageFooter: 'generated by internal team',
                displayDuration: true,
                durationInMS: true,

                data: [
                    { label: 'Project', value: 'Automation report' },
                    { label: 'Release', value: '1.2.3' },
                    { label: 'Cycle', value: 'B11221.34321' },
                    { label: 'Execution Start Time', value: start_date },
                    { label: 'Execution End Time', value: new Date().toLocaleString()}
                ]
            }
        });
    }
}
 

Feature file:

@SanityTestCases
Feature: Covering all priority scenarios of testing
    Background: open application as an admin user

    @tag1 @tag2 @tag3
    Scenario: Demonstrating feature and scenario
        Given open application as an "admin" user
 

Step definition file

Used annotation Given and how I have placed regular expression to pick any sort of string from feature while using ([^”]*) to bind the statements.

The parameterized method with username, password that can be passed directly from the feature file.

Given(/^open application as an "([^"]*)" user$/, async (username, password) => {
     await loginPage.login(username, password);
});
 

Feature file:

Keywords like Features, Scenario, Given, And , Examples are used here.

Parameterization can be used with angular brackets like <url> , <username> and <password>.

@SanityTestCases
Feature: Covering all priority scenarios of testing
    Background: open application as admin user

 @tag1 @tag2
    Scenario: Demonstrating feature and scenario
        Given open application as an "admin" user


    @tag1 @tag2
    Scenario: Demonstrating feature and scenario
        Given open application with "<url>"
        And enter details "<username>" and "<password>"

        Examples:
            | url            | username         | password |
            | user1.test.com | Value@gmail.com  | Value123 |
            | user2.test.com | Value2@gmail.com | Value123 |
            | user3.test.com | Value3@gmail.com | Value123 |
 

Step definition with the annotations – Given, When, Then, and how I have placed regular expression to pick any sort of string from feature while by using ([^”]*) to bind the statements.

Given(/^open application with "([^"]*)"$/, async (url) => {
     await loginPage.openBrowser(url);
});

Given(/^enter details "([^"]*)" and "([^"]*)"$/, async (username, password) => {
     await loginPage.login(username, password);
});

 

Page Class with methods and objects

    get txtUsername() { return BasePage.elementById("Username"); }
    get txtPassword() { return BasePage.elementById("Password"); }
    get btnLogin() { return BasePage.elementByXpath("//button[@value='login']"); }

public async login(username: string, password: string) {
        await Utils.sendKeys(this.txtUsername, username);
        await Utils.sendKeys(this.txtPassword, password);
        await Utils.click(this.btnLogin, "login submit Button and user is logging in", 50000);
    }

    public async openBrowser(url: string) {
        await browser.manage().deleteAllCookies();
        await browser.get(url);
    }

 

For more info check my Github repository:- https://github.com/khyati2010/protractor-cucumber/tree/develop

Recent Posts

See All

Comments


bottom of page