Page Object Model with Cucumber, Selenium, and TestNG

  

To implement Page Object Model (POM) in CucumberSelenium, and TestNG, you structure your automation framework to separate page-related codetest step definitions, and test runners for modularity and maintainability.


What is Page Object Model (POM)?

POM is a design pattern in Selenium that creates an object repository for web UI elements. It helps reduce code duplication and improves test maintenance.


Page Object Model Implementation


pom.xml:

<dependencies>
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-java</artifactId>
        <version>7.14.0</version>
    </dependency>
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-testng</artifactId>
        <version>7.14.0</version>
    </dependency>
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>4.21.0</version>
    </dependency>
    <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>7.10.0</version>
        <scope>test</scope>
    </dependency>
</dependencies>




LoginPage.java (Page Object Class)

package pages;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

public class LoginPage {
    WebDriver driver;

    // Constructor
    public LoginPage(WebDriver driver) {
        this.driver = driver;
    }

    // Locators
    By username = By.id("username");
    By password = By.id("password");
    By loginBtn = By.id("login");

    // Actions
    public void enterUsername(String user) {
        driver.findElement(username).sendKeys(user);
    }

    public void enterPassword(String pass) {
        driver.findElement(password).sendKeys(pass);
    }

    public void clickLogin() {
        driver.findElement(loginBtn).click();
    }
}





BaseTest.java – Setup WebDriver

package utils;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import io.cucumber.java.After;
import io.cucumber.java.Before;

public class BaseTest {
    public static WebDriver driver;

    @Before
    public void setUp() {
        driver = new ChromeDriver();
        driver.manage().window().maximize();
    }

    @After
    public void tearDown() {
        driver.quit();
    }
}




LoginSteps.java – Step Definitions

package stepdefinitions;

import io.cucumber.java.en.*;
import pages.LoginPage;
import utils.BaseTest;

public class LoginSteps {
    LoginPage loginPage;

    @Given("user is on login page")
    public void user_is_on_login_page() {
        BaseTest.driver.get("https://example.com/login");
        loginPage = new LoginPage(BaseTest.driver);
    }

    @When("user enters username {string} and password {string}")
    public void user_enters_credentials(String username, String password) {
        loginPage.enterUsername(username);
        loginPage.enterPassword(password);
    }

    @And("clicks on login button")
    public void clicks_login_button() {
        loginPage.clickLogin();
    }

    @Then("user should be redirected to dashboard")
    public void user_redirected_to_dashboard() {
        String url = BaseTest.driver.getCurrentUrl();
        assert url.contains("dashboard");
    }
}




login.feature – Feature File

Feature: Login Feature

  Scenario: Successful login
    Given user is on login page
    When user enters username "admin" and password "admin123"
    And clicks on login button
    Then user should be redirected to dashboard




TestRunner.java – Cucumber Test Runner using TestNG

package testrunner;

import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;

@CucumberOptions(
    features = "src/test/java/features",
    glue = {"stepdefinitions", "utils"},
    plugin = {"pretty", "html:target/cucumber-report.html"},
    monochrome = true
)
public class TestRunner extends AbstractTestNGCucumberTests {
}


How it works together

  • login.feature defines the behavior.

  • LoginSteps.java maps Gherkin steps to Java code.

  • LoginPage.java abstracts UI elements & actions.

  • TestRunner.java executes scenarios using TestNG.

  • BaseTest.java manages driver lifecycle.



Benefits of POM + Cucumber + Selenium + TestNG

FeatureBenefit
POMEasy maintainability & reuse of locators
CucumberReadable tests in Gherkin format
SeleniumBrowser automation
TestNGTest management, reporting, parallel execution

How to use TestNG with Selenium

  

Below are the steps and code to integrate TestNG with Selenium in Java.


What is TestNG?

TestNG (Test Next Generation) is a testing framework inspired by JUnit and NUnit. It is designed to make testing easier and more powerful with:

  • Annotations (@Test, @BeforeMethod, @AfterMethod, etc.)

  • Grouping test cases

  • Parallel execution

  • XML-based configuration

  • Data-driven testing


Steps to Integrate TestNG with Selenium Java

  • Install TestNG Plugin in Eclipse

    • Go to Help > Eclipse Marketplace

    • Search for TestNG, install, and restart Eclipse

  • Add Selenium and TestNG Dependencies in pom.xml

    <dependencies>
        <!-- Selenium -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>4.21.0</version>
        </dependency>
    
        <!-- TestNG -->
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>7.9.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    

  1. Write TestNG Test Class with Selenium Code


Example Code

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class GoogleSearchTest {

    WebDriver driver;

    @BeforeClass
    public void setup() {
        // Set path to chromedriver
        System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
        driver = new ChromeDriver();
        driver.manage().window().maximize();
    }

    @Test
    public void testGoogleSearch() {
        driver.get("https://www.google.com");

        WebElement searchBox = driver.findElement(By.name("q"));
        searchBox.sendKeys("Selenium WebDriver");
        searchBox.submit();

        // Wait and verify title
        try { Thread.sleep(2000); } catch (InterruptedException e) {}
        String title = driver.getTitle();
        Assert.assertTrue(title.contains("Selenium WebDriver"), "Title does not contain expected text!");
    }

    @AfterClass
    public void tearDown() {
        if (driver != null) {
            driver.quit();
        }
    }
}


How to Run TestNG Test
  • Right-click on the test file →  Run As → TestNG Test
  • Or create a testng.xml:
    <!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >
    <suite name="MyTestSuite">
        <test name="GoogleTest">
            <classes>
                <class name="GoogleSearchTest" />
            </classes>
        </test>
    </suite>
    
    Then right-click on testng.xml → Run As → TestNG Suite.


    TestNG Annotations Summary


    AnnotationDescription
    @TestMarks a test method
    @BeforeClassRuns once before any method in the class
    @AfterClassRuns once after all methods in the class
    @BeforeMethodRuns before each test method
    @AfterMethodRuns after each test method