Understanding Page Object Model in Cucumber

Know about Page Object Model & Page Factory in Cucumber for better object repository structuring

Get Started free
Home Guide Page Object Model in Cucumber

Page Object Model in Cucumber

By Kailash Pathak, Community Contributor -

Page Object Model is a design pattern commonly used in enterprise test automation that makes an object repository for web UI elements. It helps us to cut back duplication and improves test maintenance.Test Automation helps in achieving this with better accuracy and in a shorter period of time, keeping product release cycles shorter.

How does Page Object Model (POM) work?

We can break POM into two-parts  (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.

PageObjectModel

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.

PageObjectModel2

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 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 the test cases in a very simple format and even be read and modified by a non-technical user. 

In BDD, Given-When-Thenis the suggestive approach for creating 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

Implementing POM with Cucumber and 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

CypressInstalled

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

InstallingCucumber

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

CreateFolders

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

Create sub folders

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

Create feature files 1

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

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 |

BrowserStack Automate Banner 8

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;
  • 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.

Run feature File

Running Test in Cucumber

Run Test with Cucumber

Passed Test Result

Test Output

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

FailedTestResult

Talk to an Expert

Conclusion

POM design pattern makes these test automation frameworks 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.

Tags
Automation Frameworks Automation Testing

Featured Articles

Cucumber Best Practices to follow for efficient BDD Testing

What is Cypress Page Object Model?

Automation Tests on Real Devices & Browsers

Seamlessly Run Automation Tests on 3500+ real Devices & Browsers