diff --git a/.github/workflows/functional-test.yml b/.github/workflows/functional-test.yml index 8c0905f..2ccd591 100644 --- a/.github/workflows/functional-test.yml +++ b/.github/workflows/functional-test.yml @@ -34,13 +34,6 @@ jobs: name: Start X virtual frame buffer - run: sudo apt-get install firefox name: Install Firefox - - run: | - latest_release="$(curl https://api.github.com/repos/mozilla/geckodriver/releases/latest | jq -r .name)" - curl -L "https://github.com/mozilla/geckodriver/releases/download/v${latest_release}/geckodriver-v${latest_release}-linux64.tar.gz" \ - --output /tmp/geckodriver.tar.gz - tar -xzf /tmp/geckodriver.tar.gz - sudo mv geckodriver /usr/bin/ - name: Deploy Gecko driver - run: | npm install -g appium npm install @@ -50,6 +43,8 @@ jobs: pushd "$cwd" cd ~ appium driver install --source=local "$cwd" + appium driver run gecko install-geckodriver + export PATH="$PATH:/usr/local/bin" nohup appium server \ --port=$APPIUM_TEST_SERVER_PORT \ --address=$APPIUM_TEST_SERVER_HOST \ diff --git a/README.md b/README.md index fb7753a..27d3b01 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,9 @@ Under the hood this driver is a wrapper/proxy over `geckodriver` binary. Check t It is mandatory to have both Firefox browser installed and the geckodriver binary downloaded on the platform where automated tests are going to be executed. Firefox could be downloaded from the [official download site](https://www.mozilla.org/en-GB/firefox/all/) and the driver binary could be retrieved from the GitHub [releases page](https://github.com/mozilla/geckodriver/releases). The binary must be put into one of the folders included to PATH environment variable. On macOS it also might be necessary to run `xattr -cr ""` to avoid [notarization](https://firefox-source-docs.mozilla.org/testing/geckodriver/Notarization.html) issues. +Since driver version 1.4.0 the geckodriver binary deployment could be automated via the +[install-geckodriver](#install-geckodriver) driver script. + Then you need to decide where the automated test is going to be executed. Gecko driver supports the following target platforms: - macOS - Windows @@ -56,6 +59,21 @@ setWindowRect | See https://www.w3.org/TR/webdriver/#capabilities timeouts | See https://www.w3.org/TR/webdriver/#capabilities unhandledPromptBehavior | See https://www.w3.org/TR/webdriver/#capabilities +## Scripts + +### install-geckodriver + +This script is used to install the given or latest stable version of Geckodriver server from +the [GitHub releases](https://github.com/mozilla/geckodriver/release) page. +Run `appium driver run gecko install-geckodriver `, where `optional_version` +must be either valid Geckodriver version number or should not be present (the latest stable version is used then). +By default, the script will download and unpack the binary into `/usr/local/bin/geckodriver` +on macOS and Linux or into `%LOCALAPPDATA%\Mozilla\geckodriver.exe` on Windows. +You must also make sure the `%LOCALAPPDATA%\Mozilla` (Windows) or `/usr/local/bin/` (Linux & macOS) +folder is present in the PATH environment variable before +starting an actual automation session. The deployment script should also show a warning message if +it is unable to find the parent folder in the PATH folders list. + ## Example ```python diff --git a/scripts/install-geckodriver.mjs b/scripts/install-geckodriver.mjs index 0508e26..b2de1fc 100644 --- a/scripts/install-geckodriver.mjs +++ b/scripts/install-geckodriver.mjs @@ -11,6 +11,7 @@ import { extractFileFromZip, } from '../build/lib/utils.js'; import fs from 'node:fs/promises'; +import { exec } from 'teen_process'; const OWNER = 'mozilla'; const REPO = 'geckodriver'; @@ -33,6 +34,17 @@ const PLATFORM_MAPPING = Object.freeze({ linux: 'linux', }); +/** + * + * @param {string} dstPath + * @returns {Promise} + */ +async function clearNotarization(dstPath) { + if (process.platform === 'darwin') { + await exec('xattr', ['-cr', dstPath]); + } +} + /** * * @param {import('axios').AxiosResponseHeaders} headers @@ -250,6 +262,7 @@ async function installGeckodriver(version) { executablePath = path.join(dstFolder, 'geckodriver.exe'); await extractFileFromZip(archivePath, path.basename(executablePath), executablePath); } + await clearNotarization(executablePath); log.info(`The driver is now available at '${executablePath}'`); } finally { try {