@eyeo/get-browser-binary 0.21.0 → 0.23.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 +19 -7
- package/README.md +1 -5
- package/RELEASE_NOTES.md +11 -0
- package/package.json +1 -1
- package/src/chromium.js +2 -0
- package/src/edge.js +119 -67
- package/src/utils.js +1 -0
- package/test/browsers.js +12 -9
package/.gitlab-ci.yml
CHANGED
|
@@ -57,20 +57,32 @@ test:browsers:linux:dev:
|
|
|
57
57
|
test:browsers:windows:
|
|
58
58
|
extends: .windows
|
|
59
59
|
script:
|
|
60
|
-
|
|
61
|
-
# https://gitlab.com/eyeo/developer-experience/get-browser-binary/-/issues/
|
|
62
|
-
- npm test "--" --grep "
|
|
63
|
-
|
|
64
|
-
#
|
|
65
|
-
# https://gitlab.com/eyeo/developer-experience/get-browser-binary/-/issues/2
|
|
66
|
-
- npm test "--" --grep "firefox.*installs"
|
|
60
|
+
- npm test "--" --grep "^.*edge((?!Version:.dev).)*$"
|
|
61
|
+
# Chromium excluded until this is fixed: https://gitlab.com/eyeo/developer-experience/get-browser-binary/-/issues/87
|
|
62
|
+
# - npm test "--" --grep "^.*chromium((?!Version:.dev).)*$"
|
|
63
|
+
# Firefox excluded until this is fixed: https://gitlab.com/eyeo/developer-experience/get-browser-binary/-/issues/87
|
|
64
|
+
# - npm test "--" --grep "firefox.*installs"
|
|
67
65
|
|
|
68
66
|
test:browsers:windows:dev:
|
|
69
67
|
extends: .windows
|
|
70
68
|
script:
|
|
69
|
+
- npm test "--" --grep "edge.*Version:.dev"
|
|
71
70
|
- npm test "--" --grep "chromium.*Version:.dev"
|
|
72
71
|
allow_failure: true
|
|
73
72
|
|
|
73
|
+
test:browsers:macos:
|
|
74
|
+
stage: test
|
|
75
|
+
tags:
|
|
76
|
+
- saas-macos-medium-m1
|
|
77
|
+
# https://docs.gitlab.com/ci/runners/hosted_runners/macos/#supported-macos-images
|
|
78
|
+
image: macos-15-xcode-16
|
|
79
|
+
cache: {}
|
|
80
|
+
before_script:
|
|
81
|
+
- npm install
|
|
82
|
+
script:
|
|
83
|
+
# Only checking that latest browsers can be installed on macOS
|
|
84
|
+
- npm test -- -g ".*latest.*installs"
|
|
85
|
+
|
|
74
86
|
docs:
|
|
75
87
|
stage: docs
|
|
76
88
|
needs: []
|
package/README.md
CHANGED
|
@@ -32,11 +32,7 @@ the right side.
|
|
|
32
32
|
|
|
33
33
|
- Chromium >= 77 (Chromium ARM >= 92)
|
|
34
34
|
- Firefox >= 68
|
|
35
|
-
- Edge >= 114
|
|
36
|
-
|
|
37
|
-
Note: Installing Edge is not supported on Windows. It is assumed to be installed
|
|
38
|
-
because it is the default browser on that platform. On macOS, only the latest
|
|
39
|
-
Edge version is supported.
|
|
35
|
+
- Edge >= 114 (Linux), Edge >= latest (MacOS, Windows)
|
|
40
36
|
|
|
41
37
|
### Verbose logging
|
|
42
38
|
|
package/RELEASE_NOTES.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Unreleased
|
|
2
2
|
|
|
3
|
+
# 0.23.0
|
|
4
|
+
|
|
5
|
+
- Adds beta and dev channels to Edge on Windows and MacOS (#29)
|
|
6
|
+
- Fixes edge driver location (!145)
|
|
7
|
+
|
|
8
|
+
# 0.22.0
|
|
9
|
+
|
|
10
|
+
- Adds macOS CI job (!141)
|
|
11
|
+
- Temporarily skips failing Chromium and Firefox on Windows (!142)
|
|
12
|
+
- Disables local network access checks on Chromium v.139 (!143)
|
|
13
|
+
|
|
3
14
|
# 0.21.0
|
|
4
15
|
|
|
5
16
|
- Fixes an issue on Chromedriver (>=136) which stopped returning webdriver
|
package/package.json
CHANGED
package/src/chromium.js
CHANGED
|
@@ -248,6 +248,8 @@ export class Chromium extends Browser {
|
|
|
248
248
|
await checkExtensionPaths(extensionPaths);
|
|
249
249
|
options.addArguments(`load-extension=${extensionPaths.join(",")}`);
|
|
250
250
|
}
|
|
251
|
+
if (majorVersion >= 139)
|
|
252
|
+
options.addArguments("--disable-features=LocalNetworkAccessChecks");
|
|
251
253
|
if (headless) {
|
|
252
254
|
// https://www.selenium.dev/blog/2023/headless-is-going-away/
|
|
253
255
|
if (majorVersion >= 109)
|
package/src/edge.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import path from "path";
|
|
19
|
-
import {exec} from "child_process";
|
|
19
|
+
import {exec, spawn} from "child_process";
|
|
20
20
|
import {promisify} from "util";
|
|
21
21
|
import fs from "fs";
|
|
22
22
|
|
|
@@ -25,9 +25,8 @@ import {until, By, Builder} from "selenium-webdriver";
|
|
|
25
25
|
import edge from "selenium-webdriver/edge.js";
|
|
26
26
|
|
|
27
27
|
import {Browser} from "./browser.js";
|
|
28
|
-
import {download,
|
|
29
|
-
|
|
30
|
-
from "./utils.js";
|
|
28
|
+
import {download, getMajorVersion, checkVersion, checkPlatform, errMsg,
|
|
29
|
+
snapshotsBaseDir, checkExtensionPaths, platformArch} from "./utils.js";
|
|
31
30
|
|
|
32
31
|
let {platform} = process;
|
|
33
32
|
|
|
@@ -105,24 +104,34 @@ export class Edge extends Browser {
|
|
|
105
104
|
return {versionNumber, channel};
|
|
106
105
|
}
|
|
107
106
|
|
|
108
|
-
static #
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
107
|
+
static #appName(channel) {
|
|
108
|
+
const channels = {stable: "", beta: " Beta", dev: " Dev"};
|
|
109
|
+
|
|
110
|
+
if (platform == "linux") {
|
|
111
|
+
return channel == "stable" ?
|
|
112
|
+
"microsoft-edge" : `microsoft-edge-${channel}`;
|
|
113
|
+
}
|
|
114
|
+
else if (platform == "darwin") {
|
|
115
|
+
return `Microsoft Edge${channels[channel]}`;
|
|
116
|
+
}
|
|
117
|
+
else if (platform == "win32") {
|
|
118
|
+
return `"Edge${channels[channel]}"`;
|
|
119
|
+
}
|
|
112
120
|
}
|
|
113
121
|
|
|
114
122
|
static #getBinaryPath(channel = "stable") {
|
|
115
123
|
switch (platform) {
|
|
116
124
|
case "win32":
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
return `${programFiles}\\Microsoft\\Edge\\Application\\msedge.exe`;
|
|
125
|
+
return path.join("C:", "\"Program Files (x86)\"", "Microsoft",
|
|
126
|
+
Edge.#appName(channel), "Application", "msedge.exe");
|
|
120
127
|
case "linux":
|
|
121
|
-
return
|
|
122
|
-
"/usr/bin/microsoft-edge" : `/usr/bin/microsoft-edge-${channel}`;
|
|
128
|
+
return path.join("/usr", "bin", Edge.#appName(channel));
|
|
123
129
|
case "darwin":
|
|
124
|
-
|
|
125
|
-
|
|
130
|
+
// Root path may no longer be needed after switching to custom runners
|
|
131
|
+
// https://eyeo.atlassian.net/browse/DOPE-8
|
|
132
|
+
const homePath = process.env.CI === "true" ? "/" : process.env.HOME;
|
|
133
|
+
return path.join(homePath, "Applications", `${Edge.#appName(channel)}.app`,
|
|
134
|
+
"Contents", "MacOS", Edge.#appName(channel));
|
|
126
135
|
default:
|
|
127
136
|
checkPlatform();
|
|
128
137
|
}
|
|
@@ -141,24 +150,11 @@ export class Edge extends Browser {
|
|
|
141
150
|
* download failed.
|
|
142
151
|
*/
|
|
143
152
|
static async installBrowser(version = "latest", downloadTimeout = 0) {
|
|
144
|
-
if (platform == "win32")
|
|
145
|
-
// Edge is mandatory on Windows, can't be uninstalled or downgraded
|
|
146
|
-
// https://support.microsoft.com/en-us/microsoft-edge/why-can-t-i-uninstall-microsoft-edge-ee150b3b-7d7a-9984-6d83-eb36683d526d
|
|
147
|
-
throw new Error(`${errMsg.unsupportedPlatform}: ${platform}`);
|
|
148
|
-
|
|
149
|
-
if (platform == "darwin" && !/latest|beta|dev/.test(version))
|
|
150
|
-
throw new Error(`${errMsg.unsupportedVersion}: ${version}. Only "latest", "beta" or "dev" are supported`);
|
|
151
|
-
|
|
152
153
|
checkVersion(version, Edge.#MIN_VERSION, Edge.#CHANNELS);
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
let filename = {
|
|
156
|
-
linux: `microsoft-edge-${channel}_${versionNumber}-1_amd64.deb`,
|
|
157
|
-
darwin: `MicrosoftEdge-${versionNumber}.pkg`
|
|
158
|
-
}[platform];
|
|
154
|
+
if (!Edge.#CHANNELS.includes(version) && platform != "linux")
|
|
155
|
+
throw new Error(`${errMsg.unsupportedVersion}: ${version}. Supported versions: ${Edge.#CHANNELS.join(",")}`);
|
|
159
156
|
|
|
160
|
-
let
|
|
161
|
-
let archive = path.join(snapshotsDir, "cache", filename);
|
|
157
|
+
let {versionNumber, channel} = await Edge.#getVersionForChannel(version);
|
|
162
158
|
let binary = Edge.#getBinaryPath(channel);
|
|
163
159
|
try {
|
|
164
160
|
if (await Edge.getInstalledVersion(binary) == versionNumber)
|
|
@@ -166,18 +162,44 @@ export class Edge extends Browser {
|
|
|
166
162
|
}
|
|
167
163
|
catch (e) {}
|
|
168
164
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
165
|
+
const [plat, arch, ext] = {
|
|
166
|
+
"win32-ia32": ["Windows", "x86", ".msi"],
|
|
167
|
+
"win32-x64": ["Windows", "x64", ".msi"],
|
|
168
|
+
"linux-x64": ["Linux", "x64", ".deb"],
|
|
169
|
+
"darwin-x64": ["MacOS", "universal", ".pkg"],
|
|
170
|
+
"darwin-arm64": ["MacOS", "universal", ".pkg"]
|
|
171
|
+
}[platformArch];
|
|
172
|
+
|
|
173
|
+
let url;
|
|
174
|
+
let filename;
|
|
175
|
+
const downloadChannels = {latest: "Stable", beta: "Beta", dev: "Dev"};
|
|
176
|
+
if (!Edge.#CHANNELS.includes(version) && platform == "linux") {
|
|
177
|
+
filename = `microsoft-edge-${channel}_${versionNumber}-1_amd64.deb`;
|
|
178
|
+
url = `https://packages.microsoft.com/repos/edge/pool/main/m/microsoft-edge-${channel}/${filename}`;
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
let products = await got("https://edgeupdates.microsoft.com/api/products?view=enterprise").json();
|
|
182
|
+
for (let product of products) {
|
|
183
|
+
if (product.Product != downloadChannels[version])
|
|
184
|
+
continue;
|
|
185
|
+
|
|
186
|
+
let release = product.Releases.find(
|
|
187
|
+
r => r.Platform == plat && r.Architecture == arch);
|
|
188
|
+
if (!release)
|
|
189
|
+
continue;
|
|
190
|
+
|
|
191
|
+
({Location: url} =
|
|
192
|
+
release.Artifacts.find(a => a.Location.endsWith(ext)));
|
|
193
|
+
filename = url.split("/").pop();
|
|
194
|
+
break;
|
|
180
195
|
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (!url)
|
|
199
|
+
throw new Error(`${errMsg.browserDownload}: Release not found for Edge ${downloadChannels[version]} on ${plat} ${arch}`);
|
|
200
|
+
|
|
201
|
+
const archive = path.join(snapshotsBaseDir, "edge", "cache", filename);
|
|
202
|
+
try {
|
|
181
203
|
await download(url, archive, downloadTimeout);
|
|
182
204
|
}
|
|
183
205
|
catch (err) {
|
|
@@ -188,8 +210,41 @@ export class Edge extends Browser {
|
|
|
188
210
|
await promisify(exec)(`dpkg -i ${archive}`);
|
|
189
211
|
}
|
|
190
212
|
else if (platform == "darwin") {
|
|
191
|
-
|
|
192
|
-
|
|
213
|
+
let command;
|
|
214
|
+
if (process.env.CI === "true") {
|
|
215
|
+
// For some reason installing apps on the home directory fails on macOS
|
|
216
|
+
// runners. Using the root target as a workaround
|
|
217
|
+
// This may no longer be needed after switching to custom runners
|
|
218
|
+
// https://eyeo.atlassian.net/browse/DOPE-8
|
|
219
|
+
command = `sudo installer -pkg ${archive} -target /`;
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
await fs.promises.rm(
|
|
223
|
+
path.join(process.env.HOME, "Applications", `${Edge.#appName(channel)}.app`),
|
|
224
|
+
{force: true, recursive: true}
|
|
225
|
+
);
|
|
226
|
+
command = `installer -pkg ${archive} -target CurrentUserHomeDirectory`;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
await promisify(exec)(command);
|
|
230
|
+
}
|
|
231
|
+
else if (platform == "win32") {
|
|
232
|
+
// /S strips quotes and /C executes the runnable file
|
|
233
|
+
const installProcess = spawn("cmd", [`/S /C ${archive}`], {
|
|
234
|
+
detached: true,
|
|
235
|
+
env: process.env
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
await new Promise((resolve, reject) => {
|
|
239
|
+
function onClose(code) {
|
|
240
|
+
if (code != 0)
|
|
241
|
+
reject(new Error(`${errMsg.browserInstall}. Exit code: ${code}`));
|
|
242
|
+
|
|
243
|
+
resolve();
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
installProcess.on("close", onClose);
|
|
247
|
+
});
|
|
193
248
|
}
|
|
194
249
|
|
|
195
250
|
return {binary, versionNumber};
|
|
@@ -212,24 +267,29 @@ export class Edge extends Browser {
|
|
|
212
267
|
|
|
213
268
|
let binary;
|
|
214
269
|
let versionNumber;
|
|
215
|
-
if (
|
|
216
|
-
|
|
217
|
-
|
|
270
|
+
if (customBrowserBinary) {
|
|
271
|
+
binary = customBrowserBinary;
|
|
272
|
+
versionNumber = await Edge.getInstalledVersion(binary);
|
|
218
273
|
}
|
|
219
274
|
else {
|
|
220
|
-
binary =
|
|
221
|
-
|
|
222
|
-
await Edge.getInstalledVersion(binary);
|
|
275
|
+
({binary, versionNumber} =
|
|
276
|
+
await Edge.installBrowser(version, downloadTimeout));
|
|
223
277
|
}
|
|
224
278
|
|
|
279
|
+
if (platform == "win32")
|
|
280
|
+
// webdriver can't find the binary when subfolders are enclosed by quotes
|
|
281
|
+
binary = binary.replaceAll("\"", "");
|
|
282
|
+
|
|
225
283
|
const majorVersion = getMajorVersion(versionNumber);
|
|
226
284
|
const edgeOptions = {};
|
|
227
285
|
// https://issues.chromium.org/issues/409441960
|
|
228
286
|
if (majorVersion >= 136)
|
|
229
287
|
edgeOptions.enableExtensionTargets = true;
|
|
230
288
|
|
|
231
|
-
|
|
232
|
-
.addArguments("no-sandbox", ...extraArgs)
|
|
289
|
+
let options = new edge.Options({"ms:edgeOptions": edgeOptions})
|
|
290
|
+
.addArguments("no-sandbox", ...extraArgs)
|
|
291
|
+
.setEdgeChromiumBinaryPath(binary);
|
|
292
|
+
|
|
233
293
|
if (headless) {
|
|
234
294
|
if (versionNumber && majorVersion >= 114)
|
|
235
295
|
options.addArguments("headless=new");
|
|
@@ -244,27 +304,19 @@ export class Edge extends Browser {
|
|
|
244
304
|
options.addArguments("inprivate");
|
|
245
305
|
if (insecure)
|
|
246
306
|
options.addArguments("ignore-certificate-errors");
|
|
247
|
-
if (platform === "linux" || platform === "darwin")
|
|
248
|
-
options.setEdgeChromiumBinaryPath(binary);
|
|
249
307
|
|
|
250
308
|
let builder = new Builder();
|
|
251
309
|
builder.forBrowser("MicrosoftEdge");
|
|
252
310
|
builder.setEdgeOptions(options);
|
|
253
311
|
|
|
254
312
|
let driver;
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
catch (err) {
|
|
263
|
-
if (err.name != "SessionNotCreatedError")
|
|
264
|
-
throw err;
|
|
265
|
-
await killDriverProcess("msedgedriver");
|
|
266
|
-
}
|
|
267
|
-
}, 30000, `${errMsg.driverStart}: msedgedriver`, 1000);
|
|
313
|
+
try {
|
|
314
|
+
process.env.SE_DRIVER_MIRROR_URL = "https://msedgedriver.microsoft.com";
|
|
315
|
+
driver = edge.Driver.createSession(options);
|
|
316
|
+
}
|
|
317
|
+
catch (err) {
|
|
318
|
+
throw new Error(`${errMsg.driverStart}: msedgedriver\n${err}`);
|
|
319
|
+
}
|
|
268
320
|
|
|
269
321
|
// From Edge 134 on, developer mode needs to be enabled
|
|
270
322
|
// for custom extensions to work properly
|
package/src/utils.js
CHANGED
|
@@ -32,6 +32,7 @@ export const errMsg = {
|
|
|
32
32
|
driverStart: "Unable to start driver",
|
|
33
33
|
extensionNotFound: "Extension not found",
|
|
34
34
|
browserDownload: "Browser download failed",
|
|
35
|
+
browserInstall: "Browser installation failed",
|
|
35
36
|
browserNotInstalled: "Browser is not installed",
|
|
36
37
|
browserVersionCheck: "Checking the browser version failed",
|
|
37
38
|
elemNotFound: "HTML element not found",
|
package/test/browsers.js
CHANGED
|
@@ -180,13 +180,20 @@ for (let browser of Object.keys(BROWSERS)) {
|
|
|
180
180
|
await killDriverProcess("geckodriver");
|
|
181
181
|
|
|
182
182
|
// https://gitlab.com/eyeo/developer-experience/get-browser-binary/-/issues/77
|
|
183
|
-
if (process.platform == "win32" && browser == "chromium")
|
|
183
|
+
if (process.platform == "win32" && browser == "chromium") {
|
|
184
184
|
await killDriverProcess("chrome");
|
|
185
|
-
|
|
185
|
+
}
|
|
186
|
+
else if (process.platform == "win32" && browser == "edge") {
|
|
187
|
+
await killDriverProcess("msedgedriver");
|
|
186
188
|
await killDriverProcess("msedge");
|
|
189
|
+
}
|
|
187
190
|
}
|
|
188
191
|
|
|
189
192
|
beforeEach(function() {
|
|
193
|
+
if (browser == "edge" && process.platform != "linux" &&
|
|
194
|
+
version == "114.0.1823.82")
|
|
195
|
+
this.skip();
|
|
196
|
+
|
|
190
197
|
if (failedInstall)
|
|
191
198
|
this.skip();
|
|
192
199
|
});
|
|
@@ -194,8 +201,8 @@ for (let browser of Object.keys(BROWSERS)) {
|
|
|
194
201
|
afterEach(quitDriver);
|
|
195
202
|
|
|
196
203
|
it("installs", async function() {
|
|
197
|
-
|
|
198
|
-
|
|
204
|
+
// installing browsers may take a while on the CI
|
|
205
|
+
this.timeout(150000);
|
|
199
206
|
|
|
200
207
|
let binary;
|
|
201
208
|
let versionNumber;
|
|
@@ -360,12 +367,8 @@ for (let browser of Object.keys(BROWSERS)) {
|
|
|
360
367
|
});
|
|
361
368
|
}
|
|
362
369
|
|
|
363
|
-
|
|
364
370
|
describe("Any version", async() => {
|
|
365
|
-
it("does not install unsupported versions", async
|
|
366
|
-
if (browser == "edge" && process.platform == "win32")
|
|
367
|
-
this.skip();
|
|
368
|
-
|
|
371
|
+
it("does not install unsupported versions", async() => {
|
|
369
372
|
for (let unsupported of ["0.0", "invalid"]) {
|
|
370
373
|
await expect(BROWSERS[browser].installBrowser(unsupported))
|
|
371
374
|
.rejects.toThrow(`Unsupported browser version: ${unsupported}`);
|