Selenium script fails with TestNG annotation - java

Steps:
1. In eclipse I've created a new project named 'ForSe'.
Under 'src' folder → 'default package' I created a class named Login.java.
My code inside this class is like this:
public class Login_Valid {
public static void main(String[] args) throws InterruptedException {
System.setProperty("webdriver.chrome.driver","*my path*");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("*URL of prject ForSe*");
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.findElement(By.xpath("//*#id='email_address']")).sendKeys("*email address*");
driver.findElement(By.xpath("//*[#id='password']")).sendKeys("*Password*");
driver.findElement(By.xpath("//*[#id='login-form']/div[4]/button")).click();
}
}
The scripts run very well when I run with run as java application.
But when I use the same script with TestNG, it skips/fails my test.
Steps taken to create TestNG script is as follows:
Installed TestNG and under same src creates a new package named ForSe_TestCases.java
My TestNG scripts is as follows:
public class ForSe_TestCases
{
WebDriver driver;
String url = "*project's URL*";
#Test (priority = 0)
public void IO_login(WebDriver driver)
{
//ForSe test environment URL
driver.navigate().to(url);
//this is official email address of IO
driver.findElement(By.xpath("//*[#id='email_address']")).sendKeys("*email address*");
//this is password
driver.findElement(By.xpath("//*[#id='password']")).sendKeys("*Password*");
//click on submit button to login
driver.findElement(By.xpath("//*[#id='login-form']/div[4]/button")).click();
System.out.println("Login button pressed");
}
#BeforeTest
public void setup()
{
// Set property for Chrome
System.setProperty("webdriver.chrome.driver","*my path*");
WebDriver driver = new ChromeDriver();
//apply implicit wait
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
//maximize window
driver.manage().window().maximize();
}
}
I'm unable to understand at which step I'm going wrong. This the error message I get on running my test by Run as TestNG
[Utils] [ERROR] [Error] org.testng.TestNGException:
Cannot inject #Test annotated Method [IO_login] with [interface org.openqa.selenium.WebDriver].
===============================================
Default test
Tests run: 1, Failures: 1, Skips: 0
===============================================
===============================================
Default suite
Total tests run: 1, Failures: 1, Skips: 0
===============================================

Change below line of your code.
from public void IO_login(WebDriver driver) to public void IO_login()
Then try to run your code, it will surely work for you. For more details on this refer this below code.
public class ForSe_TestCases {
WebDriver driver;
String url = "http://google.com";
#Test (priority = 0)
public void IO_login()
{
driver.navigate().to(url);
System.out.println("Login Method");
}
#BeforeTest
public void setup()
{
System.setProperty("webdriver.chrome.driver", "C:\\Drivers\\chromedriver.exe");
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(25, TimeUnit.SECONDS);
}
}

Please replace your code with below and try, I tested it in my machine.
import org.testng.annotations.Test;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.BeforeTest;
public class Testngtest
{
WebDriver driver;
String url = "*project's URL*";
#Test (priority = 0)
public void IO_login()
{
//ForSe test environment URL
driver.navigate().to("Url");
//this is official email address of IO
driver.findElement(By.xpath("//*[#id='email_address']")).sendKeys("*email address*");
//this is password
driver.findElement(By.xpath("//*[#id='password']")).sendKeys("*Password*");
//click on submit button to login
driver.findElement(By.xpath("//*[#id='login-form']/div[4]/button")).click();
System.out.println("Login button pressed");
}
#BeforeTest
public void setup()
{
// Set property for Chrome
System.setProperty("webdriver.chrome.driver","*my path*");
driver = new ChromeDriver();
//apply implicit wait
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
//maximize window
driver.manage().window().maximize();
}
}
Below are the changes that I made to original code.
1.Removed driver parameter to IO_login method()
2.Removed declaration of web driver in setup method again, we already declared it inside the class and outside of all methods.
Let me know if you have any queries.

The problem was with setup of TestNG. Following code solved my problem:
#BeforeTest
public void setup()
{
System.setProperty("webdriver.chrome.driver", my_path);
ChromeOptions options = new ChromeOptions();
options.addArguments("test-type");
options.addArguments("start-maximized");
options.addArguments("--js-flags=--expose-gc");
options.addArguments("--enable-precise-memory-info");
options.addArguments("--disable-popup-blocking");
options.addArguments("--disable-default-apps");
options.addArguments("test-type=browser");
options.addArguments("disable-infobars");
driver = new ChromeDriver(options);
}

These can be a few of the issues:
"my path" is not a valid variable name. Change it to "my_path".
Define a String my_path = "C:\\Utility\\BrowserDrivers\\chromedriver.exe"; as a global variable.
Check the variable when you provide System.setProperty("webdriver.chrome.driver","my_path");
Don't use driver.manage().window().maximize(); instead handle it with Options Class.
WebDriver driver is defined globally at Class level, you don't have to pass it as an argument in IO_login()
Check this code:
public class TestAnyURL_TestNG
{
WebDriver driver;
String url = "http://google.com";
String my_path = "C:\\Utility\\BrowserDrivers\\chromedriver.exe";
#Test (priority = 0)
public void IO_login()
{
//ForSe test environment URL
driver.navigate().to(url);
//this is official email address of IO
driver.findElement(By.xpath("//*[#id='email_address']")).sendKeys("*email address*");
//this is password
driver.findElement(By.xpath("//*[#id='password']")).sendKeys("*Password*");
//click on submit button to login
driver.findElement(By.xpath("//*[#id='login-form']/div[4]/button")).click();
System.out.println("Login button pressed");
}
#BeforeTest
public void setup()
{
System.setProperty("webdriver.chrome.driver", my_path);
ChromeOptions options = new ChromeOptions();
options.addArguments("test-type");
options.addArguments("start-maximized");
options.addArguments("--js-flags=--expose-gc");
options.addArguments("--enable-precise-memory-info");
options.addArguments("--disable-popup-blocking");
options.addArguments("--disable-default-apps");
options.addArguments("test-type=browser");
options.addArguments("disable-infobars");
driver = new ChromeDriver(options);
}
}
Remember to:
Replace http://google.com with your own_test_URL.
Replace package demo by package your_package_name.
Replace public class TestAnyURL_TestNG with public class your_class_name
Run as "TestNG Test"
Update me the status.

Related

Multiple login sessions not getting closed with driver.close in java-selenium

I have added code snippet for further clarity.
I am using java-selenium-testNG and trying to login to a website zoho.com with 3 accounts and verifying if success. I have looked through somewhat similar issues but haven't found a solution that works in my case.
I instantiate the ChromeDriver in #BeforeMethod. Then I login to the website with first account and close the browser in my #AfterMethod.
I have to re-instantiate the browser with Driver = new ChromeDriver to login back with a new account as the instance is closed or atleast that's the feeling it gives error that the session id doesn't exists.
My issue is only the last instance of the driver is getting closed as I have driver.quit in the #AfterTest method. The other two instances remain in memory.
I have also tried using the same instance without closing the browser but in such cases the login option is not available on that particular website and my subsequent tests fail.
here is the code below for further clarification
package uk.dev.test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.*;
import io.github.bonigarcia.wdm.WebDriverManager;
import java.util.concurrent.TimeUnit;
public class zohoLogin {
WebDriver driver=null;
String winHandleBefore;
#DataProvider(name ="testData")
public Object[][] loginPasswordData()
{
return new Object[][]{
{"xxx#gmail.com",new String ("somepassword")} ,
{"yyy#gmail.com",new String ("somepassword")},
{"zzz#gmail.com",new String ("somepassword")},
};
}
#Test ( dataProvider = "testData")
public void enterUserDetails(String userEmail, String userPassword) throws InterruptedException {
driver.findElement(By.xpath("//input[#id='login_id']")).sendKeys(userEmail);
System.out.println(("Running for Test data " + userEmail));
Thread.sleep(2000);
driver.findElement(By.xpath("//button[#id='nextbtn']")).click();
Thread.sleep(2000);
System.out.println("clicked on Next");
driver.findElement(By.xpath("//input[#id='password']")).sendKeys(userPassword);
System.out.println("Entered the password");
driver.findElement(By.xpath("//button[#id='nextbtn']//span[contains(text(),'Sign in')]")).click();
System.out.println("Clicked on Signin");
Thread.sleep(2000);
}
#BeforeMethod
public void loginZoho() throws InterruptedException
{
driver = new ChromeDriver();
driver.get("https://www.zoho.com");
System.out.println("Open the browser");
driver.findElement(By.xpath("//a[#class='zh-login']")).click();
//driver.manage().timeouts().implicitlyWait(5000, TimeUnit.MILLISECONDS);
Thread.sleep(5000);
}
#AfterMethod
public void closeBrosers() throws InterruptedException {
Thread.sleep(2000);
driver.close();
System.out.println("Close the browser");
}
#BeforeTest
public void setupBrowser()
{ WebDriverManager.chromedriver().setup();
}
#AfterTest
public void tearDown()
{
driver.quit();
}
}
Attached the run results where 2 chrome driver instance can be seen.Also note the AfterMethod is not getting executed.
enter image description here
I am using driver.quit() method in selenium but facing the same issue. I think issue is related to the latest version of chromedriver.
public static void CloseDriver()
{
if (Driver != null)
{
Driver.Quit();
Driver = null;
}
}
I even tried Driver.Kill() but it resulted in closing all the browsers.

I received this message and failed: java.lang.NullPointerException at org.openqa.selenium.support.pagefactory.DefaultElementLocator.find

I am creating Page Object Model for the first time using selenium and I came across the below error, while executing the code give below. Need help in figuring out what am I missing...
java.lang.NullPointerException at org.openqa.selenium.support.pagefactory.DefaultElementLocator.find
My Code for reference:
package Pages;
import org.openqa.selenium.*;
public class BaseClass {
public static WebDriver driver;
public static String URL1 = "https://math-dad.com";
public void setupWebDriver(String drivername)
{
if (drivername.equalsIgnoreCase("Chrome"))
{
ChromeOptions options = new ChromeOptions();
options.addArguments("--disable-notifications");
System.setProperty("webdriver.chrome.driver", "C:\\Drivers\\chromedriver.exe");
driver =new ChromeDriver(options);
}
else if (drivername.equalsIgnoreCase("Fire Fox"))
{
FirefoxOptions options = new FirefoxOptions();
options.addArguments("--disable-notifications");
System.setProperty("webdriver.gecko.driver", "C:\\Drivers\\geckodriver.exe");
driver =new FirefoxDriver(options);
}
}
public BaseClass()
{
System.out.println("Base Class Initiate");
}
}
package Pages;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.CacheLookup;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class HeaderPage extends BaseClass{
#CacheLookup
#FindBy(xpath = "//div[#class='navbar-header']")
public static WebElement LOGO;
public displayHeader()
{
System.out.println(driver.findElement(By.xpath("//div[#class='navbar-header']")).getText());
}
public HeaderPage()
{
PageFactory.initElements(driver,this);
}
}
public class testHeaderPage extends HeaderPage{
#BeforeTest
public void beforeTest()
{
System.out.println("Before Test");
setupWebDriver("Chrome");
driver.get(URL1);
driver.manage().window().maximize();
driver.manage().timeouts().pageLoadTimeout(40, TimeUnit.SECONDS);
}
#Test
public void test1HeaderLOGO()
{
displayHeader(); // this is succesful
String Actual = LOGO.getText(); // Fails from this statement
System.out.println("Header LOGO: "+Actual);
String expected = "Math Dad";
Assert.assertEquals(Actual, expected, "Invalid Header");
}
#AfterTest
public void afterTest() {
drive.close();
}
}
In HeaderPage Classs, I am able to use 'driver' directly, but declaration of Page Factory element is failing. Any help on this please?
Use #BeforeClass annotation with this method so that Before Test driver can be initialized. This method will then execute Before every test.
#BeforeClass
public void setupWebDriver(String drivername) {
if (drivername.equalsIgnoreCase("Chrome"))
{
ChromeOptions options = new ChromeOptions();
options.addArguments("--disable-notifications");
System.setProperty("webdriver.chrome.driver", "C:\\Drivers\\chromedriver.exe");
driver =new ChromeDriver(options);
}
else if (drivername.equalsIgnoreCase("Fire Fox"))
{
FirefoxOptions options = new FirefoxOptions();
options.addArguments("--disable-notifications");
System.setProperty("webdriver.gecko.driver", "C:\\Drivers\\geckodriver.exe");
driver =new FirefoxDriver(options);
}
}

Unable to run TestNG test case in Eclipse with ChromeDriver

I have written below code to open a site in chrome browser and verify its title. but when using System.setProperty() to set the ChromeDriver Path, it gives me syntax error and when I commented the line I get:
java.lang.IllegalStateException: The path to the driver executable must be set by the webdriver.chrome.driver system property..
My Code :
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.Test;
public class FirsttestNGFile {
String BaseURL = "http://newtours.demoaut.com/";
System.setProperty("webdriver.chrome.driver", "E:\\Automation Jars\\chromedriver_win32\\chromedriver.exe"); -- If I comment this line, I get Illegal state Exception for chromedriver path; if not commented , I get syntax error
WebDriver driver = new ChromeDriver();
#Test
public void verifyHomePageTitle() {
driver.get(BaseURL);
String ExpectedTitle = "Welcome: Mercury Tours";
String ActualTitle = driver.getTitle();
Assert.assertEquals(ExpectedTitle, ActualTitle);
driver.quit();
}
}
You cannot define System.setProperty Globally.
Use below code and try:
WebDriver driver;
#Before
public void browser(){
System.setProperty("webdriver.chrome.driver", "D:\\Selenium\\CP-SAT\\Chromedriver\\chromedriver.exe");
driver = new ChromeDriver();
}
#Test
public void verifyHomePageTitle() {
String BaseURL = "http://newtours.demoaut.com/";
driver.get(BaseURL);
String ExpectedTitle = "Welcome: Mercury Tours";
String ActualTitle = driver.getTitle();
Assert.assertEquals(ExpectedTitle, ActualTitle);
}
#Test
public void a() {
driver.get("https://www.google.co.in/?gfe_rd=cr&ei=6PDbV-qTAZHT8gecr4qQBA");
}
#After
public void close(){
driver.quit();
}
}
If you are using Junit then use #Before or If you are using TestNG then #BeforeTest.
Reply me for further query.
Happy Learning. :-)
You should consider to use https://github.com/bonigarcia/webdrivermanager which will make the job for you:
ChromeDriverManager.getInstance().setup();
Update chrome driver path in environmental variables path and then try to use below code in your script
#BeforeClass
public void setup() {
WebDriver driver = new ChromeDriver();
}

ChromeDriver cannot navigate to URL in eclipse

I am very new to Cucumber and get the following error using ChromeDriver to request a URL:
java.lang.IllegalStateException: The path to the driver executable
must be set by the webdriver.chrome.driver system property; for more
information, see http://code.google.com/p/selenium/wiki/ChromeDriver.
The latest version can be downloaded from
http://chromedriver.storage.googleapis.com/index.html at
com.google.common.base.Preconditions.checkState(Preconditions.java:177)
My code:
package cucumber.features;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
public class AddToList {
WebDriver driver = null;
#Given("^I am on Todo site$")
public void onSite() throws Throwable {
driver = new ChromeDriver();
driver.navigate().to("http://localhost");
System.out.println("on todo site");
}
#When("^Enter a task in todo textbox$")
public void enterTask() throws Throwable {
driver = new ChromeDriver();
driver.findElement(By.name("task")).sendKeys("Test Unit Using Cucumber");
;
System.out.println("task entered");
}
#Then("^I click on add to todo$")
public void clickAddToTodo() throws Throwable {
driver = new ChromeDriver();
driver.findElement(By.xpath("//input[#value='Add to Todo' and #type='button']"));
System.out.println("add button clicked");
}
}
I had a similar problem when using selenium library. I found this line before creating my driver fixed it.
System.setProperty("webdriver.chrome.driver", PATH_TO_CHROME_DRIVER);
Here is simple project that could help you.
this.driver.get(URL);
Also, I don't think your When and Then should create new ChromeDrivers. Only the Given. I use the setUp method to instantiate it
#Before
public void setUp() {
System.setProperty("webdriver.chrome.driver", "..//..//files//drivers//chromedriver.exe");
this.driver = new ChromeDriver();
}

Appium - Unable to instantiate AndroidDriver

When I am trying to instantiate AndroidDriver class it is giving an error. Please help.
Code
import io.appium.java_client.android.AndroidDriver;
public class Testing {
#Test
public void testMethod() {
AndroidDriver driver;
DesiredCapabilities cap = new DesiredCapabilities();
cap.setCapability("deviceName", "samsung-sm_g530h-5554c610");
cap.setCapability("platformVersion", "4.4.4");
cap.setCapability("platformName", "Android");
cap.setCapability(CapabilityType.BROWSER_NAME, "");
cap.setCapability("appPackage", "com.whatsapp");
cap.setCapability("appActivity", "com.whatsapp.HomeActivity");
driver = new AndroidDriver(new URL("127.0.0.1:4723"), cap);
}
}
// Here is the error
It is giving an error: AndroidDriver is Raw type. You can initialize driver as below:
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.android.AndroidDriver;
...
public class Testing()
{
public AppiumDriver driver;
...
#BeforeTest
public void testMethod()
{
driver = new AndroidDriver(new URL(Node), capabilities);
...
}
}
I also met this problem before, but I now have solved, and the reasons for this problem is because Java - client-(version number). jar is not compatible,So I will Java - client-(version number). jar replacement into Java - the client - 3.1.0. Jar.Hope to be able to help you!
Try replacing:
driver = new AndroidDriver(new URL("127.0.0.1:4723"), cap);
With:
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), cap);
You are getting this error as AppiumDriver is now Generic, so it can be set to return elements of class MobileElement or IOSElement or AndroidElement without casting.
This change is introduced in Java client version 3.0 and above. Details can be found here
Also, app package, app activity and device name is sufficient enough to run tests. So, you can modify your code as:
import io.appium.java_client.MobileElement;
import io.appium.java_client.android.AndroidDriver;
public class Testing {
AndroidDriver<MobileElement> driver;
#Test
public void testMethod() {
DesiredCapabilities caps = new DesiredCapabilities() ;
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"samsung-sm_g530h-5554c610");
caps.setCapability(MobileCapabilityType.APP_PACKAGE, "com.whatsapp");
caps.setCapability(MobileCapabilityType.APP_ACTIVITY, "com.whatsapp.HomeActivity");
driver = new AndroidDriver<MobileElement>(new URL ("http://127.0.0.1:4723/wd/hub"),caps);
}
}
Following is the correct way to initialize Androidriver:
public class AppiumController{
public static void main(String[] args) throws MalformedURLException{
AppiumDriver<?> driver;
final String URL_STRING = "http://127.0.0.1:4723/wd/hub";
URL url = new URL(URL_STRING);
File appDirAndroid = new File("src/main/resources/app/");
File appAndroid = new File(appDirAndroid, "in.amazon.mShop.android.shopping_2018-02-22.apk");
DesiredCapabilities androidCapabilities = new DesiredCapabilities();
androidCapabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
androidCapabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, "UiAutomator2");
androidCapabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "emulator-5554");
androidCapabilities.setCapability("appPackage", "in.amazon.mShop.android.shopping");
androidCapabilities.setCapability("appActivity", "com.amazon.mShop.home.HomeActivity");
androidCapabilities.setCapability(MobileCapabilityType.APP, appAndroid.getAbsolutePath());
driver = new AndroidDriver<MobileElement>(url, androidCapabilities);
driver.closeApp();
}
}
The above piece of code will successfully launch the amazon app on emulator.

Categories