0

I'm getting NullPointerException when trying to create test by extending abstract class and test class. Error:

java.lang.NullPointerException at pages.UserRegistrationPage.fillName(UserRegistrationPage.java:61) at UserRegistrationpageTest.fillName(UserRegistrationpageTest.java:26) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124) at org.testng.internal.Invoker.invokeMethod(Invoker.java:571) at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:707) at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:979) at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125) at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109) at org.testng.TestRunner.privateRun(TestRunner.java:648) at org.testng.TestRunner.run(TestRunner.java:505) at org.testng.SuiteRunner.runTest(SuiteRunner.java:455) at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450) at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415) at org.testng.SuiteRunner.run(SuiteRunner.java:364) at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84) at org.testng.TestNG.runSuitesSequentially(TestNG.java:1187) at org.testng.TestNG.runSuitesLocally(TestNG.java:1116) at org.testng.TestNG.runSuites(TestNG.java:1028) at org.testng.TestNG.run(TestNG.java:996) at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72) at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)

The driver gets initialized, opens the test page and exception is thrown when trying to fill in the field. My classes:

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

    public class UserRegistrationPage extends AbstractPage{

        @FindBy(id = "input-firstname")
        private WebElement firstName;

        @FindBy(id = "input-lastname")
        private WebElement lastName;

        @FindBy(id = "input-email")
        private WebElement email;

        @FindBy(id = "input-telephone")
        private WebElement telephone;

        @FindBy(xpath = "//*[@id=\"input-fax\"]")
        private WebElement fax;

        @FindBy(id = "input-address-1")
        private WebElement address;

        @FindBy(id = "input-city")
        private WebElement city;

        @FindBy(id = "input-postcode")
        private WebElement postcode;

        @FindBy(id = "input-country")
        private WebElement country;

        @FindBy(id = "input-zone")
        private WebElement zone;

        @FindBy(id = "input-password")
        private WebElement password;

        @FindBy(id = "input-confirm")
        private WebElement passwordConfirm;

        @FindBy(css = "#content input[type=\"checkbox\"]:nth-child(2)")
        private WebElement agreeCheckbox;

        @FindBy (xpath = "//*[@id=\"content\"]/form/div/div/input[2]")
        private WebElement submitButton;

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


        public void fillName(String name){
            this.firstName.sendKeys(name);
        }
    }

public abstract class AbstractTest {

    protected WebDriver driver;
    @BeforeSuite
    public void setUpDriver(){
        driver = new FirefoxDriver();
    }
}

public class UserRegistrationpageTest extends AbstractTest{

    private UserRegistrationPage userRegistrationPage = new UserRegistrationPage(driver);


    @BeforeTest
    void openURL(){
        driver.get("http://88.119.151.54/opencartone/index.php?route=account/register");
    }

    @AfterTest
    void closeBrowser(){
        driver.quit();
    }

    @Test
    void fillName(){
        userRegistrationPage.fillName("John");
    }

}

What I'm missing here?

3 Answers 3

2

Reason being : 'driver' member of 'UserRegistration' page remains null , when you reach at 'userRegistrationPage.fillName("John")' line .

see this

enter image description here

This is because @BeforeSuite (method lying inside 'AbstractTest' test gets called after constructor of UserRegistrationPage gets called . So sequence right now is

1) Constructor of AbstractPage . (here your driver is null)

2) Constructor of UserRegistrationPage . (here your driver is null)

3) @BeforeSuite of AbstractTest. (here your driver will not be null , but till this time you have already initialized object of 'UserRegistrationPage' using line in 'UserRegistrationpageTest' class

private UserRegistrationPage userRegistrationPage = new UserRegistrationPage(driver);

To solve this , change initialization location of 'UserRegistrationPage' object inside 'openURL' as shown below

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

0

When using 'PageFactory' you need to initialize the WebElements. add it to the 'AbstractPage'

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

5 Comments

Strange, now getting NullPointerException, but a bit different: 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.$Proxy9.sendKeys(Unknown Source) at pages.UserRegistrationPage.fillName(UserRegistrationPage.java:61) at UserRegistrationpageTest.fillName(UserRegistrationpageTest.java:26) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
@Sig Try to move it to UserRegistrationPage constructor.
No luck, but whats strange if I replace TestNG with Junit everything works fine.
@Sig I'm not familiar enough with those platforms to help you. Post a new question with the information.
@Sig - How many @Test methods are you having in your Test class ? The @BeforeSuite is built to be executed only once per <suite> and the @BeforeTest is built to be executed only once per <test> tag. So if you need this on a per test class basis, you should be using @BeforeClass and if you need this webdriver creation on a per @Test method basis then you should be using @BeforeMethod. But remember that the moment you build tests which all share the driver object on a per class basis, you are limiting yourself to sequential execution.
0

The UserRegistrationPage which extends the AbstractPage uses the WebDriver instance driver. Hence you need to define the constructor as :

WebDriver driver;

//constructor
public UserRegistrationPage(WebDriver driver)
{
    this.driver=driver;
}

1 Comment

I believe the OP's code is already doing this by invoking super(driver). So this constructor is not needed.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.