Now see how clean your tests become. No locators, no findElement, no waits. Just clear action-and-verify steps that read like a user story.
public class BankingLoginTest extends BaseTest {
private LoginPage loginPage;
@BeforeMethod
public void goToLogin() {
getDriver().get("https://www.testerrank.com/banking");
loginPage = new LoginPage(getDriver());
}
@Test(groups = {"smoke"})
public void testSuccessfulLogin() {
DashboardPage dashboard = loginPage.loginAs(
"testuser", "password123");
Assert.assertTrue(dashboard.isLoaded(),
"Dashboard should load after login");
Assert.assertTrue(
dashboard.getWelcomeMessage().contains("Welcome"));
}
@Test(groups = {"regression"})
public void testInvalidLogin() {
loginPage.enterUsername("invalid");
loginPage.enterPassword("wrong");
loginPage.clickLogin();
Assert.assertTrue(loginPage.isErrorDisplayed());
Assert.assertEquals(loginPage.getErrorMessage(),
"Invalid credentials");
}
@Test(groups = {"regression"})
public void testLoginAndLogout() {
DashboardPage dashboard = loginPage.loginAs(
"testuser", "password123");
Assert.assertTrue(dashboard.isLoaded());
LoginPage loggedOut = dashboard.logout();
Assert.assertTrue(loggedOut.isDisplayed(),
"Should return to login page after logout");
}
}public class ShoppingFlowTest extends BaseTest {
@Test(groups = {"smoke"})
public void testSearchAndBuy() {
ShopHomePage home = new ShopHomePage(getDriver());
getDriver().get("https://www.testerrank.com/shopping");
CatalogPage catalog = home.searchFor("Laptop");
Assert.assertTrue(catalog.getProductCount() > 0,
"Search should return results");
catalog.addProductByName("Laptop Pro");
CartPage cart = home.openCart();
Assert.assertEquals(cart.getItemCount(), 1);
Assert.assertTrue(
cart.getItemNames().contains("Laptop Pro"));
CheckoutPage checkout = cart.proceedToCheckout();
checkout.fillShipping("John", "Doe", "john@doe.com",
"123 Main St", "Mumbai", "400001");
checkout.placeOrder();
Assert.assertTrue(checkout.isOrderConfirmed(),
"Order should be confirmed");
Assert.assertFalse(
checkout.getOrderNumber().isEmpty(),
"Order number should be generated");
}
}Look at how readable these tests are. Zero By.id(), zero findElement(), zero WebDriverWait. If the username field ID changes from "username" to "email", you update LoginPage.java once. All tests keep working.
The test class should only contain three things: setup, page method calls, and assertions. If you see any locators or findElement calls in a test class, something is wrong — refactor them into a page object.
Key Point: Tests with POM have zero locators, zero findElement calls. They read like user stories.