diff --git a/.travis.yml b/.travis.yml index e470797..b2b9468 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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: diff --git a/README.md b/README.md index 464d943..96588dc 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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: diff --git a/bootstrap_chromedriver.sh b/bootstrap_chromedriver.sh new file mode 100755 index 0000000..197bcdb --- /dev/null +++ b/bootstrap_chromedriver.sh @@ -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}" diff --git a/setup.py b/setup.py index 4d07bd8..df02abe 100644 --- a/setup.py +++ b/setup.py @@ -45,7 +45,6 @@ def file_path(*parts): 'jinja2', 'selenium', 'pydantic', - 'webdriver-manager', ], classifiers=[ 'Programming Language :: Python', diff --git a/tests/test_browser.py b/tests/test_browser.py index 767dbb9..73f4133 100644 --- a/tests/test_browser.py +++ b/tests/test_browser.py @@ -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 @@ -34,7 +31,7 @@ def decrypt(self, encrypted_text): """ return encrypted_text.replace('secret-', '') - return TestChrome(ChromeDriverManager().install()) + return TestChrome() @pytest.fixture @@ -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 @@ -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'] diff --git a/webdriver_recorder/plugin.py b/webdriver_recorder/plugin.py index 2aa35eb..e0b5bee 100644 --- a/webdriver_recorder/plugin.py +++ b/webdriver_recorder/plugin.py @@ -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_ @@ -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