Instantiating PageObject instances from within Cucumber StepDefinitions

493 views Asked by At

I'm trying to follow this tutorial online: https://www.youtube.com/watch?v=x5Ru0f8uOqw&list=PL_noPv5wmuO_t6yYbPfjwhJFOOcio89tI&index=14

and have coded the PageObjects, Feature file and StepDefs file exactly as per the demo. However, when I run, I get a null pointer exception at Line16, contactPage in the @When method.

public class StepDefinition {

WebDriver driver = new FirefoxDriver();
LandingPage landingPage;
ContactPage contactPage;

@Given("^I am on the zoo site$")
public void i_am_on_the_zoo_site() throws Throwable {
    LandingPage landingPage = new LandingPage(driver);
    landingPage.navigateToWebApp();
}

@When("^I click on \"(.*?)\"$")
public void i_click_on(String link) throws Throwable {
    contactPage = landingPage.navigateToContactPage(link);
}

...so I tried instantiating at the top of the class like so:-

WebDriver driver = new FirefoxDriver();
LandingPage landingPage = new LandingPage(driver);
ContactPage contactPage = new ContactPage(driver);

...and everything is happy.

Should I have to instantiate the pageobject instance in this way? What would be the best practice? And, why would the code in the demo not throw a null pointer?

For context, here are the relevant pageobjects: Abstract Page:-

public class AbstractPage {

protected WebDriver driver;

public AbstractPage (WebDriver driver){
    this.driver = driver;
}

public LandingPage navigateToWebApp(){
    driver.navigate().to("http://thetestroom.com/webapp/");
    return new LandingPage(driver);
}


public void closeDriver(){
    driver.quit();
    }
}

Landing Page:-

public class LandingPage extends AbstractPage {


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

public ContactPage navigateToContactPage(String link){
    driver.findElement(By.id(link.toLowerCase() + "_link")).click();
    return new ContactPage(driver);
    }
}

Contact Page:-

public class ContactPage extends AbstractPage{


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

public ContactPage setNameField(String value){

    driver.findElement(By.name("name_field")).sendKeys(value);
    return new ContactPage(driver);
}

//more setter methods
1

There are 1 answers

0
Ben Smith On BEST ANSWER

Yes, you do need to create new instances of the page objects i.e.

LandingPage landingPage = new LandingPage(driver);
ContactPage contactPage = new ContactPage(driver);

This is an essential practice as just having:

LandingPage landingPage

means that your landingPage variable is implicitly assigned a null value; this is why you are getting your null pointer exception.