forked from unscrambl/browser-driver-installer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
installer.js
147 lines (129 loc) · 5.4 KB
/
installer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
'use strict';
/* eslint-disable no-console */
const runNpmChildProcess = require('./runNpmChildProcess');
const path = require('path');
const execSync = require('child_process').execSync;
const shell = require('shelljs');
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 FIREFOX_BROWSER_NAME = 'firefox';
const TEMP_DIR = 'temp';
const VALID_BROWSER_NAMES = [CHROME_BROWSER_NAME, FIREFOX_BROWSER_NAME];
function installDriverWithVersion(driverName, driverBinPath, targetPath, versionObject)
{
if (checkDirectoryAndVersion(driverName, targetPath, versionObject.driverVersion))
{
return false;
}
shell.mkdir('-p', TEMP_DIR);
return runNpmChildProcess(['install', `${driverName}@${versionObject.driverNPMPackageVersion}`, '--prefix',
TEMP_DIR
]).then(
function ()
{
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;
},
function (e)
{
throw new Error('package dependencies installation failed with error, details: ' + e.toString());
});
}
function checkDirectoryAndVersion(driverName, targetPath, driverExpectedVersion)
{
if (!shell.test('-e', targetPath))
{
return false;
}
console.log(`Directory '${targetPath}' does exist.`);
console.log(`Checking if the directory contains a ${driverName}...`);
if (!shell.test('-e', path.join(targetPath, driverName)))
{
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, 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(targetPath, driverName));
return false;
}
console.log(`${driverName} version ${driverExpectedVersion} has already been installed!`);
return true;
}
function driverVersionString(driverName, targetPath)
{
let versionOutput = null;
if (driverName === CHROME_DRIVER_NAME)
{
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(targetPath, driverName) + ' -V').toString();
return versionOutput.match(GECKO_DRIVER_VERSION_REGEX)[1];
}
else
{
throw new Error(`No driver exists with the name ${driverName}.`);
}
}
function driverInstaller(browserName, browserVersion, targetPath)
{
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
// 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')));
let browserDriverVersions = null;
let driverBinPath = null;
let driverName = null;
if (browserName.toLowerCase() === CHROME_BROWSER_NAME)
{
browserDriverVersions = browserVersionsObject.chromeDriverVersions;
driverBinPath = CHROME_DRIVER_BIN_PATH;
driverName = CHROME_DRIVER_NAME;
}
else if (browserName.toLowerCase() === FIREFOX_BROWSER_NAME)
{
browserDriverVersions = browserVersionsObject.geckoDriverVersions;
driverBinPath = GECKO_DRIVER_BIN_PATH;
driverName = GECKO_DRIVER_NAME;
}
else
{
throw new Error(
`Browser name "${browserName}" is not a valid browser name. Valid browser names are: ${(VALID_BROWSER_NAMES).join(', ')}`
);
}
browserVersion = majorBrowserVersion(browserVersion);
if (browserVersion && !browserDriverVersions[browserVersion])
{
throw new Error(
`Failed to locate a version of ${driverName} that matches the installed version of ${browserName} (${browserVersion}). Valid ${browserName} versions are: ${Object.keys(browserDriverVersions).join(', ')}`
);
}
return installDriverWithVersion(driverName, driverBinPath, targetPath, browserDriverVersions[browserVersion]);
}
function majorBrowserVersion(browserVersionString)
{
return (typeof browserVersionString) === 'string' && browserVersionString.match(BROWSER_MAJOR_VERSION_REGEX)[0];
}
module.exports.driverInstaller = driverInstaller;