@eyeo/get-browser-binary 0.9.0 → 0.11.0
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/.gitlab-ci.yml +4 -6
- package/README.md +21 -1
- package/RELEASE_NOTES.md +21 -0
- package/package.json +9 -9
- package/src/browsers.js +107 -62
- package/src/utils.js +7 -7
- package/test/browsers.js +16 -6
- package/test/docker/arm64.Dockerfile +22 -0
- package/test/utils.js +1 -1
package/.gitlab-ci.yml
CHANGED
|
@@ -51,15 +51,13 @@ test:browsers:windows:
|
|
|
51
51
|
- choco upgrade -y nodejs --version 16.10.0
|
|
52
52
|
- npm install
|
|
53
53
|
script:
|
|
54
|
+
# Running Edge tests only on the preinstalled version
|
|
55
|
+
# https://gitlab.com/eyeo/developer-experience/get-browser-binary/-/issues/29
|
|
56
|
+
- npm test -- --grep "edge.*latest"
|
|
57
|
+
- npm test -- --grep "chromium"
|
|
54
58
|
# Running only a subset of Firefox tests to avoid low OS resources error
|
|
55
59
|
# https://gitlab.com/eyeo/developer-experience/get-browser-binary/-/issues/2
|
|
56
60
|
- npm test -- --grep "firefox.*installs"
|
|
57
|
-
# Running npm v8 on powershell has issues when the grep value contains the
|
|
58
|
-
# pipe (|) literal. Storing that string as a verbatim string (single quotes)
|
|
59
|
-
# and then sorrounding it with four double quotes does the trick.
|
|
60
|
-
# https://gitlab.com/eyeo/developer-experience/get-browser-binary/-/issues/29
|
|
61
|
-
- $full_tests = '(chromium|edge.*latest)'
|
|
62
|
-
- npm test -- --grep """"$full_tests""""
|
|
63
61
|
tags:
|
|
64
62
|
- shared-windows
|
|
65
63
|
- windows
|
package/README.md
CHANGED
|
@@ -84,7 +84,9 @@ npm test -- --timeout <ms>
|
|
|
84
84
|
|
|
85
85
|
### Running tests on Docker
|
|
86
86
|
|
|
87
|
-
Useful to reproduce the CI environment of the `test:browsers:linux` job
|
|
87
|
+
Useful to reproduce the CI environment of the `test:browsers:linux` job.
|
|
88
|
+
|
|
89
|
+
#### Intel/AMD architecture
|
|
88
90
|
|
|
89
91
|
```shell
|
|
90
92
|
docker build -f test/docker/Dockerfile -t browsers .
|
|
@@ -106,6 +108,24 @@ variable to `true`. Example:
|
|
|
106
108
|
TEST_KEEP_SNAPSHOTS=true npm test
|
|
107
109
|
```
|
|
108
110
|
|
|
111
|
+
#### ARM architecture (M1/M2 Apple Silicon)
|
|
112
|
+
|
|
113
|
+
Chromium (ARM native):
|
|
114
|
+
|
|
115
|
+
```shell
|
|
116
|
+
docker build -f test/docker/arm64.Dockerfile -t browsers-arm .
|
|
117
|
+
docker run --shm-size=512m -e TEST_ARGS="--grep chromium.*latest" -it browsers-arm
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Firefox (AMD emulation):
|
|
121
|
+
|
|
122
|
+
```shell
|
|
123
|
+
docker build -f test/docker/Dockerfile -t browsers-amd .
|
|
124
|
+
docker run --platform linux/amd64 --shm-size=512m -e TEST_ARGS="--grep firefox.*latest" -it browsers-amd
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Edge: Not supported
|
|
128
|
+
|
|
109
129
|
## Building the documentation
|
|
110
130
|
|
|
111
131
|
```shell
|
package/RELEASE_NOTES.md
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
# 0.11.0
|
|
2
|
+
|
|
3
|
+
- Fixes an issue on arm64 edgedriver links that prevented the driver to run on
|
|
4
|
+
M1/M2 machines (!62)
|
|
5
|
+
|
|
6
|
+
### Testing
|
|
7
|
+
|
|
8
|
+
- Enables running docker tests on arm64 platforms on Chromium (partially) and
|
|
9
|
+
Firefox (!61)
|
|
10
|
+
- Changes `TEST_URL` to a specific testpages url (!62)
|
|
11
|
+
|
|
12
|
+
# 0.10.0
|
|
13
|
+
|
|
14
|
+
- Added handling of the new headless mode in Chromium (#45)
|
|
15
|
+
- Fixed an issue that prevented Chromium to be installed on macOS ARM processors
|
|
16
|
+
(!59)
|
|
17
|
+
- Changed documentation nullable parameters to optional parameters (#41)
|
|
18
|
+
- Increased the npm geckodriver version to 3.1.0 (!57)
|
|
19
|
+
- Fixed an issue with Windows Edge and msedgedriver, which occasionally failed
|
|
20
|
+
when building the driver (!56)
|
|
21
|
+
|
|
1
22
|
# 0.9.0
|
|
2
23
|
|
|
3
24
|
- Fixed a Chromium install issue by increasing the value of
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eyeo/get-browser-binary",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "Install browser binaries and matching webdrivers",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -30,17 +30,17 @@
|
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"dmg": "^0.1.0",
|
|
32
32
|
"extract-zip": "^2.0.1",
|
|
33
|
-
"geckodriver": "
|
|
34
|
-
"got": "^
|
|
35
|
-
"jimp": "^0.
|
|
36
|
-
"selenium-webdriver": "^4.
|
|
33
|
+
"geckodriver": "3.1.0",
|
|
34
|
+
"got": "^12.5.3",
|
|
35
|
+
"jimp": "^0.22.4",
|
|
36
|
+
"selenium-webdriver": "^4.8.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"eslint": "^8.
|
|
39
|
+
"eslint": "^8.33.0",
|
|
40
40
|
"eslint-config-eyeo": "^3.2.0",
|
|
41
|
-
"expect": "^
|
|
42
|
-
"jsdoc": "^
|
|
43
|
-
"mocha": "^10.
|
|
41
|
+
"expect": "^29.4.2",
|
|
42
|
+
"jsdoc": "^4.0.0",
|
|
43
|
+
"mocha": "^10.2.0"
|
|
44
44
|
},
|
|
45
45
|
"scripts": {
|
|
46
46
|
"docs": "jsdoc --readme README.md --destination docs src/*.js",
|
package/src/browsers.js
CHANGED
|
@@ -25,7 +25,6 @@ import webdriver from "selenium-webdriver";
|
|
|
25
25
|
import chrome from "selenium-webdriver/chrome.js";
|
|
26
26
|
import firefox from "selenium-webdriver/firefox.js";
|
|
27
27
|
import edge from "selenium-webdriver/edge.js";
|
|
28
|
-
import command from "selenium-webdriver/lib/command.js";
|
|
29
28
|
import extractZip from "extract-zip";
|
|
30
29
|
|
|
31
30
|
import {download, extractTar, extractDmg, killDriverProcess, wait}
|
|
@@ -50,12 +49,19 @@ const BROWSER_DOWNLOAD_ERROR = "Browser download failed";
|
|
|
50
49
|
const BROWSER_NOT_INSTALLED_ERROR = "Browser is not installed";
|
|
51
50
|
const ELEMENT_NOT_FOUND_ERROR = "HTML element not found";
|
|
52
51
|
|
|
52
|
+
function getMajorVersion(versionNumber) {
|
|
53
|
+
let majorVersion = parseInt(versionNumber && versionNumber.split(".")[0], 10);
|
|
54
|
+
if (isNaN(majorVersion))
|
|
55
|
+
throw new Error(`${UNSUPPORTED_VERSION_ERROR}: ${versionNumber}`);
|
|
56
|
+
|
|
57
|
+
return majorVersion;
|
|
58
|
+
}
|
|
59
|
+
|
|
53
60
|
function checkVersion(version, minVersion, channels = []) {
|
|
54
61
|
if (channels.includes(version))
|
|
55
62
|
return;
|
|
56
63
|
|
|
57
|
-
|
|
58
|
-
if (isNaN(mainVersion) || mainVersion < minVersion)
|
|
64
|
+
if (getMajorVersion(version) < minVersion)
|
|
59
65
|
throw new Error(`${UNSUPPORTED_VERSION_ERROR}: ${version}`);
|
|
60
66
|
}
|
|
61
67
|
|
|
@@ -72,19 +78,17 @@ function checkPlatform() {
|
|
|
72
78
|
class Browser {
|
|
73
79
|
/**
|
|
74
80
|
* @typedef {Object} BrowserBinary
|
|
75
|
-
* @property {string} binary
|
|
76
|
-
* @property {string} versionNumber
|
|
77
|
-
* binary.
|
|
81
|
+
* @property {string} binary The path to the browser binary.
|
|
82
|
+
* @property {string} versionNumber The version number of the browser binary.
|
|
78
83
|
*/
|
|
79
84
|
|
|
80
85
|
/**
|
|
81
86
|
* Installs the browser. The installation process is detailed on the
|
|
82
87
|
* subclasses.
|
|
83
|
-
* @param {string} version
|
|
84
|
-
* Please find examples on the subclasses.
|
|
85
|
-
* @param {number
|
|
86
|
-
* install files to complete. When set to 0 there is no time limit.
|
|
87
|
-
* to 0.
|
|
88
|
+
* @param {string} [version=latest] Either full version number or
|
|
89
|
+
* channel/release. Please find examples on the subclasses.
|
|
90
|
+
* @param {number} [downloadTimeout=0] Allowed time in ms for the download of
|
|
91
|
+
* install files to complete. When set to 0 there is no time limit.
|
|
88
92
|
* @return {BrowserBinary}
|
|
89
93
|
* @throws {Error} Unsupported browser version, Unsupported platform, Browser
|
|
90
94
|
* download failed.
|
|
@@ -95,7 +99,7 @@ class Browser {
|
|
|
95
99
|
|
|
96
100
|
/**
|
|
97
101
|
* Gets the installed version returned by the browser binary.
|
|
98
|
-
* @param {string} binary
|
|
102
|
+
* @param {string} binary The path to the browser binary.
|
|
99
103
|
* @return {string} Installed browser version.
|
|
100
104
|
*/
|
|
101
105
|
static async getInstalledVersion(binary) {
|
|
@@ -119,27 +123,28 @@ class Browser {
|
|
|
119
123
|
|
|
120
124
|
/**
|
|
121
125
|
* @typedef {Object} driverOptions
|
|
122
|
-
* @property {boolean} headless=true
|
|
123
|
-
* or not.
|
|
124
|
-
*
|
|
126
|
+
* @property {boolean} [headless=true] Run the browser in headless mode,
|
|
127
|
+
* or not. In Chromium >= 111, the
|
|
128
|
+
* {@link https://developer.chrome.com/articles/new-headless/ new headless mode}
|
|
129
|
+
* is used.
|
|
130
|
+
* @property {Array.<string>} [extensionPaths=[]] Loads extensions to the
|
|
125
131
|
* browser.
|
|
126
|
-
* @property {boolean} incognito=false
|
|
132
|
+
* @property {boolean} [incognito=false] Runs the browser in incognito mode,
|
|
127
133
|
* or not.
|
|
128
|
-
* @property {boolean} insecure=false
|
|
134
|
+
* @property {boolean} [insecure=false] Forces the browser to accept insecure
|
|
129
135
|
* certificates, or not.
|
|
130
|
-
* @property {Array.<string>} [extraArgs=[]]
|
|
136
|
+
* @property {Array.<string>} [extraArgs=[]] Additional arguments to start
|
|
131
137
|
* the browser with.
|
|
132
138
|
*/
|
|
133
139
|
|
|
134
140
|
/**
|
|
135
141
|
* Installs the webdriver matching the browser version and runs the
|
|
136
142
|
* browser. If needed, the browser binary is also installed.
|
|
137
|
-
* @param {string} version
|
|
138
|
-
* Please find examples on the subclasses.
|
|
139
|
-
* @param {driverOptions
|
|
140
|
-
* @param {number
|
|
143
|
+
* @param {string} [version=latest] Either full version number or
|
|
144
|
+
* channel/release. Please find examples on the subclasses.
|
|
145
|
+
* @param {driverOptions} [options={}] Options to start the browser with.
|
|
146
|
+
* @param {number} [downloadTimeout=0] Allowed time in ms for the download of
|
|
141
147
|
* browser install files to complete. When set to 0 there is no time limit.
|
|
142
|
-
* Defaults to 0.
|
|
143
148
|
* @return {webdriver}
|
|
144
149
|
* @throws {Error} Unsupported browser version, Unsupported platform, Browser
|
|
145
150
|
* download failed, Driver download failed, Unable to start driver.
|
|
@@ -151,8 +156,8 @@ class Browser {
|
|
|
151
156
|
/**
|
|
152
157
|
* By default, extensions are disabled in incognito mode. This function
|
|
153
158
|
* enables the extension when loaded in incognito.
|
|
154
|
-
* @param {webdriver} driver
|
|
155
|
-
* @param {string} extensionTitle
|
|
159
|
+
* @param {webdriver} driver The driver controlling the browser.
|
|
160
|
+
* @param {string} extensionTitle Title of the extension to be enabled.
|
|
156
161
|
* @return {webdriver}
|
|
157
162
|
* @throws {Error} Unsupported browser version, Extension not found, HTML
|
|
158
163
|
* element not found.
|
|
@@ -185,7 +190,7 @@ class Chromium extends Browser {
|
|
|
185
190
|
"win32-x64": "win64",
|
|
186
191
|
"linux-x64": "linux",
|
|
187
192
|
"darwin-x64": "mac",
|
|
188
|
-
"
|
|
193
|
+
"darwin-arm64": "mac_arm64"
|
|
189
194
|
}[platformArch];
|
|
190
195
|
let data = await got(`https://omahaproxy.appspot.com/all.json?os=${os}`).json();
|
|
191
196
|
let release = data[0].versions.find(ver => ver.channel == channel);
|
|
@@ -212,11 +217,10 @@ class Chromium extends Browser {
|
|
|
212
217
|
/**
|
|
213
218
|
* Installs the browser. The Chromium executable gets extracted in the
|
|
214
219
|
* {@link snapshotsBaseDir} folder, ready to go.
|
|
215
|
-
* @param {string} version
|
|
216
|
-
* number (i.e. "77.0.3865.0").
|
|
217
|
-
* @param {number
|
|
218
|
-
* install files to complete. When set to 0 there is no time limit.
|
|
219
|
-
* to 0.
|
|
220
|
+
* @param {string} [version=latest] Either "latest", "beta", "dev" or a full
|
|
221
|
+
* version number (i.e. "77.0.3865.0").
|
|
222
|
+
* @param {number} [downloadTimeout=0] Allowed time in ms for the download of
|
|
223
|
+
* install files to complete. When set to 0 there is no time limit.
|
|
220
224
|
* @return {BrowserBinary}
|
|
221
225
|
* @throws {Error} Unsupported browser version, Unsupported platform, Browser
|
|
222
226
|
* download failed.
|
|
@@ -225,24 +229,41 @@ class Chromium extends Browser {
|
|
|
225
229
|
const MIN_VERSION = 75;
|
|
226
230
|
const MAX_VERSION_DECREMENTS = 200;
|
|
227
231
|
|
|
232
|
+
let binary;
|
|
233
|
+
let versionNumber;
|
|
234
|
+
let base;
|
|
235
|
+
|
|
236
|
+
async function getBase(chromiumVersion) {
|
|
237
|
+
let {chromium_base_position: chromiumBase} =
|
|
238
|
+
await got(`https://omahaproxy.appspot.com/deps.json?version=${chromiumVersion}`).json();
|
|
239
|
+
return parseInt(chromiumBase, 10);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// https://gitlab.com/eyeo/developer-experience/get-browser-binary/-/issues/46
|
|
243
|
+
if (platformArch == "linux-arm64") {
|
|
244
|
+
binary = "/usr/bin/chromium";
|
|
245
|
+
let installedVersion = await Chromium.getInstalledVersion(binary);
|
|
246
|
+
// installedVersion example: "Chromium 112.0.5615.49 built on Debian 11.6"
|
|
247
|
+
versionNumber = installedVersion.split(" ")[1];
|
|
248
|
+
base = await getBase(versionNumber);
|
|
249
|
+
return {binary, versionNumber, base};
|
|
250
|
+
}
|
|
251
|
+
|
|
228
252
|
checkVersion(version, MIN_VERSION, Chromium.#CHANNELS);
|
|
229
|
-
|
|
253
|
+
versionNumber = await Chromium.#getVersionForChannel(version);
|
|
230
254
|
|
|
231
|
-
|
|
232
|
-
await got(`https://omahaproxy.appspot.com/deps.json?version=${versionNumber}`).json();
|
|
233
|
-
let base = parseInt(chromiumBase, 10);
|
|
255
|
+
base = await getBase(versionNumber);
|
|
234
256
|
let startBase = base;
|
|
235
257
|
let [platformDir, fileName] = {
|
|
236
258
|
"win32-ia32": ["Win", "chrome-win.zip"],
|
|
237
259
|
"win32-x64": ["Win_x64", "chrome-win.zip"],
|
|
238
260
|
"linux-x64": ["Linux_x64", "chrome-linux.zip"],
|
|
239
261
|
"darwin-x64": ["Mac", "chrome-mac.zip"],
|
|
240
|
-
"
|
|
262
|
+
"darwin-arm64": ["Mac_Arm", "chrome-mac.zip"]
|
|
241
263
|
}[platformArch];
|
|
242
264
|
let archive;
|
|
243
265
|
let browserDir;
|
|
244
266
|
let snapshotsDir = path.join(snapshotsBaseDir, "chromium");
|
|
245
|
-
let binary;
|
|
246
267
|
|
|
247
268
|
while (true) {
|
|
248
269
|
browserDir = path.join(snapshotsDir, `chromium-${platformArch}-${base}`);
|
|
@@ -290,6 +311,7 @@ class Chromium extends Browser {
|
|
|
290
311
|
"win32-ia32": ["Win", "chromedriver_win32.zip", "chromedriver.exe"],
|
|
291
312
|
"win32-x64": ["Win_x64", "chromedriver_win32.zip", "chromedriver.exe"],
|
|
292
313
|
"linux-x64": ["Linux_x64", "chromedriver_linux64.zip", "chromedriver"],
|
|
314
|
+
"linux-arm64": ["", "", "chromedriver"],
|
|
293
315
|
"darwin-x64": ["Mac", "chromedriver_mac64.zip", "chromedriver"],
|
|
294
316
|
"darwin-arm64": ["Mac_Arm", "chromedriver_mac64.zip", "chromedriver"]
|
|
295
317
|
}[platformArch];
|
|
@@ -304,6 +326,13 @@ class Chromium extends Browser {
|
|
|
304
326
|
}
|
|
305
327
|
catch (e) { // zip file is either not cached or corrupted
|
|
306
328
|
let url = `https://commondatastorage.googleapis.com/chromium-browser-snapshots/${dir}/${base}/${zip}`;
|
|
329
|
+
// https://gitlab.com/eyeo/developer-experience/get-browser-binary/-/issues/46
|
|
330
|
+
// It is unclear how electron releases match Chromium versions. Once that
|
|
331
|
+
// is figured out, the link below will depend on the Chromium version.
|
|
332
|
+
// https://stackoverflow.com/questions/38732822/compile-chromedriver-on-arm
|
|
333
|
+
if (platformArch == "linux-arm64")
|
|
334
|
+
url = "https://github.com/electron/electron/releases/download/v24.1.2/chromedriver-v24.1.2-linux-arm64.zip";
|
|
335
|
+
|
|
307
336
|
try {
|
|
308
337
|
await download(url, archive);
|
|
309
338
|
}
|
|
@@ -315,6 +344,8 @@ class Chromium extends Browser {
|
|
|
315
344
|
|
|
316
345
|
await killDriverProcess("chromedriver");
|
|
317
346
|
let driverPath = path.join(cacheDir, zip.split(".")[0], driverBinary);
|
|
347
|
+
if (platformArch == "linux-arm64")
|
|
348
|
+
driverPath = path.join(cacheDir, driverBinary);
|
|
318
349
|
await fs.promises.rm(driverPath, {force: true});
|
|
319
350
|
await extractZip(archive, {dir: cacheDir});
|
|
320
351
|
|
|
@@ -333,8 +364,14 @@ class Chromium extends Browser {
|
|
|
333
364
|
let options = new chrome.Options().addArguments("no-sandbox", ...extraArgs);
|
|
334
365
|
if (extensionPaths.length > 0)
|
|
335
366
|
options.addArguments(`load-extension=${extensionPaths.join(",")}`);
|
|
336
|
-
if (headless)
|
|
337
|
-
|
|
367
|
+
if (headless) {
|
|
368
|
+
// New headless mode introduced in Chrome 111
|
|
369
|
+
// https://developer.chrome.com/articles/new-headless/
|
|
370
|
+
if (getMajorVersion(versionNumber) >= 111)
|
|
371
|
+
options.addArguments("headless=new");
|
|
372
|
+
else
|
|
373
|
+
options.headless();
|
|
374
|
+
}
|
|
338
375
|
if (insecure)
|
|
339
376
|
options.addArguments("ignore-certificate-errors");
|
|
340
377
|
if (incognito)
|
|
@@ -423,11 +460,10 @@ class Firefox extends Browser {
|
|
|
423
460
|
/**
|
|
424
461
|
* Installs the browser. The Firefox executable gets extracted in the
|
|
425
462
|
* {@link snapshotsBaseDir} folder, ready to go.
|
|
426
|
-
* @param {string} version
|
|
427
|
-
* number (i.e. "68.0").
|
|
428
|
-
* @param {number
|
|
429
|
-
* install files to complete. When set to 0 there is no time limit.
|
|
430
|
-
* to 0.
|
|
463
|
+
* @param {string} [version=latest] Either "latest", "beta" or a full version
|
|
464
|
+
* number (i.e. "68.0").
|
|
465
|
+
* @param {number} [downloadTimeout=0] Allowed time in ms for the download of
|
|
466
|
+
* install files to complete. When set to 0 there is no time limit.
|
|
431
467
|
* @return {BrowserBinary}
|
|
432
468
|
* @throws {Error} Unsupported browser version, Unsupported platform, Browser
|
|
433
469
|
* download failed.
|
|
@@ -512,11 +548,8 @@ class Firefox extends Browser {
|
|
|
512
548
|
}, 30000, `${DRIVER_START_ERROR}: geckodriver`, 1000);
|
|
513
549
|
|
|
514
550
|
for (let extensionPath of extensionPaths) {
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
.setParameter("path", extensionPath)
|
|
518
|
-
.setParameter("temporary", true)
|
|
519
|
-
);
|
|
551
|
+
let temporary = true; // Parameter not documented on the webdriver docs
|
|
552
|
+
await driver.installAddon(extensionPath, temporary);
|
|
520
553
|
}
|
|
521
554
|
return driver;
|
|
522
555
|
}
|
|
@@ -565,8 +598,7 @@ class Edge extends Browser {
|
|
|
565
598
|
versionNumbers.push(matches[2]);
|
|
566
599
|
|
|
567
600
|
let compareVersions = (v1, v2) =>
|
|
568
|
-
|
|
569
|
-
1 : -1;
|
|
601
|
+
getMajorVersion(v1) < getMajorVersion(v2) ? 1 : -1;
|
|
570
602
|
versionNumber = versionNumbers.sort(compareVersions)[0];
|
|
571
603
|
}
|
|
572
604
|
else {
|
|
@@ -613,11 +645,10 @@ class Edge extends Browser {
|
|
|
613
645
|
* Installs the browser. On Linux, Edge is installed as a system package,
|
|
614
646
|
* which requires root permissions. On MacOS, Edge is installed as a user
|
|
615
647
|
* app (not as a system app). Installing Edge on Windows is not supported.
|
|
616
|
-
* @param {string} version
|
|
617
|
-
* number (i.e. "95.0.1020.40").
|
|
618
|
-
* @param {number
|
|
619
|
-
* install files to complete. When set to 0 there is no time limit.
|
|
620
|
-
* to 0.
|
|
648
|
+
* @param {string} [version=latest] Either "latest", "beta", "dev" or a full
|
|
649
|
+
* version number (i.e. "95.0.1020.40").
|
|
650
|
+
* @param {number} [downloadTimeout=0] Allowed time in ms for the download of
|
|
651
|
+
* install files to complete. When set to 0 there is no time limit.
|
|
621
652
|
* @return {BrowserBinary}
|
|
622
653
|
* @throws {Error} Unsupported browser version, Unsupported platform, Browser
|
|
623
654
|
* download failed.
|
|
@@ -701,7 +732,7 @@ class Edge extends Browser {
|
|
|
701
732
|
"win32-x64": ["edgedriver_win64.zip", "msedgedriver.exe"],
|
|
702
733
|
"linux-x64": ["edgedriver_linux64.zip", "msedgedriver"],
|
|
703
734
|
"darwin-x64": ["edgedriver_mac64.zip", "msedgedriver"],
|
|
704
|
-
"darwin-arm64": ["
|
|
735
|
+
"darwin-arm64": ["edgedriver_mac64_m1.zip", "msedgedriver"]
|
|
705
736
|
}[platformArch];
|
|
706
737
|
let cacheDir = path.join(snapshotsBaseDir, "edge", "cache",
|
|
707
738
|
`edgedriver-${versionNumber}`);
|
|
@@ -760,7 +791,22 @@ class Edge extends Browser {
|
|
|
760
791
|
builder.setEdgeOptions(options);
|
|
761
792
|
builder.setEdgeService(serviceBuilder);
|
|
762
793
|
|
|
763
|
-
|
|
794
|
+
let driver;
|
|
795
|
+
// On Windows CI, occasionally a SessionNotCreatedError is thrown, likely
|
|
796
|
+
// due to low OS resources, that's why building the driver is retried
|
|
797
|
+
await wait(async() => {
|
|
798
|
+
try {
|
|
799
|
+
driver = await builder.build();
|
|
800
|
+
return true;
|
|
801
|
+
}
|
|
802
|
+
catch (err) {
|
|
803
|
+
if (err.name != "SessionNotCreatedError")
|
|
804
|
+
throw err;
|
|
805
|
+
await killDriverProcess("msedgedriver");
|
|
806
|
+
}
|
|
807
|
+
}, 30000, `${DRIVER_START_ERROR}: msedgedriver`, 1000);
|
|
808
|
+
|
|
809
|
+
return driver;
|
|
764
810
|
}
|
|
765
811
|
|
|
766
812
|
/** @see Browser.enableExtensionInIncognito */
|
|
@@ -787,11 +833,10 @@ class Edge extends Browser {
|
|
|
787
833
|
|
|
788
834
|
/**
|
|
789
835
|
* @type {Object}
|
|
790
|
-
* @property {Chromium} chromium
|
|
836
|
+
* @property {Chromium} chromium Browser and webdriver functionality for
|
|
791
837
|
* Chromium.
|
|
792
|
-
* @property {Firefox} firefox
|
|
793
|
-
*
|
|
794
|
-
* @property {Edge} edge - Browser and webdriver functionality for Edge.
|
|
838
|
+
* @property {Firefox} firefox Browser and webdriver functionality for Firefox.
|
|
839
|
+
* @property {Edge} edge Browser and webdriver functionality for Edge.
|
|
795
840
|
*/
|
|
796
841
|
export const BROWSERS = {
|
|
797
842
|
chromium: Chromium,
|
package/src/utils.js
CHANGED
|
@@ -28,10 +28,10 @@ import Jimp from "jimp";
|
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Downloads url resources.
|
|
31
|
-
* @param {string} url
|
|
32
|
-
* @param {string} destFile
|
|
33
|
-
* @param {number
|
|
34
|
-
* When set to 0 there is no time limit.
|
|
31
|
+
* @param {string} url The url of the resource to be downloaded.
|
|
32
|
+
* @param {string} destFile The destination file path.
|
|
33
|
+
* @param {number} [timeout=0] Allowed time in ms for the download to complete.
|
|
34
|
+
* When set to 0 there is no time limit.
|
|
35
35
|
* @throws {TypeError} Invalid URL, Download timeout.
|
|
36
36
|
*/
|
|
37
37
|
export async function download(url, destFile, timeout = 0) {
|
|
@@ -164,9 +164,9 @@ export function wait(condition, timeout = 0, message, pollTimeout = 100) {
|
|
|
164
164
|
|
|
165
165
|
/**
|
|
166
166
|
* Takes a screenshot of the full page by scrolling from top to bottom.
|
|
167
|
-
* @param {webdriver} driver
|
|
168
|
-
* @
|
|
169
|
-
*
|
|
167
|
+
* @param {webdriver} driver The driver controlling the browser.
|
|
168
|
+
* @param {boolean} [hideScrollbars=true] Hides any scrollbars before taking
|
|
169
|
+
* the screenshot, or not.
|
|
170
170
|
* @return {Jimp} A Jimp image object containing the screenshot.
|
|
171
171
|
* @example
|
|
172
172
|
* // Getting a base-64 encoded PNG from the returned Jimp image
|
package/test/browsers.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import fs from "fs";
|
|
19
|
-
import expect from "expect";
|
|
19
|
+
import {expect} from "expect";
|
|
20
20
|
import path from "path";
|
|
21
21
|
|
|
22
22
|
import {BROWSERS, snapshotsBaseDir, takeFullPageScreenshot} from "../index.js";
|
|
@@ -30,7 +30,7 @@ const VERSIONS = {
|
|
|
30
30
|
firefox: ["latest", "60.0", "beta"],
|
|
31
31
|
edge: ["latest", "95.0.1020.40", "beta", "dev"]
|
|
32
32
|
};
|
|
33
|
-
const TEST_URL = "https://
|
|
33
|
+
const TEST_URL = "https://abptestpages.org/en/exceptions/iframe_subdomains";
|
|
34
34
|
const TEST_URL_LONG_PAGE = "https://abptestpages.org/";
|
|
35
35
|
|
|
36
36
|
async function switchToHandle(driver, testFn) {
|
|
@@ -105,12 +105,14 @@ function getExtension(browser, version) {
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
async function getCachedTimes(browser) {
|
|
108
|
+
let armLinuxChromium = browser == "chromium" &&
|
|
109
|
+
process.platform == "linux" && process.arch == "arm64";
|
|
108
110
|
let cacheDir = path.join(snapshotsBaseDir, browser, "cache");
|
|
109
111
|
let cacheFiles = await fs.promises.readdir(cacheDir);
|
|
110
112
|
|
|
111
113
|
let browserCacheTime = null;
|
|
112
114
|
// Edge gets installed at OS level, that's why it's not tested here
|
|
113
|
-
if (browser != "edge") {
|
|
115
|
+
if (browser != "edge" && !armLinuxChromium) {
|
|
114
116
|
let installTypes = [".zip", ".dmg", ".bz2"];
|
|
115
117
|
let browserZip =
|
|
116
118
|
cacheFiles.find(elem => installTypes.some(type => elem.includes(type)));
|
|
@@ -120,7 +122,7 @@ async function getCachedTimes(browser) {
|
|
|
120
122
|
|
|
121
123
|
let driverCacheTime = null;
|
|
122
124
|
// Firefox install file includes the driver, that's why it's not tested here
|
|
123
|
-
if (browser != "firefox") {
|
|
125
|
+
if (browser != "firefox" && !armLinuxChromium) {
|
|
124
126
|
let driverDir = cacheFiles.find(elem => !elem.endsWith(".zip"));
|
|
125
127
|
let driverFiles = await fs.promises.readdir(path.join(cacheDir, driverDir));
|
|
126
128
|
let driverZip = driverFiles.find(elem => elem.endsWith(".zip"));
|
|
@@ -210,7 +212,13 @@ for (let browser of Object.keys(BROWSERS)) {
|
|
|
210
212
|
expect(existingCacheTimes).toEqual(emptyCacheTimes);
|
|
211
213
|
});
|
|
212
214
|
|
|
213
|
-
it("supports extra args", async()
|
|
215
|
+
it("supports extra args", async function() {
|
|
216
|
+
// https://gitlab.com/eyeo/developer-experience/get-browser-binary/-/issues/48
|
|
217
|
+
// To be removed when Edge latest version > 112
|
|
218
|
+
if (browser == "edge" && version == "latest" &&
|
|
219
|
+
process.platform == "linux")
|
|
220
|
+
this.skip();
|
|
221
|
+
|
|
214
222
|
let headless = false;
|
|
215
223
|
let extraArgs = browser == "firefox" ?
|
|
216
224
|
["--devtools"] : ["auto-open-devtools-for-tabs"];
|
|
@@ -242,7 +250,9 @@ for (let browser of Object.keys(BROWSERS)) {
|
|
|
242
250
|
});
|
|
243
251
|
|
|
244
252
|
it("loads an extension", async() => {
|
|
245
|
-
|
|
253
|
+
// Chromium's old headless mode doesn't support loading extensions
|
|
254
|
+
let headless = browser == "firefox" || (browser == "chromium" &&
|
|
255
|
+
["latest", "beta", "dev"].includes(version));
|
|
246
256
|
let {extensionPaths} = getExtension(browser, version);
|
|
247
257
|
|
|
248
258
|
driver = await BROWSERS[browser].getDriver(
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Duplicated from registry.gitlab.com/eyeo/docker/get-browser-binary:node16
|
|
2
|
+
# https://gitlab.com/eyeo/developer-experience/get-browser-binary/-/issues/46
|
|
3
|
+
FROM node:16-bullseye-slim
|
|
4
|
+
# General packages
|
|
5
|
+
RUN apt-get update && apt-get install -y git procps wget unzip bzip2 gnupg
|
|
6
|
+
# xvfb (headful browser run)
|
|
7
|
+
RUN apt-get install -y libgtk-3-0 libxt6 xvfb libnss3 libxss1
|
|
8
|
+
# General browser dependencies
|
|
9
|
+
RUN apt-get install -y libgconf-2-4 libasound2 libgbm1
|
|
10
|
+
# Edge dependencies
|
|
11
|
+
RUN apt-get install -y fonts-liberation libatomic1 xdg-utils libu2f-udev
|
|
12
|
+
|
|
13
|
+
# Chromium ARM
|
|
14
|
+
RUN apt-get install -y chromium
|
|
15
|
+
|
|
16
|
+
COPY package*.json get-browser-binary/
|
|
17
|
+
RUN cd get-browser-binary && npm install
|
|
18
|
+
|
|
19
|
+
COPY . get-browser-binary/
|
|
20
|
+
|
|
21
|
+
ENV TEST_ARGS="--grep Browser"
|
|
22
|
+
ENTRYPOINT get-browser-binary/test/docker/entrypoint.sh
|