@eyeo/get-browser-binary 0.11.0 → 0.12.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/README.md +2 -1
- package/RELEASE_NOTES.md +17 -0
- package/package.json +1 -1
- package/src/browsers.js +156 -82
- package/test/browsers.js +25 -9
package/README.md
CHANGED
|
@@ -35,7 +35,8 @@ the right side.
|
|
|
35
35
|
- Edge >= 95
|
|
36
36
|
|
|
37
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.
|
|
38
|
+
because it is the default browser on that platform. On macOS, only the latest
|
|
39
|
+
Edge version is supported.
|
|
39
40
|
|
|
40
41
|
## Development
|
|
41
42
|
|
package/RELEASE_NOTES.md
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
# 0.12.0
|
|
2
|
+
|
|
3
|
+
- Adds a new field `customBrowserBinary` to `getDriver()` options parameter that
|
|
4
|
+
accepts the path of a custom (pre-installed) browser binary. When used, that is
|
|
5
|
+
the browser that will run (#56)
|
|
6
|
+
- Fixes Edge install URLs for mac. Unfortunately, the new URLs provided by Edge
|
|
7
|
+
offer a limited number of old versions only. For that reason `latest`
|
|
8
|
+
becomes the only accepted value for Edge on mac (!64). Please see #56 as a
|
|
9
|
+
possible workaround
|
|
10
|
+
- Fixes an issue with Chromium 115 that prevented loading extensions in
|
|
11
|
+
incognito mode (#52)
|
|
12
|
+
- Logs URL info on previously uncaught http errors (!67)
|
|
13
|
+
|
|
14
|
+
### Testing
|
|
15
|
+
|
|
16
|
+
- Fixes recent failures when running Edge tests (#48)
|
|
17
|
+
|
|
1
18
|
# 0.11.0
|
|
2
19
|
|
|
3
20
|
- Fixes an issue on arm64 edgedriver links that prevented the driver to run on
|
package/package.json
CHANGED
package/src/browsers.js
CHANGED
|
@@ -47,6 +47,7 @@ const DRIVER_START_ERROR = "Unable to start driver";
|
|
|
47
47
|
const EXTENSION_NOT_FOUND_ERROR = "Extension not found";
|
|
48
48
|
const BROWSER_DOWNLOAD_ERROR = "Browser download failed";
|
|
49
49
|
const BROWSER_NOT_INSTALLED_ERROR = "Browser is not installed";
|
|
50
|
+
const BROWSER_VERSION_CHECK_ERROR = "Checking the browser version failed";
|
|
50
51
|
const ELEMENT_NOT_FOUND_ERROR = "HTML element not found";
|
|
51
52
|
|
|
52
53
|
function getMajorVersion(versionNumber) {
|
|
@@ -104,16 +105,20 @@ class Browser {
|
|
|
104
105
|
*/
|
|
105
106
|
static async getInstalledVersion(binary) {
|
|
106
107
|
let stdout;
|
|
107
|
-
|
|
108
|
-
(
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
108
|
+
try {
|
|
109
|
+
if (platform == "win32") {
|
|
110
|
+
({stdout} = await promisify(exec)(
|
|
111
|
+
`(Get-ItemProperty ${binary}).VersionInfo.ProductVersion`,
|
|
112
|
+
{shell: "powershell.exe"})
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
({stdout} = await promisify(execFile)(binary, ["--version"]));
|
|
117
|
+
}
|
|
118
|
+
return stdout.trim();
|
|
115
119
|
}
|
|
116
|
-
|
|
120
|
+
catch (e) {}
|
|
121
|
+
return "";
|
|
117
122
|
}
|
|
118
123
|
|
|
119
124
|
/**
|
|
@@ -135,6 +140,9 @@ class Browser {
|
|
|
135
140
|
* certificates, or not.
|
|
136
141
|
* @property {Array.<string>} [extraArgs=[]] Additional arguments to start
|
|
137
142
|
* the browser with.
|
|
143
|
+
* @property {string} [customBrowserBinary] Path to the browser binary to be
|
|
144
|
+
* used, instead of the browser installed by installBrowser(). This option
|
|
145
|
+
* overrides the version parameter in getDriver().
|
|
138
146
|
*/
|
|
139
147
|
|
|
140
148
|
/**
|
|
@@ -177,6 +185,7 @@ class Browser {
|
|
|
177
185
|
*/
|
|
178
186
|
class Chromium extends Browser {
|
|
179
187
|
static #CHANNELS = ["latest", "beta", "dev"];
|
|
188
|
+
static #MAX_VERSION_DECREMENTS = 200;
|
|
180
189
|
|
|
181
190
|
static async #getVersionForChannel(channel) {
|
|
182
191
|
if (!Chromium.#CHANNELS.includes(channel))
|
|
@@ -192,7 +201,14 @@ class Chromium extends Browser {
|
|
|
192
201
|
"darwin-x64": "mac",
|
|
193
202
|
"darwin-arm64": "mac_arm64"
|
|
194
203
|
}[platformArch];
|
|
195
|
-
let
|
|
204
|
+
let url = `https://omahaproxy.appspot.com/all.json?os=${os}`;
|
|
205
|
+
let data;
|
|
206
|
+
try {
|
|
207
|
+
data = await got(url).json();
|
|
208
|
+
}
|
|
209
|
+
catch (err) {
|
|
210
|
+
throw new Error(`${BROWSER_VERSION_CHECK_ERROR}: ${url}\n${err}`);
|
|
211
|
+
}
|
|
196
212
|
let release = data[0].versions.find(ver => ver.channel == channel);
|
|
197
213
|
let {current_version: version} = release;
|
|
198
214
|
|
|
@@ -214,6 +230,27 @@ class Chromium extends Browser {
|
|
|
214
230
|
}[platform];
|
|
215
231
|
}
|
|
216
232
|
|
|
233
|
+
static async #getBase(chromiumVersion) {
|
|
234
|
+
let url = `https://omahaproxy.appspot.com/deps.json?version=${chromiumVersion}`;
|
|
235
|
+
let chromiumBase;
|
|
236
|
+
try {
|
|
237
|
+
({chromium_base_position: chromiumBase} = await got(url).json());
|
|
238
|
+
}
|
|
239
|
+
catch (err) {
|
|
240
|
+
throw new Error(`${BROWSER_VERSION_CHECK_ERROR}: ${url}\n${err}`);
|
|
241
|
+
}
|
|
242
|
+
return parseInt(chromiumBase, 10);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
static async #getInstalledBrowserInfo(binary) {
|
|
246
|
+
let installedVersion = await Chromium.getInstalledVersion(binary);
|
|
247
|
+
// Linux example: "Chromium 112.0.5615.49 built on Debian 11.6"
|
|
248
|
+
// Windows example: "114.0.5735.0"
|
|
249
|
+
let versionNumber = installedVersion.split(" ")[1] || installedVersion;
|
|
250
|
+
let base = await Chromium.#getBase(versionNumber);
|
|
251
|
+
return {binary, versionNumber, base};
|
|
252
|
+
}
|
|
253
|
+
|
|
217
254
|
/**
|
|
218
255
|
* Installs the browser. The Chromium executable gets extracted in the
|
|
219
256
|
* {@link snapshotsBaseDir} folder, ready to go.
|
|
@@ -227,32 +264,19 @@ class Chromium extends Browser {
|
|
|
227
264
|
*/
|
|
228
265
|
static async installBrowser(version = "latest", downloadTimeout = 0) {
|
|
229
266
|
const MIN_VERSION = 75;
|
|
230
|
-
const MAX_VERSION_DECREMENTS = 200;
|
|
231
267
|
|
|
232
268
|
let binary;
|
|
233
269
|
let versionNumber;
|
|
234
270
|
let base;
|
|
235
271
|
|
|
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
272
|
// https://gitlab.com/eyeo/developer-experience/get-browser-binary/-/issues/46
|
|
243
|
-
if (platformArch == "linux-arm64")
|
|
244
|
-
|
|
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
|
-
}
|
|
273
|
+
if (platformArch == "linux-arm64")
|
|
274
|
+
return await Chromium.#getInstalledBrowserInfo("/usr/bin/chromium");
|
|
251
275
|
|
|
252
276
|
checkVersion(version, MIN_VERSION, Chromium.#CHANNELS);
|
|
253
277
|
versionNumber = await Chromium.#getVersionForChannel(version);
|
|
254
278
|
|
|
255
|
-
base = await getBase(versionNumber);
|
|
279
|
+
base = await Chromium.#getBase(versionNumber);
|
|
256
280
|
let startBase = base;
|
|
257
281
|
let [platformDir, fileName] = {
|
|
258
282
|
"win32-ia32": ["Win", "chrome-win.zip"],
|
|
@@ -293,7 +317,7 @@ class Chromium extends Browser {
|
|
|
293
317
|
// Chromium advises decrementing the branch_base_position when no
|
|
294
318
|
// matching build was found. See https://www.chromium.org/getting-involved/download-chromium
|
|
295
319
|
base--;
|
|
296
|
-
if (base <= startBase - MAX_VERSION_DECREMENTS)
|
|
320
|
+
if (base <= startBase - Chromium.#MAX_VERSION_DECREMENTS)
|
|
297
321
|
throw new Error(`${BROWSER_DOWNLOAD_ERROR}: Chromium base ${startBase}`);
|
|
298
322
|
}
|
|
299
323
|
else {
|
|
@@ -306,7 +330,7 @@ class Chromium extends Browser {
|
|
|
306
330
|
return {binary, versionNumber, base};
|
|
307
331
|
}
|
|
308
332
|
|
|
309
|
-
static async #installDriver(
|
|
333
|
+
static async #installDriver(startBase) {
|
|
310
334
|
let [dir, zip, driverBinary] = {
|
|
311
335
|
"win32-ia32": ["Win", "chromedriver_win32.zip", "chromedriver.exe"],
|
|
312
336
|
"win32-x64": ["Win_x64", "chromedriver_win32.zip", "chromedriver.exe"],
|
|
@@ -317,27 +341,46 @@ class Chromium extends Browser {
|
|
|
317
341
|
}[platformArch];
|
|
318
342
|
|
|
319
343
|
let cacheDir = path.join(snapshotsBaseDir, "chromium", "cache",
|
|
320
|
-
|
|
321
|
-
let archive = path.join(cacheDir, `${
|
|
322
|
-
|
|
344
|
+
"chromedriver");
|
|
345
|
+
let archive = path.join(cacheDir, `${startBase}-${zip}`);
|
|
323
346
|
try {
|
|
324
347
|
await fs.promises.access(archive);
|
|
325
348
|
await extractZip(archive, {dir: cacheDir});
|
|
326
349
|
}
|
|
327
350
|
catch (e) { // zip file is either not cached or corrupted
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
351
|
+
if (platformArch == "linux-arm64") {
|
|
352
|
+
// https://gitlab.com/eyeo/developer-experience/get-browser-binary/-/issues/46
|
|
353
|
+
// It's unclear how electron releases match Chromium versions. Once that
|
|
354
|
+
// is figured out, the link below will depend on the Chromium version.
|
|
355
|
+
// https://stackoverflow.com/questions/38732822/compile-chromedriver-on-arm
|
|
356
|
+
let url = "https://github.com/electron/electron/releases/download/v24.1.2/chromedriver-v24.1.2-linux-arm64.zip";
|
|
357
|
+
try {
|
|
358
|
+
await download(url, archive);
|
|
359
|
+
}
|
|
360
|
+
catch (err) {
|
|
361
|
+
throw new Error(`${DRIVER_DOWNLOAD_ERROR}: ${url}\n${err}`);
|
|
362
|
+
}
|
|
338
363
|
}
|
|
339
|
-
|
|
340
|
-
|
|
364
|
+
else {
|
|
365
|
+
let base = startBase;
|
|
366
|
+
while (true) {
|
|
367
|
+
let url = `https://commondatastorage.googleapis.com/chromium-browser-snapshots/${dir}/${base}/${zip}`;
|
|
368
|
+
try {
|
|
369
|
+
await download(url, archive);
|
|
370
|
+
break;
|
|
371
|
+
}
|
|
372
|
+
catch (err) {
|
|
373
|
+
if (err.name == "HTTPError") {
|
|
374
|
+
base--;
|
|
375
|
+
archive = path.join(cacheDir, `${base}-${zip}`);
|
|
376
|
+
if (base <= startBase - Chromium.#MAX_VERSION_DECREMENTS)
|
|
377
|
+
throw new Error(`${DRIVER_DOWNLOAD_ERROR}: Chromium base ${startBase}`);
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
throw new Error(`${DRIVER_DOWNLOAD_ERROR}: ${url}\n${err}`);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
341
384
|
}
|
|
342
385
|
await extractZip(archive, {dir: cacheDir});
|
|
343
386
|
}
|
|
@@ -355,11 +398,12 @@ class Chromium extends Browser {
|
|
|
355
398
|
/** @see Browser.getDriver */
|
|
356
399
|
static async getDriver(version = "latest", {
|
|
357
400
|
headless = true, extensionPaths = [], incognito = false, insecure = false,
|
|
358
|
-
extraArgs = []
|
|
401
|
+
extraArgs = [], customBrowserBinary
|
|
359
402
|
} = {}, downloadTimeout = 0) {
|
|
360
|
-
let {binary, versionNumber, base} =
|
|
403
|
+
let {binary, versionNumber, base} = customBrowserBinary ?
|
|
404
|
+
await Chromium.#getInstalledBrowserInfo(customBrowserBinary) :
|
|
361
405
|
await Chromium.installBrowser(version, downloadTimeout);
|
|
362
|
-
let driverPath = await Chromium.#installDriver(base
|
|
406
|
+
let driverPath = await Chromium.#installDriver(base);
|
|
363
407
|
let serviceBuilder = new chrome.ServiceBuilder(driverPath);
|
|
364
408
|
let options = new chrome.Options().addArguments("no-sandbox", ...extraArgs);
|
|
365
409
|
if (extensionPaths.length > 0)
|
|
@@ -388,6 +432,15 @@ class Chromium extends Browser {
|
|
|
388
432
|
|
|
389
433
|
/** @see Browser.enableExtensionInIncognito */
|
|
390
434
|
static async enableExtensionInIncognito(driver, extensionTitle) {
|
|
435
|
+
let handle = await driver.getWindowHandle();
|
|
436
|
+
|
|
437
|
+
let version = getMajorVersion(
|
|
438
|
+
(await driver.getCapabilities()).getBrowserVersion());
|
|
439
|
+
if (version >= 115)
|
|
440
|
+
// On Chromium 115 opening chrome://extensions on the default tab causes
|
|
441
|
+
// WebDriverError: disconnected. Switching to a new window as a workaround
|
|
442
|
+
await driver.switchTo().newWindow("window");
|
|
443
|
+
|
|
391
444
|
await driver.navigate().to("chrome://extensions");
|
|
392
445
|
await driver.executeScript((...args) => {
|
|
393
446
|
let enable = () => document.querySelector("extensions-manager").shadowRoot
|
|
@@ -415,6 +468,11 @@ class Chromium extends Browser {
|
|
|
415
468
|
setTimeout(() => resolve(enable()), 100);
|
|
416
469
|
});
|
|
417
470
|
}, extensionTitle, EXTENSION_NOT_FOUND_ERROR);
|
|
471
|
+
if (version >= 115)
|
|
472
|
+
// Closing the previously opened new window
|
|
473
|
+
await driver.close();
|
|
474
|
+
|
|
475
|
+
await driver.switchTo().window(handle);
|
|
418
476
|
}
|
|
419
477
|
}
|
|
420
478
|
|
|
@@ -430,7 +488,14 @@ class Firefox extends Browser {
|
|
|
430
488
|
if (!Firefox.#CHANNELS.includes(channel))
|
|
431
489
|
return channel;
|
|
432
490
|
|
|
433
|
-
let
|
|
491
|
+
let url = "https://product-details.mozilla.org/1.0/firefox_versions.json";
|
|
492
|
+
let data;
|
|
493
|
+
try {
|
|
494
|
+
data = await got(url).json();
|
|
495
|
+
}
|
|
496
|
+
catch (err) {
|
|
497
|
+
throw new Error(`${BROWSER_VERSION_CHECK_ERROR}: ${url}\n${err}`);
|
|
498
|
+
}
|
|
434
499
|
return channel == "beta" ?
|
|
435
500
|
data.LATEST_FIREFOX_DEVEL_VERSION : data.LATEST_FIREFOX_VERSION;
|
|
436
501
|
}
|
|
@@ -514,9 +579,11 @@ class Firefox extends Browser {
|
|
|
514
579
|
/** @see Browser.getDriver */
|
|
515
580
|
static async getDriver(version = "latest", {
|
|
516
581
|
headless = true, extensionPaths = [], incognito = false, insecure = false,
|
|
517
|
-
extraArgs = []
|
|
582
|
+
extraArgs = [], customBrowserBinary
|
|
518
583
|
} = {}, downloadTimeout = 0) {
|
|
519
|
-
let
|
|
584
|
+
let binary;
|
|
585
|
+
if (!customBrowserBinary)
|
|
586
|
+
({binary} = await Firefox.installBrowser(version, downloadTimeout));
|
|
520
587
|
|
|
521
588
|
let options = new firefox.Options();
|
|
522
589
|
if (headless)
|
|
@@ -527,7 +594,7 @@ class Firefox extends Browser {
|
|
|
527
594
|
options.set("acceptInsecureCerts", true);
|
|
528
595
|
if (extraArgs.length > 0)
|
|
529
596
|
options.addArguments(...extraArgs);
|
|
530
|
-
options.setBinary(binary);
|
|
597
|
+
options.setBinary(customBrowserBinary || binary);
|
|
531
598
|
|
|
532
599
|
let driver;
|
|
533
600
|
// The OS may be low on resources, that's why building the driver is retried
|
|
@@ -588,7 +655,14 @@ class Edge extends Browser {
|
|
|
588
655
|
if (Edge.#CHANNELS.includes(version) && version != "latest")
|
|
589
656
|
channel = version;
|
|
590
657
|
|
|
591
|
-
let
|
|
658
|
+
let url = `https://packages.microsoft.com/repos/edge/pool/main/m/microsoft-edge-${channel}/`;
|
|
659
|
+
let body;
|
|
660
|
+
try {
|
|
661
|
+
({body} = await got(url));
|
|
662
|
+
}
|
|
663
|
+
catch (err) {
|
|
664
|
+
throw new Error(`${BROWSER_VERSION_CHECK_ERROR}: ${url}\n${err}`);
|
|
665
|
+
}
|
|
592
666
|
let versionNumber;
|
|
593
667
|
if (Edge.#CHANNELS.includes(version)) {
|
|
594
668
|
let regex = /href="microsoft-edge-(stable|beta|dev)_(.*?)-1_/gm;
|
|
@@ -618,11 +692,7 @@ class Edge extends Browser {
|
|
|
618
692
|
return {versionNumber, channel};
|
|
619
693
|
}
|
|
620
694
|
|
|
621
|
-
static #
|
|
622
|
-
let extra = channel == "stable" ?
|
|
623
|
-
"" : " " + channel.charAt(0).toUpperCase() + channel.slice(1);
|
|
624
|
-
return `Microsoft Edge${extra}`;
|
|
625
|
-
}
|
|
695
|
+
static #darwinApp = "Microsoft Edge";
|
|
626
696
|
|
|
627
697
|
static #getBinaryPath(channel = "stable") {
|
|
628
698
|
switch (platform) {
|
|
@@ -634,8 +704,7 @@ class Edge extends Browser {
|
|
|
634
704
|
return channel == "stable" ?
|
|
635
705
|
"microsoft-edge" : `microsoft-edge-${channel}`;
|
|
636
706
|
case "darwin":
|
|
637
|
-
|
|
638
|
-
return `${process.env.HOME}/Applications/${appName}.app/Contents/MacOS/${appName}`;
|
|
707
|
+
return `${process.env.HOME}/Applications/${Edge.#darwinApp}.app/Contents/MacOS/${Edge.#darwinApp}`;
|
|
639
708
|
default:
|
|
640
709
|
checkPlatform();
|
|
641
710
|
}
|
|
@@ -659,25 +728,17 @@ class Edge extends Browser {
|
|
|
659
728
|
// https://support.microsoft.com/en-us/microsoft-edge/why-can-t-i-uninstall-microsoft-edge-ee150b3b-7d7a-9984-6d83-eb36683d526d
|
|
660
729
|
throw new Error(`${UNSUPPORTED_PLATFORM_ERROR}: ${platform}`);
|
|
661
730
|
|
|
731
|
+
if (platform == "darwin" && version != "latest")
|
|
732
|
+
// Only latest Edge is supported on macOS
|
|
733
|
+
throw new Error(`${UNSUPPORTED_VERSION_ERROR}: ${version}. Only "latest" is supported`);
|
|
734
|
+
|
|
662
735
|
const MIN_VERSION = 95;
|
|
663
736
|
checkVersion(version, MIN_VERSION, Edge.#CHANNELS);
|
|
664
737
|
let {versionNumber, channel} = await Edge.#getVersionForChannel(version);
|
|
665
738
|
|
|
666
|
-
let darwinName = {
|
|
667
|
-
stable: "MicrosoftEdge",
|
|
668
|
-
beta: "MicrosoftEdgeBeta",
|
|
669
|
-
dev: "MicrosoftEdgeDev"
|
|
670
|
-
}[channel];
|
|
671
739
|
let filename = {
|
|
672
740
|
linux: `microsoft-edge-${channel}_${versionNumber}-1_amd64.deb`,
|
|
673
|
-
darwin:
|
|
674
|
-
}[platform];
|
|
675
|
-
let darwinArch = process.arch == "arm64" ?
|
|
676
|
-
"03adf619-38c6-4249-95ff-4a01c0ffc962" :
|
|
677
|
-
"C1297A47-86C4-4C1F-97FA-950631F94777";
|
|
678
|
-
let url = {
|
|
679
|
-
linux: `https://packages.microsoft.com/repos/edge/pool/main/m/microsoft-edge-${channel}/${filename}`,
|
|
680
|
-
darwin: `https://officecdnmac.microsoft.com/pr/${darwinArch}/MacAutoupdate/${filename}`
|
|
741
|
+
darwin: `MicrosoftEdge-${versionNumber}.pkg`
|
|
681
742
|
}[platform];
|
|
682
743
|
|
|
683
744
|
let snapshotsDir = path.join(snapshotsBaseDir, "edge");
|
|
@@ -689,7 +750,20 @@ class Edge extends Browser {
|
|
|
689
750
|
}
|
|
690
751
|
catch (e) {}
|
|
691
752
|
|
|
753
|
+
let url = `https://packages.microsoft.com/repos/edge/pool/main/m/microsoft-edge-${channel}/${filename}`;
|
|
692
754
|
try {
|
|
755
|
+
if (platform == "darwin") {
|
|
756
|
+
let caskUrl = "https://formulae.brew.sh/api/cask/microsoft-edge.json";
|
|
757
|
+
let caskJson;
|
|
758
|
+
try {
|
|
759
|
+
caskJson = await got(caskUrl).json();
|
|
760
|
+
}
|
|
761
|
+
catch (err) {
|
|
762
|
+
throw new Error(`${BROWSER_VERSION_CHECK_ERROR}: ${caskUrl}\n${err}`);
|
|
763
|
+
}
|
|
764
|
+
({url} = process.arch == "arm64" ?
|
|
765
|
+
caskJson.variations.arm64_ventura : caskJson);
|
|
766
|
+
}
|
|
693
767
|
await download(url, archive, downloadTimeout);
|
|
694
768
|
}
|
|
695
769
|
catch (err) {
|
|
@@ -700,8 +774,7 @@ class Edge extends Browser {
|
|
|
700
774
|
await promisify(exec)(`dpkg -i ${archive}`);
|
|
701
775
|
}
|
|
702
776
|
else if (platform == "darwin") {
|
|
703
|
-
|
|
704
|
-
await fs.promises.rm(`${process.env.HOME}/Applications/${appName}.app`, {force: true, recursive: true});
|
|
777
|
+
await fs.promises.rm(`${process.env.HOME}/Applications/${Edge.#darwinApp}.app`, {force: true, recursive: true});
|
|
705
778
|
await promisify(exec)(`installer -pkg ${archive} -target CurrentUserHomeDirectory`);
|
|
706
779
|
}
|
|
707
780
|
|
|
@@ -715,17 +788,17 @@ class Edge extends Browser {
|
|
|
715
788
|
return installedVersion.trim().replace(/.*\s/, "");
|
|
716
789
|
}
|
|
717
790
|
|
|
718
|
-
static async #installDriver() {
|
|
791
|
+
static async #installDriver(binary) {
|
|
719
792
|
async function extractEdgeZip(archive, cacheDir, driverPath) {
|
|
720
793
|
await killDriverProcess("msedgedriver");
|
|
721
794
|
await fs.promises.rm(driverPath, {force: true});
|
|
722
795
|
await extractZip(archive, {dir: cacheDir});
|
|
723
796
|
}
|
|
724
797
|
|
|
725
|
-
let
|
|
726
|
-
let versionNumber = await Edge.#getInstalledVersionNumber(
|
|
798
|
+
let binaryPath = binary || Edge.#getBinaryPath();
|
|
799
|
+
let versionNumber = await Edge.#getInstalledVersionNumber(binaryPath);
|
|
727
800
|
if (!versionNumber)
|
|
728
|
-
throw new Error(`${BROWSER_NOT_INSTALLED_ERROR}:
|
|
801
|
+
throw new Error(`${BROWSER_NOT_INSTALLED_ERROR}. Binary path: ${binaryPath}`);
|
|
729
802
|
|
|
730
803
|
let [zip, driverBinary] = {
|
|
731
804
|
"win32-ia32": ["edgedriver_win32.zip", "msedgedriver.exe"],
|
|
@@ -768,12 +841,13 @@ class Edge extends Browser {
|
|
|
768
841
|
/** @see Browser.getDriver */
|
|
769
842
|
static async getDriver(version = "latest", {
|
|
770
843
|
headless = true, extensionPaths = [], incognito = false, insecure = false,
|
|
771
|
-
extraArgs = []
|
|
844
|
+
extraArgs = [], customBrowserBinary
|
|
772
845
|
} = {}, downloadTimeout = 0) {
|
|
773
|
-
|
|
774
|
-
|
|
846
|
+
let binary;
|
|
847
|
+
if (!customBrowserBinary && (platform == "linux" || platform == "darwin"))
|
|
848
|
+
({binary} = await Edge.installBrowser(version, downloadTimeout));
|
|
775
849
|
|
|
776
|
-
let driverPath = await Edge.#installDriver();
|
|
850
|
+
let driverPath = await Edge.#installDriver(customBrowserBinary || binary);
|
|
777
851
|
let serviceBuilder = new edge.ServiceBuilder(driverPath);
|
|
778
852
|
|
|
779
853
|
let options = new edge.Options().addArguments("no-sandbox", ...extraArgs);
|
|
@@ -782,7 +856,7 @@ class Edge extends Browser {
|
|
|
782
856
|
if (extensionPaths.length > 0)
|
|
783
857
|
options.addArguments(`load-extension=${extensionPaths.join(",")}`);
|
|
784
858
|
if (incognito)
|
|
785
|
-
options.addArguments("
|
|
859
|
+
options.addArguments("inprivate");
|
|
786
860
|
if (insecure)
|
|
787
861
|
options.addArguments("ignore-certificate-errors");
|
|
788
862
|
|
package/test/browsers.js
CHANGED
|
@@ -28,7 +28,7 @@ import "geckodriver"; // Required to set the driver path on Windows
|
|
|
28
28
|
const VERSIONS = {
|
|
29
29
|
chromium: ["latest", "75.0.3770.0", "beta", "dev"],
|
|
30
30
|
firefox: ["latest", "60.0", "beta"],
|
|
31
|
-
edge: ["
|
|
31
|
+
edge: ["dev", "latest", "beta", "95.0.1020.40"]
|
|
32
32
|
};
|
|
33
33
|
const TEST_URL = "https://abptestpages.org/en/exceptions/iframe_subdomains";
|
|
34
34
|
const TEST_URL_LONG_PAGE = "https://abptestpages.org/";
|
|
@@ -121,9 +121,10 @@ async function getCachedTimes(browser) {
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
let driverCacheTime = null;
|
|
124
|
-
//
|
|
124
|
+
// geckodriver is installed by npm, that's why Firefox is not tested here
|
|
125
125
|
if (browser != "firefox" && !armLinuxChromium) {
|
|
126
|
-
let driverDir = cacheFiles.find(
|
|
126
|
+
let driverDir = cacheFiles.find(
|
|
127
|
+
elem => !elem.endsWith(".zip") && !elem.endsWith(".pkg"));
|
|
127
128
|
let driverFiles = await fs.promises.readdir(path.join(cacheDir, driverDir));
|
|
128
129
|
let driverZip = driverFiles.find(elem => elem.endsWith(".zip"));
|
|
129
130
|
let driverStat =
|
|
@@ -147,6 +148,7 @@ for (let browser of Object.keys(BROWSERS)) {
|
|
|
147
148
|
describe(`Version: ${version}`, () => {
|
|
148
149
|
let driver = null;
|
|
149
150
|
let emptyCacheTimes = null;
|
|
151
|
+
let customBrowserBinary = null;
|
|
150
152
|
|
|
151
153
|
async function quitDriver() {
|
|
152
154
|
if (!driver)
|
|
@@ -168,7 +170,7 @@ for (let browser of Object.keys(BROWSERS)) {
|
|
|
168
170
|
this.skip();
|
|
169
171
|
|
|
170
172
|
let {binary, versionNumber} =
|
|
171
|
-
await BROWSERS[browser].installBrowser(version,
|
|
173
|
+
await BROWSERS[browser].installBrowser(version, this.timeout());
|
|
172
174
|
let browserName = browser == "edge" ? /(edge|Edge)/ : browser;
|
|
173
175
|
expect(binary).toEqual(expect.stringMatching(browserName));
|
|
174
176
|
|
|
@@ -179,6 +181,7 @@ for (let browser of Object.keys(BROWSERS)) {
|
|
|
179
181
|
|
|
180
182
|
// Adding the version number to the test title for logging purposes
|
|
181
183
|
this.test.title = `${this.test.title} [v${versionNumber}]`;
|
|
184
|
+
customBrowserBinary = binary;
|
|
182
185
|
});
|
|
183
186
|
|
|
184
187
|
it("runs", async() => {
|
|
@@ -212,13 +215,26 @@ for (let browser of Object.keys(BROWSERS)) {
|
|
|
212
215
|
expect(existingCacheTimes).toEqual(emptyCacheTimes);
|
|
213
216
|
});
|
|
214
217
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
if (browser == "edge" && version == "latest" &&
|
|
219
|
-
process.platform == "linux")
|
|
218
|
+
// This test depends on running the "installs" test
|
|
219
|
+
it("runs a custom browser binary", async function() {
|
|
220
|
+
if (!customBrowserBinary)
|
|
220
221
|
this.skip();
|
|
221
222
|
|
|
223
|
+
let names = {
|
|
224
|
+
chromium: "chrome",
|
|
225
|
+
firefox: "firefox",
|
|
226
|
+
edge: /(MicrosoftEdge|msedge)/
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
driver =
|
|
230
|
+
await BROWSERS[browser].getDriver(version, {customBrowserBinary});
|
|
231
|
+
await driver.navigate().to(TEST_URL);
|
|
232
|
+
|
|
233
|
+
expect((await driver.getCapabilities()).getBrowserName())
|
|
234
|
+
.toEqual(expect.stringMatching(names[browser]));
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
it("supports extra args", async() => {
|
|
222
238
|
let headless = false;
|
|
223
239
|
let extraArgs = browser == "firefox" ?
|
|
224
240
|
["--devtools"] : ["auto-open-devtools-for-tabs"];
|