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

Better README. Renamed Env Variables to be more specific #3

Merged
merged 15 commits into from
May 3, 2018
Merged
8 changes: 7 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
language: node_js
node_js:
- "node"
- "node"
env:
global:
- BROWSER_DRIVER_INSTALLER_CHROME_VERSION=67
Copy link
Collaborator

Choose a reason for hiding this comment

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

ideally, we could have an alias for the latest version, so we don't need to hard code this here (assuming, that is, this is possible) and we wouldn't have to change the versions here also

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've created #3 and #4

- BROWSER_DRIVER_INSTALLER_CHROMEDRIVER_PATH=./output/chromedriver
- BROWSER_DRIVER_INSTALLER_FIREFOX_VERSION=57
- BROWSER_DRIVER_INSTALLER_GECKODRIVER_PATH=./output/geckodriver
32 changes: 30 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,32 @@
[![Build Status](https://travis-ci.org/cdagli/browser-driver-installer.svg?branch=master)](https://travis-ci.org/cdagli/browser-driver-installer)
[![Build Status](https://travis-ci.org/unscrambl/browser-driver-installer.svg?branch=master)](https://travis-ci.org/unscrambl/browser-driver-installer)

# browser-driver-installer
Installs Chrome and Gecko drivers that match with the specified browser versions
Installs Chrome and Gecko drivers that match with the specified browser versions. It uses the [chromedriver](https://www.npmjs.com/package/chromedriver) and [geckodriver](https://www.npmjs.com/package/geckodriver) NPM packages to download the drivers.

#### Usage:

**Post Install Script:** If your environment has the `BROWSER_DRIVER_INSTALLER_CHROME_VERSION`, `BROWSER_DRIVER_INSTALLER_CHROMEDRIVER_PATH`, `BROWSER_DRIVER_INSTALLER_FIREFOX_VERSION`, `BROWSER_DRIVER_INSTALLER_GECKODRIVER_PATH` variables defined, a post-install script will download the `ChromeDriver` and `GeckoDriver` executables to the specified paths automatically.


**As a module:**
```
const driverInstaller = require('browser-driver-installer').driverInstaller;
driverInstaller(BROWSER_NAME, BROWSER_VERSION, TARGET_PATH);
```


**CLI Usage:**

````
Usage: index [options]

Options:

--browser-name <browserName> Browser to install the driver for
Copy link
Collaborator

Choose a reason for hiding this comment

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

in our command-line tools we do: "sets " and -h "outputs..."

--browser-version <browserVersion> Browser version string e.g. 65, 67.0.23
--target-path <targetPath> Path to install driver executable
-h, --help output usage information
````

## LICENSE
[Apache 2.0](https://github.com/unscrambl/browser-driver-installer/blob/master/LICENSE)
21 changes: 13 additions & 8 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@
const program = require('commander');
const driverInstaller = require('./installer').driverInstaller;

program
.option('--chrome-version [chromeVersion]', 'Chrome browser major version string e.g. 65')
.option('--chrome-driver-target-path [chromeDriverTargetPath]', 'Path to install Chrome driver executable')
.option('--firefox-version [firefoxVersion]', 'Firefox browser major version string e.g. 57')
.option('--firefox-driver-target-path [firefoxDriverTargetPath]',
'Path to install Firefox driver(geckoDriver) executable')
.parse(process.argv);
if (require.main === module)
{
program
.option('--browser-name <browserName>', 'Browser to install the driver for')
.option('--browser-version <browserVersion>', 'Browser version string e.g. 65, 67.0.23')
.option('--target-path <targetPath>', 'Path to install driver executable')
.parse(process.argv);

driverInstaller(program.chromeVersion, program.chromeDriverTargetPath, program.firefoxVersion, program.firefoxDriverTargetPath);
driverInstaller(program.browserName, program.browserVersion, program.targetPath);
}
else
{
module.exports.driverInstaller = driverInstaller;
}
90 changes: 45 additions & 45 deletions installer.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,21 @@ const path = require('path');
const execSync = require('child_process').execSync;
const shell = require('shelljs');

const TEMP_DIR = 'temp';
const BROWSER_MAJOR_VERSION_REGEX = new RegExp(/^(\d+)/);
const CHROME_BROWSER_NAME = 'chrome';
const CHROME_DRIVER_NAME = 'chromedriver';
const CHROME_DRIVER_BIN_PATH = path.join('node_modules', 'chromedriver', 'lib', 'chromedriver', CHROME_DRIVER_NAME);
const CHROME_DRIVER_VERSION_REGEX = new RegExp(/\w+ ([0-9]+.[0-9]+).+/);
const GECKO_DRIVER_NAME = 'geckodriver';
const GECKO_DRIVER_BIN_PATH = path.join('node_modules', 'geckodriver', GECKO_DRIVER_NAME);
const GECKO_DRIVER_VERSION_REGEX = new RegExp(/\w+\s(\d+.\d+.\d+)/);
const BROWSER_MAJOR_VERSION_REGEX = new RegExp(/^(\d+)/);
const FIREFOX_BROWSER_NAME = 'firefox';
const TEMP_DIR = 'temp';
const VALID_BROWSER_NAMES = [CHROME_BROWSER_NAME, FIREFOX_BROWSER_NAME];

function installDriverWithVersion(driverName, driverBinPath, installPath, versionObject)
function installDriverWithVersion(driverName, driverBinPath, targetPath, versionObject)
{
if (checkDirectoryAndVersion(driverName, installPath, versionObject.driverVersion))
if (checkDirectoryAndVersion(driverName, targetPath, versionObject.driverVersion))
{
return false;
}
Expand All @@ -29,8 +32,8 @@ function installDriverWithVersion(driverName, driverBinPath, installPath, versio
]).then(
function ()
{
shell.mkdir('-p', installPath);
shell.cp('-n', path.join(TEMP_DIR, driverBinPath), installPath);
shell.mkdir('-p', targetPath);
shell.cp('-n', path.join(TEMP_DIR, driverBinPath), targetPath);
shell.rm('-rf', TEMP_DIR);
console.log('package dependencies have been installed');
return true;
Expand All @@ -41,48 +44,48 @@ function installDriverWithVersion(driverName, driverBinPath, installPath, versio
});
}

function checkDirectoryAndVersion(driverName, installPath, driverExpectedVersion)
function checkDirectoryAndVersion(driverName, targetPath, driverExpectedVersion)
{
if (!shell.test('-e', installPath))
if (!shell.test('-e', targetPath))
{
return false;
}
console.log(`Directory '${installPath}' does exist.`);
console.log(`Directory '${targetPath}' does exist.`);
console.log(`Checking if the directory contains a ${driverName}...`);

if (!shell.test('-e', path.join(installPath, driverName)))
if (!shell.test('-e', path.join(targetPath, driverName)))
{
console.log(`Could not find the ${driverName} in the directory '${installPath}'. Attempting to install it...`);
console.log(`Could not find the ${driverName} in the directory '${targetPath}'. Attempting to install it...`);
return false;
}

console.log(`${driverName} found.`);
const driverMajorVersion = driverVersionString(driverName, installPath);
const driverMajorVersion = driverVersionString(driverName, targetPath);
if (driverMajorVersion !== driverExpectedVersion)
{
console.log(
`${driverName} expected version (${driverExpectedVersion}) does not match with the installed version (${driverMajorVersion}).`
);
console.log('Removing the old version...');
shell.rm(path.join(installPath, driverName));
shell.rm(path.join(targetPath, driverName));
return false;
}

console.log(`${driverName} version ${driverExpectedVersion} has already been installed!`);
return true;
}

function driverVersionString(driverName, installPath)
function driverVersionString(driverName, targetPath)
{
let versionOutput = null;
if (driverName === CHROME_DRIVER_NAME)
{
versionOutput = execSync(path.join(installPath, driverName) + ' -v').toString();
versionOutput = execSync(path.join(targetPath, driverName) + ' -v').toString();
return versionOutput.match(CHROME_DRIVER_VERSION_REGEX)[1];
}
else if (driverName === GECKO_DRIVER_NAME)
{
versionOutput = execSync(path.join(installPath, driverName) + ' -V').toString();
versionOutput = execSync(path.join(targetPath, driverName) + ' -V').toString();
return versionOutput.match(GECKO_DRIVER_VERSION_REGEX)[1];
}
else
Expand All @@ -91,52 +94,49 @@ function driverVersionString(driverName, installPath)
}
}

function driverInstaller(detectedChromeVersion, chromeDriverTargetPath, detectedFirefoxVersion, geckoDriverTargetPath)
function driverInstaller(browserName, browserVersion, targetPath)
{
const browserVersionsObject = JSON.parse(shell.cat(path.resolve(__dirname, 'driverVersions.json')));
// ChromeDriver NPM package versions are defined according to https://github.com/giggio/node-chromedriver/releases
const chromeDriverVersions = browserVersionsObject.chromeDriverVersions;

if (typeof browserName !== 'string' || typeof browserVersion !== 'string' || typeof targetPath !== 'string')
{
throw new Error('Parameters are not valid strings.');
}
// GeckoDriver NPM package versions are defined according to https://github.com/mozilla/geckodriver/releases
const geckoDriverVersions = browserVersionsObject.geckoDriverVersions;
// ChromeDriver NPM package versions are defined according to https://github.com/giggio/node-chromedriver/releases
const browserVersionsObject = JSON.parse(shell.cat(path.resolve(__dirname, 'driverVersions.json')));

detectedChromeVersion = majorBrowserVersion(detectedChromeVersion);
detectedFirefoxVersion = majorBrowserVersion(detectedFirefoxVersion);
let browserDriverVersions = null;
let driverBinPath = null;
let driverName = null;

if (detectedChromeVersion && !chromeDriverVersions[detectedChromeVersion])
if (browserName.toLowerCase() === CHROME_BROWSER_NAME)
{
throw new Error(
`Failed to locate a version of ChromeDriver that matches the installed version of Chrome (${detectedChromeVersion}). Valid Chrome versions are: ${Object.keys(chromeDriverVersions).join(', ')}`
);
browserDriverVersions = browserVersionsObject.chromeDriverVersions;
driverBinPath = CHROME_DRIVER_BIN_PATH;
driverName = CHROME_DRIVER_NAME;
}
else if (detectedChromeVersion && typeof (chromeDriverTargetPath) === 'string')
else if (browserName.toLowerCase() === FIREFOX_BROWSER_NAME)
{
return installDriverWithVersion(CHROME_DRIVER_NAME, CHROME_DRIVER_BIN_PATH, chromeDriverTargetPath,
chromeDriverVersions[detectedChromeVersion]);
browserDriverVersions = browserVersionsObject.geckoDriverVersions;
driverBinPath = GECKO_DRIVER_BIN_PATH;
driverName = GECKO_DRIVER_NAME;
}
else
{
console.log('No Chrome version or target path is provided. Skipping...');
throw new Error(
`Browser name "${browserName}" is not a valid browser name. Valid browser names are: ${(VALID_BROWSER_NAMES).join(', ')}`
);
}

if (detectedFirefoxVersion && !geckoDriverVersions[detectedFirefoxVersion])
browserVersion = majorBrowserVersion(browserVersion);

if (browserVersion && !browserDriverVersions[browserVersion])
{
throw new Error(
`Failed to locate a version of GeckoDriver that matches the installed version of Firefox (${detectedFirefoxVersion}). Valid Firefox versions are: ${Object.keys(geckoDriverVersions).join(', ')}`
`Failed to locate a version of ${driverName} that matches the installed version of ${browserName} (${browserVersion}). Valid ${browserName} versions are: ${Object.keys(browserDriverVersions).join(', ')}`
);
}
else if (detectedFirefoxVersion && (typeof geckoDriverTargetPath) === 'string')
{
return installDriverWithVersion(GECKO_DRIVER_NAME, GECKO_DRIVER_BIN_PATH, geckoDriverTargetPath,
geckoDriverVersions[
detectedFirefoxVersion]);
}
else
{
console.log('No Firefox version or target path is provided. Skipping...');
}

return false;
return installDriverWithVersion(driverName, driverBinPath, targetPath, browserDriverVersions[browserVersion]);
}

function majorBrowserVersion(browserVersionString)
Expand Down
26 changes: 15 additions & 11 deletions installer.spec.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
'use strict';
/* eslint-disable no-console */

const chai = require('chai');
const installer = require('./installer');
const expect = require('chai').expect;
Expand Down Expand Up @@ -34,43 +37,44 @@ describe('browserDriverInstaller', function ()
it('should not attempt to install anything if one of the path, version or both parameters are not provided',
function ()
{
expect(installer.driverInstaller()).to.be.false;
expect(console.log).to.have.been.calledWith(
'No Chrome version or target path is provided. Skipping...');
expect(console.log).to.have.been.calledWith(
'No Firefox version or target path is provided. Skipping...');
expect(function () { installer.driverInstaller(); }).to.throw(
'Parameters are not valid strings.');
});

it('should throw an error if the provided version does not included in the JSON file', function ()
{
const wrongVersionNumber = '1';
expect(function () { installer.driverInstaller(wrongVersionNumber, '/some/target/path'); }).to.throw(
/Failed to locate a version of ChromeDriver that matches the installed version of Chrome \(1\). Valid Chrome versions are:*/
expect(function ()
{
installer.driverInstaller('chrome', wrongVersionNumber,
'/some/target/path');
}).to.throw(
/Failed to locate a version of chromedriver that matches the installed version of chrome \(1\). Valid chrome versions are:*/
Copy link
Collaborator

Choose a reason for hiding this comment

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

Chrome

);
});

it('should install the chromedriver to specified path if the version is included in the JSON file',
function ()
{
return installer.driverInstaller('54', DRIVER_OUTPUT_PATH).then(function ()
return installer.driverInstaller('chrome', '54', DRIVER_OUTPUT_PATH).then(function ()
{
expect(shell.test('-e', path.resolve(DRIVER_OUTPUT_PATH, 'chromedriver'))).to.be.true;
});
});

it('should install the geckodriver to specified path if the version is included in the JSON file', function ()
{
return installer.driverInstaller(null, null, '55', DRIVER_OUTPUT_PATH).then(function ()
return installer.driverInstaller('firefox', '55', DRIVER_OUTPUT_PATH).then(function ()
{
expect(shell.test('-e', path.resolve(DRIVER_OUTPUT_PATH, 'geckodriver'))).to.be.true;
});
});

it('should not install again if the wanted version is already installed', function ()
{
return installer.driverInstaller('54', DRIVER_OUTPUT_PATH).then(function ()
return installer.driverInstaller('chrome', '54', DRIVER_OUTPUT_PATH).then(function ()
{
expect(installer.driverInstaller('54', DRIVER_OUTPUT_PATH)).to.be.false;
expect(installer.driverInstaller('chrome', '54', DRIVER_OUTPUT_PATH)).to.be.false;
});
});
});
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
"license": "Apache-2.0",
"main": "index.js",
"name": "browser-driver-installer",
"repository": "github:unscrambl/browser-driver-installer",
"scripts": {
"postinstall": "node ./index.js --chrome-version $CHROME_VERSION --chrome-driver-target-path $CHROMEDRIVER_PATH --firefox-version $FIREFOX_VERSION --firefox-driver-target-path $GECKODRIVER_PATH",
"postinstall": "./postinstall",
"test": "node_modules/mocha/bin/mocha *.spec.js"
},
"version": "0.0.1"
"version": "1.0.4"
}
17 changes: 17 additions & 0 deletions postinstall
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

if [[ (-n "${BROWSER_DRIVER_INSTALLER_CHROME_VERSION}") && (-n "${BROWSER_DRIVER_INSTALLER_CHROMEDRIVER_PATH}")]]; then
node ./index.js --browser-name chrome \
--browser-version "$BROWSER_DRIVER_INSTALLER_CHROME_VERSION" \
--target-path "$BROWSER_DRIVER_INSTALLER_CHROMEDRIVER_PATH"
else
echo "Environment variables for Chrome are not set, skipping post-install for Chrome"
fi

if [[ (-n "${BROWSER_DRIVER_INSTALLER_FIREFOX_VERSION}") && (-n "${BROWSER_DRIVER_INSTALLER_GECKODRIVER_PATH}")]]; then
node ./index.js --browser-name firefox \
--browser-version "$BROWSER_DRIVER_INSTALLER_FIREFOX_VERSION" \
--target-path "$BROWSER_DRIVER_INSTALLER_GECKODRIVER_PATH"
else
echo "Environment variables for Firefox are not set, skipping post-install for Firefox"
fi