Cypress Page Object Model (POM) Implementation Guide
Dive into step-by-step instructions, best practices, and expert tips to integrate POM into your Cypress testing framework seamlessly.
Join the DZone community and get the full member experience.
Join For FreeTest automation has become an integral part of the software development life cycle, and the market is growing at an exponential pace. Every day, we are getting new tools and techniques for test automation; Cypress is one of the most advanced tools for performing test automation. We have different types of framework designs patterns and models for implementing cypress automation POM (Page Object model) is one of them, it is one of the most widely used test automation design patterns. In the page object model, we use object and class for the representation of locators and functions available on the web application for each web page.
In POM, we can bifurcate a web application into multiple pages, and for each page, we can create a particular class that will depict the functionalities available on the web page.
We keep all the locators associated with the page in these classes, which helps us in identifying objects on the web page while performing automation of an application.
Advantages of POM (Page Object Model)
There are multiple advantages of POM, including making the test framework easy to use and reducing redundancy.
- Reusability of code: POM is one of the most efficient ways to increase code reusability. While performing automation when the user will be defining a page class for a particular web page, it will contain all the functions and locators associated with that page. So, the user needs to define all this information at once, and it can be used on multiple occasions where an application needs to access that page for a particular flow; all the code that is written for that page can be reused. As we have multiple classes for multiple pages, possibilities of having duplicate locators get reduced. And we can use these locators and methods across test scenarios.
- Maintainability of code: Using POM, managing and maintaining already written code is easy. As users will have all the classes associated with particular pages in one place, it becomes easy to see which pages got covered as a part of POM, and users can easily use these pages while performing automation. By creating POM, we are separating pages as layers of methods and locators for each page, so it makes it easy for the test flow code in the test layers, and all the methods and objects stay in the POM layer.
- Changes accommodation: As web applications are bound to get updated during every release, there will be changes on multiple pages; using the page object model, we can easily handle those changes in our automation. With POM, if the element locator got changed for any of the web elements, we just need to update it in a single POM file, and it will be updated for all the scenarios that we are running. Similarly, if there comes a change related to some functionality, we just need to update the implementation of the method inside the page object model, and it can be handled.
Prerequisite for POM
For implementing POM in the test framework, a user needs to have a good understanding of test automation, locating web elements on the web application UI, knowledge of writing functions and methods, and an understanding of the OOPS concept, which is very important. System wise, for implementing through Cypress, we need to have Cypress (it should be up and running ) and a web application (stable and deployed on a test environment).
Implementation of POM-Based Test Framework
We will be learning this implementation in steps that are easily understandable.
Step 1: First, you need to create a folder naming it page objects under the Cypress folder, where you will keep all your page classes.
Step 2: We will create a JavaScript file naming it as login-page.js under the page object folder; in this file, we will keep the locator of all the web elements of the login page and methods to perform login functionality.
Step 3: Inside login-page.js, we need to create a loginUser class, which we will be exporting to the test scenarios which we will be writing in gherkins; inside this class, we will be creating objects named as elements. Inside this object, we will be storing the element locators of all the web elements of the login page in the form of key and value pairs.
class loginUser{
elements = { usernameInput : () => cy.get('input[name="userName"]'), passwordInput : () => cy.get('input[name="password"]'), loginBtn : () => cy.get('input[name="submit"]'), forgotPassword : () => cy.get('input[name="forgot"]'), successTxt : () => cy.get('h4'), errorTxt : () => cy.get('span') } }
export default loginPage;
Post creating this we will be writing mentors for multiple operations which we will be doing using the login page, such as logging into the application using username and password.
So we will be creating a method for basic actions which we need to perform on the login page.
Example: click on the submit button, enter a username, enter a password, and click on forgot password.
class loginUser{
elements = { usernameInput : () => cy.get('input[name="userName"]'), passwordInput : () => cy.get('input[name="password"]'), loginBtn : () => cy.get('input[name="submit"]'), forgotPassword : () => cy.get('input[name="forgot"]'), successTxt : () => cy.get('h4'), errorTxt : () => cy.get('span') } //method for entering username enterUsername(username) { this.elements.usernameInput().clear(); this.elements.usernameInput().type(username); } //method for entering password enterPassword(password) { this.elements.passwordInput().clear(); this.elements.passwordInput().type(password); }
//method for clicking on submit button clickSubmit() { this.elements.loginBtn().click(); } //method for clicking on forgot password clickForgot() { this.elements.forgotPassword().click(); }
}
Step 4: As we are following cucumber methodology, so now we will be creating a feature file where we will be writing test steps for a particular test scenario is given, when, and then. For each step, we will be creating a separate step definition file.
Here, for the login feature, the step login into the application is defined under the common.steps.js file.
import loginPage from '../../pageobjects/loginPage'
describe('POM world test', () => {
beforeEach(function() { // executes prior each test within it block cy.visit('https://firestick.com'); }) it('Verify Login successful', () => { const loginObj = new loginPage(); loginObj.enterUsername('test123') loginObj.enterPassword('tester@12345') loginObj.clickSubmit(); loginObj.elements.successTxt().should('have.text','Login Successfully'); })
it('Verify Login unsuccessful for wrong username/password', () => { const loginObj = new loginPage(); loginObj.enterUsername('test1234') loginObj.enterPassword('tester@123') loginObj.clickSubmit(); loginObj.elements.errorTxt().should('contain','Enter your userName and password correct'); }) })
Step 6: Now you can simply run the feature file for login using cypress commands, and it will execute the test case using the Page object model. We can execute it in both modes, headed and headless.
Conclusion
POM(Page Object Model) makes test automation implementation using Cypress extremely simple and easy to understand; its layered architecture helps users easily understand the flow of data. And we can achieve a good amount of code redundancy using this; if an element locator gets changed, it’s fairly easy to accommodate these changes in automation by just changing one locator at a single location. So, the usage of the POM design pattern is very well recommended.
Ready to join the testing revolution? Discover the perfect end-to-end testing solution for your needs.
Published at DZone with permission of Yogesh Solanki. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments