Geb test ignoring GebConfig.groovy file launched in IntelliJ - intellij-idea

Running in IntelliJ IDEA.
GebConfig.groovy is in /src/test/resources.
I am using the Chrome driver.
When I type
System.setProperty("webdriver.chrome.driver", "my/path")
inside my spec file, and I right click and select run, the test works, meaning it opens Chrome and loads the page.
When I don't do that in the spec file, but just leave it in the GebConfig.groovy file, I get the error message "the page to the driver executable must be set".
There's an air-gap, so I can't copy-paste; I'll type as much as I can here:
GebConfig.groovy:
import org.openqa.selenium.chrome.ChromeDriver
...
environments {
chrome {
System.setProperty("webdriver.chrome.driver", "my/path")
driver = {new ChromeDriver()}
}
}
The spec file is really simple, like the example on GitHub
import LoginPage
import geb.spock.GebReportSpec
class LoginSpec extends GebReportSpec
{
// Works when I put this here, but I should not have to do this!
System.setProperty("webdriver.chrome.driver", "my/path")
def "user can log in" () {
when: "log in as me"
def loginPage = to LoginPage
loginPage.login("me")
then:
....
}
}

To fix your problem if you want to keep the path in the geb config, setting the path outside of the environment section like so should work:
import org.openqa.selenium.chrome.ChromeDriver
System.setProperty("webdriver.chrome.driver", "my/path")
//You can also set the driver up here as a default and running with an environment set will override it
driver = {new ChromeDriver()}
environments {
chrome {
driver = {new ChromeDriver()}
}
}
Personally I would avoid adding the driver path to the geb config and create a run configuration in intelliJ for running locally.
Right click the spec file > Click "Create 'nameOfMySpec'".
Now add your driver path to the VM parameters:
-Dgeb.env=chrome -Dwebdriver.chrome.driver=my/path
It's also worth considering a shell script that could then also be called via Jenkins etc:
mvn test -Dgeb.env=chrome -Dwebdriver.chrome.driver=my/path

Related

Selenium commands not working in Chrome web driver (working with firefox)

I'm writing integration/e2e tests and for some reason any selenium driver commands don't see to be working with chromedriver, but they are working flawlessly with firefox driver and the firefox headless driver.
Commands tried: moveByOffset, and doubleClick
Tried both Geb's Interact method
interact {
doubleClick(centerClickable)
}
and accessing the webdriver directly:
def driver = browser.getDriver()
Actions action = new Actions(driver)
WebElement element= driver.findElement(By.className("vis-drag-center"))
def doubleclick = action.doubleClick(element).build()
doubleclick.perform()
Both methods work with the firefox driver. Neither work with chrome driver.
GebConfig.groovy file is set up as thus:
import io.github.bonigarcia.wdm.WebDriverManager
import org.openqa.selenium.Dimension
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions
import org.openqa.selenium.firefox.FirefoxDriver
import org.openqa.selenium.firefox.FirefoxOptions
def chromeWebDriverVersion = '70.0.3538.67'
def driverFirefox = {
WebDriverManager.firefoxdriver().setup()
def driver = new FirefoxDriver()
driver.manage().window().setSize(new Dimension(width, height))
return driver
}
// ChromeDriver reference: https://sites.google.com/a/chromium.org/chromedriver/
// Download and configure ChromeDriver using https://github.com/bonigarcia/webdrivermanager
def driverChrome = {
WebDriverManager.chromedriver().version(chromeWebDriverVersion).setup()
def driver = new ChromeDriver()
driver.manage().window().setSize(new Dimension(width, height))
return driver
}
environments {
firefox {
driver = driverFirefox
}
chrome {
driver = driverChrome
}
//driver = driverFirefox
driver = driverChrome
I also tried version 2.43 of chrome.
Additional information:
Mac Mojave
Selenium v 3.7.0
geb v 2.2
spockcore v 1.1-groovy-2.4
groovy v 2.4.5
webdrivermanager v 3.0.0
If anyone is interested, what the test is doing: Selecting a vis.js element by clicking on it. Sleeping for a second (code not included here), then opening/activating it by double clicking it. Or dragging it.
Apart from the selenium actions everything works fine with chromedriver and geb. It's only now that I need the doubleClick and moveByOffset (not move to an element!) that I'm getting issues getting things to work properly
I found a similar question on here, might be the same issue. Maybe not. But there's no solution provided: Selenium Web Driver DragAndDropToOffset in Chrome not working?
Any help is hugely appreciated.
Thank you for your response kriegaex.
Your tests work for me as well. This leads me to think there's just some lower-level interaction between differences in how selenium's chromedriver and firefox driver have implemented the doubleclick and dragAndDropBy actions + the way our application responds to commands.
For any other people observing similar behaviour, I use a work-around where I add an additional action for chromedriver. Perhaps it's nicer to actually find out which KEYDOWN events etc. you should be using and fire those, or perhaps find out why application isn't responding to these events. But I feel like enough time is spent on this already :)
if (browser.getDriver().toString().contains("chrome")) {
// Work-around for chromedriver's double-click implementation
content.click()
}
interact {
doubleClick(content)
}
And for the dragAndDropBy:
def drag(Navigator content, int xOff, int yOff) {
//Work-around: move additional time for when chrome driver is used.
int timesToMove = browser.getDriver().toString().contains("chrome") ? 2 : 1
interact {
clickAndHold(content)
timesToMove.times {
moveByOffset(xOff, yOff)
}
release()
}
}
I just had a little bit of time and was curious because I never tried to perform a double-click in any of my tests before. So I used this page as a test case and ran the following test with both Firefox and Chrome drivers:
package de.scrum_master.stackoverflow
import geb.spock.GebReportingSpec
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
class DoubleClickTest extends GebReportingSpec {
def "double-click via Geb interaction"() {
given:
go "https://demo.guru99.com/test/simple_context_menu.html"
def doubleClickButton = $("button", text: "Double-Click Me To See Alert")
expect:
withAlert {
interact {
doubleClick(doubleClickButton)
}
} == "You double clicked me.. Thank You.."
}
def "double-click via Selenium action"() {
given:
go "https://demo.guru99.com/test/simple_context_menu.html"
def doubleClickButton = driver.findElement(By.tagName("button"))
def doubleClick = new Actions(driver).doubleClick(doubleClickButton).build()
expect:
withAlert {
doubleClick.perform()
} == "You double clicked me.. Thank You.."
}
}
It works flawlessly, both ways of double-clicking trigger the expected Javascript alert.
I am not even using the latest driver version 2.45 but 2.41 against Chrome 71 64-bit on Windows 10. Besides, I also use bonigarcia's Webdriver Manager. I have no idea what is wrong with your setup. My Selenium version is 3.14.0, a bit newer than yours, Geb 2.2, Spock 1.1-groovy-2.4, Groovy 2.4.7.
Maybe it is a MacOS thing? I cannot verify that. Maybe you just run my test first, then maybe upgrade your Selenium and if that also does not help try to downgrade the Chrome driver in order to find out if the problem could be driver version related.
Update: I upgraded to Chrome driver 2.45, the test still works.
Update 2022-02-16: Updated the test to work with another example page, because the old URL still exists, but the Javascript there no longer works.

Can selenium test run without using System.setProperty in the code?

I am able to run the selenium test in our project without using System.setProperty. Not sure how it works, we have set the environment Path variable with value "C:\Akash\Drivers" where all the drivers are stored. Can anyone explain how/ this works without setting up chrome path?
public class SeleniumTest {
public static void main(String[] args) throws MalformedURLException {
// TODO Auto-generated method stub
localSettings();
}
public static void localSettings() {
// System.setProperty("webdriver.chrome.driver", "C:\\Akash\\Drivers\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("https://www.google.com");
}
}
Please Refer official explanation given Seleniumhq & Chrome,
How it retrieves and Work with Environment Variables :
WebDriver works with Chrome through the chromedriver binary. You need to have both chromedriver and a version of chrome browser installed. chromedriver needs to be placed somewhere on your system’s path in order for WebDriver to automatically discover it. The Chrome browser itself is discovered by chromedriver in the default installation path. These both can be overridden by environment variables.
Provided by Seleniumhq, Blog Link : Click Here
Chrome Driver Setup Provisions:
Provided by Chrome, Blog Link : Click Here

How do I run GEB tests using the firefox driver?

First, where do I download the firefox driver?
How do I set Geb to run tests using this driver in a Grails application.
I'm using Grails 2.3.7, and so far, I have this:
In my GebConfig.groovy:
// Testing frameworks
def gebVersion = "0.9.2"
def seleniumVersion = "2.32.0"
dependencies {
test "org.seleniumhq.selenium:selenium-chrome-driver:$seleniumVersion"
// test "org.seleniumhq.selenium:selenium-firefox-driver:$seleniumVersion"
test "org.gebish:geb-spock:$gebVersion"
test "org.gebish:geb-junit4:$gebVersion"
test "org.seleniumhq.selenium:selenium-support:2.31.0"
test "org.seleniumhq.selenium:selenium-firefox-driver:2.31.0"
}
In GebConfig.groovy:
import org.openqa.selenium.firefox.FirefoxDriver
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.Dimension
driver = { new FirefoxDriver() }
environments {
// run as “grails -Dgeb.env=firefox test-app”
// See: http://code.google.com/p/selenium/wiki/FirefoxDriver
firefox {
driver = { new FirefoxDriver() }
}
}
This is the error I get:
Try to upgrade the driver to a more recent version. 2.52.0 is the recent by now, so the Firefox browser has likely been updated many times since that driver was build.
I.e, change to
test "org.seleniumhq.selenium:selenium-support:2.52.0"
test "org.seleniumhq.selenium:selenium-firefox-driver:2.52.0"
And you should update the gebVersion to 0.13.0 and seleniumVersion to 2.52.0
The driver is downloaded from the maven repo automatically, and make sure the GebConfig.groovy file is on the classpath - I usually put it in the global folder. See example in this repo: https://github.com/JacobAae/dm844-sample-project/

Take multiple browser snapshots

I am an ASP.NET web developer and need to submit artifacts of the developed page, to the testers.
These include:
Snapshots of the page when opened in different browsers.
Same thing, with different versions of the browsers.
I do this manually (one by one) and also from different systems.(because IE8 is available only at a particular system...so on..). Yes of course time consuming.
Is there a way that could simplify my life in this.(something like browserstack.com)
I am looking at Selenium grid. But this requires some coding too and using eclipse etc. Not sure yet if taking screenshots is possible too and I have no knowledge of selenium.
Appreciate any help in this. Thank you
Create a config file for the Selenium Hub
The file name should be for example hubConfig.json and save it in the same folder where you will start the Hub. The host contains the IP of the HUB and the port contains the port number ... :)
{
"host": "127.0.0.1",
"port": 4444
}
Run your Selenium Hub, and load the configuration file too
Create a new file with the following name: startSeleniumHub.cmd and add the following command in it:
java -jar selenium-server-standalone.jar -role hub -hubConfig hubconfig.json
You can download the latest version Selenium Server Standalone on the Selenium HQ website:
http://www.seleniumhq.org/download/
Create a config file for the Node
The file name should be for example nodeConfig.json and save it in the same folder on the same PC where you will start the Node.
{
"capabilities":[
{
"platform":"WINDOWS",
"browserName":"firefox",
"firefox_binary":"C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe",
"maxInstances":5,
"seleniumProtocol":"WebDriver"
},
{
"platform":"WINDOWS",
"browserName":"chrome",
"maxInstances":5,
"seleniumProtocol":"WebDriver"
},
{
"platform":"WINDOWS",
"browserName":"internet explorer",
"maxInstances":5,
"version":11,
"seleniumProtocol":"WebDriver"
}
],
"configuration":{
"port":5555,
"host":"IP_OF_THE_NODE_PC",
"register":true,
"hubHost":"IP_OF_THE_HUB",
"hubPort": 4444,
"maxSession":1
}
}
If something is not understandable for you in this config, you can read more details about it on the following page:
https://code.google.com/p/selenium/wiki/Grid2
If you want, you can add more browsers like Edge, Safari, Opera, etc...
Connect your PCs to the Selenium Hub as a Node with the configuration file and with the WebDrivers as well
Create a new file with the following name: startSeleniumNode.cmd and add the following command in it:
java -jar "selenium-server-standalone-X.XX.X.jar" -role node -nodeConfig "nodeConfig.json" -Dwebdriver.chrome.driver="chromedriver.exe" -Dwebdriver.ie.driver="IEDriverServer.exe"
You can download the latest Chrome and IE WebDriver on the same page where you downloaded the Selenium Server Standalone:
http://www.seleniumhq.org/download/
Write some JAVA code :)
It is just an example, I'm sure that there are better solutions. For example you can use TestNG to create different tests, add parameters to your tests, or run your tests in parallel, etc... You can find more information on the TestNG site: http://testng.org/doc/index.html
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.Platform;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.io.File;
import java.io.IOException;
import java.net.URL;
public class ScreenshotMakerTest
{
public static void main(String [] args) throws IOException
{
// Init a new DesiredCapabilites which will setup the WebDriver to open a specific browser.
DesiredCapabilities dc = new DesiredCapabilities();
// Set the browser. If you want to open a Chrome, you can modify it to: DesiredCapabilites.chrome(); etc...
dc = DesiredCapabilities.internetExplorer();
// Set the Platform. It must be the same what you defined in the nodeConfig.json.
dc.setPlatform(Platform.WINDOWS);
// Set the version of the browser. If you didn't set any version in the nodeConfig.json, you can skip this line.
dc.setVersion("11");
// Create the WebDriver which will open the given browser on a Node
WebDriver driver = new RemoteWebDriver(new URL("IP_OF_THE_HUB:4444/wd/hub"), dc);
// Open a page
driver.get("http://google.com");
// Create screenshot about the current page
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// Save the screenshot into a file
FileUtils.copyFile(scrFile, new File("c:\\screenshots\\screenshot.png"));
// Close the browser
driver.quit();
}
}
In this example, your code will open an Internet Explorer 11 on a Windows Node, open the http://google.com url and create a screenshot about it, and save it to c:/screenshots/screenshot.png.
Hope it helps.

How to run Selenium WebDriver test cases in Chrome

I tried this
WebDriver driver = new ChromeDriver();
But I'm getting the error as
Failed tests: setUp(com.TEST): The path to the driver executable must be set by the webdriver.chrome.driver system property; for more information, see code here . The latest version can be downloaded from this link
How can I make Chrome test the Selenium WebDriver test cases?
You need to download the executable driver from:
ChromeDriver Download
Then use the following before creating the driver object (already shown in the correct order):
System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
WebDriver driver = new ChromeDriver();
This was extracted from the most useful guide from the ChromeDriver Documentation.
Download the updated version of the Google Chrome driver from Chrome Driver.
Please read the release note as well here.
If the Chrome browser is updated, then you need to download the new Chrome driver from the above link, because it would be compatible with the new browser version.
public class chrome
{
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
WebDriver driver = new ChromeDriver();
driver.get("http://www.google.com");
}
}
You should download the chromeDriver in a folder, and add this folder in your PATH environment variable.
You'll have to restart your console to make it work.
If you're using Homebrew on a macOS machine, you can use the command:
brew tap homebrew/cask && brew cask install chromedriver
It should work fine after that with no other configuration.
You need to install the Chrome driver. You can install this package using NuGet as shown below:
You can use the below code to run test cases in Chrome using Selenium WebDriver:
import java.io.IOException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class ChromeTest {
/**
* #param args
* #throws InterruptedException
* #throws IOException
*/
public static void main(String[] args) throws InterruptedException, IOException {
// Telling the system where to find the Chrome driver
System.setProperty(
"webdriver.chrome.driver",
"E:/chromedriver_win32/chromedriver.exe");
WebDriver webDriver = new ChromeDriver();
// Open google.com
webDriver.navigate().to("http://www.google.com");
String html = webDriver.getPageSource();
// Printing result here.
System.out.println(html);
webDriver.close();
webDriver.quit();
}
}
Find the latest version of chromedriver here.
Once downloaded, unzip it at the root of your Python installation, e.g., C:/Program Files/Python-3.5, and that's it.
You don't even need to specify the path anywhere and/or add chromedriver to your path or the like.
I just did it on a clean Python installation and that works.
Download the latest version of the Chrome driver and use this code:
System.setProperty("webdriver.chrome.driver", "path of chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
Thread.sleep(10000);
driver.get("http://stackoverflow.com");
On Ubuntu, you can simply install the chromium-chromedriver package:
apt install chromium-chromedriver
Be aware that this also installs an outdated Selenium version. To install the latest Selenium:
pip install selenium
All the previous answers are correct. Following is the little deep dive into the problem and solution.
The driver constructor in Selenium for example
WebDriver driver = new ChromeDriver();
searches for the driver executable, in this case the Google Chrome driver searches for a Chrome driver executable. In case the service is unable to find the executable, the exception is thrown.
This is where the exception comes from (note the check state method)
/**
*
* #param exeName Name of the executable file to look for in PATH
* #param exeProperty Name of a system property that specifies the path to the executable file
* #param exeDocs The link to the driver documentation page
* #param exeDownload The link to the driver download page
*
* #return The driver executable as a {#link File} object
* #throws IllegalStateException If the executable not found or cannot be executed
*/
protected static File findExecutable(
String exeName,
String exeProperty,
String exeDocs,
String exeDownload) {
String defaultPath = new ExecutableFinder().find(exeName);
String exePath = System.getProperty(exeProperty, defaultPath);
checkState(exePath != null,
"The path to the driver executable must be set by the %s system property;"
+ " for more information, see %s. "
+ "The latest version can be downloaded from %s",
exeProperty, exeDocs, exeDownload);
File exe = new File(exePath);
checkExecutable(exe);
return exe;
}
The following is the check state method which throws the exception:
/**
* Ensures the truth of an expression involving the state of the calling instance, but not
* involving any parameters to the calling method.
*
* <p>See {#link #checkState(boolean, String, Object...)} for details.
*/
public static void checkState(
boolean b,
#Nullable String errorMessageTemplate,
#Nullable Object p1,
#Nullable Object p2,
#Nullable Object p3) {
if (!b) {
throw new IllegalStateException(format(errorMessageTemplate, p1, p2, p3));
}
}
SOLUTION: set the system property before creating driver object as follows.
System.setProperty("webdriver.gecko.driver", "path/to/chromedriver.exe");
WebDriver driver = new ChromeDriver();
The following is the code snippet (for Chrome and Firefox) where the driver service searches for the driver executable:
Chrome:
#Override
protected File findDefaultExecutable() {
return findExecutable("chromedriver", CHROME_DRIVER_EXE_PROPERTY,
"https://github.com/SeleniumHQ/selenium/wiki/ChromeDriver",
"http://chromedriver.storage.googleapis.com/index.html");
}
Firefox:
#Override
protected File findDefaultExecutable() {
return findExecutable(
"geckodriver", GECKO_DRIVER_EXE_PROPERTY,
"https://github.com/mozilla/geckodriver",
"https://github.com/mozilla/geckodriver/releases");
}
where CHROME_DRIVER_EXE_PROPERTY = "webdriver.chrome.driver"
and GECKO_DRIVER_EXE_PROPERTY = "webdriver.gecko.driver"
Similar is the case for other browsers, and the following is the snapshot of the list of the available browser implementation:
To run Selenium WebDriver test cases in Chrome, follow these steps:
First of all, set the property and Chrome driver path:
System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
Initialize the Chrome Driver's object:
WebDriver driver = new ChromeDriver();
Pass the URL into the get method of WebDriver:
driver.get("http://www.google.com");
I included the binary into my projects resources directory like so:
src\main\resources\chrome\chromedriver_win32.zip
src\main\resources\chrome\chromedriver_mac64.zip
src\main\resources\chrome\chromedriver_linux64.zip
Code:
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.SystemUtils;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.*;
import java.nio.file.Files;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public WebDriver getWebDriver() throws IOException {
File tempDir = Files.createTempDirectory("chromedriver").toFile();
tempDir.deleteOnExit();
File chromeDriverExecutable;
final String zipResource;
if (SystemUtils.IS_OS_WINDOWS) {
zipResource = "chromedriver_win32.zip";
} else if (SystemUtils.IS_OS_LINUX) {
zipResource = "chromedriver_linux64.zip";
} else if (SystemUtils.IS_OS_MAC) {
zipResource = "chrome/chromedriver_mac64.zip";
} else {
throw new RuntimeException("Unsuppoerted OS");
}
try (InputStream is = getClass().getResourceAsStream("/chrome/" + zipResource)) {
try (ZipInputStream zis = new ZipInputStream(is)) {
ZipEntry entry;
entry = zis.getNextEntry();
chromeDriverExecutable = new File(tempDir, entry.getName());
chromeDriverExecutable.deleteOnExit();
try (OutputStream out = new FileOutputStream(chromeDriverExecutable)) {
IOUtils.copy(zis, out);
}
}
}
System.setProperty("webdriver.chrome.driver", chromeDriverExecutable.getAbsolutePath());
return new ChromeDriver();
}
Download the EXE file of chromedriver and extract it in the current project location.
Here is the link, where we can download the latest version of chromedriver:
https://sites.google.com/a/chromium.org/chromedriver/
Here is the simple code for the launch browser and navigate to a URL.
System.setProperty("webdriver.chrome.driver", "path of chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("https://any_url.com");