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.
- package/install.js +151 -83
- 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
|
|
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 (
|
|
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(
|
|
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
|
-
|
|
50
|
-
|
|
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
|
-
|
|
55
|
-
await getChromeDriverVersion(getRequestOptions(`${cdnUrl}/LATEST_RELEASE`));
|
|
46
|
+
} else if (chromedriverVersion === 'LATEST') {
|
|
47
|
+
chromedriverVersion = await getChromeDriverVersion(cdnUrl, legacyCdnUrl);
|
|
56
48
|
} else {
|
|
57
|
-
const latestReleaseForVersionMatch =
|
|
49
|
+
const latestReleaseForVersionMatch = chromedriverVersion.match(/LATEST_(\d+)/);
|
|
58
50
|
if (latestReleaseForVersionMatch) {
|
|
59
|
-
|
|
60
|
-
await getChromeDriverVersion(getRequestOptions(`${cdnUrl}/LATEST_RELEASE_${majorVersion}`));
|
|
51
|
+
chromedriverVersion = await getChromeDriverVersion(cdnUrl, legacyCdnUrl, parseInt(latestReleaseForVersionMatch[1]));
|
|
61
52
|
}
|
|
62
53
|
}
|
|
63
|
-
|
|
64
|
-
const
|
|
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(
|
|
71
|
-
await extractDownload(
|
|
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
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
|
|
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
|
-
|
|
101
|
-
} else if (thePlatform
|
|
102
|
-
|
|
103
|
-
|
|
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
|
-
|
|
109
|
+
console.log('Unexpected platform or architecture:', process.platform, process.arch);
|
|
110
|
+
process.exit(1);
|
|
107
111
|
}
|
|
108
112
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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 =
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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 =
|
|
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 {
|
|
280
|
+
* @param {string} cdnUrl
|
|
281
|
+
* @param {string} legacyCdnUrl
|
|
282
|
+
* @param {number} [majorVersion]
|
|
283
|
+
* @returns {Promise<string>}
|
|
247
284
|
*/
|
|
248
|
-
async function getChromeDriverVersion(
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
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
|
-
|
|
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
|
-
|
|
415
|
+
/**
|
|
416
|
+
* @param {string} chromedriverVersion
|
|
417
|
+
*/
|
|
418
|
+
function getMacOsRealArch(chromedriverVersion) {
|
|
349
419
|
if (process.arch === 'arm64' || isEmulatedRosettaEnvironment()) {
|
|
350
|
-
|
|
351
|
-
|
|
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.
|
|
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.
|
|
33
|
-
"compare-versions": "^5.0.
|
|
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.
|
|
41
|
-
"typescript": "^
|
|
40
|
+
"eslint": "^8.42.0",
|
|
41
|
+
"typescript": "^5.1.3"
|
|
42
42
|
},
|
|
43
43
|
"engines": {
|
|
44
44
|
"node": ">=16"
|
|
45
45
|
}
|
|
46
|
-
}
|
|
46
|
+
}
|