Skip to content

Commit

Permalink
Merge pull request #706 from MartinKavik/fix/webdriver_versions
Browse files Browse the repository at this point in the history
Select correct webdriver version
  • Loading branch information
fitzgen authored Sep 9, 2019
2 parents 439e523 + a39a278 commit 15e354f
Show file tree
Hide file tree
Showing 11 changed files with 514 additions and 93 deletions.
21 changes: 21 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ chrono = "0.4.6"
assert_cmd = "0.11"
lazy_static = "1.1.0"
predicates = "1.0.0"
serial_test = "0.2"
serial_test_derive = "0.2"
tempfile = "3"

[features]
Expand Down
4 changes: 4 additions & 0 deletions RELEASE_CHECKLIST.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ This is a list of the things that need to happen during a release.
1. Create a new branch "#.#.#" where "#.#.#" is the release's version.
1. Add this release to the `CHANGELOG.md`. Use the structure of previous
entries.
1. Update `DEFAULT_CHROMEDRIVER_VERSION` in `chromedriver.rs`.
Version is the response of `https://chromedriver.storage.googleapis.com/LATEST_RELEASE`.
1. Update `DEFAULT_GECKODRIVER_VERSION` in `geckodriver.rs`.
Version is the name of the latest tag - `https://github.com/mozilla/geckodriver/releases/latest`.
1. Update the version in `Cargo.toml`.
1. Update the version number and date in `docs/index.html`.
1. Run `cargo update`.
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pub mod manifest;
pub mod npm;
pub mod progressbar;
pub mod readme;
pub mod stamps;
pub mod target;
pub mod test;
pub mod wasm_opt;
Expand Down
58 changes: 58 additions & 0 deletions src/stamps.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//! Key-value store in `*.stamps` file.

use failure::{self, ResultExt};
use std::{env, fs, path::PathBuf};

/// Get a value corresponding to the key from the JSON value.
///
/// You should use return value of function `read_stamps_file_to_json()` as `json` argument.
pub fn get_stamp_value(
key: impl AsRef<str>,
json: &serde_json::Value,
) -> Result<String, failure::Error> {
json.get(key.as_ref())
.and_then(|value| value.as_str().map(ToOwned::to_owned))
.ok_or_else(|| {
failure::err_msg(format!("cannot get stamp value for key '{}'", key.as_ref()))
})
}

/// Save the key-value pair to the store.
pub fn save_stamp_value(
key: impl Into<String>,
value: impl AsRef<str>,
) -> Result<(), failure::Error> {
let mut json = read_stamps_file_to_json().unwrap_or_else(|_| serde_json::Map::new().into());

let stamps = json
.as_object_mut()
.ok_or_else(|| failure::err_msg("stamps file doesn't contain JSON object"))?;
stamps.insert(key.into(), value.as_ref().into());

write_to_stamps_file(json)
}

/// Get the path of the `*.stamps` file that is used as the store.
pub fn get_stamps_file_path() -> Result<PathBuf, failure::Error> {
let path = env::current_exe()
.map(|path| path.with_extension("stamps"))
.context("cannot get stamps file path")?;
Ok(path)
}

/// Read `*.stamps` file and convert its content to the JSON value.
pub fn read_stamps_file_to_json() -> Result<serde_json::Value, failure::Error> {
let stamps_file_path = get_stamps_file_path()?;
let stamps_file_content =
fs::read_to_string(stamps_file_path).context("cannot find or read stamps file")?;
let json: serde_json::Value = serde_json::from_str(&stamps_file_content)
.context("stamps file doesn't contain valid JSON")?;
Ok(json)
}

fn write_to_stamps_file(json: serde_json::Value) -> Result<(), failure::Error> {
let stamps_file_path = get_stamps_file_path()?;
let pretty_json = serde_json::to_string_pretty(&json).context("JSON serialization failed")?;
fs::write(stamps_file_path, pretty_json).context("cannot write to stamps file")?;
Ok(())
}
114 changes: 21 additions & 93 deletions src/test/webdriver.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
//! Getting WebDriver client binaries.

mod chromedriver;
mod geckodriver;
mod safaridriver;

use binary_install::Cache;
use failure;
use install::InstallMode;
use std::path::PathBuf;
use target;
use PBAR;

pub use self::{
chromedriver::{get_or_install_chromedriver, install_chromedriver},
geckodriver::{get_or_install_geckodriver, install_geckodriver},
safaridriver::get_safaridriver,
};

// ------ driver helpers ------

fn get_and_notify(
cache: &Cache,
installation_allowed: bool,
Expand All @@ -25,100 +35,18 @@ fn get_and_notify(
}
}

/// Get the path to an existing `chromedriver`, or install it if no existing
/// binary is found.
pub fn get_or_install_chromedriver(
cache: &Cache,
mode: InstallMode,
) -> Result<PathBuf, failure::Error> {
if let Ok(path) = which::which("chromedriver") {
return Ok(path);
}
install_chromedriver(cache, mode.install_permitted())
}

/// Download and install a pre-built `chromedriver` binary.
pub fn install_chromedriver(
cache: &Cache,
installation_allowed: bool,
) -> Result<PathBuf, failure::Error> {
let target = if target::LINUX && target::x86_64 {
"linux64"
} else if target::MACOS && target::x86_64 {
"mac64"
} else if target::WINDOWS {
"win32"
} else {
bail!("chromedriver binaries are unavailable for this target")
};

let url = format!(
"https://chromedriver.storage.googleapis.com/2.46/chromedriver_{}.zip",
target
);
match get_and_notify(cache, installation_allowed, "chromedriver", &url)? {
Some(path) => Ok(path),
None => bail!(
"No cached `chromedriver` binary found, and could not find a global \
`chromedriver` on the `$PATH`. Not installing `chromedriver` because of noinstall \
mode."
),
}
}

/// Get the path to an existing `geckodriver`, or install it if no existing
/// binary is found.
pub fn get_or_install_geckodriver(
cache: &Cache,
mode: InstallMode,
) -> Result<PathBuf, failure::Error> {
if let Ok(path) = which::which("geckodriver") {
return Ok(path);
}
install_geckodriver(cache, mode.install_permitted())
}

/// Download and install a pre-built `geckodriver` binary.
pub fn install_geckodriver(
cache: &Cache,
installation_allowed: bool,
) -> Result<PathBuf, failure::Error> {
let (target, ext) = if target::LINUX && target::x86 {
("linux32", "tar.gz")
} else if target::LINUX && target::x86_64 {
("linux64", "tar.gz")
} else if target::MACOS {
("macos", "tar.gz")
} else if target::WINDOWS && target::x86 {
("win32", "zip")
} else if target::WINDOWS && target::x86_64 {
("win64", "zip")
} else {
bail!("geckodriver binaries are unavailable for this target")
};
struct Collector(Vec<u8>);

let url = format!(
"https://github.com/mozilla/geckodriver/releases/download/v0.24.0/geckodriver-v0.24.0-{}.{}",
target,
ext,
);
match get_and_notify(cache, installation_allowed, "geckodriver", &url)? {
Some(path) => Ok(path),
None => bail!(
"No cached `geckodriver` binary found, and could not find a global `geckodriver` \
on the `$PATH`. Not installing `geckodriver` because of noinstall mode."
),
impl Collector {
pub fn take_content(&mut self) -> Vec<u8> {
// TODO: replace with `std::mem::take` once stable
std::mem::replace(&mut self.0, Vec::default())
}
}

/// Get the path to an existing `safaridriver`.
///
/// We can't install `safaridriver` if an existing one is not found because
/// Apple does not provide pre-built binaries. However, `safaridriver` *should*
/// be present by default.
pub fn get_safaridriver() -> Result<PathBuf, failure::Error> {
match which::which("safaridriver") {
Ok(p) => Ok(p),
Err(_) => bail!("could not find `safaridriver` on the `$PATH`"),
impl curl::easy::Handler for Collector {
fn write(&mut self, data: &[u8]) -> Result<usize, curl::easy::WriteError> {
self.0.extend_from_slice(data);
Ok(data.len())
}
}
Loading

0 comments on commit 15e354f

Please sign in to comment.