UNPKG

4.46 kBPlain TextView Raw
1#!/usr/bin/env node
2
3const debug = require('debug')('selenium-standalone:cli');
4
5const minimist = require('minimist');
6const which = require('which');
7const merge = require('lodash.merge');
8const mapValues = require('lodash.mapvalues');
9const path = require('path');
10
11const selenium = require('../');
12const defaultConfig = require('../lib/default-config');
13
14const actions = {
15 start: function (options) {
16 const killEvents = ['exit', 'SIGTERM', 'SIGINT'];
17
18 selenium.start(options, started);
19
20 function started(err, cp) {
21 if (err) {
22 if (cp) {
23 cp.kill('SIGINT');
24 }
25 throw err;
26 }
27
28 console.log('Selenium started');
29
30 killEvents.forEach(register);
31
32 function register(evName) {
33 process.on(evName, kill);
34 }
35
36 function unregister(evName) {
37 process.removeListener(evName, kill);
38 }
39
40 function kill() {
41 killEvents.forEach(unregister);
42 cp.kill('SIGTERM');
43 }
44 }
45 },
46 install: function (options) {
47 const ProgressBar = require('progress');
48 let bar;
49 let firstProgress = true;
50
51 // eslint-disable-next-line no-param-reassign
52 options.progressCb = options.silent ? null : progressCb;
53
54 selenium.install(options, installed);
55
56 function installed(err) {
57 if (err) {
58 throw err;
59 }
60 }
61
62 function progressCb(total, progress, chunk, url, reset) {
63 if (firstProgress) {
64 console.log('');
65 firstProgress = false;
66 }
67
68 if (reset || !bar) {
69 bar = new ProgressBar('[:bar] :percent ' + url, {
70 curr: progress,
71 total: total,
72 complete: '=',
73 incomplete: ' ',
74 width: 20,
75 });
76 }
77
78 bar.tick(chunk);
79 }
80 },
81};
82
83function parseCommandAndOptions(javaPath) {
84 const argv = minimist(process.argv.slice(2), {
85 string: [
86 'version',
87 'drivers.chrome.version',
88 'drivers.ie.version',
89 'drivers.firefox.version',
90 'drivers.edge.version',
91 ],
92 });
93
94 const action = argv._[0];
95
96 if (!action) {
97 throw new Error('No action provided');
98 }
99 if (action !== 'install' && action !== 'start') {
100 throw new Error('Invalid action "' + action + ' (Valid actions are [' + Object.keys(actions).join(', ') + '])');
101 }
102
103 // everything after `selenium-standalone install [options] --` will be in argv._
104 const seleniumArgs = argv._.slice(1);
105
106 // build a new map removing `_` and --config from argv
107 let options = Object.keys(argv).reduce((acc, cur) => {
108 if (cur !== '_' && cur !== 'config') {
109 acc[cur] = argv[cur];
110 }
111
112 return acc;
113 }, {});
114
115 // If a config file was specified, load it
116 let configFromFile = {};
117
118 if (argv.config) {
119 try {
120 configFromFile = require(path.resolve(process.cwd(), argv.config));
121 if (typeof configFromFile !== 'object') {
122 throw new Error('Config file does not exports an object');
123 }
124 } catch (err) {
125 throw new Error('Error parsing config file : ' + (err.message || err));
126 }
127 }
128
129 // Merge default options, options from config file then command line options
130 options = merge({}, defaultConfig, configFromFile, options);
131
132 // Ignore extra default drivers if specified in config file
133 if (configFromFile.drivers && options.ignoreExtraDrivers) {
134 options.drivers = mapValues(configFromFile.drivers, (config, name) => {
135 return merge({}, defaultConfig.drivers[name], config);
136 });
137 }
138
139 if (seleniumArgs.length) {
140 options.seleniumArgs = seleniumArgs;
141 } else if (!Array.isArray(options.seleniumArgs)) {
142 options.seleniumArgs = [];
143 }
144 options.spawnOptions = {
145 stdio: 'inherit',
146 };
147
148 options.logger = options.silent ? null : console.log;
149 options.javaPath = javaPath;
150
151 return [action, options];
152}
153
154// Export the command line parsing function for tests.
155module.exports = parseCommandAndOptions;
156
157if (!process.env || !process.env.NODE_ENV || process.env.NODE_ENV !== 'test-cli-parameters') {
158 which('java', function javaFound(errWhich, javaPath) {
159 debug('Started via CLI with: ', process.argv);
160
161 let params;
162
163 try {
164 if (errWhich) {
165 throw errWhich;
166 }
167 params = parseCommandAndOptions(javaPath);
168 } catch (err) {
169 process.stderr.write((err.message || err) + '\n');
170 process.stderr.write('Usage: selenium-standalone action [options]\n');
171 process.exit(255);
172 }
173 actions[params[0]](params[1]);
174 });
175}