2
class LoginPage(){

///line of code


public LoginPage(WebDriver driver) {           
         this.driver = driver; 
         PageFactory.initElements(driver, this);
}

Can someone please explain the constructor part of the code. I don't understand why we declare a constructor and pass the driver instance here.

What makes passing the driver into the constructor such a common pattern?

2

2 Answers 2

3

This is just one of the approaches how you can initialize elements associated with your page. Here you just use the classic way to initialize everything when you object is being instantiated.

  1. You pass your WebDriver to the constructor of your class so that you have the WebDriver field withing the object of your class and you can access WebDriver functionality from your class's methods (which are not shown in your code snippets).
  2. You invoke PageFactory.initElements(driver, this); so that Selenium wraps the fields which are annotated with proxy objects.

Both the points above can be either done within a constructor so that they are executed when you do LoginPage loginPage = new LoginPage(driver); (i.e. instantiate your page object) or do it separately using setter methods and call initElements(..) outside of your class code. The author of your example obviously chose the first option.

1

There are multiple reasons for that. But first let's fix this code first:

class LoginPage(){
    WebDriver driver; //here you have global variable for this page object

    public LoginPage(WebDriver driver) {           
         this.driver = driver; 
         PageFactory.initElements(driver, this);
    }
}

You will want to have access to driver instance. You will need in more complicated PageObject some methods that will use any of methods implemented in Selenium such as: wait, findElement, getCurrentUrl and many more

Secondly your test will have some Steps where you actually create static instance of driver for example (using JUnit 4)

public class LoginTest {
    static WebDriver driver; //again global variable for test    

    @Before
    public void setUp() {
        driver = new ChromeDriver();
        driver.get("https://google.com/");
    }

    @Test
    public void testLoginPage() {
        LoginPage loginPage = new LoginPage(this.driver);
        // then perform some steps assertions 
        // and use another pageobject
        OtherPage otherPage = new OtherPage(this.driver);
    }
}

With this approach you are certain that:

  1. Always page objects in one test class will have the same instance of driver.
  2. Your page objects actually doesn't need to know anything about specific driver (if you change in your Test Class ChromeDriver() to FirefoxDriver() your page objects are good to go.

And that's why this approach is so common. Because it prevents a bunch of issues and reduce maintenance time for fixing tests.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.