Skip to content

Commit

Permalink
geckodriver: Read Firefox version by launching binary if mozversion f…
Browse files Browse the repository at this point in the history
…ails (#685)

In some circumstances mozversion's attempt to read the Firefox version
from ini files can fail. This can be, for example, when the "binary"
is actaully a shell script that launches the real Firefox. In that
case it isn't necessarily possible to locate the ini files without
making the user explicitly provide a path. Instead fall back on
running `firefox -version` in this case and extracting the binary from
the returned string.

Fixes: SeleniumHQ/selenium#3884
Source-Repo: https://github.com/mozilla/geckodriver
Source-Revision: 6d1c7f28da90910c05426bbda8a70c42676033fa

committer: Andreas Tolfsen <atomozilla.com>

UltraBlame original commit: cfb7c7e11f6acd6a5b72d102317a1533f4ccd83c
  • Loading branch information
marco-c committed Oct 1, 2019
1 parent 48eec01 commit 818c25d
Showing 1 changed file with 39 additions and 9 deletions.
48 changes: 39 additions & 9 deletions testing/geckodriver/src/capabilities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use mozprofile::preferences::Pref;
use mozprofile::profile::Profile;
use mozrunner::runner::platform::firefox_default_path;
use mozversion::{self, firefox_version, Version};
use regex::bytes::Regex;
use rustc_serialize::base64::FromBase64;
use rustc_serialize::json::Json;
use std::collections::BTreeMap;
Expand All @@ -14,7 +15,8 @@ use std::io::BufWriter;
use std::io::Cursor;
use std::io;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use std::process::{Command, Stdio};
use std::str::{self, FromStr};
use webdriver::capabilities::{BrowserCapabilities, Capabilities};
use webdriver::error::{ErrorStatus, WebDriverError, WebDriverResult};
use zip;
Expand Down Expand Up @@ -53,20 +55,48 @@ impl<'a> FirefoxCapabilities<'a> {
.and_then(|x| x.canonicalize().ok())
}

fn version(&mut self) -> Result<Option<String>, mozversion::Error> {
fn version(&mut self) -> Option<String> {
if let Some(ref binary) = self.chosen_binary {
if let Some(value) = self.version_cache.get(binary) {
return Ok(Some((*value).clone()));
return Some((*value).clone());
}
let rv = try!(firefox_version(&*binary)).version_string;
debug!("Trying to read firefox version from ini files");
let rv = firefox_version(&*binary)
.ok()
.and_then(|x| x.version_string)
.or_else(|| {
debug!("Trying to read firefox version from binary");
self.version_from_binary(binary)
});
if let Some(ref version) = rv {
debug!("Found version {}", version);
self.version_cache
.insert(binary.clone(), version.clone());
} else {
debug!("Failed to get binary version");
}
Ok(rv)
rv
} else {

Ok(None)
None
}
}

fn version_from_binary(&self, binary: &PathBuf) -> Option<String> {
let version_regexp = Regex::new(r#"\d+\.\d+(?:[a-z]\d+)?"#).expect("Error parsing version regexp");
let output = Command::new(binary)
.args(&["-version"])
.stdout(Stdio::piped())
.spawn()
.and_then(|child| child.wait_with_output())
.ok();

if let Some(x) = output {
version_regexp.captures(&*x.stdout)
.and_then(|captures| captures.get(0))
.and_then(|m| str::from_utf8(m.as_bytes()).ok())
.map(|x| x.into())
} else {
None
}
}
}
Expand All @@ -88,7 +118,7 @@ impl<'a> BrowserCapabilities for FirefoxCapabilities<'a> {
}

fn browser_version(&mut self, _: &Capabilities) -> WebDriverResult<Option<String>> {
self.version().or_else(|x| Err(convert_version_error(x)))
Ok(self.version())
}

fn platform_name(&mut self, _: &Capabilities) -> WebDriverResult<Option<String>> {
Expand All @@ -104,7 +134,7 @@ impl<'a> BrowserCapabilities for FirefoxCapabilities<'a> {
}

fn accept_insecure_certs(&mut self, _: &Capabilities) -> WebDriverResult<bool> {
let version_str = try!(self.version().or_else(|x| Err(convert_version_error(x))));
let version_str = self.version();
if let Some(x) = version_str {
Ok(try!(Version::from_str(&*x).or_else(|x| Err(convert_version_error(x)))).major >= 52)
} else {
Expand Down

0 comments on commit 818c25d

Please sign in to comment.