diff --git a/Dockerfile-dev b/Dockerfile-dev index 9a245c23..7818637e 100644 --- a/Dockerfile-dev +++ b/Dockerfile-dev @@ -28,7 +28,7 @@ RUN cd /opt/OpenWPM/ \ RUN sudo mkdir /opt/firefox/ && \ sudo mv /opt/OpenWPM/firefox-bin /opt/firefox/firefox-bin -ENV FF_BIN_PATH=/opt/firefox/firefox-bin +ENV FIREFOX_BINARY=/opt/firefox/firefox-bin/firefox-bin #============================================================= # Make the shell within the Docker environment more useful diff --git a/README.md b/README.md index cf0e8263..1a511c7e 100644 --- a/README.md +++ b/README.md @@ -412,6 +412,21 @@ additional dependencies, which can be installed by running `install-dev.sh`. Once installed, execute `py.test -vv` in the test directory to run all tests. +### Mac OSX + +To install the dependencies on Mac OSX, run `install-mac.sh` instead of +`install.sh` and `install-dev.sh`. +This will download Firefox ESR into the current folder, move geckodriver +next to the Firefox binary and install development dependencies. +For the OpenWPM to be aware of which Firefox installation to run, set the +FIREFOX_BINARY environment variable before running any commands. + +Example, running the OpenWPM tests on Mac OSX: + + export FIREFOX_BINARY="$(PWD)/Firefox.app/Contents/MacOS/firefox-bin" + python -m pytest -vv + + Troubleshooting --------------- diff --git a/automation/DeployBrowsers/deploy_firefox.py b/automation/DeployBrowsers/deploy_firefox.py index 97e79a93..69755523 100755 --- a/automation/DeployBrowsers/deploy_firefox.py +++ b/automation/DeployBrowsers/deploy_firefox.py @@ -10,7 +10,7 @@ from selenium import webdriver from . import configure_firefox from ..Commands.profile_commands import load_profile from ..MPLogger import loggingclient -from ..utilities.platform_utils import ensure_firefox_in_path +from ..utilities.platform_utils import get_firefox_binary_path, get_geckodriver_executable_path from .selenium_firefox import (FirefoxBinary, FirefoxLogInterceptor, FirefoxProfile, Options) @@ -22,7 +22,8 @@ def deploy_firefox(status_queue, browser_params, manager_params, """ launches a firefox instance with parameters set by the input dictionary """ - ensure_firefox_in_path() + firefox_binary_path = get_firefox_binary_path() + geckodriver_executable_path = get_geckodriver_executable_path() root_dir = os.path.dirname(__file__) # directory of this file logger = loggingclient(*manager_params['logger_address']) @@ -153,8 +154,8 @@ def deploy_firefox(status_queue, browser_params, manager_params, # Launch the webdriver status_queue.put(('STATUS', 'Launch Attempted', None)) - fb = FirefoxBinary() - driver = webdriver.Firefox(firefox_profile=fp, firefox_binary=fb, + fb = FirefoxBinary(firefox_path=firefox_binary_path) + driver = webdriver.Firefox(firefox_profile=fp, firefox_binary=fb, executable_path=geckodriver_executable_path, firefox_options=fo, log_path=interceptor.fifo) # set window size diff --git a/automation/utilities/platform_utils.py b/automation/utilities/platform_utils.py index 3c36e9ae..f8bb3e5c 100644 --- a/automation/utilities/platform_utils.py +++ b/automation/utilities/platform_utils.py @@ -30,28 +30,40 @@ def parse_http_stack_trace_str(trace_str): return stack_trace -def ensure_firefox_in_path(): +def get_firefox_binary_path(): """ - If ../../firefox-bin/ or os.environ["FF_BIN_PATH"] exists, - add it to the PATH. - If firefox-bin does not exist, we throw a RuntimeError. + If ../../firefox-bin/firefox-bin or os.environ["FIREFOX_BINARY"] exists, + return it. Else, throw a RuntimeError. """ - if "FF_BIN_PATH" in os.environ: - ffbin = os.environ["FF_BIN_PATH"] + if "FIREFOX_BINARY" in os.environ: + firefox_binary_path = os.environ["FIREFOX_BINARY"] else: root_dir = os.path.dirname(__file__) # directory of this file - ffbin = os.path.abspath(root_dir + "/../../firefox-bin") - if os.path.isdir(ffbin): - curpath = os.environ["PATH"] - if ffbin not in curpath: - os.environ["PATH"] = ffbin + os.pathsep + curpath + firefox_binary_path = os.path.abspath(root_dir + "/../../firefox-bin/firefox-bin") + if os.path.isfile(firefox_binary_path): + return firefox_binary_path else: raise RuntimeError( - "The `firefox-bin` directory is not found in the root of the " - "OpenWPM directory (did you run the install script " - "(`install.sh`)?), and no valid alternative directory " - "was specified by the environment variable FF_BIN_PATH.") + "The `firefox-bin/firefox-bin` binary is not found in the root " + "of the OpenWPM directory (did you run the install script " + "(`install.sh`)?), and no valid alternative path " + "was specified by the environment variable FIREFOX_BINARY.") +def get_geckodriver_executable_path(): + """ + If the geckodriver executable does not exist next to the Firefox binary, + we throw a RuntimeError. + """ + firefox_binary_path = get_firefox_binary_path() + geckodriver_executable_path = os.path.dirname(firefox_binary_path) + "/geckodriver" + + if os.path.isfile(geckodriver_executable_path): + return geckodriver_executable_path + else: + raise RuntimeError( + "The `geckodriver` executable is not found next to the " + "Firefox binary. Did you run the install script " + "(`install.sh`)?") def get_version(): """Return OpenWPM version tag/current commit and Firefox version """ @@ -63,10 +75,10 @@ def get_version(): with open(ver, 'r') as f: openwpm = f.readline().strip() - ensure_firefox_in_path() + firefox_binary_path = get_firefox_binary_path() import six try: - firefox = subprocess.check_output(["firefox", "--version"]) + firefox = subprocess.check_output([firefox_binary_path, "--version"]) except subprocess.CalledProcessError as e: six.raise_from( RuntimeError("Firefox not found. Did you run `./install.sh`?"), diff --git a/install-mac.sh b/install-mac.sh index 8da97d24..307a5fa3 100755 --- a/install-mac.sh +++ b/install-mac.sh @@ -14,7 +14,7 @@ brew install leveldb pip install -U -r requirements.txt # Make npm packages available -sudo apt-get -yq install npm +brew install node # Grab the latest version of Firefox ESR. # For security reasons it is very important to keep up with patch releases @@ -41,3 +41,11 @@ rm firefox.dmg # npm geckodriver 1.5.x = geckodriver 0.15.0 npm install geckodriver@1.5.0 cp node_modules/geckodriver/geckodriver Firefox.app/Contents/MacOS/ + +# Dependencies for OpenWPM development -- NOT needed to run the platform. +# * Required for compiling Firefox extension +npm install jpm -g + +cd test +pip install -U -r requirements.txt +cd - diff --git a/test/manual_test.py b/test/manual_test.py index 723a6854..9e3f2340 100644 --- a/test/manual_test.py +++ b/test/manual_test.py @@ -9,6 +9,7 @@ from selenium import webdriver from selenium.webdriver.firefox.firefox_binary import FirefoxBinary from automation.DeployBrowsers import configure_firefox +from automation.utilities.platform_utils import get_firefox_binary_path, get_geckodriver_executable_path from .conftest import create_xpi from .utilities import BASE_TEST_URL, start_server @@ -24,11 +25,6 @@ OPENWPM_LOG_PREFIX = "console.log: openwpm: " INSERT_PREFIX = "Array" BASE_DIR = dirname(dirname(realpath(__file__))) EXT_PATH = join(BASE_DIR, 'automation', 'Extension', 'firefox') -if "FF_BIN_PATH" in os.environ: - FF_BIN_PATH = os.environ["FF_BIN_PATH"] -else: - FF_BIN_PATH = join(BASE_DIR, 'firefox-bin') -FF_BIN = join(FF_BIN_PATH, 'firefox') class Logger(): @@ -91,11 +87,10 @@ def start_webdriver(with_extension=False): webdriver A selenium webdriver instance. """ - path = os.environ['PATH'] - if FF_BIN_PATH not in path: - os.environ['PATH'] = FF_BIN_PATH + os.pathsep + path + firefox_binary_path = get_firefox_binary_path() + geckodriver_executable_path = get_geckodriver_executable_path() - fb = FirefoxBinary() + fb = FirefoxBinary(firefox_path=firefox_binary_path) server, thread = start_server() def register_cleanup(driver): @@ -123,12 +118,13 @@ def start_webdriver(with_extension=False): configure_firefox.optimize_prefs(fp) return register_cleanup( - webdriver.Firefox(firefox_binary=fb, firefox_profile=fp)) + webdriver.Firefox(firefox_binary=fb, firefox_profile=fp, executable_path=geckodriver_executable_path)) def start_jpm(): + firefox_binary_path = get_firefox_binary_path() cmd_jpm_run = "jpm run --binary-args 'url %s' -b %s" % (BASE_TEST_URL, - FF_BIN) + firefox_binary_path) server, thread = start_server() try: # http://stackoverflow.com/a/4417735/3104416 diff --git a/test/test_env.py b/test/test_env.py index 3141f9f6..4891d07d 100644 --- a/test/test_env.py +++ b/test/test_env.py @@ -2,7 +2,7 @@ from __future__ import absolute_import, print_function import re from os.path import dirname, isdir, isfile, join, realpath -from os import environ +from automation.utilities.platform_utils import get_firefox_binary_path, get_geckodriver_executable_path from .openwpmtest import OpenWPMTest @@ -15,13 +15,10 @@ class TestDependencies(OpenWPMTest): self.assert_is_installed("npm") self.assert_is_installed("jpm") self.assert_is_installed('firefox') - if "FF_BIN_PATH" in environ: - ff_bin_dir = environ["FF_BIN_PATH"] - else: - ff_bin_dir = join(self.BASE_DIR, "firefox-bin") - assert isdir(ff_bin_dir) - ff_binary = join(ff_bin_dir, "firefox") - assert isfile(ff_binary) + firefox_binary_path = get_firefox_binary_path() + geckodriver_executable_path = get_geckodriver_executable_path() + assert isfile(firefox_binary_path) + assert isfile(geckodriver_executable_path) def test_py_pkgs(self): PY_REQUIREMENTS_TXT = join(self.BASE_DIR, "requirements.txt")