driver.findElement used outside the method throwing Nullpointer Exception in POM model



  • I have created two class files 'LoginPage.java' and 'orangeHRM.java'

    Now as part of POM, I have initialized the 'LoginPage' object in 'OrangeHRM'

    LoginPage LP = new LoginPage(driver);
    

    I have declared constructor in LoginPage file

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

    Now in the LoginPage.Java file if I use driver as a statement it is throwing NullpointerException. see the below code:

    WebElement username = **driver**.findElement(By.xpath("//input[@name='txtUsername' and @id='txtUsername']"));
        WebElement password = **driver**.findElement(By.xpath("//input[@name='txtPassword' and @id='txtPassword']"));   
        WebElement loginbtn = **driver**.findElement(By.xpath("//input[@type='submit' and @id='btnLogin']"));
    
        public void Login(String UName,String Pwd)
        {
            username.sendKeys(UName);
            password.sendKeys(Pwd);
            loginbtn.click();
        }
    

    Where as if I use driver inside a method in LoginPage.java it is working fine.see the below code:

    By username = By.xpath("//input[@name='txtUsername' and @id='txtUsername']");
        By password = By.xpath("//input[@name='txtPassword' and @id='txtPassword']");   
        By loginbtn = By.xpath("//input[@type='submit' and @id='btnLogin']");
    
        public void Login(String UName,String Pwd)
        {
            **driver**.findElement(username).sendKeys(UName);
            **driver**.findElement(password).sendKeys(Pwd);
            **driver**.findElement(loginbtn).click();
        }
    

    Can someone please explain me the reason why I should not use WebElement declaration using driver in POM model.

    LoginPage with WebElement decalarion:

    package common;
    import org.openqa.selenium.By;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.testng.Assert;
    
    public class LoginPage
    {
    
        WebDriver driver;
        public LoginPage(WebDriver driver) 
        {
            this.driver=driver;
        }
    
    
        WebElement username = driver.findElement(By.xpath("//input[@name='txtUsername' and @id='txtUsername']"));
        WebElement password = driver.findElement(By.xpath("//input[@name='txtPassword' and @id='txtPassword']"));   
        WebElement loginbtn = driver.findElement(By.xpath("//input[@type='submit' and @id='btnLogin']"));
    
        public void Login(String UName,String Pwd)
        {
            username.sendKeys(UName);
            password.sendKeys(Pwd);
            loginbtn.click();
        }
    
    
        public void VerifyTitle(String actualtitle, String expectedtitle)
          {
              Assert.assertEquals(actualtitle, expectedtitle);
          }
    
    }
    

    OrangeHRM File:

    package frameWork;
    
    import java.util.concurrent.TimeUnit;
    
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.chrome.ChromeDriver;
    import org.testng.annotations.Test;
    
    import common.LoginPage;
    
    public class OrangeHRM
    {
    
        LoginPage LP;
        public static WebDriver driver;
    
        @Test
        public void Login()
        {
            System.setProperty("webdriver.chrome.driver", "D://Pavani//Automation Testing//Drivers//chromedriver.exe");
             driver = new ChromeDriver();
            driver.get("https://opensource-demo.orangehrmlive.com/");
            driver.manage().window().maximize();
             LP = new LoginPage(driver);
            driver.manage().timeouts().implicitlyWait(100, TimeUnit.SECONDS);
            LP.Login("Admin", "admin123");
            String actual = "OrangeHRM";
            String expected = driver.getTitle();
            LP.VerifyTitle(actual, expected);       
        }
    
    }
    


  • To explain this:

    Try the below code:

    public class HelloWorld{
    
         public static void main(String []args){
            test t=new test(5);
            System.out.println(t.a);
            System.out.println(t.b);
            System.out.println(t.c);
            System.out.println(t.d);
         }
    
    }
    
    
         class test{
             int a;
             int b;
             public test(int val){
                 this.a=val;
             }
    
             int c=1+this.a;
             int d=1+a;
         }
    

    Here you can see that whatever you pass, c and d always returns 1.

    This is because the declared (without assigning any value) class variables will get initialized to its default value when we create an object. So a and b will have '0' as default value.

    Also, whatever class variable declaration you will make will be executed before the actual constructor code. The compiler will move class declarations to the top of your actual constructor. This ensures that first all class variables are initialized before executing the actual constructor code.

    Read below answer for explanation:

    https://stackoverflow.com/questions/18830103/why-instance-variables-get-initialized-before-constructor-called

    So, c=1+this.a and d=1+a;

    will get executed before "this.a=val" as they are class variables

    Now coming to your problem:

    1. you have declared webdriver in login page ( a class varaible )
    2. Now when you create the login page object, the driver will be initialized with the value "null" ( As you have not assigned any value during class declaration)
    3. Now you were expecting this.driver=driver to get executed before :

    WebElement username = driver.findElement

    But as in the above example, as webelement declaration is in class level, this will get executed well before the actual constructor code.

    1. so when you try to get driver.findelement , you are trying to get findelement from a null object. Hence you get null point exception

    So the solution is to call the findelement inside the constructor

     WebDriver driver;
     WebElement username;
     WebElement password;
    
    
        public LoginPage(WebDriver driver) 
        {
        this.driver=driver;
        username = this.driver.findElement(By.xpath("//input[@name='txtUsername' and @id='txtUsername']"));
        password = this.driver.findElement(By.xpath("//input[@name='txtPassword' and @id='txtPassword']"));   
        }
    


Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2