Skip to content
Advertisement

I can’t work out why “this.driver is null” when running an assertion

First time poster so apologies if I’m breaking some guidelines.

I’m teaching myself Java/Selenium/Chromedriver and I’ve hit the first problem that I haven’t been able to work out myself. I’ll do my best to represent it below but please ask for more info if I haven’t included what I needed to! Here is the test:

    @Test
public void loginAsTomSmith(){
    LoginPage loginPage = homePage.clickFormAuthentication();
    loginPage.enterUsername("tomsmith");
    loginPage.enterPassword("SuperSecretPassword!");
    SecureAreaPage secureAreaPage = loginPage.clickLogin();
    secureAreaPage.getBannerText();

    assertTrue(secureAreaPage.getBannerText()
                    .contains("You logged into a secure area!"),"Incorrect message displayed");
}

As you can see, I pass the driver from the homepage right over to the login page in my first step (I think). I then eventually pass it over to the secureareapage and it’s there that I get the following error when I run the assertion:

java.lang.NullPointerException: Cannot invoke "org.openqa.selenium.WebDriver.findElement(org.openqa.selenium.By)" because "this.driver" is null

It’s notable that I’ve been following an online course but I’m going rogue for this specific project and doing a few things that I wasn’t taught. For example, in the course every page object is a distinct class whereas I’ve decided to have all pages be an extension of a base page class so they can share basic methods more easily. I’m starting to worry that there have been consequences of that decision that I didn’t understand.

Anyway, since the project is so small it probably makes sense to post it in full. Thanks in advance for your help. Huge fan of your work!

package pages;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

public class BasePage{
    protected WebDriver driver;

    protected BasePage(WebDriver driver){
        this.driver = driver;
    }

    protected void clickLink(By linkTextBy){
        driver.findElement(linkTextBy).click();
    }

    protected void populateTextField(By textFieldBy, String inputText){
        driver.findElement(textFieldBy).sendKeys(inputText);

    }

    protected void clickButton(By buttonBy){
        driver.findElement(buttonBy).click();

    }
}

package pages;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

public class HomePage extends BasePage{
//    private WebDriver driver;
    private By formAuthenticationLink = By.linkText("Form Authentication");

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

    public LoginPage clickFormAuthentication(){
        clickLink(formAuthenticationLink);
        return new LoginPage(driver);
    }

}
package pages;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

public class LoginPage extends BasePage{
    private By usernameTextField= By.id("username");
    private By passwordTextField = By.id("password");
    private By loginButton = By.className("radius");


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

    public void enterUsername(String username){
        populateTextField(usernameTextField, username);
    }

    public void enterPassword(String password){
        populateTextField(passwordTextField, password);
    }

    public SecureAreaPage clickLogin(){
        clickButton(loginButton);
        return new SecureAreaPage(driver);
    }
}
package pages;

import org.openqa.selenium.*;
import org.openqa.selenium.WebDriver;

public class SecureAreaPage extends BasePage {
    private WebDriver driver;
    private By loginBanner = By.id("flash");

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

    public String getBannerText(){
        return driver.findElement(loginBanner).getText();
    }

}
package base;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import pages.HomePage;

public class BaseTests {
    private WebDriver driver;

        protected HomePage homePage;

        @BeforeClass
        public void setUp(){
            System.setProperty("webdriver.chrome.driver", "resources/chromedriver.exe");
            driver = new ChromeDriver();
            driver.get("https://the-internet.herokuapp.com/");

            homePage = new HomePage(driver);
        }

        @AfterClass
        public void tearDown(){
            driver.quit();
        }
}
package base;

import static org.testng.Assert.*;

import org.testng.annotations.Test;
import pages.LoginPage;
import pages.SecureAreaPage;

public class LoginTests extends BaseTests {

    @Test
    public void loginAsTomSmith(){
        LoginPage loginPage = homePage.clickFormAuthentication();
        loginPage.enterUsername("tomsmith");
        loginPage.enterPassword("SuperSecretPassword!");
        SecureAreaPage secureAreaPage = loginPage.clickLogin();
        secureAreaPage.getBannerText();

        assertTrue(secureAreaPage.getBannerText()
                        .contains("You logged into a secure area!"),"Incorrect message displayed");
    }
}

Advertisement

Answer

Your SecureAreaPage contains a field private WebDriver driver; that you never initialize (in the constructor you call super(driver); but you never initialize the field in SecureAreaPage).

In the method getBannerText() you call driver.findElement(loginBanner) which accesses the field from SecureAreaPage.

Since every subclass of BasePage has access to the driver field in BasePage you do not need hat field. Remove it and everything should work.

The principle behind this is that the field driver of the class SecureAreaPage “shadows” the field driver of the class BasePage.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement