How To Reference WebDriver in Page Object Models(POM classes) and Test Classes in Selenium

Temi OdeyTemi Odey
3 min read

In automation Testing, structuring your project using the Page Object Model (POM) is one of the most effective ways to build a maintainable and scalable test framework. A critical part of this structure is how you manage your WebDriver instance. Improper initialization or reference of the WebDriver can lead to test failures, exceptions, or inconsistent test behavior.

In this article, I’ll walk you through best practices for instantiating and referencing WebDriver across your POM classes and test classes, helping you build a reusable and clean Selenium framework.

What is WebDriver?

WebDriver is a core interface in Selenium that serves as the bridge between your code and the browser. It controls browser actions, allowing your script to interact with web elements and navigate URLs.

Each browser (Chrome, Firefox, Safari, etc.) has its own driver class — such as ChromeDriver, FirefoxDriver, or SafariDriver. These classes implement the WebDriver interface and allows you to launch and manipulate browser instances.

When building a framework, using WebDriver effectively means passing it between your test and page classes — not creating new instances repeatedly.

❌ Don’t instantiate WebDriver in every class — this leads to unnecessary browser instances and breaks test flow.

✅ Instead, instantiate it once in the test class (or a base class), and pass it as a reference to POM classes.

Using WebDriver: POM Class vs. Test Class

In a well-structured framework, you should separate your Page Object class from your Test class. Typically, you’d organize them into separate packages:

  • pages package → contains all your POM classes

  • tests package → contains all your test classes

Structure of a POM Class

In the POM class:

  • Identify the web-elements you want to interact with.

  • Declare instance variables for WebDriver and any other Selenium utilities (e.g., Actions class).

  • Use a constructor to pass in the WebDriver instance.

  • Define reusable methods to interact with the page.

Sample Login Page Class- LoginPage.java

public class LoginPage {

    WebDriver driver;
    Actions action;

    //Constructor
    public LoginPage(WebDriver driver) {
      PageFactory.initElement(driver, this);
      action = new Actions(driver);
// pagefactory is a factory class to make using page objects and declaring elements easier and simpler
    }

    //Locators
    By usernameField = By.id("username");
    By passwordField = By.id("password");
    By loginButton = By.id("login");

    //Login Method
    public void login(String username, String password) {
        driver.findElement(usernameField).sendKeys(username);
        driver.findElement(passwordField).sendKeys(password);
        driver.findElement(loginButton).click();

    }

}

Structure of a Test Class

In your test class:

  • Instantiate the WebDriver.

  • Open the desired URL.

  • Instantiate the POM class and use its methods to perform actions.

Sample Login Test Class - LoginTest.java

public class LoginTest {
    WebDriver driver;

    @BeforeMethod
    public void setup() {
//instantiating driver
        driver = new ChromeDriver();
        driver.manage().window().maximize();
        driver.get("https://whatever-example.com");
    }

    @Test
    public void callLogin() {
        LoginPage loginPage = new LoginPage(driver);
        loginPage.login("user", "password");
    }

    @AfterMethod
    public void tearDown() {
        driver.quit();
    }

}

Referencing WebDriver via BaseTest

Another approach to instantiating your WebDriver for use in other test class(es) is to use a BaseTest class for initializing and cleaning up the WebDriver. Then, extend it in your test classes.

Sample Base Test Class - BaseTest.java

Public class BaseTest {

Protected WebDriver driver;


@BeforeClass
public void setup() {

        WebDriverManager.chromedriver().setup();
        driver = new ChromeDriver();
        driver.manage().window().maximize();
        driver.get("https://whatever-example.com");

    }


    @AfterClass
    public void tearDown() {
        driver.quit();
    }


}

Sample LoginTest.java Extending BaseTest

Public class LoginTest  extends BaseTest{

@Test
    public void loginFunction {
        LoginPage loginPage = new LoginPage(driver);
        loginPage.login("user", "password");
    }


}

Conclusion

Properly referencing WebDriver in your POM and test classes is essential for building a robust, scalable automation framework. Avoid the temptation to create WebDriver instances in every page or use static drivers indiscriminately. Instead:

  • Instantiate WebDriver once (either in the test or a base class).

  • Pass it to page classes through constructors.

  • Keep your logic separated using the Page Object Model pattern.

This leads to cleaner, more maintainable code that scales well with larger test suites.

Happy Testing! 🚀

7
Subscribe to my newsletter

Read articles from Temi Odey directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Temi Odey
Temi Odey

I help build better software through smart testing processes, in-depth quality analysis, and proactive defect management.