This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I am learning appium and trying to call an object from one class to another and facing null pointer exception.
Below is my code :
public class TestCommons {
public AndroidDriver driver;
public void setUp() {
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("deviceName", "MotoE");
File file = new File("D:/APK1/com.vector.guru99.apk");
capabilities.setCapability("app", file);
try {
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
public void tearDown() {
driver.closeApp();
}
}
I wanted to use above class i.e "TestCommons" in other class. I want to use driver object.
Second class is below :
public class Day03 extends TestCommons {
TestCommons commons = new TestCommons();
#BeforeClass
public void beforeClass() {
commons.setUp();
}
#Test(enabled = true)
public void f() {
if (driver.findElement(By.id("com.vector.guru99:id/action_quiz")).isDisplayed()) {
System.out.println("Quiz is displayed");
driver.findElement(By.id("com.vector.guru99:id/action_quiz")).click();
System.out.println("quiz is click");
}
}
#AfterClass(enabled = true)
public void afterClass() {
commons.tearDown();
}
}
Getting null pointer in second program #:
if(driver.findElement(By.id("com.vector.guru99:id/action_quiz")).isDisplayed();
Can anyone clarify me please.
You have one of two issues.
1) driver was not set properly in setUp(). If this is the case you probably got an exception. Check your logs to make sure that there isn't an exception there.
2) driver.findElement(By.id("com.vector.guru99:id/action_quiz")) is returning null. You can check this by setting a debug point and running evaluate expression on that call.
try this way:
public class TestCommons {
public static AndroidDriver driver;
#BeforeClass
public void setUp() {
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("deviceName", "MotoE");
File file = new File("D:/APK1/com.vector.guru99.apk");
capabilities.setCapability("app", file);
try {
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
#AfterClass
public void tearDown() {
driver.closeApp();
}
}
public class Day03 extends TestCommons {
#Test(enabled = true)
public void f() {
if (driver.findElement(By.id("com.vector.guru99:id/action_quiz")).isDisplayed()) {
System.out.println("Quiz is displayed");
driver.findElement(By.id("com.vector.guru99:id/action_quiz")).click();
System.out.println("quiz is click");
}
}
}
Related
I have 20 pages and each page have 2 testcases and each testcase download a number of files. I want to change the download directory for each test case at runtime.
Here is the 'TestBaseClass' code which downloading all the files in one particular folder from where I have to separate them as per category and place them into a particular folder.
There are 20 folders and each folder is having 2 subfolders 'ChapterLevel' & 'PracticeLevel' in which I do have to place it manually.
Is it possible to change the download directory by passing a variable during runtime?
My TestBaseClass code:
public static WebDriver driver;
public static void initialization() throws InvocationTargetException {
try {
// Setting new download directory path
Map<String, Object> prefs = new HashMap<String, Object>();
// Use File.separator as it will work on any OS
prefs.put("download.default_directory", "C:\\Users\\pd\\Desktop\\AHNPTTest");
// Adding cpabilities to ChromeOptions
ChromeOptions options = new ChromeOptions();
options.setExperimentalOption("prefs", prefs);
// Launching browser with desired capabilities
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver(options);
} catch (Exception e) {
// generic exception handling
e.printStackTrace();
}
driver.manage().window().maximize();
driver.manage().deleteAllCookies();
driver.manage().timeouts().pageLoadTimeout(40, TimeUnit.SECONDS);
driver.manage().timeouts().implicitlyWait(25, TimeUnit.SECONDS);
}
Here is my testcase:
public class ANA_TC16_RiskAnalysisNewTest extends TestBaseClass {
ANA_RiskAnalysisNewPage New;
#BeforeMethod
public void setUp() {
try {
initialization();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
login();
New = new ANA_RiskAnalysisNewPage();
}
#Test
public void chapterrLevelTest() throws Exception {
New.hoverTest();
New.clickBottomOptions();
New.chapterOption();
New.TopX();
New.ATISlider();
New.conditionSelection();
New.takeScreenshot("Risk Analysis New Chapter Level Image");
New.downloadOptions();
New.isFileDownloaded();
}
#Test
public void practiceLevelTest() throws Exception {
New.hoverTest();
New.clickBottomOptions();
New.providerOption();
New.TopX();
New.ATISlider();
New.conditionSelection();
New.takeScreenshot("Risk Analysis New Practice Level Image");
New.downloadOptions();
New.isFileDownloaded();
}
}
Suppose you want to specify download folder for each test method.
Add parameter for downloadPath in initialization in TestBaseClass.
Add parameter for downloadPath in setup in ANA_TC16_RiskAnalysisNewTest, remove the #BerforMethod annotation and update each test method to call setup in begin with desired downloadPath.
public class TestBaseClass {
public static void initialization(String downloadPath) throws InvocationTargetException {
try {
// Setting new download directory path
Map<String, Object> prefs = new HashMap<String, Object>();
// Use File.separator as it will work on any OS
prefs.put("download.default_directory", downloadPath);
...
public class ANA_TC16_RiskAnalysisNewTest extends TestBaseClass {
ANA_RiskAnalysisNewPage New;
// #BeforeMethod
public void setUp(String downloadPath) {
try {
initialization(downloadPath);
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
login();
New = new ANA_RiskAnalysisNewPage();
}
#Test
public void chapterrLevelTest() throws Exception {
setUp("C:\\Users\\pd\\Desktop\\AHNPTTest\\ANA_TC16_RiskAnalysis\\ChapterLevel");
New.hoverTest();
...
}
#Test
public void practiceLevelTest() throws Exception {
setUp("C:\\Users\\pd\\Desktop\\AHNPTTest\\ANA_TC16_RiskAnalysis\\PracticeLevel");
New.hoverTest();
...
}
...
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
java.lang.NullPointerException is appearing
(1 answer)
Getting error exception in thread "main" java.lang.NullPointerException
(2 answers)
java.lang.NullPointerException using static WebDriver instance
(1 answer)
Closed 2 years ago.
I am new to the selenium automation world, Getting java.lang.NullPointerException error which trying to call the function to take a screenshot in a test method on Selenium. I am pretty sure I have missed initialize or return the driver somewhere. below is the code.
baseTest class where I am initializing the webdriver
public class baseTest {
public Properties objProp = new Properties();
FileInputStream readProp;
{
try {
readProp = new FileInputStream("C:\\Users\\kiran\\IdeaProjects\\SelProject2\\src\\test\\java\\appDetails.properties");
objProp.load(readProp);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
protected WebDriver driver;
#BeforeClass
public void beforeSuite()
{
System.setProperty(objProp.getProperty("browser"),objProp.getProperty("driverPath"));
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.get(objProp.getProperty("URL"));
}
#AfterSuite
public void afterSuite()
{
if(null != driver)
{
driver.close();
driver.quit();
}
}
public WebDriver getDriver()
{
return driver;
}
}
All my tests extends the baseTest function link shown below
public class loginFunction extends baseTest {
guruLoginPage objLogin;
guruHomePage objHome;
takeScreenshot objSS = new takeScreenshot(driver);
//readExcel readObj;
#Test
public void performLogin() throws IOException, InterruptedException {
objLogin = new guruLoginPage(driver);
String loginPageTitle = objLogin.getTitle();
Assert.assertTrue(loginPageTitle.contains("Demo Site"));
objSS.screenshot();
objLogin.loginAction(objProp.getProperty("appUsername"), objProp.getProperty("appPassword"));
Thread.sleep(2000);
objHome = new guruHomePage(driver);
Assert.assertTrue(objHome.validateLogin().contains("Manger Id : mngr242657"));
Thread.sleep(2000);
objSS.screenshot();
}
}
when i write this piece of code in the loginfunction, it works fine, but when i am trying to optimize and put it in a separate class and call the method I am getting java.lang.NullPointerException error
public class takeScreenshot{
WebDriver driver;
public takeScreenshot(WebDriver driver)
{
this.driver=driver;
PageFactory.initElements(driver,this);
}
public void screenshot() throws IOException {
String fileSuffix = DateTime.now().toString("yyyy-dd-MM-HH-mm-ss");
TakesScreenshot ss = ((TakesScreenshot)this.driver);
File srcFile = ss.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(srcFile,new File("C:\\Users\\kiran\\IdeaProjects\\SelProject2\\src\\test\\java\\Screenshots\\"+fileSuffix+".jpg"));
}
}
I want to pass my WebDriver to another class instead of passing it to the individual methods within that class. That would mean passing it to the constructor of the class when I create an instance of it. Here is my code, and my issue further below -
public class StepDefinitions{
public static WebDriver driver = null;
CustomWaits waits;
#Before("#setup")
public void setUp() {
driver = utilities.DriverFactory.createDriver(browserType);
System.out.println("# StepDefinitions.setUp(), driver = " + driver);
waits = new CustomWaits(driver);
}
}
public class CustomWaits {
WebDriver driver;
public CustomWaits(WebDriver driver){
this.driver = driver;
}
public boolean explicitWaitMethod(String id) {
boolean status = false;
try {
WebDriverWait wait = new WebDriverWait(driver, 30);
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(id)));
status = element.isDisplayed();
} catch (NullPointerException e){
e.printStackTrace();
}
return status;
}
}
The error I am getting in is NullPointerException when a method of that class is called within an #Given, #When, etc. This is a scope issue I cannot resolve.
Feature File:
#test
Feature: Test
#setup
Scenario: Navigate to Webpage and Assert Page Title
Given I am on the "google" Website
Then page title is "google"
Here is the step definition:
#Given("^element with id \"([^\"]*)\" is displayed$")
public void element_is_displayed(String link) throws Throwable {
if (waits.explicitWaitMethod(link)) {
// This is where waits becomes null when I put a breakpoint
driver.findElement(By.id(link)).isDisplayed();
} else {
System.out.println("Timed out waiting for element to display");
}
}
I would do something like this.
public class StepDefinitions{
public StepDefinitions() {
driver = utilities.DriverFactory.createDriver(browserType);
System.out.println("# StepDefinitions.setUp(), driver = " + driver);
waits = new CustomWaits(driver);
}
public static WebDriver driver = null;
public static CustomWaits waits;
#Given("^element with id \"([^\"]*)\" is displayed$")
public void element_is_displayed(String link) throws Throwable {
if (waits.explicitWaitMethod(link)) {
// This is where waits becomes null when I put a breakpoint
driver.findElement(By.id(link)).isDisplayed();
} else {
System.out.println("Timed out waiting for element to display");
}
}
}
public class CustomWaits {
private static WebDriver driver;
public CustomWaits(WebDriver driver){
this.driver = driver;
}
public boolean explicitWaitMethod(String id) {
boolean status = false;
try {
WebDriverWait wait = new WebDriverWait(driver, 30);
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(id)));
status = element.isDisplayed();
} catch (NullPointerException e){
e.printStackTrace();
}
return status;
}
}
I'm new in java, using it for automatic tests. Please help me what I'm doing wrong with this code?
public static WebDriver driver = null;
public static WebDriver getDriver() {
if (driver == null) {
File fileIE = new File("src//test/java/iedriver.exe");
System.setProperty("webdriver.ie.driver", fileIE.getAbsolutePath());
}
try {
driver = new InternetExplorerDriver();
}
catch (Exception e)
e.printStackTrace();
}
Try to add DesiredCapabilities to your code.
if (driver == null) {
File fileIE = new File("src//test/java/iedriver.exe");
System.setProperty("webdriver.ie.driver", fileIE.getAbsolutePath());
DesiredCapabilities ieCapabilities = DesiredCapabilities.internetExplorer();
try {
driver = new InternetExplorerDriver(ieCapabilities);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
the DesiredCapabilities help to set properties for the WebDriver. A typical usecase would be to set the path for any type of the WebDriver if your local installation doesn't correspond to the default settings.
You can read about class DesiredCapabilities and about its' using here: DesiredCapabilities
I am using a custom WebDriverEventListener in my Selenium tests for logging and screenshot purposes. It works fine:
When for example an element is not found in the browser window an exception is thrown by the webdriver and the onException() method is properly triggerd
#Override
public void onException(Throwable throwable, WebDriver driver) {
// do stuff
}
When I throw an Exception myself like this: throw new WebDriverException("my message"); the event is not triggered.
Can someone explain this behavior?
If you want to do some action when test failed or some exception, you can add to your test a rule(add in class where is #Before setUp()):
#Rule
public TestRule testWatcher = new TestWatcher() {
#Override
public void succeeded(Description test){
for (LogEntry log : driver.manage().logs().get(LogType.DRIVER).getAll()) {
System.out.println("Level:" + log.getLevel().getName());
System.out.println("Message:" + log.getMessage());
System.out.println("Time:" + log.getTimestamp());
System.out.println("-----------------------------------------------");
}
System.out.println();
#Override
public void failed(Throwable t, Description test) {
String testName = test.getClassName();
String subTestName = test.getMethodName();
String screenShotName = String.format("%s\\%s", testName, screenShotName);
if (driver instanceof TakesScreenshot) {
File tempFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
try {
System.out.println(">>>>>>>>>>LOGS: " + yourDirForImages + "\\" + screenShotName + ".png");
FileUtils.copyFile(tempFile, new File(String.format("%s.png", screenShotName)));
} catch (IOException e) {
e.printStackTrace();
}
}
}
Listener can be used for doing some code when its trigger some action, beforeCLick if there is header, logo, or footer.
public class ListenerMethodsImplementation extends AbstractWebDriverEventListener {
public void beforeClickOn(WebElement element, WebDriver myTestDriver) {
assertTrue("No Logo!", myTestDriver.findElements(By.id("logo")) == 1);
}
How to use it:
#Before
public void setUp() {
EventFiringWebDriver myTestDriver = new EventFiringWebDriver(driver);
ListenerMethodsImplementation myListener = new ListenerMethodsImplementation();
myTestDriver.register(myListener);
driver = myTestDriver;
}
How to get driver from listener: ((EventFiringWebDriver) driver).getWrappedDriver()
PS it's only a little portion from my code but i think this will help you.
Now I understand that because the listener is only registered to the WebDriver itelf it won't handle exceptions outsite the WebDriver.
In the abstract test case I did the following as part of a suggestion by Andrian Durlestean.
eventListener = new CustomWebDriverEventListener();
driver = new EventFiringWebDriver(driver).register(eventListener);
#Rule
public TestWatcher watchman = new TestWatcher() {
protected void failed(Throwable e, Description description) {
RuntimeException exception = (RuntimeException) e;
eventListener.onException(e, getDriver());
if (exception instanceof RuntimeException) {
throw exception;
}
};
};