top of page
  • Writer's picturekhyati sehgal

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

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

5 views0 comments

Recent Posts

See All

JavaScript elements handling in selenium

As we see most of the applications are moving towards development with Angular, React, Aurelia, JS, TS bases scripting language and framework which uses these scripting languages. When it comes to Qua

bottom of page