</>

Technology

Page Object Model

Difficulty

Intermediate

Interview Question

What is fluent interface / method chaining in POM? Show an example.

Answer

Fluent Interface / Method Chaining in POM

Method chaining makes tests read like a natural sentence by returning this (same page) or the next page object from each method.

Without Method Chaining (Verbose)

Java
@Test
public void testCheckout() {
    loginPage.enterEmail("alice@test.com");
    loginPage.enterPassword("Pass@123");
    loginPage.clickLogin();

    productPage.searchProduct("Laptop");
    productPage.selectProduct("MacBook Pro");
    productPage.clickAddToCart();

    cartPage.clickCheckout();
    cartPage.enterAddress("123 QA Street");
    cartPage.clickPlaceOrder();

    Assert.assertTrue(confirmPage.isOrderConfirmed());
}

With Method Chaining (Clean & Readable)

Java
@Test
public void testCheckout() {
    boolean confirmed = loginPage
        .enterEmail("alice@test.com")
        .enterPassword("Pass@123")
        .clickLogin()                     // returns ProductPage
        .searchProduct("Laptop")
        .selectProduct("MacBook Pro")
        .clickAddToCart()                 // returns CartPage
        .clickCheckout()                  // returns CheckoutPage
        .enterAddress("123 QA Street")
        .clickPlaceOrder()                // returns ConfirmPage
        .isOrderConfirmed();

    Assert.assertTrue(confirmed);
}

Implementation — Return This (Same Page)

Java
// LoginPage.java
public class LoginPage extends BasePage {
    private By emailInput    = By.id("email");
    private By passwordInput = By.id("password");
    private By loginBtn      = By.cssSelector("[data-testid='login-btn']");

    public LoginPage(WebDriver driver) { super(driver); }

    public LoginPage enterEmail(String email) {
        type(emailInput, email);
        return this;   // ← returns same page
    }

    public LoginPage enterPassword(String password) {
        type(passwordInput, password);
        return this;   // ← returns same page
    }

    public ProductPage clickLogin() {
        click(loginBtn);
        return new ProductPage(driver);   // ← returns NEXT page
    }
}
Java
// ProductPage.java
public class ProductPage extends BasePage {
    private By searchInput   = By.id("search");
    private By addToCartBtn  = By.cssSelector("[data-testid='add-to-cart']");

    public ProductPage(WebDriver driver) { super(driver); }

    public ProductPage searchProduct(String name) {
        type(searchInput, name);
        driver.findElement(By.id("search-btn")).click();
        return this;
    }

    public ProductPage selectProduct(String productName) {
        click(By.xpath("//h3[text()='" + productName + "']"));
        return this;
    }

    public CartPage clickAddToCart() {
        click(addToCartBtn);
        return new CartPage(driver);   // ← transition to next page
    }
}

Complex Chaining — With Assertions Built In

Java
// Return this even from assertion methods for chain continuation
public LoginPage verifyErrorMessage(String expected) {
    String actual = getText(errorMsg);
    Assert.assertEquals(actual, expected, "Error message mismatch");
    return this;   // can continue chaining
}

// Usage:
loginPage
    .enterEmail("bad@test.com")
    .enterPassword("wrong")
    .clickLoginExpectingError()
    .verifyErrorMessage("Invalid credentials")
    .verifyEmailFieldHighlighted();

Benefits

  • Readability — test reads like a user story
  • Fewer variables — no need to store intermediate page objects
  • Conciseness — fewer lines of code
  • Business alignment — PO/BA can read and verify the test flow

Follow AutomateQA

Related Topics