Implementation of Page Object Model in Playwright

















What is Page Object Model (POM) in Playwright? A Complete Beginner-to-Advanced Guide with Cucumber and TestNG

If you are working in test automation, especially with modern tools like Playwright, you have probably heard about the Page Object Model (POM) design pattern. Whether you are an automation tester, SDET, or someone preparing for interviews, understanding POM is extremely important.

In this detailed, SEO-optimized, AdSense-friendly guide, you will learn:

  • What is Page Object Model (POM)?

  • Why POM is important in Playwright automation

  • Benefits of using POM

  • Real-time example using Playwright + Cucumber + TestNG

  • Complete framework structure explanation

  • Automation of OrangeHRM login page using POM

Let’s start step by step.


What is Page Object Model (POM)?

Page Object Model (POM) is a design pattern used in test automation where each web page (or component) of an application is represented as a separate class.

In simple words:

👉 Every page = One Java class
👉 All locators = Inside that class
👉 All actions (methods) = Inside that class

Instead of writing element locators and actions directly inside test scripts, we define them in separate Page Classes.

Each Page Class contains:

  • Locators – Web elements on that page (like username field, password field, login button)

  • Methods – Actions that can be performed on those elements (like enterUsername(), clickLogin())

This creates a clean separation between:

  • Test Logic

  • Page Structure


Page Object Model in Playwright

When using Playwright with Java, the Page Object Model works beautifully because Playwright provides powerful APIs for interacting with web elements.

In POM with Playwright:

  • Each webpage is represented as a class.

  • Inside that class:

    • Define locators for elements.

    • Define methods to interact with those elements.

  • In test scripts:

    • Call the methods from the Page Object class.

Instead of this (bad practice):

page.fill("#username", "admin"); page.fill("#password", "admin123"); page.click("#login");

We do this (clean practice):

loginPage.enterUsername("admin"); loginPage.enterPassword("admin123"); loginPage.clickLogin();

This makes the automation framework scalable and maintainable.


Why Use Page Object Model in Playwright?

Playwright supports:

  • Parallel execution

  • Cross-browser testing

  • Complex UI interactions

  • Modern web applications

In large automation projects, tests can become messy if everything is written inside test classes.

Using POM helps:

1. Structured Framework

Your automation code becomes organized and readable.

2. Easy Maintenance

If a locator changes, you update it in one place (Page class) instead of updating 50 test cases.

3. Better Collaboration

Teams can work on different page classes independently.

4. Clean Architecture

UI layer and test logic layer remain separate.


Benefits of Page Object Model

Let’s understand the advantages clearly.

1. Reusability

Common actions like login can be reused across multiple test cases.

Example:

  • Login test

  • Logout test

  • Add Employee test

  • Delete Employee test

All can reuse loginPage.login() method.


2. Maintainability

If the login button locator changes:

Old:

"#button[type='submit']"

New:

"button.oxd-button"

You only change it in LoginPage.java, not in every test file.


3. Readability

Test scripts become business-readable:

loginPage.login("admin", "admin123");

Instead of technical locator-heavy code.


4. Separation of Concerns

  • Page classes → Handle UI elements

  • Test classes → Handle validations and scenarios

This follows good automation design principles.


Website to be Automated

For this example, we are automating the OrangeHRM demo application:

https://opensource-demo.orangehrmlive.com/web/index.php/auth/login

This is a popular demo website used for automation practice.


Automation Framework Structure (Playwright + Cucumber + TestNG)

In this example, we are using:

  • Playwright (for browser automation)

  • Cucumber (for BDD)

  • TestNG (for execution)

  • Maven (for dependency management)


1. Maven Dependencies

Below are the required dependencies for Playwright, Cucumber, and TestNG:

<dependencies> <!-- Playwright --> <dependency> <groupId>com.microsoft.playwright</groupId> <artifactId>playwright</artifactId> <version>1.44.0</version> </dependency> <!-- Cucumber --> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-java</artifactId> <version>7.16.1</version> </dependency> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-testng</artifactId> <version>7.16.1</version> </dependency> <!-- TestNG --> <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>7.9.0</version> <scope>test</scope> </dependency> </dependencies>

These dependencies allow integration between Playwright, Cucumber, and TestNG.


2. Feature File (login.feature)

Feature files are written using Gherkin syntax.

Feature: Login Feature Scenario: Successful Login Given User is on login page When User enters username "admin" and password "admin123" Then User should see the dashboard page

This makes tests readable for non-technical stakeholders.


3. PlaywrightFactory.java (Browser Setup Utility)

This class is responsible for:

  • Initializing Playwright

  • Launching browser

  • Creating context

  • Providing Page object

  • Closing browser

It follows centralized browser management.

Key responsibilities:

  • Avoid duplicate browser initialization code

  • Improve framework scalability

  • Maintain single browser lifecycle control


4. LoginPage.java (Page Object Class)

This is the core of the Page Object Model.

Inside this class:

Locators:

  • Username field

  • Password field

  • Login button

  • Dashboard header text

Methods:

  • navigateToLoginPage()

  • enterUsername()

  • enterPassword()

  • clickLogin()

  • isDashboardVisible()

This class represents the Login Page completely.

Important design rule:

Page class should never contain assertions
It should only contain page-related actions

Assertions should be in step definitions or test classes.


5. LoginSteps.java (Step Definitions)

This class connects feature file steps to Java implementation.

Annotations used:

  • @Before

  • @Given

  • @When

  • @Then

  • @After

Flow:

  1. Initialize browser

  2. Navigate to login page

  3. Enter credentials

  4. Click login

  5. Verify dashboard

  6. Close browser

This maintains clear separation between:

  • Business steps (feature file)

  • Technical implementation (step definitions)

  • Page interactions (page class)


6. TestRunner.java (Cucumber + TestNG)

The TestRunner class:

  • Executes feature files

  • Connects glue code

  • Generates reports

  • Controls execution behavior

Key attributes:

  • features → Path of feature files

  • glue → Path of step definitions

  • plugin → Reporting configuration

  • monochrome → Clean console output

This enables BDD-style execution with TestNG support.


7. TestNG.xml (Optional Execution)

TestNG.xml allows:

  • Suite-level execution

  • Multiple runner classes

  • Group execution

  • Parallel execution control

Though optional, it is helpful in enterprise frameworks.


How the Complete Flow Works

Let’s understand execution flow:

  1. TestRunner starts execution.

  2. Cucumber reads login.feature.

  3. Step definitions get triggered.

  4. PlaywrightFactory initializes browser.

  5. LoginPage methods perform actions.

  6. TestNG validates assertion.

  7. Browser closes.

  8. Report gets generated.

This is a professional-level automation architecture.


Best Practices for Page Object Model in Playwright

To make your framework more robust:

1. Use Proper Locators

Prefer:

  • data-testid

  • role selectors

  • text selectors

Avoid unstable XPath.


2. Use Constructor Injection

Pass Page object via constructor (as shown in example).


3. Avoid Hardcoding URLs

Store URLs in config files.


4. Use Base Page Class

Create a BasePage with common methods like:

  • waitForElement

  • click

  • fill

  • scroll

Then extend it in all page classes.


5. Add Logging

Use logging framework to track execution steps.


Real-World Importance of POM

In real-time IT projects:

  • Applications have 100+ pages

  • Hundreds of test scenarios

  • Frequent UI changes

Without POM:

  • Maintenance becomes nightmare

  • Tests break frequently

  • Code duplication increases

With POM:

  • Clean structure

  • Easy debugging

  • Faster execution

  • Better team collaboration


Is Page Object Model Mandatory in Playwright?

No, but it is highly recommended.

For small scripts, you may skip it.

For professional automation frameworks, POM is considered a best practice.


Who Should Learn Page Object Model?

  • Automation Testers

  • SDET Engineers

  • QA Engineers

  • Software Developers

  • Freshers preparing for interviews

  • Anyone learning Playwright with Java

Since you are already working with automation topics and preparing technical content, mastering POM will significantly improve your framework design skills.


Conclusion

The Page Object Model (POM) is one of the most powerful design patterns in test automation. When combined with Playwright, Cucumber, and TestNG, it creates a highly scalable and maintainable automation framework.

In this guide, we covered:

  • What is POM

  • Why use POM in Playwright

  • Benefits of Page Object Model

  • Complete framework structure

  • OrangeHRM login automation example

  • Best practices

If you want to build a professional automation framework, always follow the Page Object Model design pattern.


Suggested Posts:

1. Handle IFrames in Playwright
2. Automate Login Page in Playwright
3. Comma Selectors in Playwright
4. Handle Alerts in Playwright
5. How to Show Visible Elements in Playwright

Comma Selectors in Playwright

















Comma Selectors in Playwright Java – Complete Guide with Examples

When working with modern web automation frameworks, flexibility in element selection is extremely important. In Playwright Java, one powerful yet often underused feature is the comma selector. Comma selectors allow you to combine multiple CSS selectors into a single locator, making your automation scripts more efficient, readable, and maintainable.

In this comprehensive guide, you’ll learn:

  • What comma selectors are in Playwright

  • How comma selectors work in Playwright Java

  • Practical real-world use cases

  • Java code examples with explanation

  • Best practices for maintainable test automation

  • SEO-friendly automation insights for testers and developers

If you are learning Playwright automation with Java, this guide will help you write smarter locators and reduce duplication in your test scripts.


What Are Comma Selectors in Playwright?

In Playwright Java, comma selectors refer to compound CSS selectors separated by commas (,) that allow you to target multiple elements at once.

This works exactly like standard CSS selector grouping.

Basic Syntax

Locator locator = page.locator("selector1, selector2, selector3");

This means:

  • Match all elements that satisfy selector1

  • OR match all elements that satisfy selector2

  • OR match all elements that satisfy selector3

Playwright merges all matching elements into a single Locator collection.

Why Use Comma Selectors in Playwright?

Comma selectors are extremely useful in automation testing when:

  • An element may appear in different formats.

  • UI changes dynamically (mobile vs desktop).

  • Different builds show slightly different element names.

  • You want to perform bulk operations on multiple element types.

Instead of writing separate locators and conditionally handling them, you can combine them in a single line.

This improves:

  • Test readability

  • Code reusability

  • Maintenance

  • Stability of automation scripts


How Comma Selectors Work in Playwright Java

Let’s understand how Playwright evaluates comma selectors step by step.

1. Multiple Selectors in One Locator

When you write:

page.locator("a:has-text('Gmail'), a:has-text('GoogleMail')");

Playwright will:

  • Find all <a> elements containing "Gmail"

  • Find all <a> elements containing "GoogleMail"

  • Combine results into one locator


2. Merging Results

If both selectors match elements, Playwright merges them into a single collection.

You can then:

  • Click

  • Count

  • Assert visibility

  • Extract text

  • Filter using nth(), first(), or last()


3. Works Like CSS

Since Playwright supports CSS selectors, comma selectors follow standard CSS behavior.

Example:

page.locator("h1, h2, h3");

This selects all heading elements from <h1>, <h2>, and <h3>.


Website Example Used in This Guide

We will use:

https://www.google.com/

This example demonstrates how comma selectors work when selecting links like:

  • Gmail

  • Images

  • GoogleMail (if present in some variations)


Complete Java Playwright Example – Comma Selectors

Below is the full working Playwright Java code:

import com.microsoft.playwright.Browser; import com.microsoft.playwright.BrowserType; import com.microsoft.playwright.Locator; import com.microsoft.playwright.Page; import com.microsoft.playwright.Playwright; public class CommaSelectorsExample { public static void main(String[] args) { // this code will click Gmail or if instead of Gmail GoogleMail is present like or condition Playwright playwright = Playwright.create(); Browser browser = playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(false)); Page p1 = browser.newPage(); p1.navigate("https://www.google.co.in"); p1.locator("a:has-text('Gmail'),a:has-text('GoogleMail') ").click(); //For two links comma separated selector code is there Page p2 = browser.newPage(); p2.navigate("https://www.google.co.in"); Locator lc = p2.locator("a:has-text('Gmail'),a:has-text('Images') "); System.out.println(lc.count()); //click on Gmail by using xpath Page p3 = browser.newPage(); p2.navigate("https://www.google.co.in"); Locator gmailLocator = p2.locator("//a[text()='Gmail'] | //a[text()='GooleMail'] "); System.out.println(gmailLocator.textContent()); gmailLocator.click(); browser.close(); playwright.close(); } }


Code Explanation in Detail

Let’s break the code into simple steps so beginners can clearly understand it.


(a) Launching the Browser

Playwright playwright = Playwright.create(); Browser browser = playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(false));
  • Creates Playwright instance

  • Launches Chromium browser

  • setHeadless(false) allows you to see browser execution


(b) Navigating to the Website

p1.navigate("https://www.google.co.in");

This opens Google homepage.


(c) Using Comma Selector for OR Condition

p1.locator("a:has-text('Gmail'),a:has-text('GoogleMail') ").click();

This means:

  • If "Gmail" link exists → click it

  • If "GoogleMail" exists instead → click it

This behaves like a logical OR condition in automation.


(d) Counting Multiple Elements

Locator lc = p2.locator("a:has-text('Gmail'),a:has-text('Images') "); System.out.println(lc.count());

This counts how many elements match:

  • Gmail

  • Images

If both exist → count = 2
If only one exists → count = 1


(e) XPath Alternative Using Pipe Operator

Locator gmailLocator = p2.locator("//a[text()='Gmail'] | //a[text()='GooleMail'] ");

Here:

  • | works as OR in XPath

  • Similar concept to comma in CSS


Real-World Use Cases of Comma Selectors in Automation

Let’s explore practical automation scenarios.


1. Handling UI Variations

Sometimes in different environments:

  • Dev shows "Submit"

  • QA shows "Continue"

  • Prod shows "Proceed"

Instead of writing separate logic:

page.locator("button:has-text('Submit'), button:has-text('Continue'), button:has-text('Proceed')").click();

This makes your test environment-independent.


2. Mobile vs Desktop Testing

In responsive websites:

  • Desktop: <button>

  • Mobile: <a> styled as button

You can write:

page.locator("button#login, a#login").click();


3. Bulk Heading Validation

Locator headings = page.locator("h1, h2, h3"); System.out.println("Total headings: " + headings.count());

Useful for SEO validation testing.


4. Error Message Validation

Sometimes error messages appear as:

  • <div class="error">

  • <span class="error-text">

You can combine:

page.locator("div.error, span.error-text");


Advantages of Comma Selectors in Playwright

1. Reduces Code Duplication

No need to write multiple locators.

2. Improves Maintainability

One combined selector is easier to update.

3. Cleaner Test Logic

Avoids complex if-else blocks.

4. Flexible for Dynamic UIs

Works well with modern JavaScript-heavy applications.


Important Points to Remember

✔ Comma selectors follow CSS rules.
✔ Playwright returns a merged list of matched elements.
✔ You can filter using .first(), .last(), .nth(index).
✔ Use carefully — too many combined selectors reduce readability.


Best Practices for Using Comma Selectors

To keep your automation framework maintainable:

Use Only When Necessary

Don’t combine unrelated elements.

Keep Selectors Readable

Avoid extremely long comma-separated selectors.

Prefer Unique Identifiers

If possible, use id, data-testid, or stable attributes.

Combine with Assertions

After locating, verify visibility:

Locator element = page.locator("selector1, selector2"); if(element.count() > 0){ element.first().click(); }


CSS vs XPath – OR Conditions

Selector TypeOR Syntax
CSSselector1, selector2
XPath`//path1

Both achieve similar functionality.

In Playwright Java:

  • CSS is generally faster and cleaner.

  • XPath is useful for complex DOM traversal.


When NOT to Use Comma Selectors

Avoid using them when:

  • Elements are unrelated.

  • You need strict element control.

  • Test clarity is reduced.

Overusing comma selectors can make debugging harder.


Advanced Example – Filtering After Comma Selector

Locator locator = page.locator("button.primary, button.secondary"); locator.filter(new Locator.FilterOptions().setHasText("Submit")).click();

This selects:

  • Either primary or secondary button

  • But only if it contains "Submit"


Summary

Comma selectors in Playwright Java are a powerful way to:

  • Combine multiple element locators

  • Handle dynamic UI changes

  • Reduce duplication

  • Improve automation efficiency

They work exactly like CSS comma-separated selectors and are extremely helpful in real-world automation scenarios.

By using comma selectors wisely, you can create:

  • Stable automation frameworks

  • Clean test cases

  • Scalable test architecture

If you are preparing for automation interviews or building enterprise-level frameworks, mastering comma selectors will give you an edge.



Suggested Posts:

1. Handle IFrames in Playwright
2. Automate Login Page in Playwright
3. Comma Selectors in Playwright
4. Handle Alerts in Playwright
5. Handle Dynamic Webtable in Playwright