chromedriver 79.0.2 → 80.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/install.js CHANGED
@@ -1,14 +1,17 @@
1
1
  'use strict';
2
+ // @ts-check
2
3
 
3
- const extractZip = require('extract-zip');
4
4
  const fs = require('fs');
5
5
  const helper = require('./lib/chromedriver');
6
- const request = require('request');
6
+ const axios = require('axios').default;
7
7
  const mkdirp = require('mkdirp');
8
8
  const path = require('path');
9
9
  const del = require('del');
10
10
  const child_process = require('child_process');
11
11
  const os = require('os');
12
+ const url = require('url');
13
+ const https = require('https');
14
+ const extractZip = require('extract-zip');
12
15
  const { getChromeVersion } = require('@testim/chrome-version');
13
16
 
14
17
  const skipDownload = process.env.npm_config_chromedriver_skip_download || process.env.CHROMEDRIVER_SKIP_DOWNLOAD;
@@ -23,115 +26,110 @@ const configuredfilePath = process.env.npm_config_chromedriver_filepath || proce
23
26
 
24
27
  // adapt http://chromedriver.storage.googleapis.com/
25
28
  cdnUrl = cdnUrl.replace(/\/+$/, '');
26
- let platform = process.platform;
27
-
29
+ const platform = validatePlatform();
28
30
  const detect_chromedriver_version = process.env.npm_config_detect_chromedriver_version || process.env.DETECT_CHROMEDRIVER_VERSION;
29
31
  let chromedriver_version = process.env.npm_config_chromedriver_version || process.env.CHROMEDRIVER_VERSION || helper.version;
30
- if (platform === 'linux') {
31
- if (process.arch === 'arm64' || process.arch === 'x64') {
32
- platform += '64';
33
- } else {
34
- console.log('Only Linux 64 bits supported.');
35
- process.exit(1);
36
- }
37
- } else if (platform === 'darwin' || platform === 'freebsd') {
38
- if (process.arch === 'x64') {
39
- // @ts-ignore
40
- platform = 'mac64';
41
- } else {
42
- console.log('Only Mac 64 bits supported.');
43
- process.exit(1);
44
- }
45
- } else if (platform !== 'win32') {
46
- console.log('Unexpected platform or architecture:', process.platform, process.arch);
47
- process.exit(1);
48
- }
49
- let tmpPath;
50
- const chromedriverBinaryFileName = process.platform === 'win32' ? 'chromedriver.exe' : 'chromedriver';
51
32
  let chromedriverBinaryFilePath;
52
33
  let downloadedFile = '';
53
34
 
54
- Promise.resolve().then(function () {
55
- if (detect_chromedriver_version === 'true') {
56
- // Refer http://chromedriver.chromium.org/downloads/version-selection
57
- return getChromeVersion().then(function (chromeVersion) {
35
+ (async function install() {
36
+ try {
37
+ if (detect_chromedriver_version === 'true') {
38
+ // Refer http://chromedriver.chromium.org/downloads/version-selection
39
+ const chromeVersion = await getChromeVersion();
58
40
  console.log("Your Chrome version is " + chromeVersion);
59
41
  const chromeVersionWithoutPatch = /^(.*?)\.\d+$/.exec(chromeVersion)[1];
60
- return getChromeDriverVersion(getRequestOptions(cdnUrl + '/LATEST_RELEASE_' + chromeVersionWithoutPatch));
61
- }).then(function () {
42
+ await getChromeDriverVersion(getRequestOptions(cdnUrl + '/LATEST_RELEASE_' + chromeVersionWithoutPatch));
62
43
  console.log("Compatible ChromeDriver version is " + chromedriver_version);
63
- });
64
- }
65
- if (chromedriver_version === 'LATEST') {
66
- return getChromeDriverVersion(getRequestOptions(`${cdnUrl}/LATEST_RELEASE`));
67
- } else {
68
- const latestReleaseForVersionMatch = chromedriver_version.match(/LATEST_(\d+)/);
69
- if (latestReleaseForVersionMatch) {
70
- const majorVersion = latestReleaseForVersionMatch[1];
71
- return getChromeDriverVersion(getRequestOptions(`${cdnUrl}/LATEST_RELEASE_${majorVersion}`));
72
44
  }
73
- }
74
- })
75
- .then(() => {
76
- tmpPath = findSuitableTempDirectory();
45
+ if (chromedriver_version === 'LATEST') {
46
+ await getChromeDriverVersion(getRequestOptions(`${cdnUrl}/LATEST_RELEASE`));
47
+ } else {
48
+ const latestReleaseForVersionMatch = chromedriver_version.match(/LATEST_(\d+)/);
49
+ if (latestReleaseForVersionMatch) {
50
+ const majorVersion = latestReleaseForVersionMatch[1];
51
+ await getChromeDriverVersion(getRequestOptions(`${cdnUrl}/LATEST_RELEASE_${majorVersion}`));
52
+ }
53
+ }
54
+ const tmpPath = findSuitableTempDirectory();
55
+ const chromedriverBinaryFileName = process.platform === 'win32' ? 'chromedriver.exe' : 'chromedriver';
77
56
  chromedriverBinaryFilePath = path.resolve(tmpPath, chromedriverBinaryFileName);
78
- })
79
- .then(verifyIfChromedriverIsAvailableAndHasCorrectVersion)
80
- .then(chromedriverIsAvailable => {
81
- if (chromedriverIsAvailable) return;
82
- console.log('Current existing ChromeDriver binary is unavailable, proceeding with download and extraction.');
83
- return downloadFile().then(extractDownload);
84
- })
85
- .then(() => copyIntoPlace(tmpPath, libPath))
86
- .then(fixFilePermissions)
87
- .then(() => console.log('Done. ChromeDriver binary available at', helper.path))
88
- .catch(function (err) {
57
+ const chromedriverIsAvailable = await verifyIfChromedriverIsAvailableAndHasCorrectVersion();
58
+ if (!chromedriverIsAvailable) {
59
+ console.log('Current existing ChromeDriver binary is unavailable, proceeding with download and extraction.');
60
+ await downloadFile(tmpPath);
61
+ await extractDownload(tmpPath);
62
+ }
63
+ await copyIntoPlace(tmpPath, libPath);
64
+ fixFilePermissions();
65
+ console.log('Done. ChromeDriver binary available at', helper.path);
66
+ } catch (err) {
89
67
  console.error('ChromeDriver installation failed', err);
90
68
  process.exit(1);
91
- });
69
+ }
70
+ })();
71
+
72
+ function validatePlatform() {
73
+ /** @type string */
74
+ let thePlatform = process.platform;
75
+ if (thePlatform === 'linux') {
76
+ if (process.arch === 'arm64' || process.arch === 'x64') {
77
+ thePlatform += '64';
78
+ } else {
79
+ console.log('Only Linux 64 bits supported.');
80
+ process.exit(1);
81
+ }
82
+ } else if (thePlatform === 'darwin' || thePlatform === 'freebsd') {
83
+ if (process.arch === 'x64') {
84
+ thePlatform = 'mac64';
85
+ } else {
86
+ console.log('Only Mac 64 bits supported.');
87
+ process.exit(1);
88
+ }
89
+ } else if (thePlatform !== 'win32') {
90
+ console.log('Unexpected platform or architecture:', process.platform, process.arch);
91
+ process.exit(1);
92
+ }
93
+ return thePlatform;
94
+ }
92
95
 
93
- function downloadFile() {
96
+ async function downloadFile(dirToLoadTo) {
94
97
  if (detect_chromedriver_version !== 'true' && configuredfilePath) {
95
98
  downloadedFile = configuredfilePath;
96
99
  console.log('Using file: ', downloadedFile);
97
- return Promise.resolve();
100
+ return;
98
101
  } else {
99
102
  const fileName = `chromedriver_${platform}.zip`;
100
- const tempDownloadedFile = path.resolve(tmpPath, fileName);
103
+ const tempDownloadedFile = path.resolve(dirToLoadTo, fileName);
101
104
  downloadedFile = tempDownloadedFile;
102
105
  const formattedDownloadUrl = `${cdnUrl}/${chromedriver_version}/${fileName}`;
103
106
  console.log('Downloading from file: ', formattedDownloadUrl);
104
107
  console.log('Saving to file:', downloadedFile);
105
- return requestBinary(getRequestOptions(formattedDownloadUrl), downloadedFile);
108
+ await requestBinary(getRequestOptions(formattedDownloadUrl), downloadedFile);
106
109
  }
107
110
  }
108
111
 
109
112
  function verifyIfChromedriverIsAvailableAndHasCorrectVersion() {
110
113
  if (!fs.existsSync(chromedriverBinaryFilePath))
111
- return false;
114
+ return Promise.resolve(false);
112
115
  const forceDownload = process.env.npm_config_chromedriver_force_download === 'true' || process.env.CHROMEDRIVER_FORCE_DOWNLOAD === 'true';
113
116
  if (forceDownload)
114
- return false;
117
+ return Promise.resolve(false);
115
118
  console.log('ChromeDriver binary exists. Validating...');
116
119
  const deferred = new Deferred();
117
120
  try {
118
121
  fs.accessSync(chromedriverBinaryFilePath, fs.constants.X_OK);
119
122
  const cp = child_process.spawn(chromedriverBinaryFilePath, ['--version']);
120
123
  let str = '';
121
- cp.stdout.on('data', function (data) {
122
- str += data;
123
- });
124
- cp.on('error', function () {
125
- deferred.resolve(false);
126
- });
127
- cp.on('close', function (code) {
124
+ cp.stdout.on('data', data => str += data);
125
+ cp.on('error', () => deferred.resolve(false));
126
+ cp.on('close', code => {
128
127
  if (code !== 0)
129
128
  return deferred.resolve(false);
130
129
  const parts = str.split(' ');
131
130
  if (parts.length < 3)
132
131
  return deferred.resolve(false);
133
132
  if (parts[1].startsWith(chromedriver_version)) {
134
- console.log(str);
135
133
  console.log(`ChromeDriver is already available at '${chromedriverBinaryFilePath}'.`);
136
134
  return deferred.resolve(true);
137
135
  }
@@ -169,59 +167,46 @@ function findSuitableTempDirectory() {
169
167
  console.log(candidatePath, 'is not writable:', e.message);
170
168
  }
171
169
  }
172
-
173
170
  console.error('Can not find a writable tmp directory, please report issue on https://github.com/giggio/chromedriver/issues/ with as much information as possible.');
174
171
  process.exit(1);
175
172
  }
176
173
 
177
-
178
174
  function getRequestOptions(downloadPath) {
179
- const options = { uri: downloadPath, method: 'GET' };
180
- const protocol = options.uri.substring(0, options.uri.indexOf('//'));
181
- const proxyUrl = protocol === 'https:'
175
+ /** @type import('axios').AxiosRequestConfig */
176
+ const options = { url: downloadPath, method: "GET" };
177
+ const urlParts = url.parse(downloadPath);
178
+ const isHttps = urlParts.protocol === 'https:';
179
+ const proxyUrl = isHttps
182
180
  ? process.env.npm_config_https_proxy
183
181
  : (process.env.npm_config_proxy || process.env.npm_config_http_proxy);
184
182
  if (proxyUrl) {
185
- options.proxy = proxyUrl;
186
- }
187
-
188
- options.strictSSL = !!process.env.npm_config_strict_ssl;
189
-
190
- // Use certificate authority settings from npm
191
- let ca = process.env.npm_config_ca;
192
-
193
- // Parse ca string like npm does
194
- if (ca && ca.match(/^".*"$/)) {
195
- try {
196
- ca = JSON.parse(ca.trim());
197
- } catch (e) {
198
- console.error('Could not parse ca string', process.env.npm_config_ca, e);
199
- }
183
+ const proxyUrlParts = url.parse(proxyUrl);
184
+ options.proxy = {
185
+ host: proxyUrlParts.hostname,
186
+ port: proxyUrlParts.port ? parseInt(proxyUrlParts.port) : 80,
187
+ protocol: proxyUrlParts.protocol
188
+ };
200
189
  }
201
190
 
202
- if (!ca && process.env.npm_config_cafile) {
203
- try {
204
- ca = fs.readFileSync(process.env.npm_config_cafile, { encoding: 'utf8' })
205
- .split(/\n(?=-----BEGIN CERTIFICATE-----)/g);
206
-
207
- // Comments at the beginning of the file result in the first
208
- // item not containing a certificate - in this case the
209
- // download will fail
210
- if (ca.length > 0 && !/-----BEGIN CERTIFICATE-----/.test(ca[0])) {
211
- ca.shift();
191
+ if (isHttps) {
192
+ // Use certificate authority settings from npm
193
+ let ca = process.env.npm_config_ca;
194
+ if (ca)
195
+ console.log('Using npmconf ca.');
196
+
197
+ if (!ca && process.env.npm_config_cafile) {
198
+ try {
199
+ ca = fs.readFileSync(process.env.npm_config_cafile, { encoding: 'utf8' });
200
+ } catch (e) {
201
+ console.error('Could not read cafile', process.env.npm_config_cafile, e);
212
202
  }
213
-
214
- } catch (e) {
215
- console.error('Could not read cafile', process.env.npm_config_cafile, e);
203
+ console.log('Using npmconf cafile.');
216
204
  }
217
- }
218
205
 
219
- if (ca) {
220
- console.log('Using npmconf ca');
221
- options.agentOptions = {
206
+ options.httpsAgent = new https.Agent({
207
+ rejectUnauthorized: !!process.env.npm_config_strict_ssl,
222
208
  ca: ca
223
- };
224
- options.ca = ca;
209
+ });
225
210
  }
226
211
 
227
212
  // Use specific User-Agent
@@ -232,94 +217,90 @@ function getRequestOptions(downloadPath) {
232
217
  return options;
233
218
  }
234
219
 
235
- function getChromeDriverVersion(requestOptions) {
236
- const deferred = new Deferred();
237
- request(requestOptions, function (err, response, data) {
238
- if (err) {
239
- deferred.reject('Error with http(s) request: ' + err);
240
- } else {
241
- chromedriver_version = data.trim();
242
- deferred.resolve(true);
243
- }
244
- });
245
- return deferred.promise;
220
+ /**
221
+ *
222
+ * @param {import('axios').AxiosRequestConfig} requestOptions
223
+ */
224
+ async function getChromeDriverVersion(requestOptions) {
225
+ console.log('Finding Chromedriver version.');
226
+ const response = await axios(requestOptions);
227
+ chromedriver_version = response.data.trim();
228
+ console.log(`Chromedriver version is ${chromedriver_version}.`);
246
229
  }
247
230
 
248
- function requestBinary(requestOptions, filePath) {
249
- const deferred = new Deferred();
250
-
231
+ /**
232
+ *
233
+ * @param {import('axios').AxiosRequestConfig} requestOptions
234
+ * @param {string} filePath
235
+ */
236
+ async function requestBinary(requestOptions, filePath) {
237
+ const outFile = fs.createWriteStream(filePath);
238
+ let response;
239
+ try {
240
+ response = await axios.create(requestOptions)({ responseType: 'stream' });
241
+ } catch (error) {
242
+ if (error && error.response) {
243
+ if (error.response.status)
244
+ console.error('Error status code:', error.response.status);
245
+ if (error.response.data) {
246
+ error.response.data.on('data', data => console.error(data.toString('utf8')));
247
+ await new Promise((resolve) => {
248
+ error.response.data.on('finish', resolve);
249
+ error.response.data.on('error', resolve);
250
+ });
251
+ }
252
+ }
253
+ throw new Error('Error with http(s) request: ' + error);
254
+ }
251
255
  let count = 0;
252
256
  let notifiedCount = 0;
253
- const outFile = fs.openSync(filePath, 'w');
254
-
255
- const client = request(requestOptions);
256
-
257
- client.on('error', function (err) {
258
- deferred.reject('Error with http(s) request: ' + err);
259
- });
260
-
261
- client.on('data', function (data) {
262
- fs.writeSync(outFile, data, 0, data.length, null);
257
+ response.data.on('data', data => {
263
258
  count += data.length;
264
- if ((count - notifiedCount) > 800000) {
259
+ if ((count - notifiedCount) > 1024 * 1024) {
265
260
  console.log('Received ' + Math.floor(count / 1024) + 'K...');
266
261
  notifiedCount = count;
267
262
  }
268
263
  });
269
-
270
- client.on('end', function () {
271
- console.log('Received ' + Math.floor(count / 1024) + 'K total.');
272
- fs.closeSync(outFile);
273
- deferred.resolve(true);
264
+ response.data.on('end', () => console.log('Received ' + Math.floor(count / 1024) + 'K total.'));
265
+ const pipe = response.data.pipe(outFile);
266
+ await new Promise((resolve, reject) => {
267
+ pipe.on('finish', resolve);
268
+ pipe.on('error', reject);
274
269
  });
275
-
276
- return deferred.promise;
277
270
  }
278
271
 
279
- function extractDownload() {
272
+ async function extractDownload(dirToExtractTo) {
280
273
  if (path.extname(downloadedFile) !== '.zip') {
281
274
  fs.copyFileSync(downloadedFile, chromedriverBinaryFilePath);
282
275
  console.log('Skipping zip extraction - binary file found.');
283
- return Promise.resolve();
276
+ return;
277
+ }
278
+ console.log('Extracting zip contents.');
279
+ try {
280
+ await extractZip(path.resolve(downloadedFile), { dir: dirToExtractTo });
281
+ } catch (error) {
282
+ throw new Error('Error extracting archive: ' + error);
284
283
  }
285
- const deferred = new Deferred();
286
- console.log('Extracting zip contents');
287
- extractZip(path.resolve(downloadedFile), { dir: tmpPath }, function (err) {
288
- if (err) {
289
- deferred.reject('Error extracting archive: ' + err);
290
- } else {
291
- deferred.resolve(true);
292
- }
293
- });
294
- return deferred.promise;
295
284
  }
296
285
 
297
-
298
- function copyIntoPlace(originPath, targetPath) {
299
- return del(targetPath)
300
- .then(function () {
301
- console.log("Copying to target path", targetPath);
302
- fs.mkdirSync(targetPath);
303
-
304
- // Look for the extracted directory, so we can rename it.
305
- const files = fs.readdirSync(originPath);
306
- const promises = files.map(function (name) {
307
- const deferred = new Deferred();
308
-
309
- const file = path.join(originPath, name);
310
- const reader = fs.createReadStream(file);
311
-
312
- const targetFile = path.join(targetPath, name);
313
- const writer = fs.createWriteStream(targetFile);
314
- writer.on("close", function () {
315
- deferred.resolve(true);
316
- });
317
-
318
- reader.pipe(writer);
319
- return deferred.promise;
320
- });
321
- return Promise.all(promises);
286
+ async function copyIntoPlace(originPath, targetPath) {
287
+ await del(targetPath);
288
+ console.log("Copying to target path", targetPath);
289
+ fs.mkdirSync(targetPath);
290
+
291
+ // Look for the extracted directory, so we can rename it.
292
+ const files = fs.readdirSync(originPath);
293
+ const promises = files.map(name => {
294
+ return new Promise((resolve) => {
295
+ const file = path.join(originPath, name);
296
+ const reader = fs.createReadStream(file);
297
+ const targetFile = path.join(targetPath, name);
298
+ const writer = fs.createWriteStream(targetFile);
299
+ writer.on("close", () => resolve());
300
+ reader.pipe(writer);
322
301
  });
302
+ });
303
+ await Promise.all(promises);
323
304
  }
324
305
 
325
306
 
@@ -329,7 +310,7 @@ function fixFilePermissions() {
329
310
  const stat = fs.statSync(helper.path);
330
311
  // 64 == 0100 (no octal literal in strict mode)
331
312
  if (!(stat.mode & 64)) {
332
- console.log('Fixing file permissions');
313
+ console.log('Fixing file permissions.');
333
314
  fs.chmodSync(helper.path, '755');
334
315
  }
335
316
  }
@@ -17,7 +17,7 @@ function getPortFromArgs(args) {
17
17
  }
18
18
  process.env.PATH = path.join(__dirname, 'chromedriver') + path.delimiter + process.env.PATH;
19
19
  exports.path = process.platform === 'win32' ? path.join(__dirname, 'chromedriver', 'chromedriver.exe') : path.join(__dirname, 'chromedriver', 'chromedriver');
20
- exports.version = '79.0.3945.36';
20
+ exports.version = '80.0.3987.16';
21
21
  exports.start = function(args, returnPromise) {
22
22
  let command = exports.path;
23
23
  if (!fs.existsSync(command)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chromedriver",
3
- "version": "79.0.2",
3
+ "version": "80.0.2",
4
4
  "keywords": [
5
5
  "chromedriver",
6
6
  "selenium"
@@ -26,11 +26,11 @@
26
26
  "update-chromedriver": "node update.js"
27
27
  },
28
28
  "dependencies": {
29
- "@testim/chrome-version": "^1.0.3",
30
- "del": "^4.1.1",
31
- "extract-zip": "^1.6.7",
32
- "mkdirp": "^0.5.1",
33
- "request": "^2.88.0",
29
+ "@testim/chrome-version": "^1.0.7",
30
+ "axios": "^0.19.2",
31
+ "del": "^5.1.0",
32
+ "extract-zip": "^2.0.0",
33
+ "mkdirp": "^1.0.4",
34
34
  "tcp-port-used": "^1.0.1"
35
35
  }
36
36
  }