I've posted below some sample code which I've done so far and I'm getting an Exception java.lang.NullPointerException.
Base Class:
public class TestBase {
public static WebDriver driver= null;
#BeforeSuite
public void initialize(){
System.setProperty("webdriver.chrome.driver","...chromedriver_win32\\chromedriver.exe");
WebDriver driver=new ChromeDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.get("abcd.com");
}
#AfterSuite
public void TearDownTest()
{
TestBase.driver.quit();
}
}
Login Page:
public class LoginPage {
WebDriver driver;
public LoginPage(WebDriver driver)
{
this.driver= driver;
}
#FindBy(how=How.XPATH, using="//*[#id='email_id']") WebElement EmailTextBox;
#FindBy(how=How.XPATH, using="//*[#id='password']")WebElement PassworTextBox;
#FindBy(how=How.XPATH, using="//*[#id='frm_login']/div[4]/input") WebElement LoginButton;
public void setemail(String strmail)
{
EmailTextBox.sendKeys(strmail);
}
public void setpwd(String strpwd)
{
try
{
PassworTextBox.sendKeys(strpwd);
}
catch (TimeoutException e)
{
System.out.println("Time out exception " + e);
}
catch (ElementNotSelectableException e) {
System.out.println("Element not selectable exception " + e);
} catch (NoSuchElementException e) {
System.out.println("No such element found " + e);
} catch (ElementNotVisibleException e) {
e.printStackTrace();
} catch (Exception e) {
System.out.println("Something Wrong " + e);
}
}
public void ClickLoginBtn()
{
LoginButton.click();
}
}
LoginTest class:
public class LoginTest extends TestBase{
#Test
public void init()
{
System.out.println("In the init method");
LoginPage lg=PageFactory.initElements(driver, LoginPage.class);
lg.setpwd("123123");
lg.setemail("abc#gmail.com");
lg.ClickLoginBtn();
}
}
I am getting the NullPointerException while setting the username and password. Could you please help me?
I am new to the POM with PageFactory so I dont have any idea How to resolve it but If anyone can help me with that it would be big help to me.
You shouldn't initialise the WebDriver instance i.e. driver twice as follows:
public static WebDriver driver= null;
and
WebDriver driver=new ChromeDriver();
Keep the global declaration as:
public static WebDriver driver= null;
And channge the line as:
driver=new ChromeDriver();
Try to add a timeout after driver.get("abcd.com"); to be sure page has finished to load, and can find WebElements defining EmailTextBox and PassworTextBox.
Or use a WebDriverWait like this
new WebDriverWait(driver, 10))
.until(ExpectedConditions.visibilityOf(By.id("someid")));
I hope you have initialized the page factory elements like so
public LoginPage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
In your Test class,
I would place
LoginPage lg = new LoginPage(driver);
Read more here:
https://www.seleniumeasy.com/selenium-tutorials/page-factory-pattern-in-selenium-webdriver
Related
I am a manual tester learning Selenium+Java at the moment. Thanks to a lot of brilliant answers at Stack Overflow, I managed to take screenshot when SoftAssert fails, but I'm now struggling with attaching these screenshot on Allure report. Can someone tell me what to add to my code to have these screenshot attached to the Allure report? Many thanks!!
//Override my onAssertFailure:**
public class CustomSoftAssert extends SoftAssert{
#Override
public void onAssertFailure(IAssert<?> assertCommand, AssertionError ex)
{
WebDriver driver = TestBase.getDriver1();
Reporting.takeScreenshot(driver);
}
//takeScreenshot method:
public static void takeScreenshot(WebDriver driver) {
try
{
TakesScreenshot ts=(TakesScreenshot) driver;
File source=ts.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(source, new File("./screenshots/"+System.currentTimeMillis()+".png"));
System.out.println("Screenshot taken");
}
catch (Exception e)
{
System.out.println("Exception while taking screenshot "+e.getMessage());
}
}
//onTestFailure method in AllureTestListener**
#Override
public void onTestFailure(ITestResult iTestResult) {
System.out.println("I am in onTestFailure method " + getTestMethodName(iTestResult) + " failed");
Object testClass = iTestResult.getInstance();
WebDriver driver = TestBase.getDriver1();
// Allure ScreenShotRobot and SaveTestLog
if (driver instanceof WebDriver) {
System.out.println("Screenshot captured for test case:" + getTestMethodName(iTestResult));
saveScreenshotPNG(driver);
}
// Save a log on allure.
saveTextLog(getTestMethodName(iTestResult) + " failed and screenshot taken.");
}```
Class1:
public class LaunchApp {
AndroidDriver<WebElement> driver;
#BeforeTest
public void Test1() throws MalformedURLException {
DesiredCapabilities capability = new DesiredCapabilities();
capability.setCapability("deviceName", "Android");
capability.setCapability("platformName", "Android");
capability.setCapability("platformVersion", "5.1.1");
capability.setCapability("deviceName", "Samsung Galaxy On5");
capability.setCapability("app",
"D:\\whatsapp.apk");
capability.setCapability("PackageName",
"com.movocado.socialbostonsports");
capability.setCapability("ActivityName",
"com.movocado.socialbostonsports.Activity.LogInSceen");
try {
driver = new AndroidDriver<WebElement>(new URL(
"http://127.0.0.1:4723/wd/hub"), capability);
} catch (MalformedURLException e) {
e.printStackTrace();
}
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
Class2:
public class DrawerMenuTest {
AndroidDriver<WebElement> driver;
#Test(priority = 1)
public void DrawerMenuIcon() {
WebElement drawerMenu = driver.findElement(By
.id("com.movocado.socialbostonsports:id/rel_drawer"));
try {
drawerMenu.click();
} catch (NullPointerException e) {
System.out.println(e.getMessage());
}
}
Problem:
Second class is showing NullPointerException. Suggest me a solution.
You are initializing AndroidDriver into LaunchApp but does not pass this driver reference into DrawerMenuTest where you are creating only refrence variable of AndroidDriver with null that's causes of NullPointerException.
To overcome it you should create separate singlton class which will give single instance of AndroidDriver to each and every class as below :-
public class DriverInit {
private AndroidDriver<WebElement> driver;
private static DriverInit driverInit = null;
public static DriverInit getInstance() {
if (driverInit == null) {
driverInit = new DriverInit();
}
return driverInit;
}
private DriverInit() {
DesiredCapabilities capability = new DesiredCapabilities();
capability.setCapability("deviceName", "Android");
capability.setCapability("platformName", "Android");
capability.setCapability("platformVersion", "5.1.1");
capability.setCapability("deviceName", "Samsung Galaxy On5");
capability.setCapability("app", "D:\\whatsapp.apk");
capability.setCapability("PackageName", "com.movocado.socialbostonsports");
capability.setCapability("ActivityName", "com.movocado.socialbostonsports.Activity.LogInSceen");
this.driver = new AndroidDriver<WebElement>(new URL(
"http://127.0.0.1:4723/wd/hub"), capability);
this.driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
public WebDriver getDriver() {
return this.driver;
}
}
Now you can use this into LaunchApp class as below :-
public class LaunchApp {
AndroidDriver<WebElement> driver;
#BeforeTest
public void Test1() throws MalformedURLException {
driver = DriverInit.getInstance().getDriver();
//now do your stuff with this driver
}
}
And use in DrawerMenuTest class as below :-
public class DrawerMenuTest {
AndroidDriver<WebElement> driver;
#Test(priority = 1)
public void DrawerMenuIcon() {
//get driver instance first
driver = DriverInit.getInstance().getDriver();
WebElement drawerMenu = driver.findElement(By
.id("com.movocado.socialbostonsports:id/rel_drawer"));
try {
drawerMenu.click();
} catch (NullPointerException e) {
System.out.println(e.getMessage());
}
}
}
Hope it helps..:)
I am running tests with WebDriver, when a test fails, the browser does not close. On a Windows machine this is a huge problem because I then have several instances of the Firefox still running in the background. Kindly advise
Here's the code :
public static WebDriver driver;
private String sTestCaseName;
#BeforeMethod
public void beforeMethod() throws Exception {
DOMConfigurator.configure("log4j.xml");
sTestCaseName = Constant.Login_Name;
Log.startTestCase(sTestCaseName);
new BaseClass(driver);
}
#Test(description = "Login", enabled = true)
public void TestLogin_Success() throws Exception {
try {
driver = new FirefoxDriver();
LoginBuilder.Execute(driver);
Log.info("Successfully Login!");
} catch (Exception e) {
Log.error(e.getMessage());
throw (e);
}
}
#Test(description = "Login_Failed", enabled = true)
public void TestLogin_Failed() throws Exception {
try {
driver = new FirefoxDriver();
LoginBuilder.Execute_Failed(driver);
Log.info("Unsuccessfully Login!");
} catch (Exception e) {
Log.error(e.getMessage());
throw (e);
}
}
#AfterMethod
public void afterMethod() {
Log.endTestCase(sTestCaseName);
driver.close();
}
Add finally block to your try catch block.
Close the WebDriver there.
Sample code snippet
try {
....
....
} catch(Exception e) {
....
....
} finally {
....
driver.close();
}
More info on Dispose, Close and Quit - Difference between webdriver.Dispose(), .Close() and .Quit()
Call driver.quit() instead of driver.close()
#AfterMethod
public void afterMethod() {
Log.endTestCase(sTestCaseName);
driver.quit();
}
Why don't you try to use #AfterClass
Complete code is written to fetch data from excel and login to Gmail, but while trying to do so my browser had opened and also the desired page got opened and as well as login id was picked from excel and stored in the variable sUsername, but unable to locate the xpath as- element=driver.findElement(by.id("Email")); but when I print element it holds "null", where as expected was some address of the locator id. Further by using the address of id I would had used with sendkeys to enter the email address in the text box.
But the following error was displayed:
java.lang.NullPointerException
at appModules.SignIN.Execute(SignIN.java:21)
Login class-where the locator issue exists: at - Login1.userName(driver).sendKeys(sUsername);
public class Login1 {
//private static WebDriver driver=null;
private static WebElement element=null;
public static WebElement userName(WebDriver driver)
{
try {
System.out.println("aaa");
System.out.println("bb");
element=driver.findElement(By.name("Email"));
System.out.println("ccc");
} catch (Exception e) {
// TODO: handle exception
System.out.println(element);
}
return element;
}
public static WebElement btn_login(WebDriver driver)
{
element= driver.findElement(By.id("next"));
return element;
}
public static WebElement passWord(WebDriver driver)
{
element= driver.findElement(By.id("Passwd"));
return element;
}
public static WebElement btn_SignIN(WebDriver driver)
{
element= driver.findElement(By.id("signIn"));
return element;
}
}
This is the SigniN class where iam getting the java null pointer exception--issue exists: at- Login1.userName(driver).sendKeys(sUsername);
public class SignIN {
private static WebDriver driver=null;
public static void Execute (int iTestCaseRow)
{
String sUsername=ExcelUtils1.getCellData(iTestCaseRow,Constant1.col_UserName);
System.out.println(sUsername);
//driver.ma3nage().window().maximize();
//driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);
Login1.userName(driver).sendKeys(sUsername);
//driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);
Login1.btn_login(driver).click();
String pass=ExcelUtils1.getCellData(iTestCaseRow, Constant1.col_password1);
Login1.passWord(driver).sendKeys(pass);
Login1.btn_SignIN(driver).click();
}
}
This is where I have instantiate the browser--
public class Utils1 {
public static WebDriver driver;
public static WebDriver OpenBrowser(int iTestCaseRow) {
String sBrowserName;
System.out.println(iTestCaseRow);
sBrowserName = ExcelUtils1.getCellData(iTestCaseRow,
Constant1.col_browser);
if (sBrowserName.equals("Mozilla")) {
driver = new FirefoxDriver();
// Log.info("New driver instantiated");
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
// Log.info("Implicit wait applied on the driver for 10 seconds");
driver.get(Constant1.URL);
// Log.info("Web application launched successfully");
}
return driver;
}
}
It is good practice to deal with internally as well explicit wait for locating element. If there is page related activity then also need to use wait for page to load.
Please follow bellow code
For internal Wait
protected WebElement waitForPresent(final String locator) {
// timeout is your default wait timeout in long.
return waitForPresent(locator, timeout);
}
For Explicit Wait
protected WebElement waitForPresent(final String locator, long timeout) {
WebDriverWait wait = new WebDriverWait(driver, timeout);
WebElement ele = null;
try {
ele = wait.until(ExpectedConditions
.presenceOfElementLocated(locator));
} catch (Exception e) {
throw e;
}
return ele;
}
protected WebElement waitForNotPresent(final String locator, long timeout) {
timeout = timeout * 1000;
long startTime = System.currentTimeMillis();
WebElement ele = null;
while ((System.currentTimeMillis() - startTime) < timeout) {
try {
ele = findElement(locator);
Thread.sleep(1000);
} catch (Exception e) {
break;
}
}
return ele;
}
Just spit balling here, but in addition to the copy/paste issues stated above.. I don't see where you do a 'get' to load the gmail page for the driver instance you are creating? Something like..
driver.get("https://mail.google.com/something");
Also, it would probably be a good idea to put an explicit wait in place for the "Email" field before doing the findElement as the page may still be rendering:
Wait<WebDriver> doFluentWait = fluentWait = new FluentWait<>(driver).withTimeout(PAGE_LOAD_WAIT, TimeUnit.SECONDS)
.pollingEvery(POLLING_INTERVAL, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
and then do something like
doFluentWait.until(WebDriverUtil.elementIsVisible(By.name("Email")));
I am using Java with Webdriver, and I am having problem with taking screenshots with failed test.
My jUnit test:
....
public class TestGoogleHomePage extends Browser {
....
#Test
public void testLoadGoogle() {
//this test will fail
}
}
My Browser class:
public class Browser {
protected static WebDriver driver;
public Browser() {
driver = new FirefoxDriver();
}
.....
#Rule
public TestWatcher watchman = new TestWatcher() {
#Override
protected void failed(Throwable e, Description description) {
File scrFile = ((TakesScreenshot) driver)
.getScreenshotAs(OutputType.FILE);
try {
FileUtils.copyFile(scrFile, new File(
"C:\\screenshot.png"));
} catch (IOException e1) {
System.out.println("Fail to take screen shot");
}
// this won't work
// driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
#Override
protected void succeeded(Description description) {
....
}
};
#After
public void closeBrowser() {
driver.quit();
}
}
The execution of the test will result in the following error message (part of the error message):
org.openqa.selenium.remote.SessionNotFoundException: The FirefoxDriver cannot be used after quit() was called.
Looks like it is complaining about my #After method.
I have tried to change the Browser class to be:
public class Browser {
protected static WebDriver driver;
public Browser() {
driver = new FirefoxDriver();
}
.....
#Rule
public TestWatcher watchman = new TestWatcher() {
#Override
protected void failed(Throwable e, Description description) {
File scrFile = ((TakesScreenshot) driver)
.getScreenshotAs(OutputType.FILE);
try {
FileUtils.copyFile(scrFile, new File(
"C:\\screenshot.png"));
} catch (IOException e1) {
System.out.println("Fail to take screen shot");
}
driver.quit();
}
#Override
protected void succeeded(Description description) {
....
driver.quit();
}
};
}
And the above codes work fine. But I don't want to quit the driver there because there might be something else I want to clean up after each test run, and I want to close the browser in the #After method.
Is there a way I can do that?
The problem is because of the following code:
#After
public void closeBrowser() {
driver.quit();
}
The driver.quit() is attempting to close the browser after EVERY test; and it is getting executed before the call-back methods of your TestWatcher. This is preventing TestWatcher from getting a handle of the driver. Try using a more restrictive life-cycle annotation like #AfterClass or #AfterSuite.