</>

Technology

Cucumber

Difficulty

Advanced

Interview Question

How do you integrate Cucumber with Page Object Model (POM)?

Answer

Cucumber + Page Object Model Integration

Project Structure

CODE
src/
  test/
    java/
      pages/
        BasePage.java          ← shared driver methods
        LoginPage.java         ← login locators + actions
        DashboardPage.java     ← dashboard locators + actions
        CheckoutPage.java
      stepDefinitions/
        LoginSteps.java        ← calls LoginPage methods
        CheckoutSteps.java
      hooks/
        Hooks.java             ← @Before driver init, @After quit
      context/
        TestContext.java        ← shared state (PicoContainer)
      runners/
        TestRunner.java

TestContext — Shared Driver via DI

Java
package context;

import org.openqa.selenium.WebDriver;
import pages.*;

public class TestContext {
    public WebDriver driver;
    public LoginPage loginPage;
    public DashboardPage dashboardPage;
    public CheckoutPage checkoutPage;

    public TestContext() {
        // driver initialized in @Before hook
    }
}

Hooks.java — Driver Lifecycle

Java
package hooks;

import context.TestContext;
import io.cucumber.java.Before;
import io.cucumber.java.After;
import io.cucumber.java.Scenario;
import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import pages.*;

public class Hooks {

    private final TestContext ctx;

    public Hooks(TestContext ctx) {
        this.ctx = ctx;
    }

    @Before
    public void setUp() {
        WebDriverManager.chromedriver().setup();
        ctx.driver = new ChromeDriver();
        ctx.driver.manage().window().maximize();

        // Initialize all page objects with the same driver
        ctx.loginPage      = new LoginPage(ctx.driver);
        ctx.dashboardPage  = new DashboardPage(ctx.driver);
        ctx.checkoutPage   = new CheckoutPage(ctx.driver);
    }

    @After
    public void tearDown(Scenario scenario) {
        if (scenario.isFailed()) {
            byte[] screenshot = ((TakesScreenshot) ctx.driver)
                .getScreenshotAs(OutputType.BYTES);
            scenario.attach(screenshot, "image/png", "Failure Screenshot");
        }
        ctx.driver.quit();
    }
}

LoginPage.java — Page Object

Java
package pages;

import org.openqa.selenium.*;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;

public class LoginPage extends BasePage {

    @FindBy(id = "username")
    private WebElement usernameField;

    @FindBy(id = "password")
    private WebElement passwordField;

    @FindBy(css = "button[type='submit']")
    private WebElement loginButton;

    @FindBy(css = ".error-message")
    private WebElement errorMessage;

    public LoginPage(WebDriver driver) {
        super(driver);
        PageFactory.initElements(driver, this);
    }

    public void navigateTo(String url) {
        driver.get(url + "/login");
    }

    public void enterUsername(String username) {
        usernameField.clear();
        usernameField.sendKeys(username);
    }

    public void enterPassword(String password) {
        passwordField.clear();
        passwordField.sendKeys(password);
    }

    public void clickLogin() {
        loginButton.click();
    }

    public String getErrorMessage() {
        return errorMessage.getText();
    }
}

LoginSteps.java — Step Definitions Call POM

Java
package stepDefinitions;

import context.TestContext;
import io.cucumber.java.en.*;
import static org.testng.Assert.*;

public class LoginSteps {

    private final TestContext ctx;

    public LoginSteps(TestContext ctx) {  // PicoContainer injects
        this.ctx = ctx;
    }

    @Given("the user is on the login page")
    public void navigateToLogin() {
        ctx.loginPage.navigateTo(System.getProperty("baseUrl", "https://example.com"));
    }

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

    @When("the user clicks the Login button")
    public void clickLogin() {
        ctx.loginPage.clickLogin();
    }

    @Then("the user should be on the dashboard")
    public void verifyDashboard() {
        assertTrue(ctx.driver.getTitle().contains("Dashboard"));
    }

    @Then("the error message {string} should be displayed")
    public void verifyError(String expected) {
        assertEquals(expected, ctx.loginPage.getErrorMessage());
    }
}

Feature File

Gherkin
Feature: User Login

  @smoke @P1
  Scenario: Login with valid credentials
    Given the user is on the login page
    When the user enters username "admin@test.com" and password "Admin@123"
    And the user clicks the Login button
    Then the user should be on the dashboard

  @regression
  Scenario: Login with invalid password
    Given the user is on the login page
    When the user enters username "admin@test.com" and password "wrong"
    And the user clicks the Login button
    Then the error message "Invalid credentials" should be displayed

Follow AutomateQA

Related Topics