Page factory returns null in Selenium

1.5k views Asked by At

I have Hooks.java for driver class,LoginPage.java for all login page objects and step definition class. My page factory object is not initializing in my login class, it returns null due to null driver. Driver class having @Before tag and its initiate before all classes but the driver is null. When I use PageFactory.initElements(driver, LoginPage.class); in the hook class that time page factory initialize and program runs successfully. I am using it in LoginPage constructor, just wondering what I am doing wrong. Why page factory returns null? How to use page factory.

Following is the error java.lang.NullPointerException: Cannot invoke "org.openqa.selenium.WebElement.sendKeys(java.lang.CharSequence[])" because "steps.LoginPage.txtUserNameBox" is null

Please help. Thanks

Hooks.java 
package steps;


import Util.GetConfigProp;
import io.cucumber.java.After;
import io.cucumber.java.Before;
import io.cucumber.java8.En;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.PageFactory;

import java.io.IOException;

import java.net.URL;
import java.util.concurrent.TimeUnit;

public class Hooks extends BaseUtil implements En {

    BaseUtil base;
    //    GetConfigProp prop;
    static GetConfigProp prop;

    static {
        try {
            prop = new GetConfigProp();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public Hooks() {
        //Default constructor
        Before(() -> {
            DesiredCapabilities cap = new DesiredCapabilities();
            cap.setBrowserName("chrome");
            cap.setPlatform(Platform.WINDOWS);
            cap.setCapability("marionette", true);
            ChromeOptions COptions = new ChromeOptions();
            COptions.merge(cap);

            String hubUrl = null; //get hub url from properties file
            hubUrl = prop.getHubUrl();
            base.driver = new RemoteWebDriver(new URL(hubUrl), COptions);

            base.driver.navigate().to(prop.getUrl()); //get url from properties file
            base.driver.manage().window().maximize();
            base.driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
//            PageFactory.initElements(driver, LoginPage.class);

        });
    }

    public Hooks(BaseUtil base) {
        this.base = base;
    }


    public WebDriver getDriver() {
        return base.driver;

    }

    @After
    public void tearDown() {
        base.driver.quit();

    }
}
LoginPage.java
    package steps;


import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
import org.openqa.selenium.support.PageFactory;

public class LoginPage extends BaseUtil {
    BaseUtil base;
    @FindBy(how = How.ID, using = "user-name")
    public static WebElement txtUserNameBox;

    @FindBy(how = How.ID, using = "password")
    public static WebElement txtPassword;

    @FindBy(how = How.ID, using = "login-button")
    public static WebElement btnLogin;

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


    public void login() {

        System.out.println("this is title" + base.driver.getTitle());
        System.out.println("this is getwindow" + base.driver.getWindowHandle());
        txtUserNameBox.sendKeys("standard_user");
        txtPassword.sendKeys("secret_sauce");
        btnLogin.click();
    }

public void loginPassword() {
   //to be implement

}
}
MyStepdefs8.java
    package steps;

import io.cucumber.java8.En;


public class MyStepdefs8 extends LoginPage implements En {

    BaseUtil base;
    LoginPage login = new LoginPage();

    public MyStepdefs8(BaseUtil base) {
        this.base = base;
    }

    public MyStepdefs8() {
        Given("the user is on landing page", () -> {
            login.login();
        });
        When("^the user clicks button$", () -> {
            System.out.println("this is second step");
            loginPassword();
        });
    }

}
2

There are 2 answers

2
Priyanka On

In the class MyStepdefs8, when you are creating the object of LoginPage initializes the default constructor for LoginPage class. And hence it returns null when you are calling WebElements as they are not initialized yet.

LoginPage login = new LoginPage(driver);
1
Apps Maven On

Pass the driver instance when you are creating the object of Login Page in MyStepdefs8 class.

LoginPage login = new LoginPage(driver);

Otherwise it is initializing the default constructor of the Login Page.