chromedriver 114.0.0 → 114.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.
Files changed (2) hide show
  1. package/install.js +151 -83
  2. package/package.json +6 -6
package/install.js CHANGED
@@ -1,16 +1,16 @@
1
1
  'use strict';
2
2
  // @ts-check
3
3
 
4
- const fs = require('fs');
4
+ const fs = require('node:fs');
5
5
  const helper = require('./lib/chromedriver');
6
6
  const axios = require('axios');
7
- const path = require('path');
8
- const child_process = require('child_process');
9
- const os = require('os');
10
- const url = require('url');
11
- const https = require('https');
12
- const { promisify } = require('util');
13
- const { finished } = require('stream');
7
+ const path = require('node:path');
8
+ const child_process = require('node:child_process');
9
+ const os = require('node:os');
10
+ const url = require('node:url');
11
+ const https = require('node:https');
12
+ const { promisify } = require('node:util');
13
+ const { finished } = require('node:stream');
14
14
  const extractZip = require('extract-zip');
15
15
  const { getChromeVersion } = require('@testim/chrome-version');
16
16
  const HttpsProxyAgent = require('https-proxy-agent');
@@ -19,57 +19,56 @@ const { compareVersions } = require('compare-versions');
19
19
 
20
20
  const finishedAsync = promisify(finished);
21
21
 
22
- const skipDownload = process.env.npm_config_chromedriver_skip_download || process.env.CHROMEDRIVER_SKIP_DOWNLOAD;
23
- if (skipDownload === 'true') {
22
+ const skipDownload = (process.env.npm_config_chromedriver_skip_download || process.env.CHROMEDRIVER_SKIP_DOWNLOAD) === 'true';
23
+ if (skipDownload) {
24
24
  console.log('Found CHROMEDRIVER_SKIP_DOWNLOAD variable, skipping installation.');
25
25
  process.exit(0);
26
26
  }
27
27
 
28
- const libPath = path.join(__dirname, 'lib', 'chromedriver');
29
- let cdnUrl = process.env.npm_config_chromedriver_cdnurl || process.env.CHROMEDRIVER_CDNURL || 'https://chromedriver.storage.googleapis.com';
30
- const configuredfilePath = process.env.npm_config_chromedriver_filepath || process.env.CHROMEDRIVER_FILEPATH;
31
-
32
- // adapt http://chromedriver.storage.googleapis.com/
33
- cdnUrl = cdnUrl.replace(/\/+$/, '');
34
- const detect_chromedriver_version = process.env.npm_config_detect_chromedriver_version || process.env.DETECT_CHROMEDRIVER_VERSION;
35
- const include_chromium = (process.env.npm_config_include_chromium || process.env.INCLUDE_CHROMIUM) === 'true';
36
- let chromedriver_version = process.env.npm_config_chromedriver_version || process.env.CHROMEDRIVER_VERSION || helper.version;
37
- let chromedriverBinaryFilePath;
38
- let downloadedFile = '';
39
- let platform = '';
40
-
41
28
  (async function install() {
29
+ let cdnUrl = process.env.npm_config_chromedriver_cdnurl || process.env.CHROMEDRIVER_CDNURL || 'https://googlechromelabs.github.io';
30
+ const legacyCdnUrl = process.env.npm_config_chromedriver_legacy_cdnurl || process.env.CHROMEDRIVER_LEGACY_CDNURL || 'https://chromedriver.storage.googleapis.com';
31
+ // adapt http://chromedriver.storage.googleapis.com/
32
+ cdnUrl = cdnUrl.replace(/\/+$/, '');
33
+ let chromedriverVersion = process.env.npm_config_chromedriver_version || process.env.CHROMEDRIVER_VERSION || helper.version;
34
+ const detectChromedriverVersion = (process.env.npm_config_detect_chromedriver_version || process.env.DETECT_CHROMEDRIVER_VERSION) === 'true';
42
35
  try {
43
- if (detect_chromedriver_version === 'true') {
36
+ if (detectChromedriverVersion) {
37
+ const includeChromium = (process.env.npm_config_include_chromium || process.env.INCLUDE_CHROMIUM) === 'true';
44
38
  // Refer http://chromedriver.chromium.org/downloads/version-selection
45
- const chromeVersion = await getChromeVersion(include_chromium);
39
+ const chromeVersion = await getChromeVersion(includeChromium);
46
40
  console.log("Your Chrome version is " + chromeVersion);
47
41
  const versionMatch = /^(.*?)\.\d+$/.exec(chromeVersion);
48
42
  if (versionMatch) {
49
- const chromeVersionWithoutPatch = versionMatch[1];
50
- await getChromeDriverVersion(getRequestOptions(cdnUrl + '/LATEST_RELEASE_' + chromeVersionWithoutPatch));
51
- console.log("Compatible ChromeDriver version is " + chromedriver_version);
43
+ chromedriverVersion = await getChromeDriverVersion(cdnUrl, legacyCdnUrl, parseInt(versionMatch[1]));
44
+ console.log("Compatible ChromeDriver version is " + chromedriverVersion);
52
45
  }
53
- }
54
- if (chromedriver_version === 'LATEST') {
55
- await getChromeDriverVersion(getRequestOptions(`${cdnUrl}/LATEST_RELEASE`));
46
+ } else if (chromedriverVersion === 'LATEST') {
47
+ chromedriverVersion = await getChromeDriverVersion(cdnUrl, legacyCdnUrl);
56
48
  } else {
57
- const latestReleaseForVersionMatch = chromedriver_version.match(/LATEST_(\d+)/);
49
+ const latestReleaseForVersionMatch = chromedriverVersion.match(/LATEST_(\d+)/);
58
50
  if (latestReleaseForVersionMatch) {
59
- const majorVersion = latestReleaseForVersionMatch[1];
60
- await getChromeDriverVersion(getRequestOptions(`${cdnUrl}/LATEST_RELEASE_${majorVersion}`));
51
+ chromedriverVersion = await getChromeDriverVersion(cdnUrl, legacyCdnUrl, parseInt(latestReleaseForVersionMatch[1]));
61
52
  }
62
53
  }
63
- platform = validatePlatform();
64
- const tmpPath = findSuitableTempDirectory();
54
+ let tmpPath = findSuitableTempDirectory(chromedriverVersion);
55
+ const extractDirectory = tmpPath;
56
+ const majorVersion = parseInt(chromedriverVersion.split('.')[0]);
57
+ const useLegacyMethod = majorVersion <= 114;
58
+ const platform = getPlatform(chromedriverVersion);
59
+ const downloadedFile = getDownloadFilePath(useLegacyMethod, tmpPath, platform);
60
+ if (!useLegacyMethod) {
61
+ tmpPath = path.join(tmpPath, path.basename(downloadedFile, path.extname(downloadedFile)));
62
+ }
65
63
  const chromedriverBinaryFileName = process.platform === 'win32' ? 'chromedriver.exe' : 'chromedriver';
66
- chromedriverBinaryFilePath = path.resolve(tmpPath, chromedriverBinaryFileName);
67
- const chromedriverIsAvailable = await verifyIfChromedriverIsAvailableAndHasCorrectVersion();
64
+ const chromedriverBinaryFilePath = path.resolve(tmpPath, chromedriverBinaryFileName);
65
+ const chromedriverIsAvailable = await verifyIfChromedriverIsAvailableAndHasCorrectVersion(chromedriverVersion, chromedriverBinaryFilePath);
68
66
  if (!chromedriverIsAvailable) {
69
67
  console.log('Current existing ChromeDriver binary is unavailable, proceeding with download and extraction.');
70
- await downloadFile(tmpPath);
71
- await extractDownload(tmpPath);
68
+ await downloadFile(useLegacyMethod ? legacyCdnUrl : cdnUrl, useLegacyMethod, downloadedFile, chromedriverVersion, platform, detectChromedriverVersion);
69
+ await extractDownload(extractDirectory, chromedriverBinaryFilePath, downloadedFile);
72
70
  }
71
+ const libPath = path.join(__dirname, 'lib', 'chromedriver');
73
72
  await copyIntoPlace(tmpPath, libPath);
74
73
  fixFilePermissions();
75
74
  console.log('Done. ChromeDriver binary available at', helper.path);
@@ -79,50 +78,83 @@ let platform = '';
79
78
  }
80
79
  })();
81
80
 
82
- function validatePlatform() {
83
- /** @type string */
84
- let thePlatform = process.platform;
81
+ /**
82
+ * @param {string} chromedriverVersion
83
+ */
84
+ function getPlatform(chromedriverVersion) {
85
+ const thePlatform = process.platform;
85
86
  if (thePlatform === 'linux') {
86
- if (process.arch === 'arm64' || process.arch === 'x64') {
87
- thePlatform += '64';
87
+ if (process.arch === 'arm64' || process.arch === 's390x' || process.arch === 'x64') {
88
+ return 'linux64';
88
89
  } else {
89
90
  console.log('Only Linux 64 bits supported.');
90
91
  process.exit(1);
91
92
  }
92
93
  } else if (thePlatform === 'darwin' || thePlatform === 'freebsd') {
93
- const osxPlatform = getMacOsRealArch();
94
+ const osxPlatform = getMacOsRealArch(chromedriverVersion);
94
95
 
95
96
  if (!osxPlatform) {
96
97
  console.log('Only Mac 64 bits supported.');
97
98
  process.exit(1);
98
99
  }
99
100
 
100
- thePlatform = osxPlatform;
101
- } else if (thePlatform !== 'win32') {
102
- console.log('Unexpected platform or architecture:', process.platform, process.arch);
103
- process.exit(1);
101
+ return osxPlatform;
102
+ } else if (thePlatform === 'win32') {
103
+ if (compareVersions(chromedriverVersion, '115') < 0) {
104
+ return 'win32';
105
+ }
106
+ return (process.arch === 'x64') ? 'win64' : 'win32';
104
107
  }
105
108
 
106
- return thePlatform;
109
+ console.log('Unexpected platform or architecture:', process.platform, process.arch);
110
+ process.exit(1);
107
111
  }
108
112
 
109
- async function downloadFile(dirToLoadTo) {
110
- if (detect_chromedriver_version !== 'true' && configuredfilePath) {
111
- downloadedFile = configuredfilePath;
112
- console.log('Using file: ', downloadedFile);
113
- return;
113
+ /**
114
+ * @param {string} cdnUrl
115
+ * @param {boolean} useLegacyDownloadMethod
116
+ * @param {string} downloadedFile
117
+ * @param {string} chromedriverVersion
118
+ * @param {string} platform
119
+ * @param {boolean} detectChromedriverVersion
120
+ */
121
+ async function downloadFile(cdnUrl, useLegacyDownloadMethod, downloadedFile, chromedriverVersion, platform, detectChromedriverVersion) {
122
+ const configuredfilePath = process.env.npm_config_chromedriver_filepath || process.env.CHROMEDRIVER_FILEPATH;
123
+ if (detectChromedriverVersion && configuredfilePath) {
124
+ console.log('Using file: ', configuredfilePath);
125
+ return configuredfilePath;
114
126
  } else {
115
- const fileName = `chromedriver_${platform}.zip`;
116
- const tempDownloadedFile = path.resolve(dirToLoadTo, fileName);
117
- downloadedFile = tempDownloadedFile;
118
- const formattedDownloadUrl = `${cdnUrl}/${chromedriver_version}/${fileName}`;
119
- console.log('Downloading from file: ', formattedDownloadUrl);
120
- console.log('Saving to file:', downloadedFile);
121
- await requestBinary(getRequestOptions(formattedDownloadUrl), downloadedFile);
127
+ const fileName = path.basename(downloadedFile);
128
+ if (useLegacyDownloadMethod) {
129
+ const formattedDownloadUrl = `${cdnUrl}/${chromedriverVersion}/${fileName}`;
130
+ console.log('Downloading from file: ', formattedDownloadUrl);
131
+ await requestBinary(getRequestOptions(formattedDownloadUrl), downloadedFile);
132
+ } else {
133
+ const dlBaseUrl = 'https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing'; // todo: make this configurable?
134
+ const formattedDownloadUrl = `${dlBaseUrl}/${chromedriverVersion}/${platform}/${fileName}`;
135
+ console.log('Downloading from file: ', formattedDownloadUrl);
136
+ await requestBinary(getRequestOptions(formattedDownloadUrl), downloadedFile);
137
+ }
122
138
  }
123
139
  }
124
140
 
125
- function verifyIfChromedriverIsAvailableAndHasCorrectVersion() {
141
+ /**
142
+ * @param {any} useLegacyPath
143
+ * @param {string} dirToLoadTo
144
+ * @param {string} platform
145
+ */
146
+ function getDownloadFilePath(useLegacyPath, dirToLoadTo, platform) {
147
+ const fileName = useLegacyPath ? `chromedriver_${platform}.zip` : `chromedriver-${platform}.zip`;
148
+ const downloadedFile = path.resolve(dirToLoadTo, fileName);
149
+ console.log('Saving to file:', downloadedFile);
150
+ return downloadedFile;
151
+ }
152
+
153
+ /**
154
+ * @param {string} chromedriverVersion
155
+ * @param {string} chromedriverBinaryFilePath
156
+ */
157
+ function verifyIfChromedriverIsAvailableAndHasCorrectVersion(chromedriverVersion, chromedriverBinaryFilePath) {
126
158
  if (!fs.existsSync(chromedriverBinaryFilePath))
127
159
  return Promise.resolve(false);
128
160
  const forceDownload = process.env.npm_config_chromedriver_force_download === 'true' || process.env.CHROMEDRIVER_FORCE_DOWNLOAD === 'true';
@@ -142,7 +174,7 @@ function verifyIfChromedriverIsAvailableAndHasCorrectVersion() {
142
174
  const parts = str.split(' ');
143
175
  if (parts.length < 3)
144
176
  return deferred.resolve(false);
145
- if (parts[1].startsWith(chromedriver_version)) {
177
+ if (parts[1].startsWith(chromedriverVersion)) {
146
178
  console.log(`ChromeDriver is already available at '${chromedriverBinaryFilePath}'.`);
147
179
  return deferred.resolve(true);
148
180
  }
@@ -155,7 +187,10 @@ function verifyIfChromedriverIsAvailableAndHasCorrectVersion() {
155
187
  return deferred.promise;
156
188
  }
157
189
 
158
- function findSuitableTempDirectory() {
190
+ /**
191
+ * @param {string} chromedriverVersion
192
+ */
193
+ function findSuitableTempDirectory(chromedriverVersion) {
159
194
  const now = Date.now();
160
195
  const candidateTmpDirs = [
161
196
  process.env.npm_config_tmp,
@@ -167,7 +202,7 @@ function findSuitableTempDirectory() {
167
202
 
168
203
  for (const tempDir of candidateTmpDirs) {
169
204
  if (!tempDir) continue;
170
- const namespace = chromedriver_version;
205
+ const namespace = chromedriverVersion;
171
206
  const candidatePath = path.join(tempDir, namespace, 'chromedriver');
172
207
  try {
173
208
  fs.mkdirSync(candidatePath, { recursive: true });
@@ -242,15 +277,38 @@ function getRequestOptions(downloadPath) {
242
277
  }
243
278
 
244
279
  /**
245
- *
246
- * @param {import('axios').AxiosRequestConfig} requestOptions
280
+ * @param {string} cdnUrl
281
+ * @param {string} legacyCdnUrl
282
+ * @param {number} [majorVersion]
283
+ * @returns {Promise<string>}
247
284
  */
248
- async function getChromeDriverVersion(requestOptions) {
249
- console.log('Finding Chromedriver version.');
250
- // @ts-expect-error
251
- const response = await axios.request(requestOptions);
252
- chromedriver_version = response.data.trim();
253
- console.log(`Chromedriver version is ${chromedriver_version}.`);
285
+ async function getChromeDriverVersion(cdnUrl, legacyCdnUrl, majorVersion) {
286
+ if (majorVersion == null || majorVersion > 114) {
287
+ console.log('Finding Chromedriver version.');
288
+ let chromedriverVersion;
289
+ if (majorVersion) {
290
+ const requestOptions = getRequestOptions(`${cdnUrl}/chrome-for-testing/latest-versions-per-milestone.json`);
291
+ // @ts-expect-error
292
+ const response = await axios.request(requestOptions);
293
+ chromedriverVersion = response.data?.milestones[majorVersion.toString()]?.version;
294
+ } else {
295
+ const requestOptions = getRequestOptions(`${cdnUrl}/chrome-for-testing/last-known-good-versions.json`);
296
+ // @ts-expect-error
297
+ const response = await axios.request(requestOptions);
298
+ chromedriverVersion = response.data?.channels?.Stable?.version;
299
+ }
300
+ console.log(`Chromedriver version is ${chromedriverVersion}.`);
301
+ return chromedriverVersion;
302
+ } else {
303
+ console.log('Finding Chromedriver version using legacy method.');
304
+ const urlPath = majorVersion ? `LATEST_RELEASE_${majorVersion}` : 'LATEST_RELEASE';
305
+ const requestOptions = getRequestOptions(`${legacyCdnUrl}/${urlPath}`);
306
+ // @ts-expect-error
307
+ const response = await axios.request(requestOptions);
308
+ const chromedriverVersion = response.data.trim();
309
+ console.log(`Chromedriver version is ${chromedriverVersion}.`);
310
+ return chromedriverVersion;
311
+ }
254
312
  }
255
313
 
256
314
  /**
@@ -296,7 +354,12 @@ async function requestBinary(requestOptions, filePath) {
296
354
  });
297
355
  }
298
356
 
299
- async function extractDownload(dirToExtractTo) {
357
+ /**
358
+ * @param {string} dirToExtractTo
359
+ * @param {string} chromedriverBinaryFilePath
360
+ * @param {string} downloadedFile
361
+ */
362
+ async function extractDownload(dirToExtractTo, chromedriverBinaryFilePath, downloadedFile) {
300
363
  if (path.extname(downloadedFile) !== '.zip') {
301
364
  fs.copyFileSync(downloadedFile, chromedriverBinaryFilePath);
302
365
  console.log('Skipping zip extraction - binary file found.');
@@ -310,6 +373,10 @@ async function extractDownload(dirToExtractTo) {
310
373
  }
311
374
  }
312
375
 
376
+ /**
377
+ * @param {string} originPath
378
+ * @param {string} targetPath
379
+ */
313
380
  async function copyIntoPlace(originPath, targetPath) {
314
381
  fs.rmSync(targetPath, { recursive: true, force: true });
315
382
  console.log(`Copying from ${originPath} to target path ${targetPath}`);
@@ -345,17 +412,18 @@ function fixFilePermissions() {
345
412
  }
346
413
  }
347
414
 
348
- function getMacOsRealArch() {
415
+ /**
416
+ * @param {string} chromedriverVersion
417
+ */
418
+ function getMacOsRealArch(chromedriverVersion) {
349
419
  if (process.arch === 'arm64' || isEmulatedRosettaEnvironment()) {
350
- if (compareVersions(chromedriver_version, '106.0.5249.61') < 0) {
351
- return 'mac64_m1';
352
- }
353
-
354
- return 'mac_arm64';
420
+ return compareVersions(chromedriverVersion, '106.0.5249.61') < 0
421
+ ? 'mac64_m1'
422
+ : compareVersions(chromedriverVersion, '115') < 0 ? 'mac_arm64' : 'mac-arm64';
355
423
  }
356
424
 
357
425
  if (process.arch === 'x64') {
358
- return 'mac64';
426
+ return compareVersions(chromedriverVersion, '115') < 0 ? 'mac64' : 'mac-x64';
359
427
  }
360
428
 
361
429
  return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chromedriver",
3
- "version": "114.0.0",
3
+ "version": "114.0.2",
4
4
  "keywords": [
5
5
  "chromedriver",
6
6
  "selenium"
@@ -29,18 +29,18 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "@testim/chrome-version": "^1.1.3",
32
- "axios": "^1.2.1",
33
- "compare-versions": "^5.0.1",
32
+ "axios": "^1.4.0",
33
+ "compare-versions": "^5.0.3",
34
34
  "extract-zip": "^2.0.1",
35
35
  "https-proxy-agent": "^5.0.1",
36
36
  "proxy-from-env": "^1.1.0",
37
37
  "tcp-port-used": "^1.0.1"
38
38
  },
39
39
  "devDependencies": {
40
- "eslint": "^8.29.0",
41
- "typescript": "^4.9.3"
40
+ "eslint": "^8.42.0",
41
+ "typescript": "^5.1.3"
42
42
  },
43
43
  "engines": {
44
44
  "node": ">=16"
45
45
  }
46
- }
46
+ }