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

    0
      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
      • 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
        CommentedDec 21, 2017 at 12:19
      • @Sig Try to move it to UserRegistrationPage constructor.
        – Guy
        CommentedDec 21, 2017 at 12:32
      • No luck, but whats strange if I replace TestNG with Junit everything works fine.
        – Sig
        CommentedDec 21, 2017 at 12:56
      • @Sig I'm not familiar enough with those platforms to help you. Post a new question with the information.
        – Guy
        CommentedDec 21, 2017 at 13:02
      • @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.CommentedDec 22, 2017 at 3:19
      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
      • I believe the OP's code is already doing this by invoking super(driver). So this constructor is not needed.CommentedDec 22, 2017 at 3:17

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.