DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Overcoming MFA Test Automation Challenges
  • Design Patterns for Scalable Test Automation Frameworks
  • Running and Debugging Tests With Playwright UI Mode
  • Exploring Playwright’s Feature “Copy Prompt”

Trending

  • Java Virtual Threads and Scaling
  • Revolutionizing Financial Monitoring: Building a Team Dashboard With OpenObserve
  • My LLM Journey as a Software Engineer Exploring a New Domain
  • Concourse CI/CD Pipeline: Webhook Triggers
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Testing, Tools, and Frameworks
  4. Implementing Page Object Model for Playwright Tests

Implementing Page Object Model for Playwright Tests

In this article, we will be discussing the Page Object Model and how we can leverage its benefits in implementing Playwright tests.

By 
Gunjan Kaushik user avatar
Gunjan Kaushik
·
Dec. 22, 23 · Tutorial
Likes (1)
Comment
Save
Tweet
Share
3.3K Views

Join the DZone community and get the full member experience.

Join For Free

Test automation eases the test execution in the software development lifecycle, but it comes with its own set of challenges. One of the most important aspects of writing effective automation suites is their maintainability. To be able to scale the frameworks easily, it is essential to write clear, modular, and segregated scripts to minimize inter-dependence. If the scripts are written without any format, it can lead to a lot of overhead in their maintenance. This is where the Page Object Model comes to the rescue. In this article, we will be discussing the Page Object Model and how we can leverage its benefits in Playwright tests.

What Is a Page Object Model?

Page Object Model, or POM is an automation pattern that helps to create reusable components by encapsulating elements of a web page along with their interactions in a single class. These classes are a representation of each web page of the application and serve as reusable components.

Each page object class contains the implementation details to facilitate interaction with the user interface.

What Are the Benefits of Using the Page Object Model?

Page Object Model comes with several benefits for the creation of robust and scalable frameworks. Some of the advantages are discussed below:

Improves Test Code Maintainability

  • The test code becomes cleaner and easier to maintain by encapsulating page interactions.
  • If the UI is updated anywhere in the future, it is easy to update only the page class, reducing the need to make huge changes in the framework.
  • Whenever new tests are added, only page object methods are required without the need to work on element locators again.
  • Segregation between the test code and the UI interaction code is promoted.

Promotes Reusability

  • Using page object classes, we can share the common actions across multiple tests.
  • Since page objects encapsulate reusable logic, code duplicity is reduced.
  • For example, a login page can be used for multiple tests using the login method.

Hides UI Implementation Details

  • Test methods or test scripts work with methods like login(), search(), etc. directly without the need to expose the code within these methods.
  • Test scripts do not directly interact with the UI elements, hence protecting the scripts from the effect of UI changes.

Robust Tests, Less Vulnerable to UI Changes

  • The test scripts are less brittle to UI changes. If any UI element is updated, only the page object class needs to be updated.
  • As compared to updating many locators spread across the script, it is very easy to maintain the scripts using POM.

Clean Separation of Test Code and Page Interactions

  • The test case logic is focused on validations rather than UI details.
  • The test actions are translated to UI interactions using the page object.
  • Separation makes code modular and easier to maintain.

What Are the Disadvantages Related to the Page Object Model?

While the Page Object Model provides a lot of benefits, there are some potential drawbacks that one should consider.

Complexity Due To Additional Classes

  • Other than maintaining the tests, additional page object classes are introduced.
  • More files and classes are created in the project structure.
  • New members might take some time to understand the page object structure.

Page Object Needs to Sync With UI

  • If there is any update in the UI, the page object needs to be updated to accommodate the changes.
  • If any additional feature is added to the web page, corresponding page objects might need the addition of new methods to handle the same.
  • Using page objects will not eliminate the need for maintenance of any change in the flow, and locators will still require maintenance of the page objects.

Abstraction Layer Is Added

  • Although abstraction helps hide UI implementation details, it can become difficult to access or verify elements at times.
  • It can sometimes lead to difficulty in debugging issues.

Now that we understand what the page object model is and how it can be helpful to us let us see how we can implement it in our Playwright Tests.

Implementing Page Object Model for Playwright Tests

To begin writing Playwright tests, ensure that you have downloaded and installed Visual Studio Code. Also, download and install Node JS in your system.

Let us now look through the steps to creating the structure of our Playwright Page Object Model project.

1. Create a new directory for the project. I have created a directory called PlaywrightPOM in my system.

2. Next, we open the directory in Visual Studio Code(VS Code)we created in Step#1. Click on File > Open > Select the directory name you have created(PlaywrightPOM).

You will see it in the VS Code Explorer, as shown below:

playwrightPOM

3. We next install the playwright by clicking on Terminal > New Terminal. In the terminal, write the below command:

npm init playwright@latest

This command will prompt you to answer certain questions and select them as per your requirements.

Once the above command is executed, you will see that files and folders have been added to the project, as shown in the snapshot below:

files and folders

4.  Next, we will create two more folders, viz, pages, and utilities in the project directory. The pages folder will hold the page objects of our page object model. The Utilities folder, on the other hand, will contain common utilities(if any) for the project.
pages and utilities

5. Before we start writing the scripts, we will install the browsers by entering the below command in the terminal:

npx playwright install

6. We are now all set with our project structure, and we will now start writing our tests, but before that, let us see the use case steps that we will be using to implement the POM for the Playwright Test.

  1. Navigate to testgrid.io.
  2. Click on the Get Started button.
  3. Enter details in the Sign Up Form.

Note that you can automate your own use case by following the approach mentioned below.

7. To achieve this, we will be using Typescript. Let us first create one file inside the pages folder and name it home.page.ts. In this file, we will write our code to locate the elements on the page and perform actions on them:

home.page.ts

TypeScript
 
import { expect, Locator, Page } from '@playwright/test';

export class TestGridHomePage{

readonly url="https://testgrid.io/";

readonly page: Page;

readonly getStartedButton: Locator;



constructor(page: Page){

this.page = page;

this.getStartedButton = page.locator('text=Get started');

}



async goTo(){

await this.page.goto(this.url);

}



async getStarted(){

await this.getStartedButton.click();

}





}


Code Walkthrough

TypeScript
 
import { expect, Locator, Page } from '@playwright/test';


Imports Playwright test library classes that will be used in the page object.

export class TestGridHomePage{

Defines the TestGridHomePage class that will contain the page object logic.

TypeScript
 
readonly url="https://testgrid.io/";

readonly page: Page;

readonly getStartedButton: Locator;


Read-only fields are declared where:
  • URL is used to declare the TestGrid base URL.
  • Page, field of type Page that will reference the Playwright Page object.
  • getStartedButton, locator field to store the Get Started button locator.
TypeScript
 
constructor(page: Page){

this.page = page;

this.getStartedButton = page.locator('text=Get started');

}


  • Constructor is created to accept the Page object and initialize the page and locator fields.

TypeScript
 
async goTo(){

await this.page.goto(this.url);

}


  • goTo() method is used to navigate to the base URL.

TypeScript
 
async getStarted(){

await this.getStartedButton.click();

}


  • getStarted() method is used to click on the Get Started button.

We will create another page class, viz, register..page.ts, that will be used to hold the elements of the Sign Up page that we see after clicking on the Get Started button. The code for the same will be:

register.page.ts

TypeScript
 
import { expect, Locator, Page } from '@playwright/test';

export class RegistrationPage{

readonly page: Page;

readonly fullName: Locator;

readonly email: Locator;

readonly mobile: Locator;

readonly password: Locator;

readonly signUpButton: Locator;



constructor(page: Page){

this.page = page;

this.fullName = page.locator('id=full_name');

this.email = page.locator('id=business_email');

this.mobile = page.locator('id=mobile_number');

this.password = page.locator('id=password');

this.signUpButton = page.locator('id=signin-button');

}



async fillForm(){

await this.fullName.fill("Your Name");

await this.email.fill("Your email id");

await this.mobile.fill("Your mobile number");

await this.password.fill("Your choice password");

await this.signUpButton.click();

}



}


Code Walkthrough

TypeScript
 
readonly page: Page;

readonly fullName: Locator;

readonly email: Locator;

readonly mobile: Locator;

readonly password: Locator;

readonly signUpButton: Locator;


  • Read-only fields are declared for the page, and the signup form elements.

TypeScript
 
constructor(page: Page){

this.page = page;

this.fullName = page.locator('id=full_name');

this.email = page.locator('id=business_email');

this.mobile = page.locator('id=mobile_number');

this.password = page.locator('id=password');

this.signUpButton = page.locator('id=signin-button');

}


  • A constructor is created to initialize the page and its elements using the locators.

TypeScript
 
async fillForm(){

await this.fullName.fill("Your Name");

await this.email.fill("Your email id");

await this.mobile.fill("Your mobile number");

await this.password.fill("Your choice password");

await this.signUpButton.click();

}


  • The fillForm() method is used to fill in the details of the signup form. You can add more lines of code to the method to handle specific scenarios in your case.

8. The next step is to write the test file to execute our test case. We create a home.test.ts file and write the below code in it:

TypeScript
 
import{test,expect} from '@playwright/test';

import { TestGridHomePage } from "../pages/home.page";

import { RegistrationPage } from '../pages/register.page';

test('TestGrid Get Started Flow',async ({page}) => {

const homePage = new TestGridHomePage(page);

const regPage = new RegistrationPage(page);

await homePage.goTo();

await homePage.getStarted();

const delay = ms => new Promise(resolve => setTimeout(resolve, ms));

await delay(10000);

await regPage.fillForm();

})


Code Walkthrough

TypeScript
 
import { TestGridHomePage } from "../pages/home.page";

import { RegistrationPage } from '../pages/register.page';


We import the required pages in the test.

TypeScript
 
const homePage = new TestGridHomePage(page);

const regPage = new RegistrationPage(page);


References to the pages of the POM are created using which we will refer to the methods of the page classes.
TypeScript
 
await homePage.goTo();

await homePage.getStarted();


  • The goTo() and the getStarted() methods of the home page are called to navigate to the URL and click on the Get Started Button respectively.

TypeScript
 
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));

await delay(5000);


  • We are using a promise to set a timeout to handle network lags here. You may use other ways to handle timeout scenarios in your project as per your requirements.

await regPage.fillForm();

  • Finally, we call the fillForm() method to fill up the details in the sign up form using the registration page object.

Once these files are created, your project directory will look like the below:

directory

9. You can now execute this test file using the below command:

npx playwright test home.test.ts –headed

By default, the playwright executes in headless mode; hence, use –headed to execute the test in headed mode. Once this command is executed, you will see that your test is executed, and the results are displayed in the console as below: 

console

Additionally, you can look at the generated report to look at the results of execution:

get started flow

Conclusion

To summarise the Page Object Model, we can conclude on below points:

  • Page Object Model POM is a design pattern that helps to create a robust and maintainable automation framework.
  • Due to the ease of handling the scripts and segregating the test logic from the UI interactions, POM helps in creating efficient and scalable frameworks.
  • POM eases the process of updating the page objects in case of changes in the UI or the flow by just having the need to update the page object classes with minimal need to touch the test scripts.
  • Although POM makes the tests more readable and maintainable, it might sometimes create problems in debugging issues.
  • POM when implemented in a clear and concise manner, can help in creating modular frameworks reusing page objects wherever necessary.
Object model Testing Test automation

Published at DZone with permission of Gunjan Kaushik. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Overcoming MFA Test Automation Challenges
  • Design Patterns for Scalable Test Automation Frameworks
  • Running and Debugging Tests With Playwright UI Mode
  • Exploring Playwright’s Feature “Copy Prompt”

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!