Page object models in CypressIO

Page object model[POM] framework is a design pattern where page objects are separated from automation Test scripts. Page Objects are nothing but web elements present on the web page like Buttons, links, tabs, text bars, etc.., The page object pattern contains classes with the locators and methods.

A page object is an object-oriented class that serves as an interface to a page. Here the web pages are represented as javascript classes, and the various elements on the page are defined as a method on the javascript classes.

We have to create a page object class for every page present in the application. If the application is a single page application (spa) we have to create page object classes for each tab.

The main advantages of the Page object models are :

  • Code reusability
  • Maintainable
  • Removes code duplication

pom-diagram-cypress

Let us consider a scenario where you will be entering the same username and password for a few sites. When you open the respective website in chrome you have to give the same username and password again and again to login to the sites.

As a lifesaver, chrome permits us to save the password automatically. When required chrome auto-fills the username and password.

In the future, if you change the user name or password which is the same for multiple sites, we can update the new password at one place in the setting of the chrome and after that, the new password can be used everywhere.

In the same way, Page object models are like the lifesaver where it auto-fills the user name and password when the locators are called.

In the future, if the locators of an element are changed, then we can update the new locator of the element in the POM class and not in every test scripts. POM class serves as the interface between the credentials and the website, where only when you call the POM the credentials will be filled.

Usually, page object operations should return fundamental types (strings, numbers, etc). However, it’s important to point out that we can also return another page object (that’s a good practice if we’re navigating to another page).

Creation of POM class

  • Create a folder named Pages under the integration folder of the cypress.
  • In the folder name Pages, create a .js file where you have to use the locators and the methods again and again in the various test scripts as below image.

pom-folder-creation-cypress

In the below .js script of the Pages folder, there are four methods namely,

  • visit() : The function of this method is to visit the respective URL
  • fillName(value) : The function of this method is as follows,
    • to get the element
    • to clear the already existing value
    • types the value which is passed in this method.

Whenever the fillName(value) method is called, it returns the typed value. In this case, the username is returned.

  • fillPassword(value) : The function of this method is as follows,
    • to get the element
    • to clear the already existing value
    • types the value which is passed in this method.

Whenever the fillPassword(value) method is called, it returns the typed value. In this case, the password is returned.

  • submit() : The function of this method is to click the Sign in button. The value of the button is stored in the variable name button
  • We should export the login page class so that the locators and the methods can be reused/ imported into the other .js files.
  • We can import the LoginPage class in any of our test scripts.
class LoginPage {
visit(){
  cy.visit("http://zero.webappsecurity.com/login.html")
}
fillName(value){
  const field=cy.get("#user_login")
  field.clear()
  field.type(value)
  return this
}
fillPassword(value){
  const field=cy.get("#user_password")
  field.clear()
  field.type(value)
  return this
}
submit(){
 const button= cy.contains("Sign in")
 button.click()
}
}
export default LoginPage 

The main aim of this test script is to inherit the URL and the locators which are in the Pages folder.

To use the locators of the loginpage.js in the HomePage.js we should import the class : LoginPage on the HomePage by passing the path of the file in the HomePage.js as below,

import LoginPage from '../pages/loginpage'

Example program :

import LoginPage from '../pages/loginpage'
describe("Homepage", function () {
  it("try to login", () => {
    const lp=new LoginPage()
    lp.visit()
    lp.fillName("chercher.tech")
    lp.fillPassword("password");
    lp.submit();
    cy.title().should('be.equal','Zero - Log in')
  })
  })

To override the locators in the LoginPage class execute the HomePage.js file in the test runner.
pom-execution-testrunner-cypress-io

Output :

pom-output-cypress-io

But usually, for testing, we follow the below procedure by having the locators in one separate file and their function in another file and the test script.

  • Create a folder named Pages and functions under the integration folder of the cypress.
  • In the folder name Pages, create a .js file where you have to use the locators, and in the functions folder create the .js file where you have to use the function of the locators[methods] again and again in the various test scripts as below image.

pom-folder-creation-cypressio

In the loginpage.js the locators are alone defined with the class name Login_page.

class Login_Page {
 username(){
 return cy.get("#user_login")
}
}
export default Login_Page 

In the login_func.js the function of the locators is defined and the class LoginFunc is extended to the class LoginPage so that the LoginFunc class makes use of the locators present inside the LoginPage class.

import LoginPage from "../pages/loginpage"
class LoginFunc extends LoginPage {
    visit(){
      cy.visit("http://zero.webappsecurity.com/login.html")
    }
    fillName(value){
      this.username().clear()
      this.username().type(value) 
      return this
    }  
    }
    export default LoginFunc

The main aim of the below test script is to inherit the locators and its functions which are in the Pages and functions folder.

To use the locators of the loginpage.js in the HomePage.js we should import the class : LoginFunc on the HomePage by passing the path of the file in the HomePage.js as below.

We haven't imported the LoginPage class since the LoginFunc is extended to the LoginPage class, so the LoginFunc automatically inherits the LoginPage class.

import LoginFunc from '../functions/login_func'
describe("Homepage", function () {
  it("try to login", () => {
    const lf=new LoginFunc()
    lf.visit()
    lf.fillName("Cherchertech")
  })
  })

Output :
pom-output-cypress

The below image was taken from the official website of cypress which gives the disadvantage and the reason why the Cypress team suggests we should not use the page object models in CypressIO.

pom-problems-cypress

0 results
Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions