1

Im using Cucumber BDD framework with Selenium+Java. Now, I have made on BaseClass.Java in which i declare on public static WebDriver driver;

Now, in my .feature file i have many scenarios and in each scenario's steps: Given, when, then - i need to initialize the PageFactory.initElements(driver, class) again as if i dont do, then i get nullpointer expection.

Now, instead of creating object of each PageObject class and then passing main driver instance in it's constructor, im extending all PO classes and STep definition class the BaseClass.java. Now, these directly have the driver instance inherited.

There is no need to create object of any class and its working fine as only 1 driver session is maintained throughout my test.

So, none of my class has its own local WebDriver driver; instance as its using the driver , that it inherited by default from the base class.

Is it ok to use such design pattern?

1
  • No, it is not OK. You should use dependency injection capabilities of Cucumber. Either picocontainer, or guice or spring.
    – Alexey R.
    Dec 23, 2021 at 21:48

1 Answer 1

0

Ideas like base classes and util classes are usually anti-patterns (see here and here). One basic heuristic for good OO design is composition over inheritance, because it gives more flexibility in changes and makes unit testing easier.

As Alexey said, you can use dependency injection to create your page objects. You can see an example project here.

Generally speaking, you can do like this:

Step file:

class Step {

constructor(Driver driver) { this.driver = driver; }

fun openMainPage() {
 this.mainPage = new MainPage(this.driver)
 this.mainPage.open()
}

fun login(username, password) {
 this.loggedPage = this.mainPage.login(username, password)
}

}

Then on each page object, you can receive the driver in the constructor:\

class MainPage {

constructor(Driver driver) { this.driver = driver; }


fun login(username, password) {
 fillUsername(username)
 fillPassword(password)
 clickOnLogin()
 return new LoginPage(this.driver)
}

}

And if you have a sub-component in a page object, you can pass either a Driver or a WebElement in the constructor, so this object can use only what you control.

And you can unit test the page objects by passing a fake Driver/WebElements, which you can control in the tests.

By using dependency injection, a change in one page object won't affect others and you will be able to use stack traces to easily track issues.

Your Answer

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

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