Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Select correct webdriver version #706

Merged
merged 2 commits into from
Sep 9, 2019

Conversation

MartinKavik
Copy link
Contributor

Closes #611

Changes

  • webdriver.rs split into chromedriver.rs, geckodriver.rs and safaridriver.rs for better code organization.
  • Functions install_geckodriver and install_chromedriver fetches info about the latest *driver version so they can find out if we are using the latest *driver.

Testing

  • I've tested it locally on Windows 10 - it downloads both drivers without problems.
  • There are new / updated curl calls - should I test it in unit/integration tests somehow? (Is there an example for inspiration?)

Possible future improvements

  • We can fetch info about a new [chrome/gecko]driver only when testing fails because of old driver and then restart testing.
    • + A little bit faster testing.
    • + We probably don't need internet connection during testing.
    • + Less requests to fetched endpoints.
    • - It's not possible to determine exact fail reason.
    • - We have to remember to restart it only once to prevent infinite loop.
    • - More complex code.
    • - Probably premature optimization because those fetches aren't noticeable during testing.
  • Downloaded/cached drivers are never deleted/invalidated - we can delete old driver(s) when the newer one has been downloaded.
    • Probably out of scope this issue. Maybe general problem/feature of wasm-pack cache / crate binary-install.
  • We can find out versions of the installed browsers and then download compatible drivers.
    • It's not super easy and we would need platform-specific code which can be error prone.
    • See comments for functions get_chromedriver_url and get_geckodriver_url for more info.

@fitzgen fitzgen self-requested a review August 22, 2019 17:06
@fitzgen
Copy link
Member

fitzgen commented Aug 22, 2019

Thanks for sending in this PR! Will take a look at this next week, after rust conf.

Copy link
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great step forward -- thanks @MartinKavik! However, I have some concerns that I think we need to address before merging this. See inline comments below.

handle.perform()?;

let contents = handle.get_ref();
Ok(String::from_utf8_lossy(&contents.0).into_owned())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already a fallible method, and if the string contains non-utf-8 bits, I'd rather fail loudly than silently introduce replacement chars:

Suggested change
Ok(String::from_utf8_lossy(&contents.0).into_owned())
let vers = String::from_utf8(contents.0)
.context("chromedriver's LATEST_RELEASE is not valid UTF-8")?;
Ok(vers)

/// The official algorithm for `chromedriver` version selection:
/// https://chromedriver.chromium.org/downloads/version-selection
fn get_chromedriver_url(target: &str) -> Result<String, failure::Error> {
let chromedriver_version = fetch_chromedriver_version()?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should only check once per day, similar to how we throttle checking crates.io for new versions of wasm-pack itself being released.

Additionally, I think we should have a default, fallback version for when devs are offline. We can't make it impossible to run tests when one isn't connected to the internet. For this default version, we would manually keep it up to date with each wasm-pack release, and the fetch_chromedriver_version function would return it when the HTTP request otherwise fails. (Of course, the default would have to be downloaded at least once, but this would allow tests to work offline after it had been downloaded at least once).

fn fetch_chromedriver_version() -> Result<String, failure::Error> {
let mut handle = curl::easy::Easy2::new(Collector(Vec::new()));
handle.url("https://chromedriver.storage.googleapis.com/LATEST_RELEASE")?;
handle.perform()?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should have .context("...")s added as well to help debugging / inform users as to what is going wrong when HTTP requests fail.

/// https://firefox-source-docs.mozilla.org/testing/geckodriver/Support.html#supported-platforms
fn get_geckodriver_url(target: &str, ext: &str) -> Result<String, failure::Error> {
// JSON example: `{"id":15227534,"tag_name":"v0.24.0","update_url":"/mozzila...`
let latest_tag_json = fetch_latest_geckodriver_tag_json()?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically all the same comments from the chromedriver module apply here, including the .context("...")s.

@MartinKavik
Copy link
Contributor Author

Changes in the latest commit (I can squash them before merging if you want):

  • new file src/stamps.rs
    • super simple key-value file store for saving versions + timestamps
  • new file tests/all/stamps.rs
    • tests for stamps.rs
    • I've tried to write it as simple as possible but I'm waiting for review comments about best practices and file testing
    • added library serial_test
  • updated RELEASE_CHECKLIST so we don't forget to update driver versions
  • updated webdrivers*
    • see comment above function get_chromedriver_url or get_geckodriver_url - there is a new algorithm for getting driver version (it should be similar to your comment - check once per day, "offline" mode, etc.)
  • added contexts - I'm waiting for review comments about wording and failure / error handling best practices

I've tested it with a local project and it seems working even without internet connection (if drivers are already downloaded).

Your comments from the previous review should be resolved.
Thanks for reviews!

Copy link
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks wonderful! Thanks @MartinKavik for following through with addressing feedback and for your patience.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Headless Chrome test fails
3 participants