How can I solve this error of BDD-Cucumber? - cucumber

java.lang.IllegalStateException: The driver executable must exist: D:\Cucumber_BDD\CucumberJavaD:\Cucumber_BDD\CucumberJava\src\test\resources\drivers\chromedriver.exe
at org.openqa.selenium.internal.Require$FileStateChecker.isFile(Require.java:342)
at org.openqa.selenium.remote.service.DriverService.checkExecutable(DriverService.java:147)
at org.openqa.selenium.remote.service.DriverService.findExecutable(DriverService.java:142)
at org.openqa.selenium.chrome.ChromeDriverService.access$000(ChromeDriverService.java:39)
at org.openqa.selenium.chrome.ChromeDriverService$Builder.findDefaultExecutable(ChromeDriverService.java:233)
at org.openqa.selenium.remote.service.DriverService$Builder.build(DriverService.java:437)
at org.openqa.selenium.chrome.ChromeDriverService.createDefaultService(ChromeDriverService.java:128)
at org.openqa.selenium.chrome.ChromeDriver.(ChromeDriver.java:49)
at StepDefinitions.GoogleSearchSteps.browser_is_open(GoogleSearchSteps.java:23)
at ?.browser is open(file:///D:/Cucumber_BDD/CucumberJava/src/test/resources/Features/GoogleSearch.feature:4)
This is the code I'm using,
public class GoogleSearchSteps {
WebDriver driver = null;
#Given("browser is open")
public void browser_is_open() {
System.out.println("Inside Step - browser is open");
String projectPath= System.getProperty("user.dir");
System.out.println("Project path is"+projectPath);
System.setProperty("webdriver.chrome.driver",projectPath+"D:/Cucumber_BDD/CucumberJava/src/test/resources/drivers/chromedriver.exe");
driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(40,TimeUnit.SECONDS);
driver.manage().timeouts().pageLoadTimeout(40, TimeUnit.SECONDS);
driver.manage().window().maximize();
}

This projectPath+"D:/Cucumber_BDD/CucumberJava/src/test/resources/drivers/chromedriver.exe" results in the path of D:\Cucumber_BDD\CucumberJavaD:\Cucumber_BDD\CucumberJava\src\test\resources\drivers\chromedriver.exe that looks not valid as you just concatenate two paths which originate from root D:\.
I am not sure why you're doing so, but if you have your executable at D:/Cucumber_BDD/CucumberJava/src/test/resources/drivers/chromedriver.exe just use:
System.setProperty("webdriver.chrome.driver","D:/Cucumber_BDD/CucumberJava/src/test/resources/drivers/chromedriver.exe");

Related

Appium: Unable to find element in Android chrome browser by ID and Name, getting "InvalidArgumentException"

I'm using Appium (v1.15.1) to find email a password fields from "http://facebook.com" with Chrome browser on Android device, and i'm unable to find email and password fields elements using method findElementById('') and findElementByName(''). I've tried to find it using XPath and it works.
This is my code:
public class Browse extends BaseMobile {
public static void main(String[] args) throws MalformedURLException {
AndroidDriver<AndroidElement> driver = capabilities();
driver.get("http://facebook.com");
driver.findElementById("m_login_email").sendKeys("prueba#mail.com"); // not working
driver.findElementByName("pass").sendKeys("123456789"); // not working
driver.findElementByXPath("//*[#name='login']").click();
}
}
capabilities:
public class BaseMobile {
public static AndroidDriver<AndroidElement> capabilities() throws MalformedURLException {
AndroidDriver<AndroidElement> androidDriver;
String serverUrl = "http://127.0.0.1:4723/wd/hub";
DesiredCapabilities cap = new DesiredCapabilities();
cap.setCapability(MobileCapabilityType.DEVICE_NAME, "Android device");
cap.setCapability(MobileCapabilityType.BROWSER_NAME, "Chrome");
androidDriver = new AndroidDriver<AndroidElement>(new URL(serverUrl), cap);
androidDriver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);
return androidDriver;
}
}
Error:
Exception in thread "main"
org.openqa.selenium.InvalidArgumentException: invalid argument:
invalid locator
(Session info: chrome=79.0.3945.136)
EDIT(1): As suggested I printed page source and I'm getting it without any problem. Added appium log too.
console log: System.out.println(driver.getPageSource());
Appium log
After driver.get("http://facebook.com"); line try to print page source and see if it is getting page source or not. Try System.out.println(driver.getPagesource());

Cucumber, biggest challenge, browser invoke

In my framework each feature file when converted to step def I have to put browser invoke codes (SetProperties) and for each operations new windows comes. Please help me resolve the issue I tried inherentance where i put the codes and extended to step def classes did not work. I want to open one browser and that will do the operations for every feature files.
For example: I have a feature file for login content verification and another feature file for after login.
I put in the login the userName and Password again I had to put userName and password cor the other feature file after login along with browser invoke codes.
if you are still looking for answer. I would suggest initialize your browser in every step definition file or inside page object class(if you are using POM). create a class e.g: TestContext.java initialize your webdriver in that class.
public class TestContext {
private WebDriverLibrary webDriverLibrary;
private PageObjectLibrary pageObjectLibrary;
public TestContext() {
webDriverLibrary = new WebDriverLibrary();
pageObjectLibrary = new PageObjectLibrary(webDriverLibrary.getDriver());
}
// return WebDriverLibrary object
public WebDriverLibrary getWebDriverLibrary() {
return webDriverLibrary;
}
// return PageObjectLibrary object
public PageObjectLibrary getPageObjectLibrary() {
return pageObjectLibrary;
}
}
public class WebDriverLibrary {
private static WebDriver driver;
private static DriverType driverType;
private static EnvironmentType environmentType;
public WebDriverLibrary() {
driverType = FileReaderLibrary.getInstance().getConfigReader().getBrowser();
environmentType = FileReaderLibrary.getInstance().getConfigReader().getEnvironment();
}
// return webdriver instance
public WebDriver getDriver() {
if (driver == null)
driver = createDriver();
return driver;
}
private WebDriver createDriver() {
switch (environmentType) {
case LOCAL:
driver = createLocalDriver();
break;
case REMOTE:
driver = createRemoteDriver();
break;
}
return driver;
}
}
Hope this helps you.

TestNG Close Browsers after Parallel Test Execution

I want to close browsers after completion of all test. Problem is I am not able to close the browser since the object created ThreadLocal driver does not recognize the driver after completion of test value returning is null.
Below is my working code
package demo;
import java.lang.reflect.Method;
import org.openqa.selenium.By;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class ParallelMethodTest {
private static ThreadLocal<dummy> driver;
private int input;
private int length;
#BeforeMethod
public void beforeMethod() {
System.err.println("Before ID" + Thread.currentThread().getId());
System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
if (driver == null) {
driver = new ThreadLocal<dummy>();
}
if (driver.get()== null) {
driver.set(new dummy());
}
}
#DataProvider(name = "sessionDataProvider", parallel = true)
public static Object[][] sessionDataProvider(Method method) {
int len = 12;
Object[][] parameters = new Object[len][2];
for (int i = 0; i < len; i++) {
parameters[i][0] = i;
parameters[i][1]=len;
}
return parameters;
}
#Test(dataProvider = "sessionDataProvider")
public void executSessionOne(int input,int length) {
System.err.println("Test ID---" + Thread.currentThread().getId());
this.input=input;
this.length=length;
// First session of WebDriver
// find user name text box and fill it
System.out.println("Parameter size is:"+length);
driver.get().getDriver().findElement(By.name("q")).sendKeys(input + "");
System.out.println("Input is:"+input);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#AfterMethod
public void afterMethod() {
System.err.println("After ID" + Thread.currentThread().getId());
driver.get().close();
}
}
package demo;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterClass;
public class dummy {
public WebDriver getDriver() {
return newDriver;
}
public void setNewDriver(WebDriver newDriver) {
this.newDriver = newDriver;
}
private WebDriver newDriver;
public dummy() {
newDriver = new ChromeDriver();
newDriver.get("https://www.google.co.in/");
}
#AfterClass
public void close(){
if(newDriver!=null){
System.out.println("In After Class");
newDriver.quit();
}
}
}
Thanks in Advance.
private static ThreadLocal<dummy> driver is added at the class level. What is happening is that you have already declared the variable at class level. i.e. memory is already allocated to it. Multiple threads are just setting and resetting the values of the same variable.
What you need to do is create a factory that will return an instance of Driver based on a parameter you pass to it.Logic can be anything but taking a general use case example the factory will create a new object and return only if an existing object doesn't exist. Declare and initialise the driver (from factory) in your #Test Methods
Sample code for the factory would be something like
static RemoteWebDriver firefoxDriver;
static RemoteWebDriver someOtherDriver;
static synchronized RemoteWebDriver getDriver(String browser, String browserVersion, String platform, String platformVersion)
{
if (browser == 'firefox')
{
if (firefoxDriver == null)
{
DesiredCapabilities cloudCaps = new DesiredCapabilities();
cloudCaps.setCapability("browser", browser);
cloudCaps.setCapability("browser_version", browserVersion);
cloudCaps.setCapability("os", platform);
cloudCaps.setCapability("os_version", platformVersion);
cloudCaps.setCapability("browserstack.debug", "true");
cloudCaps.setCapability("browserstack.local", "true");
firefoxDriver = new RemoteWebDriver(new URL(URL),cloudCaps);
}
}
else
{
if (someOtherDriver == null)
{
DesiredCapabilities cloudCaps = new DesiredCapabilities();
cloudCaps.setCapability("browser", browser);
cloudCaps.setCapability("browser_version", browserVersion);
cloudCaps.setCapability("os", platform);
cloudCaps.setCapability("os_version", platformVersion);
cloudCaps.setCapability("browserstack.debug", "true");
cloudCaps.setCapability("browserstack.local", "true");
someOtherDriver = new RemoteWebDriver(new URL(URL),cloudCaps);
}
return someOtherDriver;
}
You have a concurrency issue: multiple threads can create a ThreadLocal instance because dummy == null can evaluate to true on more than one thread when run in parallel. As such, some threads can execute driver.set(new dummy()); but then another thread replaces driver with a new ThreadLocal instance.
In my experience it is simpler and less error prone to always use ThreadLocal as a static final to ensure that multiple objects can access it (static) and that it is only defined once (final).
You can see my answers to the following Stack Overflow questions for related details and code samples:
How to avoid empty extra browser opens when running parallel tests with TestNG
Session not found exception with Selenium Web driver parallel execution of Data Provider test case
This is happening because you are creating the driver instance in beforeMethod function so it's scope ends after the function ends.
So when your afterMethod start it's getting null because webdriver instance already destroy as beforeMethod function is already completed.
Refer below links:-
http://www.java-made-easy.com/variable-scope.html
What is the default scope of a method in Java?

How to avoid empty extra browser opens when running parallel tests with TestNG

While I'm running parallel test cases using TestNG and selenium-webdriver, there are some browser instances that open empty and doesn't close even after the execution finish. I have read several topics on different forums asking about similar problems but none of them seems to be the same issue.
Also seems like more empty browsers are open when I add more test to the suite. I'm not sure what of the following information will be relevant for this problem but I will try to provide a complete picture of what I have:
I'm using (as mentioned) TestNG - webdriver.
I'm working with page objects pattern.
I'm running my automation from a javafx interface, which allow the user to select some options.
I'm using ChromeDriver to emulate mobile devices.
I'm using a local thread of the driver which allow me to use an exclusive static driver for each test.
No empty browser are open when I don't run in parallel.
This is my TestNg.xml:
<suite name="Suite" parallel="classes" thread-count="4">
<test name="Test">
<groups>
<run>
<!-- Use include to specify what you want to run or exclude to not run the mentioned group(s) -->
<include name="fullRegression"/>
<exclude name="brokenOrDevelopment"/>
</run>
</groups>
<packages>
<!-- Packages who contains the test cases classes -->
<package name="Test"/>
</packages>
This is the class which create the driver instance
public class TestCaseConfiguration {
protected HomePageObjects homePage = null;
protected DesiredCapabilities capabilities;
protected ExtentReports REPORTMANAGER;
protected ExtentTest REPORT;
public static ThreadLocal<ChromeDriver> driver;
#BeforeMethod(alwaysRun = true)
public void setup() throws InterruptedException {
System.setProperty("webdriver.chrome.driver", "src/Tools/chromedriver.exe");//chrome driver version 2.20 | We need to have a relative path since no all the user will have the driver on C:
capabilities = DesiredCapabilities.chrome();
Map<String, String> mobileEmulation = new HashMap<String, String>();
mobileEmulation.put("deviceName", Constants.DEVICE);
Map<String, Object> chromeOptions = new HashMap<String, Object>();
chromeOptions.put("mobileEmulation", mobileEmulation);
capabilities.setCapability(ChromeOptions.CAPABILITY, chromeOptions);
/**
* dirver is a ThreadLocal<ChromeDriver>. This allows the driver to be static and available for the complete project, and exclusive for each thread.
*/
driver=new ThreadLocal<ChromeDriver>()
{
#Override
protected ChromeDriver initialValue()
{
return new ChromeDriver(capabilities);
}
};
driver.get().manage().deleteAllCookies();
driver.get().manage().timeouts().implicitlyWait(40, TimeUnit.SECONDS);
driver.get().navigate().to(Constants.DOMAIN);
homePage = PageFactory.initElements(driver.get(), HomePageObjects.class);
}
#AfterMethod(alwaysRun = true)
public void close() throws InterruptedException {
driver.get().close();
driver.get().quit();
}
}
This class is extended by each test case class. The tests run as expected, the only problem seems to be the extra browser instances.
Doesn't anyone know how can I avoid that issue or if I'm doing something wrong?
Thanks for the help.
This is how the browser looks when open empty
You are creating a new ThreadLocal<ChromeDriver> instance and reassigning driver each time setup runs. Imagine the following scenario where setup is called in parallel by multiple threads:
Thread0 creates a ThreadLocal<ChromeDriver> instance, assigns it to driver, and calls driver.get(). One browser is now open.
Thread1 creates a ThreadLocal<ChromeDriver> instance, assigns it to driver (replacing the one assigned to it by Thread0), and calls driver.get(). Two browsers are now open, one per ThreadLocal instance.
Thread0 calls driver.get() again but driver no longer references the same ThreadLocal instance so a new browser is opened. Three browsers are now open, one in an "orphaned" ThreadLocal instance and two in the referenced ThreadLocal.
Now imagine that scenario but with more than two threads! You'll have lots of "orphaned" ThreadLocal instances floating around, some of which having a ChromeDriver instance associated with some thread(s) but no objects on any threads with references to the ThreadLocal in order to "get" them.
To fix the problem I recommend marking driver as final and assigning a ThreadLocal instance to it once.
e.g.
public class TestCaseConfiguration {
protected HomePageObjects homePage = null;
protected ExtentReports REPORTMANAGER;
protected ExtentTest REPORT;
public static final ThreadLocal<ChromeDriver> driver;
private static final Set<ChromeDriver> drivers = Collections.newSetFromMap(new ConcurrentHashMap<>());
static {
System.setProperty("webdriver.chrome.driver", "src/Tools/chromedriver.exe");//chrome driver version 2.20 | We need to have a relative path since no all the user will have the driver on C:
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
Map<String, String> mobileEmulation = new HashMap<String, String>();
mobileEmulation.put("deviceName", Constants.DEVICE);
Map<String, Object> chromeOptions = new HashMap<String, Object>();
chromeOptions.put("mobileEmulation", mobileEmulation);
capabilities.setCapability(ChromeOptions.CAPABILITY, chromeOptions);
/**
* dirver is a ThreadLocal<ChromeDriver>. This allows the driver to be static and available for the complete project, and exclusive for each thread.
*/
driver = new ThreadLocal<ChromeDriver>() {
#Override
protected ChromeDriver initialValue() {
ChromeDriver chromeDriver = new ChromeDriver(capabilities);
drivers.add(chromeDriver);
return chromeDriver;
}
};
}
#BeforeMethod(alwaysRun = true)
public void setup() throws InterruptedException {
driver.get().manage().deleteAllCookies();
driver.get().manage().timeouts().implicitlyWait(40, TimeUnit.SECONDS);
driver.get().navigate().to(Constants.DOMAIN);
homePage = PageFactory.initElements(driver.get(), HomePageObjects.class);
}
#AfterSuite(alwaysRun = true)
public void close() throws InterruptedException {
for (ChromeDriver chromeDriver : drivers) {
try {
chromeDriver.quit();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
i created separate method in libFile which i call in every testcase..
#Libraryfile
//Variable declaration
WebDriver driver=null;
protected WebDriver getDriverInstance(){
driver=new FirefoxDriver();
return driver;
}
#testcase class - i am calling above method in #BeforeMethod
//Variable declaration
WebDriver driver=null;
#BeforeMethod
public void setUp(){
driver=getDriverInstance();
}
this has solved my Multiple empty browser instances

I am unable to fetch excel data to selenium code At ubuntu o/s

public class ReadAndWrite {
public static void main(String[] args) throws InterruptedException, BiffException, IOException
{
System.out.println("hello");
ReadAndWrite.login();
}
public static void login() throws BiffException, IOException, InterruptedException{
WebDriver driver=new FirefoxDriver();
driver.get("URL");
System.out.println("hello");
FileInputStream fi = new FileInputStream("/home/sagarpatra/Desktop/Xpath.ods");
System.out.println("hiiiiiii");
Workbook w = Workbook.getWorkbook(fi);
Sheet sh = w.getSheet(1);
//or w.getSheet(Sheetnumber)
//String variable1 = s.getCell(column, row).getContents();
for(int row=1; row <=sh.getRows();row++)
{
String username = sh.getCell(0, row).getContents();
System.out.println("Username "+username);
driver.get("URL");
driver.findElement(By.name("Email")).sendKeys(username);
String password= sh.getCell(1, row).getContents();
System.out.println("Password "+password);
driver.findElement(By.name("Passwd")).sendKeys(password);
Thread.sleep(10000);
driver.findElement(By.name("Login")).click();
System.out.println("Waiting for page to load fully...");
Thread.sleep(30000);
}
driver.quit();
}
}
I don't know what is wrong with my code, or how to fix it. It outputs the following error:
Exception in thread "main" jxl.read.biff.BiffException: Unable to recognize OLE stream
at jxl.read.biff.CompoundFile.<init>(CompoundFile.java:116)
at jxl.read.biff.File.<init>(File.java:127)
at jxl.Workbook.getWorkbook(Workbook.java:221)
at jxl.Workbook.getWorkbook(Workbook.java:198)
at test.ReadTest.main(ReadTest.java:19)
I would try using Apache MetaModel instead. I have had better luck with that, than using JXL. Here is a example project I wrote that reads from a .XLSX file. I use this library to run tests on a Linux Jenkins server from .XLS files generated on MS Windows.
Also, it should be noted that this library is also perfect for making a parameterized DataProvider that queries a database with JDBC.
Using JXL, you limit yourself to one data type, either .XLS or .CSV. I believe MetaModel is actually using JXL under the hood and wrapping it to make it easier to use. So, it also would support the OpenOffice documents in the same fashion and suffer the same file compatibility issues.

Resources