Skip to content

Commit

Permalink
fix FirefoxDriver initialization failed. (#232)
Browse files Browse the repository at this point in the history
  • Loading branch information
vmi committed Mar 20, 2017
1 parent f45cd14 commit 64bf30f
Show file tree
Hide file tree
Showing 15 changed files with 217 additions and 275 deletions.
2 changes: 2 additions & 0 deletions RELEASENOTE.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Selenese Runner Java Relase Note
* Add local file detector for file uploading by RemoteWebDriver. (#231)
* Catch up Selenium 3.3.1.
* Update dependency versions.
* Fix FirefoxDriver initialization failed. (#232)
* Note: Several tests fail with Firefox. I think that this is a problem of Selenium 3.3.1.

### 3.2.0

Expand Down
6 changes: 3 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ It supports test-case and test-suite which are Selenium IDE's native format.</de
<htmlunit-driver.version>2.25</htmlunit-driver.version>
<httpclient.version>4.5.3</httpclient.version>
<httpcore.version>4.4.6</httpcore.version>
<slf4j.version>1.7.24</slf4j.version>
<slf4j.version>1.7.25</slf4j.version>
<maven.version.rules>file://${basedir}/version-rules.xml</maven.version.rules>
<shade.java.srcdir>src/shade/java</shade.java.srcdir>
<shade.java.destdir>target/shade-classes</shade.java.destdir>
Expand Down Expand Up @@ -503,7 +503,7 @@ It supports test-case and test-suite which are Selenium IDE's native format.</de
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.1</version>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>xalan</groupId>
Expand Down Expand Up @@ -559,7 +559,7 @@ It supports test-case and test-suite which are Selenium IDE's native format.</de
<dependency>
<groupId>org.littleshoot</groupId>
<artifactId>littleproxy</artifactId>
<version>0.5.3</version>
<version>1.1.2</version>
<scope>test</scope>
<exclusions>
<exclusion>
Expand Down
245 changes: 113 additions & 132 deletions src/main/java/jp/vmi/selenium/webdriver/FirefoxDriverFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,19 @@

import java.io.File;
import java.io.IOException;
import java.util.Map;

import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.firefox.FirefoxBinary;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.firefox.GeckoDriverService;
import org.openqa.selenium.firefox.internal.ProfilesIni;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.JsonObject;

import jp.vmi.selenium.selenese.utils.PathUtils;

import static jp.vmi.selenium.webdriver.DriverOptions.DriverOption.*;
Expand All @@ -36,126 +34,74 @@ public String getBrowserName() {
return BROWSER_NAME;
}

/**
* System property name for specifying Firefox binary.
*/
public static final String WEBDRIVER_FIREFOX_BIN = "webdriver.firefox.bin";
@Override
protected DesiredCapabilities setupProxy(DesiredCapabilities caps, DriverOptions driverOptions) {
if (driverOptions.has(PROXY)) {
String[] p = driverOptions.get(PROXY).split(":", 2);
String proxy = p[0];
int port = p.length == 2 ? Integer.parseInt(p[1]) : 80;
JsonObject json = new JsonObject();
json.addProperty("proxyType", "MANUAL");
json.addProperty("httpProxy", proxy);
json.addProperty("httpProxyPort", port);
json.addProperty("sslProxy", proxy);
json.addProperty("sslProxyPort", port);
if (driverOptions.has(NO_PROXY)) {
// don't work?
json.addProperty("noProxy", driverOptions.get(NO_PROXY));
}
caps.setCapability("proxy", json);
}
return caps;
}

@Override
public WebDriver newInstance(DriverOptions driverOptions) {
if (driverOptions.has(GECKODRIVER)) {
String executable = PathUtils.normalize(driverOptions.get(GECKODRIVER));
if (!new File(executable).canExecute())
throw new IllegalArgumentException("Missing GeckoDriver: " + executable);
System.setProperty(GeckoDriverService.GECKO_DRIVER_EXE_PROPERTY, executable);
}
FirefoxOptions firefoxOptions = new FirefoxOptions();
DesiredCapabilities requiredCaps = new DesiredCapabilities();
setupProxy(requiredCaps, driverOptions);
firefoxOptions.addRequiredCapabilities(requiredCaps);
firefoxOptions.addDesiredCapabilities(driverOptions.getCapabilities());
String firefoxBin = getFirefoxBinary(driverOptions);
if (firefoxBin != null)
firefoxOptions.setBinary(firefoxBin);
if (driverOptions.has(CLI_ARGS))
firefoxOptions.addArguments(driverOptions.getCliArgs());
FirefoxProfile profile = getFirefoxProfile(driverOptions);
if (profile != null)
firefoxOptions.setProfile(profile);
FirefoxDriver driver = new FirefoxDriver(firefoxOptions);
setInitialWindowSize(driver, driverOptions);
return driver;
}

/**
* set driver specific capabilities.
* set driver specific capabilities for RemoteWebDriver.
*
* @param caps desired capabilities.
* @param driverOptions driver options.
* @param isRemote set up for remote if true.
*/
public static void setDriverSpecificCapabilities(DesiredCapabilities caps, DriverOptions driverOptions, boolean isRemote) {
setFirefoxBinary(caps, driverOptions, isRemote);
setFirefoxProfile(caps, driverOptions, isRemote);
}

private static void setFirefoxBinary(DesiredCapabilities caps, DriverOptions driverOptions, boolean isRemote) {
// Set up firefox binary.
// Validate "webdriver.firefox.bin" value bacause FirefoxBinary only ignore invalid it.
String firefoxBin = System.getProperty(WEBDRIVER_FIREFOX_BIN);
// Override by command line option.
if (driverOptions.has(FIREFOX)) {
firefoxBin = driverOptions.get(FIREFOX);
System.setProperty(WEBDRIVER_FIREFOX_BIN, firefoxBin);
}
if (isRemote) {
if (firefoxBin != null) {
caps.setCapability(FirefoxDriver.BINARY, firefoxBin);
log.info("Firefox binary: {}", firefoxBin);
}
if (driverOptions.has(CLI_ARGS))
log.warn("Ignore --cli-args with RemoteWebDriver.");
return;
}
FirefoxBinary binary;
try {
if (firefoxBin != null) {
File file = new File(firefoxBin);
if (!file.isFile() || !file.canExecute())
throw new IllegalArgumentException("Missing Firefox binary: " + firefoxBin);
binary = new FirefoxBinary(file);
log.info("Firefox binary: {}", firefoxBin);
} else {
binary = new FirefoxBinary();
}
} catch (WebDriverException e) {
throw new IllegalArgumentException(e.getMessage(), e);
}
if (driverOptions.has(CLI_ARGS)) {
String[] cliArgs = driverOptions.getCliArgs();
binary.addCommandLineOptions(cliArgs);
log.info("Command line arguments: [{}]", StringUtils.join(cliArgs, "] ["));
}
boolean isFirst = true;
for (Map.Entry<String, String> entry : driverOptions.getEnvVars().entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
binary.setEnvironmentProperty(key, value);
if (isFirst) {
log.info("Envrionment variables:");
isFirst = false;
}
log.info("- [{}]=[{}]", key, StringEscapeUtils.escapeJava(value));
}
caps.setCapability(FirefoxDriver.BINARY, binary);
}

private static void setFirefoxProfile(DesiredCapabilities caps, DriverOptions driverOptions, boolean isRemote) {
FirefoxProfile profile;
if (driverOptions.has(PROFILE) || driverOptions.has(PROFILE_DIR)) {
// Create FirefoxProfile and set to DesiredCapabilities.
// (FirefoxProfile object can work with both local and remote FirefoxDriver
// see: https://code.google.com/p/selenium/wiki/DesiredCapabilities#Firefox_specific)
String profileName = driverOptions.get(PROFILE);
String profileDir = driverOptions.get(PROFILE_DIR);
if (profileName != null) {
if (profileDir != null)
throw new IllegalArgumentException("Can't specify both '--profile' and '--profile-dir' at once");
// see http://code.google.com/p/selenium/wiki/TipsAndTricks
ProfilesIni allProfiles = new ProfilesIni();
profile = allProfiles.getProfile(profileName);
if (profile == null)
throw new IllegalArgumentException("Profile '" + profile + "' does not exist.");
log.info("Firefox profile: {}", profileName);
} else {
File dir = new File(profileDir);
if (!dir.isDirectory())
throw new IllegalArgumentException("Missing profile directory: " + profileDir);
profile = new FirefoxProfile(dir);
log.info("Firefox profile directory: {}", profileDir);
}
} else {
profile = new FirefoxProfile();
profile.setPreference("browser.startup.homepage", "about:blank");
profile.setPreference("startup.homepage_welcome_url", "about:blank");
profile.setPreference("startup.homepage_welcome_url.additional", "about:blank");
public static void setDriverSpecificCapabilitiesForRemoteWebDriver(DesiredCapabilities caps, DriverOptions driverOptions) {
String firefoxBin = getFirefoxBinary(driverOptions);
if (firefoxBin != null) {
caps.setCapability(FirefoxDriver.BINARY, firefoxBin);
log.info("Firefox binary: {}", firefoxBin);
}
if (driverOptions.has(CLI_ARGS))
log.warn("Ignore --cli-args with RemoteWebDriver.");
FirefoxProfile profile = getFirefoxProfile(driverOptions);
if (driverOptions.has(PROXY)) {
String[] pss = driverOptions.get(PROXY).split(":");
if (pss.length == 2) {
String host = pss[0];
int port = Integer.parseInt(pss[1]);
String noProxy = driverOptions.has(NO_PROXY) ? driverOptions.get(NO_PROXY) : " ";
// see https://developer.mozilla.org/en-US/docs/Mozilla/Preferences/Mozilla_networking_preferences#Proxy
profile.setPreference("network.proxy.type", 1); // 1 = MANUAL
profile.setPreference("network.proxy.http", host);
profile.setPreference("network.proxy.http_port", port);
profile.setPreference("network.proxy.ssl", host);
profile.setPreference("network.proxy.ssl_port", port);
profile.setPreference("network.proxy.ftp", host);
profile.setPreference("network.proxy.ftp_port", port);
profile.setPreference("network.proxy.socks", host);
profile.setPreference("network.proxy.socks_port", port);
profile.setPreference("network.proxy.no_proxies_on", noProxy);
} else {
log.warn("Invalid proxy format (\"HOST:PORT\" required): {}", driverOptions.get(PROXY));
}
if (profile == null)
profile = new FirefoxProfile();
setProxyConfiguration(profile, driverOptions);
}
if (isRemote) {
if (profile != null) {
String json;
try {
json = profile.toJson();
Expand All @@ -164,25 +110,60 @@ private static void setFirefoxProfile(DesiredCapabilities caps, DriverOptions dr
}
caps.setCapability(FirefoxDriver.PROFILE, json);
log.info("Convert Firefox profile to JSON: {} bytes", json.length());
} else {
caps.setCapability(FirefoxDriver.PROFILE, profile);
}
}

@Override
public WebDriver newInstance(DriverOptions driverOptions) {
if (driverOptions.has(GECKODRIVER)) {
String executable = PathUtils.normalize(driverOptions.get(GECKODRIVER));
if (!new File(executable).canExecute())
throw new IllegalArgumentException("Missing GeckoDriver: " + executable);
System.setProperty(GeckoDriverService.GECKO_DRIVER_EXE_PROPERTY, executable);
private static String getFirefoxBinary(DriverOptions driverOptions) {
if (driverOptions.has(FIREFOX))
return driverOptions.get(FIREFOX);
else
return System.getProperty(FirefoxDriver.SystemProperty.BROWSER_BINARY);
}

private static FirefoxProfile getFirefoxProfile(DriverOptions driverOptions) {
if (!driverOptions.has(PROFILE) && !driverOptions.has(PROFILE_DIR))
return null;
FirefoxProfile profile;
// Create FirefoxProfile and set to DesiredCapabilities.
// (FirefoxProfile object can work with both local and remote FirefoxDriver
// see: https://code.google.com/p/selenium/wiki/DesiredCapabilities#Firefox_specific)
String profileName = driverOptions.get(PROFILE);
String profileDir = driverOptions.get(PROFILE_DIR);
if (profileName != null) {
if (profileDir != null)
throw new IllegalArgumentException("Can't specify both '--profile' and '--profile-dir' at once");
// see http://code.google.com/p/selenium/wiki/TipsAndTricks
ProfilesIni allProfiles = new ProfilesIni();
profile = allProfiles.getProfile(profileName);
if (profile == null)
throw new IllegalArgumentException("Profile '" + profile + "' does not exist.");
log.info("Firefox profile: {}", profileName);
} else {
File dir = new File(profileDir);
if (!dir.isDirectory())
throw new IllegalArgumentException("Missing profile directory: " + profileDir);
profile = new FirefoxProfile(dir);
log.info("Firefox profile directory: {}", profileDir);
}
DesiredCapabilities caps = DesiredCapabilities.firefox();
setupProxy(caps, driverOptions);
caps.merge(driverOptions.getCapabilities());
setDriverSpecificCapabilities(caps, driverOptions, false);
FirefoxDriver driver = new FirefoxDriver(caps);
setInitialWindowSize(driver, driverOptions);
return driver;
return profile;
}

private static void setProxyConfiguration(FirefoxProfile profile, DriverOptions driverOptions) {
String proxy = driverOptions.get(PROXY);
String[] ps = proxy.split(":", 2);
String host = ps[0];
int port = ps.length == 2 ? Integer.parseInt(ps[1]) : 80;
String noProxy = driverOptions.has(NO_PROXY) ? driverOptions.get(NO_PROXY) : " ";
// see https://developer.mozilla.org/en-US/docs/Mozilla/Preferences/Mozilla_networking_preferences#Proxy
profile.setPreference("network.proxy.type", 1); // 1 = MANUAL
profile.setPreference("network.proxy.http", host);
profile.setPreference("network.proxy.http_port", port);
profile.setPreference("network.proxy.ssl", host);
profile.setPreference("network.proxy.ssl_port", port);
profile.setPreference("network.proxy.ftp", host);
profile.setPreference("network.proxy.ftp_port", port);
profile.setPreference("network.proxy.socks", host);
profile.setPreference("network.proxy.socks_port", port);
profile.setPreference("network.proxy.no_proxies_on", noProxy);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public WebDriver newInstance(DriverOptions driverOptions) {
caps.setBrowserName(browser);
log.info("Remote browser: {}", browser);
if ("firefox".equalsIgnoreCase(browser))
FirefoxDriverFactory.setDriverSpecificCapabilities(caps, driverOptions, true);
FirefoxDriverFactory.setDriverSpecificCapabilitiesForRemoteWebDriver(caps, driverOptions);
if ("chrome".equalsIgnoreCase(browser))
ChromeDriverFactory.setDriverSpecificCapabilities(caps, driverOptions);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,8 @@ public void issue179() {

@Test
public void issue190() {
// FIXME Don't work with FirefoxDriver of Selenium 3.3.1.
assumeNot(FIREFOX);
runner.setTimeout(3000);
execute("testcase_issue190");
assertThat(result, is(instanceOf(Error.class)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import jp.vmi.selenium.selenese.result.Success;
import jp.vmi.selenium.testutils.DriverDependentTestCaseTestBase;

import static jp.vmi.selenium.webdriver.WebDriverManager.*;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;

Expand All @@ -13,6 +14,8 @@ public class WindowSelectorTest extends DriverDependentTestCaseTestBase {

@Test
public void testSelectWindow() {
// FIXME Don't work with FirefoxDriver of Selenium 3.3.1.
assumeNot(FIREFOX);
execute("testcase_issue199");
assertThat(result, is(instanceOf(Success.class)));
}
Expand Down
Loading

0 comments on commit 64bf30f

Please sign in to comment.