What is Page Object Model (POM)?
- It is used to create a separate class or object repository for each page of the application under test.
- Instead of writing locators and actions directly inside the test scripts, you define them in Page Classes.
- Each class contains: Locators (elements on that page), Methods (actions or business logic you can perform on that page)
- Each webpage of the application is represented as a class.
- Inside that class: Define locators for elements on the page (e.g., username field, login button). Define methods to interact with those elements (e.g., enterUsername(), clickLogin()).
- You just call the methods from the Page Object class instead of repeating locators and actions.
- Create LoginPage class → define locators & methods.
- Create HomePage class → define locators & methods.
- In the test file, call loginPage.login("user","pass") and verify HomePage actions.
Why Use POM in Playwright?
- Playwright supports parallel execution and complex applications → POM keeps tests structured.
- Large projects with many pages and workflows become easier to manage.
- Helps teams follow clean automation architecture, where any change in UI affects only Page Object files, not every test.
- Reusability: Common actions can be reused across multiple tests.
- Maintainability: If a locator changes, you update it in one place (Page Class), not across all tests.
- Readability: Test scripts become more readable since they call methods like loginPage.enterUsername() instead of handling locators directly.
- Separation of Concerns: Test logic and page structure are kept separate.
Website to be automated:
https://opensource-demo.orangehrmlive.com/web/index.php/auth/login
1. Maven Dependencies
Added dependencies of Cucumber, TestNG and Playwright
<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>
login.feature
)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
package utils; import com.microsoft.playwright.*; public class PlaywrightFactory { private static Playwright playwright; private static Browser browser; private static BrowserContext context; private static Page page; public static void initBrowser() { playwright = Playwright.create(); browser = playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(false)); context = browser.newContext(); page = context.newPage(); } public static Page getPage() { return page; } public static void closeBrowser() { browser.close(); playwright.close(); } }
package pages; import com.microsoft.playwright.Page; public class LoginPage { private Page page; // Locators private String usernameField = "#username"; private String passwordField = "#password"; private String loginButton = "#button[type='submit']"; private String dashboardText = "h6[class='oxd-text oxd-text--h6 oxd-topbar-header-breadcrumb-module']"; // Constructor public LoginPage(Page page) { this.page = page; } public void navigateToLoginPage() { page.navigate("https://opensource-demo.orangehrmlive.com/web/index.php/auth/login"); } public void enterUsername(String username) { page.fill(usernameField, username); } public void enterPassword(String password) { page.fill(passwordField, password); } public void clickLogin() { page.click(loginButton); } public boolean isDashboardVisible() { return page.isVisible(dashboardText); } }
package stepdefinitions; import com.microsoft.playwright.Page; import io.cucumber.java.After; import io.cucumber.java.Before; import io.cucumber.java.en.*; import pages.LoginPage; import utils.PlaywrightFactory; import org.testng.Assert; public class LoginSteps { private Page page; private LoginPage loginPage; @Before public void setup() { PlaywrightFactory.initBrowser(); page = PlaywrightFactory.getPage(); loginPage = new LoginPage(page); } @Given("User is on login page") public void user_is_on_login_page() { loginPage.navigateToLoginPage(); } @When("User enters username {string} and password {string}") public void user_enters_username_and_password(String username, String password) { loginPage.enterUsername(username); loginPage.enterPassword(password); loginPage.clickLogin(); } @Then("User should see the dashboard page") public void user_should_see_the_dashboard_page() { Assert.assertTrue(loginPage.isDashboardVisible(), "Dashboard"); } @After public void tearDown() { PlaywrightFactory.closeBrowser(); } }
package testrunners; import io.cucumber.testng.AbstractTestNGCucumberTests; import io.cucumber.testng.CucumberOptions; @CucumberOptions( features = "src/test/java/features", glue = {"stepdefinitions"}, plugin = {"pretty", "html:target/cucumber-report.html"}, monochrome = true ) public class TestRunner extends AbstractTestNGCucumberTests { }
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" > <suite name="Cucumber with TestNG"> <test name="CucumberTests"> <classes> <class name="testrunners.TestRunner" /> </classes> </test> </suite>
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