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
