0
votes

Selenium pageFactory NullPointerException. Any help will be appreciated. It works for the login of setUp(), but after that driver comes up null.

public class TestBase {

    public WebDriver driver;
    String url = PropertiesFile.readPropertiesFile("autUrl");

    public WebDriver getDriver() {
        System.setProperty("webdriver.chrome.driver", 
        System.getProperty("user.dir") + "/driver/chromedriver.exe");

        driver = new ChromeDriver();

        return driver;
    }

    public void getUrl(String url) {
        driver.get(url);
        driver.manage().window().maximize();
    }

    public void init() {
        getDriver();
        getUrl(url);
    }
}



public class LogInPage extends TestBase {
    WebDriver driver;
    @FindBy(id = "loginEmail")public WebElement userName_field;
    @FindBy(name = "password")public WebElement password_field;
    @FindBy(xpath = "//*[@id='main-content']/aside/div/form/input[2]")public WebElement SignMeIn_btn;

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

    // Login
    public void logIn(String userName, String password) {
        userName_field.sendKeys(userName);
        password_field.sendKeys(password);
        SignMeIn_btn.click();
    }

}


   public class LogIn extends TestBase {

    LogInPage logInPage;

    private String user = PropertiesFile.readPropertiesFile("user");
    private String password = PropertiesFile.readPropertiesFile("password");



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


    public void setUp(){
        init();
    }


    public void logIn(){
        logInPage = new LogInPage(driver);
        logInPage.logIn(user, password);
    }

}

public class PortalsPage extends TestBase {

    WebDriver driver;

    @FindBy(id = "loginEmail") public WebElement userName_field;
    @FindBy(xpath=".//*[@id='tabDetail']") public WebElement tenantPage_li;
    @FindBy(id="tabDetail") public WebElement ownerPage_li;
    @FindBy(xpath="//a[contains(@href,'tenant.action')]") public WebElement tenantPortal_link;
    @FindBy(xpath="//a[contains(@href,'owner.action')]") public WebElement ownerPortal_link;

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


    public void goToPortals(){      
        userName_field.sendKeys("a");
        tenantPage_li.click();
    }

}

public class Portals extends TestBase {
    PortalsPage portals;
    WebDriver driver;

    @BeforeClass
    public void setUp(){
        LogIn login = new LogIn(driver);
        login.setUp();
        login.logIn();

    }

    @Test
    public void goToPortal(){
        portals = new PortalsPage(driver);
        portals.goToPortals();
    }
}

Following exception I got:

FAILED: goToPortal java.lang.NullPointerException at org.openqa.selenium.support.pagefactory.DefaultElementLocator.findElement(DefaultElementLocator.java:69) at org.openqa.selenium.support.pagefactory.internal.LocatingElementHandler.invoke(LocatingElementHandler.java:38) at com.sun.proxy.$Proxy6.sendKeys(Unknown Source) at com.demo.pages.PortalsPage.goToPortals(PortalsPage.java:30) at com.demo.control.Portals.goToPortal(Portals.java:28) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80) at org.testng.internal.Invoker.invokeMethod(Invoker.java:714) at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901) at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231) at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127) at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111) at org.testng.TestRunner.privateRun(TestRunner.java:767) at org.testng.TestRunner.run(TestRunner.java:617) at org.testng.SuiteRunner.runTest(SuiteRunner.java:334) at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329) at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291) at org.testng.SuiteRunner.run(SuiteRunner.java:240) at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86) at org.testng.TestNG.runSuitesSequentially(TestNG.java:1198) at org.testng.TestNG.runSuitesLocally(TestNG.java:1123) at org.testng.TestNG.run(TestNG.java:1031) at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:132) at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:230) at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:76)

1
what does TestBase look like? Why do all the classes extend it and they each have their own driver instance except for Login?so cal cheesehead
Basically I want to get the driver's instance from TestBase. I was trying to with or without the local class instance in the Portals class. Tried both ways and got the same result.ktmrocks
I have added the TestBase class code as wellktmrocks

1 Answers

2
votes

Your current approach seems to be a bit convoluted. But without delving into the details of what other approach you can use to fix your overall design, here's a cleaned up version of your code, that should work.

The idea here is that you only need page classes (the ones that end with *Page which represent a particular page, and exposes some business functions that can be executed on that particular page) and test classes, with the test class themselves extending from your TestBase

So here are the classes

LoginPage.java

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

public class LogInPage {
    @FindBy(id = "loginEmail")
    private WebElement userNameTextField;
    @FindBy(name = "password")
    private WebElement passwordTextField;
    @FindBy(xpath = "//*[@id='main-content']/aside/div/form/input[2]")
    private WebElement signInButton;

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

    public void logIn(String userName, String password) {
        userNameTextField.sendKeys(userName);
        passwordTextField.sendKeys(password);
        signInButton.click();
    }

}

PortalsPage.java

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

public class PortalsPage {
    @FindBy(id = "loginEmail")
    private WebElement usernameTextField;
    @FindBy(xpath = ".//*[@id='tabDetail']")
    private WebElement tenantPage;
    @FindBy(id = "tabDetail")
    private WebElement ownerPage;
    @FindBy(xpath = "//a[contains(@href,'tenant.action')]")
    private WebElement tenantPortalLink;
    @FindBy(xpath = "//a[contains(@href,'owner.action')]")
    private WebElement ownerPortalLink;


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

    public void goToPortals() {
        usernameTextField.sendKeys("a");
        tenantPage.click();
    }
}

TestBase.java

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class TestBase {
    private WebDriver driver;

    protected WebDriver getDriver() {
        if (driver != null) {
            return driver;
        }
        System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir") + "/driver/chromedriver.exe");
        driver = new ChromeDriver();
        return driver;
    }

    public void getUrl(String url) {
        getDriver().get(url);
        getDriver().manage().window().maximize();
    }

}

PortalsTest.java

import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class PortalsTest extends TestBase {
    private PortalsPage portals;
    private String user = PropertiesFile.readPropertiesFile("user");
    private String password = PropertiesFile.readPropertiesFile("password");
    private String url = PropertiesFile.readPropertiesFile("autUrl");


    @BeforeClass
    public void setUp() {
        LogInPage login = new LogInPage(getDriver());
        getUrl(url);
        login.logIn(user, password);
    }

    @Test
    public void goToPortal() {
        portals = new PortalsPage(getDriver());
        portals.goToPortals();
    }
}