Page Object Model in Cucumber using Cypress

KailashPathak
8 min readSep 28, 2022

This blog originally published in https://www.browserstack.com/guide/page-object-model-in-cucumber

What is Page Object Model (POM)?

Page Object Model is a design pattern commonly used in test automation that makes an object repository for web UI elements. It helps us to cut back duplication and improves test maintenance.

We can break POM into two-part (PO+ M)

In POM we create objects of page class and by using this object we are able to interact with web elements and also the method of page class.

In POM each page within the web application contains a corresponding Page Class that includes the Web Elements and the Methods which operate on those Web Elements.

Benefit of Page Object Model:

  1. Code Re-usability: POM increases code reusability. Teams can write common methods which can be used for various pages. for instance, if there’s a date functionality that’s used on a different page. So, we will create a common method to handle the date functionality and use the identical for every page class.
  2. Code Readability: POM Improves readability because of the clean separation between test code and page-specific code as each web page has its individual class file to store its Locators, Methods, and Test Steps.
  • The page class file contains methods and related locators for the specific web page,
  • The Test class file contains related test steps for a specific web page.

For example, we have a home web page for which we can create 2 class files:

  • Page class : homePage.js: which contains locators and methods related to the home page
  • Test Class (homeTest.spec.js): It contains test steps related to the home page

3. Code Maintenance: Code maintenance is easy with POM. just in case any change comes we are able to directly change the code at the method level (the common method) and updates will reflect everywhere.

What is Cucumber and BDD?

Cucumber is a testing tool that supports behavior-driven development (BDD).

BDD aqueduct the space between business stakeholders and also the technical team through a standard platform and communication among the team becomes more transparent.

Gherkin language is used to write test cases in a very simple format and even be read and modified by a non-technical user.

In BDD, “Given-When-Then” is the suggestive approach for writing test cases.

Here is an example for better understanding:

Given the user has entered valid credentials

When a user clicks on the sign-in button

Then validates the content on the home page after login

Installing Cypress

Implement POM (Page Object Model) using the Cucumber and Cypress using the below high-level steps for Cypress installation

Step 1: Create a folder and Generate package.json

  • Create a project, here naming it as cypress_cucumber_updated
  • Use npm init command to create package.json file

Step 2: Install Cypress

To install Cypress, still, in the project folder, run > npm install cypress — save-dev

Once installed, Cypress version 9.7.0 is reflected as seen below

Installing Cucumber

Step 1: To install cucumber run this command run > npm install — save-dev cypress-cucumber-preprocessor

Once installed, Cucumber devDependency in package.json can be seen as below

Step 2: Add below code snippet in cypress > plugins > index.js

const cucumber = require(“cypress-cucumber-preprocessor”).default;

module.exports = (on, config) => {

on(“file:preprocessor”, cucumber());

};

Step 3: Add the below code snippet in package.json

“cypress-cucumber-preprocessor”: {

“nonGlobalStepDefinitions”: true

}

Step 4: Add the below line in cypress.json

{

“testFiles”: “**/*.feature”

}

Create a Folder Structure

Step 1: Create folder POM inside “Integration/examples”. Under POM create further TWO folder names Tests and Pages

Step 2

Create two subfolders for Home and log-in test under the Pages and Tests folder

Step 3

Now Create Two Feature files for Home and Login with name (HomeTest.feature, LoginTest.feature)

Create Feature files

In the first test case, we want to login with the valid and invalid user

Write the below code under the LoginTest.feature file attached below. LoginTest.feature file contain 2 Scenarios

Feature: I want to login into the site with valid and invalid data and search T-shirt

Background:

Given I navigate to the Website

Scenario: Login as new sign up user with valid data

When I entered valid crediential

| email | validpassword |

| qatubeupdate@yopmail.com | 12345 |

When User click on sign in button

Then Validate the title after login

Scenario: Login as new sign up user with invalid data

When I entered invalid crediential

| email | invalidpassword |

| qatubeupdate@yopmail.com | 123456 |

When User click on sign in button

Then Error message should display

| errormessage |

| Authentication failed |

In the second test case, we have to verify the links after successful login

Write the below code under the HomeTest.feature file attached below

Feature: I want open the Site and verify links in Home Page

Background:

Given I navigate to the Website

Scenario: Verify content in Home Page

When I views links in Home Page of the Site

| HomePageLinks |

| Contact us |

| Sign in |

| Women |

| Popular |

| Best Seller |

| Cart |

Create Page Class

We have created our feature file above now we need to create our page classes

Create loginPage.js class to cover login with valid/ invalid user scenario

Here we created Methods for enterUrl,enterUserNamePassword,clickOnSignInButton and validateErrorMessage() and we have exported the login object.

We will use these methods in our page class

/// <reference types =”cypress”/>

class LoginPage {

enetURL() {

cy.visit(“http://automationpractice.com/");

}

enterUserNamePassword(username, password) {

cy.contains(“Sign in”).click();

cy.get(“#email”).clear();

cy.get(“#email”).type(username);

cy.get(“#passwd”).clear();

cy.get(“#passwd”).type(password);

return this;

}

clickOnSignInButton() {

return cy.get(“#SubmitLogin”).click();

}

verifyPageTitle() {

return cy.title().should(“eq”, “My account — My Store”);

}

validateErrorMessage(errorMessage) {

return cy.contains(errorMessage);

}

}

const login = new LoginPage();

export default login;

Code walkthrough

In line #4 we have created the enterUrl() method to enter the site URL ,In line #7 we have created the enterUserNamePassword() method to enter the username and password on the login screen

In line #15 we have created clickOnSignInButton() method to click on Sign-in button,In line #18 we have created verifyPageTitle() method to verify page title after login

In the line #21 we have created validateErrorMessage() method to verify the error message when the user enters an invalid username and password,

In line #26 we are creating the object of login (*After this we need not create the object in the test class) and in #27 We are just exporting the object.

Create a homePage.js class to verify the contents on the Home page after login

/// <reference types =”cypress”/>

class HomePage {

searchItem(element) {

cy.contains(element.HomePageLinks).should(“be.visible”);

return this;

}

}

const homepage = new HomePage();

export default homepage;

In line #4 we have created searchItem() method to verify links on the home page

In line #9 we are creating the object of the homepage (*After this we need not create the object in the homePagetest class)

Create Test Class

Methods in page class are already created, now will use these methods in the Test class. Create loginTest.spec.js class to cover scenario login with valid/ invalid user

**NOTE: Make sure when creating a test class, “Given”, “When” and “Then” mapping should be the same as given in the respective feature file

import login from “../../Pages/LoginPage/loginPage”;

// Scenario 1 : Login with Valid crediential

Given(“I navigate to the Website”, () => {

cy.visit(“http://automationpractice.com/");

});

When(“I entered valid crediential”, (datatable) => {

datatable.hashes().forEach((element) => {

login.enterUserNamePassword(element.email, element.validpassword);

});

});

When(“User click on sign in button”, () => {

login.clickOnSignInButton();

});

Then(“Validate the title after login”, () => {

login.verifyPageTitle();

});

// Scenario 2 : Login with Invalid crediential and Verify error messsage

When(“I entered invalid crediential”, (datatable) => {

datatable.hashes().forEach((element) => {

login.enterUserNamePassword(element.email, element.invalidpassword);

});

});

When(“User click on sign in button”, () => {

login.clickOnSignInButton();

});

Then(“Error message should display”, (datatable) => {

datatable.hashes().forEach((element) => {

login.validateErrorMessage(element.errormessage);

});

});

Create homeTest.spec.js class to verify the link on the home page

import homePage from “../../Pages/HomePage/homePage”;

Given(“I navigate to the Website”, () => {

cy.visit(“http://automationpractice.com/");

});

When(“I views links in Home Page of the Site”, (datatable) => {

datatable.hashes().forEach((element) => {

homePage.searchItem(element);

});

});

Run Test Class

Run the test class using the following command:
yarn run cypress open

Both the feature files HomeTest.feature and LoginTest.feature can be seen. You can run either of these features or both of them.

Running Test in Cucumber

Passed Test Result

Failed Test Result

In the below screenshot we can see the test case is failed also in log in THEN part we can see the message “Authentication failed” is displaying

Conclusion

POM design pattern makes the test automation framework user-friendly by keeping tests and the element locators separate. it supports code reuse and code maintenance where changes to the UI for locating the elements are confined to the automation code only, without affecting the automated test cases.

Using Cucumber in the POM design pattern makes test cases more readable and easy to understand for the non-technical user.

☕️ Happy testing! ☕️

For more blogs please follow the below link

https://qaautomationlabs.com/blogs/

--

--

KailashPathak

|| Cypress.io Ambassador || https://qaautomationlabs.com/blogs || PMI-ACP® |ITIL® || PRINCE2® || Cypress|| Selenium| WebdriverIO |API Automation QATube®