How do I run GEB tests using the firefox driver? - selenium

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/

Related

Selenium Chromedriver opens with data:, in navigation bar

if i open Chrome via chromedriver and navigate to a URL i only get a data:, in the navigation bar. All googled solutions (right chromedriverversion, protocoll in URL, etc.) didnt help me.
package de.vhv.selenium;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class OpenChromeAndNavigate {
#Test
public void test() {
System.setProperty("webdriver.chrome.driver", "C://vhventw//selenium//chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("https://www.google.de");
}
}
In addition everything works if i add --headless and listen to the debugport. But i dont want to let it run headless.
package de.vhv.selenium;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class OpenChromeAndNavigate {
#Test
public void test() {
System.setProperty("webdriver.chrome.driver", "C://vhventw//selenium//chromedriver.exe");
WebDriver driver = new ChromeDriver(getDesiredCapabilities());
driver.get("https://www.google.de");
}
private ChromeOptions getDesiredCapabilities() {
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless");
// options.addArguments("--disable-extensions"); // disabling extensions
// options.addArguments("--disable-gpu"); // applicable to windows os only
// options.addArguments("--disable-dev-shm-usage"); // overcome limited resource problems
// options.addArguments("--no-sandbox");
options.addArguments("--remote-debugging-port=9223");
return options;
}
}
Any ideas what i can try?
Setup:
Chrome Version = 71.0.3578.80
Chromedriver Version = 2.46.628402
I figured out, that the line
options.addArguments("--remote-debugging-port=9225");
fixed my problem. I already used it in headless runs to listen to the port and watch the headless run. But it fixed my problem with headfull runs.
return new ChromeDriver(getDesiredCapabilities());
private ChromeOptions getDesiredCapabilities() {
ChromeOptions options = new ChromeOptions();
//options.addArguments("--headless");
options.addArguments("--disable-extensions"); // disabling extensions
options.addArguments("--disable-gpu"); // applicable to windows os only
options.addArguments("--disable-dev-shm-usage"); // overcome limited resource problems
options.addArguments("--no-sandbox");
options.addArguments("--remote-debugging-port=9225");
return options;
}
You need to take care of a couple of things:
Not sure about your project structure but I will suggest to avoid the . character and the word selenium within the package name as in:
package de.vhv.selenium;
The Value part passed through System.setProperty() line containing the absolute path of chromedriver.exe should be expressed through escaped backslashes as:
System.setProperty("webdriver.chrome.driver", "C:\\vhventw\\selenium\\chromedriver.exe");
As per ChromeDriver - WebDriver for Chrome:
If you are using Chrome version 72, please download ChromeDriver 2.46 or ChromeDriver 72.0.3626.69
As per best practices:
Upgrade JDK to recent levels JDK 8u202.
Upgrade Selenium to current levels Version 3.141.59.
Upgrade ChromeDriver to current ChromeDriver v73.0.3683.68 level.
Keep Chrome version between Chrome v73 levels. (as per ChromeDriver v73.0.3683.68 release notes)
Clean your Project Workspace through your IDE and Rebuild your project with required dependencies only.
If your base Web Client version is too old, then uninstall it through Revo Uninstaller and install a recent GA and released version of Web Client.
Take a System Reboot.
Execute your #Test.
Always invoke driver.quit() within tearDown(){} method to close & destroy the WebDriver and Web Client instances gracefully.
I was struggling with the same issue, then I realised that I forgot to start the test with :
$I->amOnPage('/');
definitely to try before digging deeper.

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.

Geb test ignoring GebConfig.groovy file launched in IntelliJ

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

Geb: How to use Marionette instead of selenium Webdriver?

It is known issue that, Firefox version 47.0.1 is not compatible with Selenium latest version. Even Firefox is announcing to use Marionette instead. Can someone give some details instruction on how to use Marionette with Geb?
As a maven project, I tried all the version of Selenium with Geb but could not be successfull. I tried the following versions;
2.50.0
2.50.1
2.51.0
2.52.0
2.53.0
2.53.1
2.6.0
2.7.0
2.8.0
2.9.0
If this is not the right place to ask this, please guide me.
I have the next configuration in GebConfig.groovy:
firefox {
System.setProperty("webdriver.gecko.driver","path/geckodriver")
driver = {new MarionetteDriver()}
}
I am using selenium 3.0.1 and I using the -Dgeb.env=firefox system property in order to make sure it takes my Firefox configuration and it working fine for me
Regards
Download the latest version of selenium standard version 2.53.1 from selenium.hq.org.downloads and try to use the newest version of the Firefox.
With version 48 of Firefox, it looks like the only solution is using marionnette, however I have not been able to get this to work in Geb yet.
This is what I have tried in GebConfig.groovy:
environments {
firefox {
driver = {
DesiredCapabilities dc = DesiredCapabilities.firefox();
LoggingPreferences prefs = new LoggingPreferences();
prefs.enable(LogType.BROWSER, Level.WARNING);
dc.setCapability(CapabilityType.LOGGING_PREFS, prefs);
dc.setCapability("marionette", true);
String currentDir = System.getProperty("user.dir");
String marionetteDriverLocation = currentDir + "/WebDriver/wires";
System.setProperty("webdriver.gecko.driver", marionetteDriverLocation);
FirefoxProfile p = new FirefoxProfile();
p.setPreference("webdriver.gecko.driver", marionetteDriverLocation);
p.setPreference("webdriver.log.file", "/tmp/firefox_console");
p.setPreference("toolkit.telemetry.enabled", false);
p.setPreference("geo.enabled", false);
p.setPreference("plugins.update.notifyUser", false);
p.setPreference("datareporting.healthreport.service.enabled", false);
p.setPreference("datareporting.healthreport.uploadEnabled", false);
p.setPreference("datareporting.policy.dataSubmissionEnabled",false);
p.setPreference("datareporting.healthreport.service.firstRun", false);
p.setPreference("datareporting.healthreport.logging.consoleEnabled", false);
p.setPreference("reader.parse-on-load.enabled", false);
dc.setCapability(FirefoxDriver.PROFILE, p);
def driver = new FirefoxDriver(dc)
driver.manage().timeouts().pageLoadTimeout(45, TimeUnit.SECONDS)
return driver
}
It should work with any of the late Selenium versions. (everything > 2.50 not sure for earlier versions)
Marionette is an external driver, it's not included in the Selenium packages (yet?)
You need to Download the gecko driver here https://github.com/mozilla/geckodriver/releases
then point selenium to the location of the geckodriver.exe
You can do that as Nelson said before in GebConfig with:
import org.openqa.selenium.firefox.MarionetteDriver
driver = {
System.setProperty("webdriver.gecko.driver","path/geckodriver")
new MarionetteDriver()
}
to make that work you will need some dependencies in your buildscript, I'm working with gradle, yours might look different, just look into what yours need to look like on maven central
compile('info.novatec.testit:webtester-support-marionette:2.0.4') { transitive = false }
compile "org.seleniumhq.selenium:selenium-firefox-driver:$seleniumVersion"
compile "org.seleniumhq.selenium:selenium-support:$seleniumVersion"
(selenium support might not be necessary for you)
If you need more help, a more specific description of where you are failing would be helpful, you can also look here for a working project (with maven):
http://seleniumsimplified.com/2016/04/how-to-use-the-firefox-marionette-driver/
public class Driver {
public FirefoxDriver getFirefoxDriver(){
System.setProperty("webdriver.gecko.driver", "./geckodriver.exe");
System.setProperty(FirefoxDriver.SystemProperty.DRIVER_USE_MARIONETTE, "true");
System.setProperty(FirefoxDriver.SystemProperty.BROWSER_LOGFILE, "/dev/null");
FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);
return new FirefoxDriver(options);
}
}

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.