Skip to content

Commit

Permalink
- Removes runtime installation of chromedriver (#17)
Browse files Browse the repository at this point in the history
- Adds a convenience script to install chromedriver ad-hoc
- Runs bootstrap_chromedriver script as part of travis install phase; this is not packaged or installed as part of the plugin's install process
- Updates README with chromedriver bootstrapping instructions for developers who want to test locally
  • Loading branch information
Tom Thorogood authored Jun 10, 2020
1 parent 3ef11b0 commit 7bfcb53
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 11 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
language: python
python: ["3.6"]
addons:
chrome: stable
install:
- CHROMEDRIVER_DIR=/usr/local/bin CHROMEDRIVER_DIST=linux64 sudo ./bootstrap_chromedriver.sh
- pip install -U pip setuptools tox
- git describe --tags > webdriver_recorder/VERSION
script:
Expand Down
41 changes: 40 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,18 @@ pip install uw-webdriver-recorder

## Maintaining this plugin

It is highly recommended that you create a virtualenv in your repository directory:

```
python3 -m virtualenv env # Run once
source env/bin/activate
```

Otherwise, you'll need to make sure that dependencies for this package are natively discoverable on your system.
See [Requirements](#requirements).

To test this plugin, make sure you have `tox` installed (`pip install tox`) then run `tox`. This will test, lint, and
run coverage reports.
run coverage reports. (If you have a virtualenv, make sure to activate it before running tox.)

To build this plugin for release, you can do `python setup.py sdist`, to prepare for uploading to PyPI, or you can
install to a local python environment with `pip install .` or even `python setup.py install`. All of these options
Expand All @@ -22,6 +32,35 @@ show a version of `0.0.1`; that is because our versioning is managed by our repo
resolved by our release process.


## Requirements

You must have `chromedriver` available in your environment.
See the [official documentation](https://chromedriver.chromium.org/) to understand the driver and its installation
process.

### Installing and configuring the chromedriver

For the purposes of testing and maintaining this package, there is a convenience script to help download and install
the `chromedriver`, a required binary for this plugin. For development, it is recommended that you install
chromedriver to your virtualenv like so:

```
python3 -m virtualenv env
CHROMEDRIVER_DIST=mac64 ./bootstrap_chromedriver.sh # The default install location is in env/bin
```

Then, it will always be in your path, as long as your working in your virtualenv (`source env/bin/activate`).

This script is not installed as part of this plugin, and is only available from the git repository. There are a number
of solutions available to install chromedriver on your system, but this plugin does not assume that responsibility.

If your system has chromedriver installed somewhere undiscoverable, you can explicitly provide the correct path by
setting the CHROME_BIN environment variable:

```
CHROME_BIN="/path/to/google-chrome-stable" pytest
```

## Running it
Assume the following file:

Expand Down
34 changes: 34 additions & 0 deletions bootstrap_chromedriver.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/usr/bin/env bash

# This is meant as a developer tool so that developers can easily install chromedriver to their system for
# testing locally. This can also be used inside automation scripts to install the chromedriver in a production
# environment.

# You can set CHROMEDRIVER_DIR in order to customize
# the output location of the installed binary, and CHROMEDRIVER_DIST to customize the appropriate
# driver distribution; distributions should be provided in the format "linux64", "mac64", "win32," etc.
# By default CHROMEDRIVER_DIR is assumed to be the virtualenv bin directory, and the distribution is assumed to be
# linux64.
#
# To install in your virtualenv on a mac (a developer use case):
# CHROMEDRIVER_DIST=mac64 ./bootstrap_chromedriver.sh
#
# To install in /usr/local/bin on linux (a VM/container use case):
# CHROMEDRIVER_DIR=/usr/local/bin CHROMEDRIVER_DIST=linux64 sudo ./bootstrap_chromedriver.sh

set -e
CHROMEDRIVER_DIR=${CHROMEDRIVER_DIR:-env/bin}
CHROMEDRIVER_DIST=${CHROMEDRIVER_DIST:-linux64}
export CHROMEDRIVER_BIN="${CHROMEDRIVER_DIR}/chromedriver"
export CHROMEDRIVER_VERSION=$(curl https://chromedriver.storage.googleapis.com/LATEST_RELEASE)
CHROMEDRIVER_URL="https://chromedriver.storage.googleapis.com/${CHROMEDRIVER_VERSION}/chromedriver_${CHROMEDRIVER_DIST}.zip"

# Create the destination dir if it does not already exist, and remove any existing chromedriver binaries
test -d "${CHROMEDRIVER_DIR}" || mkdir -p "${CHROMEDRIVER_DIR}"
test -f "${CHROMEDRIVER_BIN}" && rm "${CHROMEDRIVER_BIN}"

echo "Installing chromedriver ${CHROMEDRIVER_VERSION} for ${CHROMEDRIVER_DIST} to ${CHROMEDRIVER_DIR}"
curl "${CHROMEDRIVER_URL}" > /tmp/chromedriver.zip
unzip /tmp/chromedriver.zip -d "${CHROMEDRIVER_DIR}"
chmod 755 "${CHROMEDRIVER_DIR}/chromedriver"
export PATH="${PATH}:${CHROMEDRIVER_DIR}"
1 change: 0 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ def file_path(*parts):
'jinja2',
'selenium',
'pydantic',
'webdriver-manager',
],
classifiers=[
'Programming Language :: Python',
Expand Down
11 changes: 4 additions & 7 deletions tests/test_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@
import os
import time
from datetime import datetime
from typing import NoReturn, Optional
from typing import NoReturn

import pytest
from selenium import webdriver
from selenium.common.exceptions import WebDriverException
from selenium.webdriver import DesiredCapabilities
from selenium.webdriver.remote.command import Command
from webdriver_manager.chrome import ChromeDriverManager

from webdriver_recorder.browser import Chrome, BrowserError, logger, _xpath_contains

Expand All @@ -34,7 +31,7 @@ def decrypt(self, encrypted_text):
"""
return encrypted_text.replace('secret-', '')

return TestChrome(ChromeDriverManager().install())
return TestChrome()


@pytest.fixture
Expand Down Expand Up @@ -64,7 +61,7 @@ def test_context_stops_client_on_exit(url):
class TestChrome(Chrome):
def __init__(self):
self.is_stopped = False
super().__init__(ChromeDriverManager().install())
super().__init__()

def stop_client(self):
self.is_stopped = True
Expand Down Expand Up @@ -206,7 +203,7 @@ def patch_execute(*args, **kwargs):
def test_incorrect_chrome_bin():
os.environ['CHROME_BIN'] = '/path/to/chrome'
with pytest.raises(WebDriverException):
browser = Chrome(ChromeDriverManager().install())
browser = Chrome()
del os.environ['CHROME_BIN']


Expand Down
3 changes: 1 addition & 2 deletions webdriver_recorder/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import jinja2
import pytest
from pydantic import BaseModel, root_validator
from webdriver_manager.chrome import ChromeDriverManager

from . import browser as browser_

Expand Down Expand Up @@ -96,7 +95,7 @@ def browser(chrome):
def chrome():
if 'CHROME_BIN' not in os.environ:
warnings.warn('Environment variable CHROME_BIN undefined. Using system default for Chrome.')
with browser_.Chrome(ChromeDriverManager().install()) as browser:
with browser_.Chrome() as browser:
yield browser


Expand Down

0 comments on commit 7bfcb53

Please sign in to comment.