0

I am launching the application with username and password fetched from Excel. I'm getting an error in .sendKeys().

import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class Readdata {
    public FileInputStream fileInput;
    static String path;
    public File testdatafile;
    public XSSFWorkbook workbook;
    public XSSFSheet sheet;
    public XSSFRow Row;

    Readdata(String path) {
        this.path = path;
    }

    public static int getRowcount(String sheetname) throws IOException {
        File testDataFile = new File(path);
        FileInputStream fileInput = new FileInputStream(testDataFile);
        XSSFWorkbook workbook = new XSSFWorkbook(fileInput);
        XSSFSheet sheet = workbook.getSheet(sheetname);
        Row row = sheet.getRow(0);
        int rowCount = sheet.getLastRowNum();
        workbook.close();
        fileInput.close();

        return rowCount;
    }

    public static int getCellCount(String sheetname, int rownum) throws IOException {
        File testDataFile = new File(path);
        FileInputStream fileInput = new FileInputStream(testDataFile);
        XSSFWorkbook workbook = new XSSFWorkbook(fileInput);
        XSSFSheet sheet = workbook.getSheet(sheetname);
        XSSFRow Row = sheet.getRow(rownum);
        int cellcount = Row.getLastCellNum();
        workbook.close();

        return cellcount;
    }

    public static String getCelldata(String sheetname, int rownum, int colnum) throws IOException {
        File testDataFile = new File(path);
        FileInputStream fileInput = new FileInputStream(testDataFile);
        XSSFWorkbook workbook = new XSSFWorkbook(fileInput);
        XSSFSheet sheet = workbook.getSheet(sheetname);
        XSSFRow Row = sheet.getRow(rownum);
        XSSFCell cell = Row.getCell(colnum);
        DataFormatter fm = new DataFormatter();
        String data;
        try {
            data = fm.formatCellValue(cell);

        } catch (Exception e) {
            data = "";
        }
        workbook.close();
        fileInput.close();

        return data;
    }
}

Launch the browser and read data from Excel file.

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import java.io.IOException;
import java.time.Duration;

public class Excelreader {
    @Test(dataProvider = "DataValidate")
    public static void Admin() throws IOException, InterruptedException, IllegalArgumentException {
        String Un = null;
        String Password = null;
        String exp = null;
        WebDriver driver = new ChromeDriver();

        driver.get("https://opensource-demo.orangehrmlive.com/web/index.php/auth/login");
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
        Thread.sleep(1000);
        driver.findElement(By.xpath("//input[@name='username']")).clear();
        Thread.sleep(1000);
        WebElement user = driver.findElement(By.xpath("//input[@name='username']"));
        user.sendKeys(Un);
        Thread.sleep(1000);
        driver.findElement(By.xpath("//input[@name='password']")).clear();
        Thread.sleep(1000);
        WebElement pass = driver.findElement(By.xpath("//input[@name='password']"));
        pass.sendKeys(Password);
        Thread.sleep(1000);
        driver.findElement(By.xpath("//button[@type='submit']")).click();
        String exp_title = "https://opensource-demo.orangehrmlive.com/web/index.php/admin/viewSystemUsers";
        String act_title = driver.getTitle();
        if (exp.equals("Valid")) {
            if (exp_title.equals(act_title)) {
                driver.findElement(By.xpath("//*[@id='app']/div[1]/div[1]/header/div[1]/div[2]/ul/li/span/p")).click();
                driver.findElement(By.xpath("//*[@id='app']/div[1]/div[1]/header/div[1]/div[2]/ul/li/ul/li[4]/a")).click();
                Assert.assertTrue(true);
            }

        } else if (exp.equals("Invalid")) {
            if (exp_title.equals(act_title)) {
                driver.findElement(By.xpath("//*[@id='app']/div[1]/div[1]/header/div[1]/div[2]/ul/li/span/p")).click();
                driver.findElement(By.xpath("//*[@id='app']/div[1]/div[1]/header/div[1]/div[2]/ul/li/ul/li[4]/a")).click();
                Assert.assertTrue(false);
            }
        }
    }

    @DataProvider(name = "DataValidate")
    public Object[][] getdata() throws IOException {
        String path = "src/main/resources/Excelfile.xlsx";
        Readdata dt = new Readdata(path);
        int totalrowc = dt.getRowcount("Login");
        int totalc = dt.getCellCount("Login", 1);
        String logindata[][] = new String[totalrowc][totalc];
        for (int i = 1; i < totalrowc; i++) {
            for (int j = 1; j < totalc; j++) {
                logindata[i][j] = dt.getCelldata("Login", i, j);
            }
        }

        return logindata;
    }
}

I tried the above code but it gives the error in the line no 26 which is

WebElement user = driver.findElement(By.xpath("//input[@name='username']"));
user.sendKeys(un);

WebElement pass =  driver.findElement(By.xpath("//input[@name='password']"));
pass.sendKeys(pw);

Excel sheet data
Error message

1
  • 1
    Screenshots of the UI are great, screenshots of errors are not. Please read why a screenshot of code/HTML/errors is a bad idea. Edit your question and add the error message as text, properly formatted. Commented Apr 20, 2024 at 13:51

2 Answers 2

1

The main reason for the exception is that you've declared

String Un = null;

at the top of Admin() and then never set the value so at the point of

user.sendKeys(Un);

it's still null so it throws. I'm assuming you intended for the DataProvider to set those values but you haven't added those variables as parameters (and then you need to remove the declarations where you set everything to null).


Some feedback

  1. Naming is important. It will make your code more readable and understandable if you use more descriptive and accurate names. Un is not very descriptive where userName is. Your class is named Excelreader but it's where your test lives. LoginTests would be a more accurate name.

  2. In your Readdata.java class, your methods are opening the XLSX from scratch, reading it, and then closing the file each time. This is highly inefficient. I rewrote that class to be more efficient and renamed it to ExcelIo.java.

  3. I also rewrote the getData() DataProvider method to use the new ExcelIo.java class and to be more efficient.

  4. The Selenium lead and contributors have said multiple times not to use implicit waits. Also, sleeps are a bad practice. You should prefer WebDriverWait when a wait is needed. Wait for clickable when you need to click an element and wait for visible for just about everything else. See below for examples

    import org.openqa.selenium.support.ui.ExpectedConditions;
    import org.openqa.selenium.support.ui.WebDriverWait;
    
    WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    wait.until(ExpectedConditions.elementToBeClickable(locator)).click();
    wait.until(ExpectedConditions.visibilityOfElementLocated(locator)).getText();
    
  5. The URL in exp_title is not a page title, it's the URL. That validation will always fail because the page title is always, "OrangeHRM", no matter what page you are on. I changed the assert to verify the expected landing page URL for the dashboard. Feel free to change it to whatever else you want. I just wanted to demonstrate a valid test.

  6. You have the logout steps in both the if and else branch. Rather than maintain them in both places, instead put them ahead of the assert so the code only exists once and is easier to maintain. NOTE: You don't actually need to log out since you've finished the test anyway. You could but it just takes that much longer for the test to complete.

  7. Don't always use Assert.assertTrue(). In your case, you should use

    Assert.assertEquals(actualUrl, expectedUrl, "Verify dashboard URL")
    
  8. Always put an assert comment. In a sea of asserts, it will be very helpful to you or whoever investigates failures to know what the intended validation was, e.g.

    Assert.assertEquals(actualUrl, expectedUrl, "Verify dashboard URL")
                                                ^ assert comment
    
  9. I didn't know what Exp was meant to indicate so I left it out. I'm assuming it has something to do with valid vs error cases? Generally you should only store actual test data in the datasheet, database, etc. Whether a test is testing a "valid" case or an error case should be coded into the test itself.

  10. Your logout locators were really long XPaths. These are going to be very brittle... likely to break with small page changes. I changed them to a much shorter, simpler CSS selector.


The updated code

ExcelIo.java (formerly Readdata.java)

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ExcelIo {
    private Workbook workbook;
    private Sheet sheet;

    public ExcelIo(String pathName, String sheetName) throws FileNotFoundException, IOException {
        FileInputStream file = new FileInputStream(new File(pathName));
        workbook = new XSSFWorkbook(file);
        sheet = workbook.getSheet(sheetName);
    }

    public int getCellCount(int rowIndex) {
        return sheet.getRow(rowIndex).getPhysicalNumberOfCells();
    }

    public String getCellValue(int rowIndex, int cellIndex) {
        return sheet.getRow(rowIndex).getCell(cellIndex).getStringCellValue();
    }

    public int getRowCount() {
        return sheet.getPhysicalNumberOfRows();
    }
}

LoginTest.java (formerly Excelreader.java)

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.annotations.*;

import java.io.IOException;
import java.time.Duration;

public class LoginTest {
    @Test(dataProvider = "LoginData")
    public void WhenLoggingInExpectDashboardUrl(String username, String password, String exp)
            throws IOException, InterruptedException, IllegalArgumentException {

        WebDriver driver = new ChromeDriver();

        driver.get("https://opensource-demo.orangehrmlive.com/web/index.php/auth/login");
        driver.manage().window().maximize();
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));

        // login
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//input[@name='username']"))).sendKeys(username);
        driver.findElement(By.xpath("//input[@name='password']")).sendKeys(password);
        driver.findElement(By.xpath("//button[@type='submit']")).click();

        String expectedUrl = "https://opensource-demo.orangehrmlive.com/web/index.php/dashboard/index";
        String actualUrl = driver.getCurrentUrl();
        Assert.assertEquals(actualUrl, expectedUrl, "Verify URL");

        // logout
        wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("p.oxd-userdropdown-name"))).click();
        wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("a[href*='logout']"))).click();

        driver.quit();
    }

    @DataProvider(name = "LoginData")
    public Object[][] getData() throws IOException {
        String path = "src/main/resources/Excelfile.xlsx";
        String sheetName = "Login";

        ExcelIo excelIo = new ExcelIo(path, sheetName);
        int rowCount = excelIo.getRowCount() - 1;
        System.out.println("rowCount: " + rowCount);
        int cellCount = excelIo.getCellCount(0);
        String logindata[][] = new String[rowCount][cellCount];
        for (int rowIndex = 1; rowIndex <= rowCount; rowIndex++) {
            for (int cellIndex = 0; cellIndex < cellCount; cellIndex++) {
                logindata[rowIndex - 1][cellIndex] = excelIo.getCellValue(rowIndex, cellIndex);
            }
        }

        return logindata;
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the feedback .I will follow the same .
0

The error you are getting (java.lang.IllegalArgumentException: Keys to send should be a not null CharSequence) comes from this line:

        user.sendKeys(Un);

It's telling you that Un is null.

Looking carefully at your code, it is not difficult to see that this is indeed the case. The only other line in your code that mentions the variable Un is this one:

        String Un = null;

This declares the variable and sets its value to null. Nothing changes the value of this variable by the time you get to the line user.sendKeys(Un), hence the exception.

If you want the values read from your Excel spreadsheet to be passed into your test method, then you need to specify them as method parameters:

    public static void Admin(String Un, String Password, String exp) throws IOException, InterruptedException, IllegalArgumentException {

        // declarations of variables Un, Password and exp removed as they are now parameters

        WebDriver driver = new ChromeDriver();

        // rest of method ...

Finally, you might want to adjust your getdata() method to ignore the header row of the spreadsheet.

Comments

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.