2

I am attempting to make a simple framework using Selenium for Java. One of the unfortunate aspects of trying to set this up has been that I don't have access to edit the SYSTEM level variables on my Windows machine.

In attempting to run a single JUnit test that is merely trying to go to a website, and then assert it's on the page I pointed it at, I keep receiving an error that the path to the ChromeDriver executable must be set. I do have this downloaded locally.

Caused by: java.lang.IllegalStateException: The path to the driver executable must be set by the webdriver.chrome.driver system property; for more information, see https://github.com/SeleniumHQ/selenium/wiki/ChromeDriver. The latest version can be downloaded from http://chromedriver.storage.googleapis.com/index.html

Now, I can avoid that error by just throwing a System.setProperty("webdriver.chrome.driver", "/path/to/myexecutable.exe") in a class within the main entry point of a program, but not sure how to get around this with using a unit test.

My basic test:

package com.mytestpackage;

import org.junit.Assert;
import org.junit.Test;

public class UnitTest {

    @Test
    public void canGoToHomePage() {
        Pages.homePage().goTo();
        Assert.assertTrue(Pages.homePage().isAt());
    }
}

And my three simple classes - Browser, HomePage, and Pages:

Browser

package com.mytestpackage;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class Browser {

    static WebDriver driver = new ChromeDriver();

    public static void goTo(String url) {
        driver.get(url);
    }

    public static String title() {
        return driver.getTitle();
    }
}

HomePage

package com.mytestpackage;

public class HomePage {

    static String url = "http://test.salesforce.com";
    static String title = "Login | Salesforce";

    public void goTo() {
        Browser.goTo(url);
    }

    public boolean isAt() {
        return Browser.title().equals(title);
    }
}

Pages

package com.mytestpackage;

public class Pages {

    public static HomePage homePage() {
        return new HomePage();
    }
}

The main point of frustration is not being able to edit the system variables. Any hackaround/workaround suggestions would be greatly appreciated.

trebleCode
  • 2,134
  • 19
  • 34

1 Answers1

5

It seems that the problem you see is solved by WebDriverManager - official docs

We are using it in our framework, and it makes all users free from carrying about system properties and versions of a chromedriver. (When you use executable of a chromedriver you will need to be sure to keep it updated with the browser updates as well)

Add the following method to your test class:

@BeforeClass
public static void setupClass() {
    WebDriverManager.chromedriver().setup();
}

And don't forget to attach a dependency to WebDriverManager in your pom.xml (Java 8 or upper required):

<dependency>
    <groupId>io.github.bonigarcia</groupId>
    <artifactId>webdrivermanager</artifactId>
    <version>3.0.0</version>
    <scope>test</scope>
</dependency>

... or in Gradle project:

dependencies {
    testCompile("io.github.bonigarcia:webdrivermanager:3.0.0")
}

Important sidenote: remove 'static' from your WebDriver field declaration in a Browser class. Keeping static will not allow you do proceed with parallel tests execution.

Vladimir Efimov
  • 797
  • 5
  • 13
  • Thanks @Vladimir Efimov. This resulted in errors with slf4j initially. I'm still trying to work through them. I'm also behind a corporate proxy so am likley going to have to do some further customizations. Thanks for pointing this out though, it will likely be very helpful. – trebleCode Nov 21 '18 at 19:19
  • Unfortunately for me, my company is blocking me getting to chromedriver.storage.googleapis.com which that repository tries to reach out to to forcibly download, so that option is dead in the water for me :( However I'm not blocked from the mirror listed for chrome, so that may work! http://npm.taobao.org/mirrors/chromedriver – trebleCode Nov 21 '18 at 19:26
  • 1
    If you've arrived here from the future with Google, adding the above dependencies did fix, however there were some additional steps. Create a file called 'log4j.properties' somewhere in your project, and point the configuration class path to the log4j config file. See: https://stackoverflow.com/questions/7421612/slf4j-failed-to-load-class-org-slf4j-impl-staticloggerbinder and https://stackoverflow.com/questions/12532339/no-appenders-could-be-found-for-loggerlog4j – trebleCode Nov 21 '18 at 19:33
  • 1
    Of note, my call in the `@BeforeClass setupClass()` looked like: `WebDriverManager.chromedriver().proxy("mycompanyproxy.site.com:1234").useMirror().setup();` The `useMirror()` option works but it cycles through all the versions it finds and chooses an option, which causes some delays but hey it works! – trebleCode Nov 21 '18 at 19:34