Bird
Raised Fist0
Selenium Javatesting~15 mins

Base page class pattern in Selenium Java - Build an Automation Script

Choose your learning style10 modes available
Automate login page using base page class pattern
Preconditions (2)
Step 1: Open the browser and navigate to the login page URL
Step 2: Enter 'testuser' in the username input field
Step 3: Enter 'Test@1234' in the password input field
Step 4: Click the login button
Step 5: Verify that the user is redirected to the dashboard page by checking the URL contains '/dashboard'
✅ Expected Result: User successfully logs in and dashboard page is displayed with URL containing '/dashboard'
Automation Requirements - Selenium WebDriver with Java
Assertions Needed:
Verify username input field is present and enabled
Verify password input field is present and enabled
Verify login button is clickable
Verify URL contains '/dashboard' after login
Best Practices:
Use BasePage class to hold common WebDriver and wait utilities
Use explicit waits for element visibility and clickability
Use Page Object Model to separate page actions and locators
Use meaningful method names for page actions
Automated Solution
Selenium Java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;

// BasePage class holds common driver and wait
public class BasePage {
    protected WebDriver driver;
    protected WebDriverWait wait;

    public BasePage(WebDriver driver) {
        this.driver = driver;
        this.wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    protected WebElement waitForVisibility(By locator) {
        return wait.until(ExpectedConditions.visibilityOfElementLocated(locator));
    }

    protected WebElement waitForClickable(By locator) {
        return wait.until(ExpectedConditions.elementToBeClickable(locator));
    }
}

// LoginPage class extends BasePage and contains login page actions
public class LoginPage extends BasePage {
    private By usernameInput = By.id("username");
    private By passwordInput = By.id("password");
    private By loginButton = By.id("loginBtn");

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

    public void enterUsername(String username) {
        WebElement userField = waitForVisibility(usernameInput);
        userField.clear();
        userField.sendKeys(username);
    }

    public void enterPassword(String password) {
        WebElement passField = waitForVisibility(passwordInput);
        passField.clear();
        passField.sendKeys(password);
    }

    public void clickLogin() {
        WebElement loginBtn = waitForClickable(loginButton);
        loginBtn.click();
    }
}

// Test class to automate the login test case
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class LoginTest {
    private WebDriver driver;
    private LoginPage loginPage;

    @BeforeEach
    public void setUp() {
        driver = new ChromeDriver();
        driver.manage().window().maximize();
        driver.get("https://example.com/login");
        loginPage = new LoginPage(driver);
    }

    @Test
    public void testSuccessfulLogin() {
        loginPage.enterUsername("testuser");
        loginPage.enterPassword("Test@1234");
        loginPage.clickLogin();

        // Wait for URL to contain '/dashboard'
        boolean urlContainsDashboard = new WebDriverWait(driver, Duration.ofSeconds(10))
            .until(d -> d.getCurrentUrl().contains("/dashboard"));

        Assertions.assertTrue(urlContainsDashboard, "URL should contain '/dashboard' after login");
    }

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

The BasePage class holds the WebDriver and WebDriverWait objects. It provides common methods to wait for element visibility and clickability. This avoids repeating wait code in every page class.

The LoginPage class extends BasePage and contains locators and actions specific to the login page. It uses the wait methods from BasePage to ensure elements are ready before interacting.

The LoginTest class sets up the ChromeDriver, opens the login page URL, and uses the LoginPage methods to perform login steps. It then waits for the URL to contain '/dashboard' and asserts this condition to verify successful login.

This structure follows the Page Object Model and uses explicit waits for reliability. It keeps code clean, reusable, and easy to maintain.

Common Mistakes - 4 Pitfalls
Not using explicit waits and directly interacting with elements
Duplicating WebDriver and wait code in every page class
Using hardcoded Thread.sleep() for waiting
Locating elements inside test methods instead of page classes
Bonus Challenge

Now add data-driven testing with 3 different username and password combinations

Show Hint

Practice

(1/5)
1. What is the main purpose of a BasePage class in Selenium Java testing?
easy
A. To define the main method for running tests
B. To store test data for different test cases
C. To group common web actions and avoid code repetition across page classes
D. To handle database connections during tests

Solution

  1. Step 1: Understand the role of BasePage

    The BasePage class contains common methods like click, type, and wait that many page classes use.
  2. Step 2: Identify the benefit

    By grouping these common actions, BasePage helps avoid repeating the same code in every page class.
  3. Final Answer:

    To group common web actions and avoid code repetition across page classes -> Option C
  4. Quick Check:

    BasePage groups common actions = A [OK]
Hint: BasePage holds shared actions to reuse in all pages [OK]
Common Mistakes:
  • Confusing BasePage with test data storage
  • Thinking BasePage runs tests directly
  • Mixing BasePage with database handling
2. Which of the following is the correct way to declare a BasePage class constructor that accepts a WebDriver instance in Java?
easy
A. public BasePage(WebDriver driver) { this.driver = driver; }
B. public void BasePage(WebDriver driver) { this.driver = driver; }
C. BasePage(WebDriver driver) { driver = this.driver; }
D. public BasePage() { WebDriver driver; }

Solution

  1. Step 1: Identify correct constructor syntax

    In Java, constructors have no return type and match the class name exactly.
  2. Step 2: Check parameter assignment

    The constructor should assign the passed driver to the class field using this.driver = driver;.
  3. Final Answer:

    public BasePage(WebDriver driver) { this.driver = driver; } -> Option A
  4. Quick Check:

    Constructor no return + this.driver = driver [OK]
Hint: Constructor has no return type and uses this.driver = driver [OK]
Common Mistakes:
  • Adding void return type to constructor
  • Reversing assignment order
  • Declaring driver inside constructor without class field
3. Given the following BasePage method, what will be the output if the element is not found within 5 seconds?
public void clickElement(By locator) {
  WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
  wait.until(ExpectedConditions.elementToBeClickable(locator)).click();
  System.out.println("Clicked successfully");
}
medium
A. Prints 'Clicked successfully' after clicking the element
B. Prints 'Clicked successfully' immediately without waiting
C. Throws NoSuchElementException and prints 'Clicked successfully'
D. Throws TimeoutException and does not print anything

Solution

  1. Step 1: Understand WebDriverWait behavior

    The wait.until waits up to 5 seconds for the element to be clickable.
  2. Step 2: Outcome if element not found

    If the element is not clickable within 5 seconds, wait.until throws a TimeoutException and the click and print statements are skipped.
  3. Final Answer:

    Throws TimeoutException and does not print anything -> Option D
  4. Quick Check:

    Wait fails = TimeoutException, no print [OK]
Hint: Wait throws TimeoutException if element not clickable in time [OK]
Common Mistakes:
  • Assuming print runs even if element not found
  • Confusing TimeoutException with NoSuchElementException
  • Thinking click happens immediately without wait
4. Identify the error in this BasePage method and how to fix it:
public void enterText(By locator, String text) {
  WebElement element = driver.findElement(locator);
  element.sendKeys();
}
medium
A. sendKeys() is missing the text argument; fix by adding sendKeys(text)
B. findElement should be replaced with findElements
C. Method should return boolean indicating success
D. Locator type By is incorrect; use String instead

Solution

  1. Step 1: Check sendKeys usage

    The sendKeys method requires a String argument to input text.
  2. Step 2: Fix the method call

    Change element.sendKeys(); to element.sendKeys(text); to send the provided text.
  3. Final Answer:

    sendKeys() is missing the text argument; fix by adding sendKeys(text) -> Option A
  4. Quick Check:

    sendKeys needs text argument [OK]
Hint: sendKeys always needs the text argument [OK]
Common Mistakes:
  • Calling sendKeys without arguments
  • Using findElements instead of findElement for single element
  • Changing locator type incorrectly
5. You have a BasePage with a method public boolean isElementVisible(By locator) that returns true if element is visible. How would you use this method in a LoginPage class to verify the login button is visible before clicking it?
hard
A. if (isElementVisible()) { clickElement(loginButtonLocator); }
B. if (isElementVisible(loginButtonLocator)) { clickElement(loginButtonLocator); }
C. clickElement(loginButtonLocator); isElementVisible(loginButtonLocator);
D. isElementVisible(loginButtonLocator); clickElement();

Solution

  1. Step 1: Use isElementVisible with locator argument

    The method requires a By locator to check visibility, so pass loginButtonLocator.
  2. Step 2: Conditionally click if visible

    Use an if statement to call clickElement(loginButtonLocator) only if the element is visible.
  3. Final Answer:

    if (isElementVisible(loginButtonLocator)) { clickElement(loginButtonLocator); } -> Option B
  4. Quick Check:

    Check visibility with locator before click [OK]
Hint: Check visibility with locator before clicking [OK]
Common Mistakes:
  • Calling isElementVisible without locator argument
  • Clicking without checking visibility
  • Calling clickElement without locator
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard