@eyeo/get-browser-binary 0.2.0 → 0.3.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 CHANGED
@@ -19,7 +19,15 @@ cache:
19
19
  paths:
20
20
  - node_modules/
21
21
 
22
- test:linux:
22
+ test:basic:
23
+ stage: test
24
+ before_script:
25
+ - npm install
26
+ script:
27
+ - npm run lint
28
+ - npm test -- --grep "Utils"
29
+
30
+ test:browsers:linux:
23
31
  stage: test
24
32
  before_script:
25
33
  - apt-get update && apt-get install -y procps
@@ -32,13 +40,9 @@ test:linux:
32
40
  - rm microsoft.*
33
41
  - apt-get update && apt-get install -y microsoft-edge-stable
34
42
  script:
35
- - npm run lint
36
- - xvfb-run -a npm test -- -g "chromium (latest|beta)"
37
- - xvfb-run -a npm test -- -g "chromium dev"
38
- - xvfb-run -a npm test -- -g "chromium 77"
39
- - xvfb-run -a npm test -- -g "(edge|firefox)"
43
+ - xvfb-run -a npm test -- --grep "Browser"
40
44
 
41
- test:windows:
45
+ test:browsers:windows:
42
46
  stage: test
43
47
  variables:
44
48
  CI_PROJECT_ID_MAINSTREAM: 36688302
@@ -52,11 +56,8 @@ test:windows:
52
56
  - choco upgrade -y nodejs --version 16.10.0
53
57
  - npm install
54
58
  script:
55
- - npm test -- -g "chromium latest"
56
- - npm test -- -g "chromium beta"
57
- - npm test -- -g "chromium dev"
58
- - npm test -- -g "chromium 77"
59
- - npm test -- -g "edge"
59
+ - npm test -- --grep "chromium"
60
+ - npm test -- --grep "edge"
60
61
  tags:
61
62
  - shared-windows
62
63
  - windows
package/README.md CHANGED
@@ -25,10 +25,9 @@ import {BROWSERS} from "@eyeo/get-browser-binary";
25
25
  await driver.navigate().to("https://example.com/");
26
26
  await driver.quit();
27
27
  })();
28
-
29
28
  ```
30
29
 
31
- [test/runner.js](https://gitlab.com/eyeo/developer-experience/get-browser-binary/-/blob/main/test/runner.js)
30
+ [test/browsers.js](https://gitlab.com/eyeo/developer-experience/get-browser-binary/-/blob/main/test/browsers.js)
32
31
  provides other usage examples of the library.
33
32
 
34
33
  For more information, please refer to the [API documention](https://gitlab.com/eyeo/developer-experience/get-browser-binary/-/jobs/artifacts/main/file/docs/index.html?job=docs).
@@ -48,15 +47,30 @@ the right side.
48
47
  npm install
49
48
  ```
50
49
 
50
+ ### Folders to ignore / cache
51
+
52
+ All browser and webdriver files will be downloaded to the `./browser-snapshots`
53
+ folder, which probably makes sense to be ignored (for instance, by adding it to
54
+ `.gitignore`).
55
+
56
+ On the other hand, `./browser-snapshots/<browser_name>/cache` will hold all the
57
+ downloaded installation files required by `<browser_name>`. Therefore, it may be
58
+ useful to add `./browser-snapshots/*/cache` to the list of cached folders in
59
+ your CI pipeline configuration.
60
+
51
61
  ## Testing
52
62
 
53
- The `grep` option filters the tests to run with a regular expression. Example:
63
+ Running all tests:
54
64
 
55
65
  ```shell
56
- npm test -- -g "chromium latest"
66
+ npm test
57
67
  ```
58
68
 
59
- Note: Running all Chromium tests at once is currently not working.
69
+ The `grep` option filters the tests to run with a regular expression. Example:
70
+
71
+ ```shell
72
+ npm test -- --grep "chromium latest"
73
+ ```
60
74
 
61
75
  ## Building the documentation
62
76
 
package/RELEASE_NOTES.md CHANGED
@@ -1,3 +1,11 @@
1
+ # 0.3.0
2
+
3
+ - Adds incognito mode support to all browsers (#5)
4
+ - Exports the utils download function (#12)
5
+ - Adds the details of the directories to ignore / cache to the README (#13)
6
+ - Fixes Chromium tests execution on all platforms (#3)
7
+ - Updates the geckodriver package (#14)
8
+
1
9
  # 0.2.0
2
10
 
3
11
  Change `Browser.getDriver` signature to use `driverOptions` parameter.
package/index.js CHANGED
@@ -16,3 +16,4 @@
16
16
  */
17
17
 
18
18
  export * from "./src/browsers.js";
19
+ export {download} from "./src/utils.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eyeo/get-browser-binary",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Download browser binaries and matching webdrivers",
5
5
  "repository": {
6
6
  "type": "git",
@@ -19,7 +19,7 @@
19
19
  "dmg": "^0.1.0",
20
20
  "extract-zip": "^2.0.1",
21
21
  "fs-extra": "^10.0.0",
22
- "geckodriver": "^2.0.4",
22
+ "geckodriver": "^3.0.2",
23
23
  "got": "^11.8.2",
24
24
  "msedgedriver": "^91.0.0",
25
25
  "selenium-webdriver": "^4.2.0"
@@ -32,8 +32,8 @@
32
32
  "mocha": "^10.0.0"
33
33
  },
34
34
  "scripts": {
35
- "docs": "jsdoc --readme README.md --destination docs src/browsers.js",
35
+ "docs": "jsdoc --readme README.md --destination docs src/*.js",
36
36
  "lint": "eslint --ext js .",
37
- "test": "mocha test/runner.js --"
37
+ "test": "mocha test/*.js --"
38
38
  }
39
39
  }
package/src/browsers.js CHANGED
@@ -27,8 +27,8 @@ import firefox from "selenium-webdriver/firefox.js";
27
27
  import command from "selenium-webdriver/lib/command.js";
28
28
  import extractZip from "extract-zip";
29
29
 
30
- import {download, extractTar, extractDmg, runWinInstaller, getBrowserVersion}
31
- from "./utils.js";
30
+ import {download, extractTar, extractDmg, runWinInstaller, getBrowserVersion,
31
+ killDriverProcess} from "./utils.js";
32
32
 
33
33
  /**
34
34
  * Root folder where browser and webdriver binaries get downloaded.
@@ -37,9 +37,9 @@ import {download, extractTar, extractDmg, runWinInstaller, getBrowserVersion}
37
37
  export let snapshotsBaseDir = path.join(process.cwd(), "browser-snapshots");
38
38
 
39
39
  let {until, By} = webdriver;
40
- const ERROR_INCOGNITO_NOT_SUPPORTED = "Incognito mode is not supported";
41
40
  const ERROR_DOWNLOAD_NOT_SUPPORTED =
42
41
  "Downloading this browser is not supported";
42
+ let platform = `${process.platform}-${process.arch}`;
43
43
 
44
44
  /**
45
45
  * Base class for browser download functionality. Please see subclasses for
@@ -89,6 +89,7 @@ class Browser {
89
89
  * no effect.
90
90
  * @param {driverOptions?} options - Options to start the browser with.
91
91
  * @return {webdriver}
92
+ * @throws {Error} Unsupported webdriver version.
92
93
  */
93
94
  static async getDriver(version, options = {}) {
94
95
  // to be implemented by the subclass
@@ -102,7 +103,10 @@ class Browser {
102
103
  * @return {webdriver}
103
104
  */
104
105
  static async enableExtensionInIncognito(driver, extensionTitle) {
105
- throw new Error(ERROR_INCOGNITO_NOT_SUPPORTED);
106
+ // Allowing the extension in incognito mode can't happen programmatically:
107
+ // https://stackoverflow.com/questions/57419654
108
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=1729315
109
+ // That is done through the UI, to be implemented by the subclass
106
110
  }
107
111
  }
108
112
 
@@ -159,17 +163,13 @@ class Chromium extends Browser {
159
163
 
160
164
  let revision = parseInt(chromiumRevision, 10);
161
165
  let startingRevision = revision;
162
- let platform = `${process.platform}-${process.arch}`;
163
-
164
- let buildTypes = {
166
+ let [platformDir, fileName] = {
165
167
  "win32-ia32": ["Win", "chrome-win.zip"],
166
168
  "win32-x64": ["Win_x64", "chrome-win.zip"],
167
169
  "linux-x64": ["Linux_x64", "chrome-linux.zip"],
168
170
  "darwin-x64": ["Mac", "chrome-mac.zip"],
169
171
  "dawrin-arm64": ["Mac_Arm", "chrome-mac.zip"]
170
- };
171
-
172
- let [platformDir, fileName] = buildTypes[platform];
172
+ }[platform];
173
173
  let archive = null;
174
174
  let browserDir = null;
175
175
  let snapshotsDir = path.join(snapshotsBaseDir, "chromium");
@@ -229,15 +229,13 @@ class Chromium extends Browser {
229
229
  }
230
230
 
231
231
  static async #installDriver(revision, version) {
232
- let platform = `${process.platform}-${process.arch}`;
233
- let buildTypes = {
232
+ let [dir, zip, driver] = {
234
233
  "win32-ia32": ["Win", "chromedriver_win32.zip", "chromedriver.exe"],
235
234
  "win32-x64": ["Win_x64", "chromedriver_win32.zip", "chromedriver.exe"],
236
235
  "linux-x64": ["Linux_x64", "chromedriver_linux64.zip", "chromedriver"],
237
236
  "darwin-x64": ["Mac", "chromedriver_mac64.zip", "chromedriver"],
238
237
  "darwin-arm64": ["Mac_Arm", "chromedriver_mac64.zip", "chromedriver"]
239
- };
240
- let [dir, zip, driver] = buildTypes[platform];
238
+ }[platform];
241
239
 
242
240
  let cacheDir = path.join(snapshotsBaseDir, "chromium", "cache", version);
243
241
  let destinationDir = path.join(process.cwd(), "node_modules",
@@ -247,25 +245,17 @@ class Chromium extends Browser {
247
245
  await download(`https://commondatastorage.googleapis.com/chromium-browser-snapshots/${dir}/${revision}/${zip}`,
248
246
  archive);
249
247
  await extractZip(archive, {dir: cacheDir});
248
+ // avoid driver copy failing if the file would be locked
249
+ await killDriverProcess(Chromium.#DRIVER);
250
250
  await fs.promises.mkdir(destinationDir, {recursive: true});
251
- try {
252
- await fs.promises.copyFile(path.join(cacheDir, zip.split(".")[0], driver),
253
- path.join(destinationDir, driver));
254
- }
255
- catch (err) {
256
- // https://gitlab.com/eyeo/developer-experience/get-browser-binary/-/issues/3
257
- if (!err.toString().includes("copyfile"))
258
- throw err;
259
- }
251
+ await fs.promises.copyFile(path.join(cacheDir, zip.split(".")[0], driver),
252
+ path.join(destinationDir, driver));
260
253
  }
261
254
 
262
255
  /** @see Browser.getDriver */
263
256
  static async getDriver(version, {headless = true, extensionPaths = [],
264
257
  incognito = false, insecure = false,
265
258
  extraArgs = []} = {}) {
266
- if (incognito)
267
- throw new Error(ERROR_INCOGNITO_NOT_SUPPORTED);
268
-
269
259
  let {binary, revision, downloadedVersion} =
270
260
  await Chromium.downloadBinary(version);
271
261
  await Chromium.#installDriver(revision, downloadedVersion);
@@ -277,6 +267,8 @@ class Chromium extends Browser {
277
267
  options.headless();
278
268
  if (insecure)
279
269
  options.addArguments("ignore-certificate-errors");
270
+ if (incognito)
271
+ options.addArguments("incognito");
280
272
  options.setChromeBinaryPath(binary);
281
273
 
282
274
  let builder = new webdriver.Builder();
@@ -285,6 +277,41 @@ class Chromium extends Browser {
285
277
 
286
278
  return builder.build();
287
279
  }
280
+
281
+ /** @see Browser.enableExtensionInIncognito */
282
+ static async enableExtensionInIncognito(driver, extensionTitle) {
283
+ let version = await getBrowserVersion(driver);
284
+ if (version < 75)
285
+ // The UI workaround needs a chromedriver >= 75
286
+ throw new Error(`Only supported on Chromium >= 75. Current version: ${version}`);
287
+
288
+ await driver.navigate().to("chrome://extensions");
289
+ await driver.executeScript(`
290
+ let enable = () => document.querySelector("extensions-manager").shadowRoot
291
+ .querySelector("extensions-detail-view").shadowRoot
292
+ .getElementById("allow-incognito").shadowRoot
293
+ .getElementById("crToggle").click();
294
+
295
+ let extensions = document.querySelector("extensions-manager").shadowRoot
296
+ .getElementById("items-list").shadowRoot
297
+ .querySelectorAll("extensions-item");
298
+
299
+ return new Promise((resolve, reject) => {
300
+ let extensionDetails;
301
+ for (let {shadowRoot} of extensions) {
302
+ if (shadowRoot.getElementById("name").innerHTML != arguments[0])
303
+ continue;
304
+
305
+ extensionDetails = shadowRoot.getElementById("detailsButton");
306
+ }
307
+
308
+ if (!extensionDetails)
309
+ reject("Extension was not found");
310
+
311
+ extensionDetails.click();
312
+ setTimeout(() => resolve(enable()), 100);
313
+ });`, extensionTitle);
314
+ }
288
315
  }
289
316
 
290
317
  /**
@@ -326,18 +353,18 @@ class Firefox {
326
353
  }
327
354
 
328
355
  static async #downloadFirefox(version) {
329
- let {platform} = process;
330
- if (platform == "win32")
331
- platform += "-" + process.arch;
332
- let buildTypes = {
356
+ let [buildPlatform, fileName] = {
333
357
  "win32-ia32": ["win32", `Firefox Setup ${version}.exe`],
334
358
  "win32-x64": ["win64", `Firefox Setup ${version}.exe`],
335
- "linux": ["linux-x86_64", `firefox-${version}.tar.bz2`],
336
- "darwin": ["mac", `Firefox ${version}.dmg`]
337
- };
359
+ "linux-x64": ["linux-x86_64", `firefox-${version}.tar.bz2`],
360
+ "darwin-x64": ["mac", `Firefox ${version}.dmg`],
361
+ "darwin-arm64": ["mac", `Firefox ${version}.dmg`]
362
+ }[platform];
338
363
 
339
364
  let snapshotsDir = path.join(snapshotsBaseDir, "firefox");
340
365
  let browserDir = path.join(snapshotsDir, `firefox-${platform}-${version}`);
366
+ let archive = path.join(snapshotsDir, "cache", fileName);
367
+
341
368
  try {
342
369
  await fs.promises.access(browserDir);
343
370
  return Firefox.#getFirefoxBinary(browserDir);
@@ -345,10 +372,6 @@ class Firefox {
345
372
  catch (e) {}
346
373
 
347
374
  await fs.promises.mkdir(path.dirname(browserDir), {recursive: true});
348
-
349
- let [buildPlatform, fileName] = buildTypes[platform];
350
- let archive = path.join(snapshotsDir, "cache", fileName);
351
-
352
375
  try {
353
376
  await fs.promises.access(archive);
354
377
  }
@@ -409,14 +432,10 @@ class Firefox {
409
432
 
410
433
  /** @see Browser.enableExtensionInIncognito */
411
434
  static async enableExtensionInIncognito(driver, extensionTitle) {
412
- // Allowing the extension in private browsing can't happen programmatically:
413
- // https://bugzilla.mozilla.org/show_bug.cgi?id=1729315
414
- // Therefore, that is done through the UI
415
435
  let version = await getBrowserVersion(driver);
416
- if (version < 87) {
436
+ if (version < 87)
417
437
  // The UI workaround assumes web elements only present on Firefox >= 87
418
438
  throw new Error(`Only supported on Firefox >= 87. Current version: ${version}`);
419
- }
420
439
 
421
440
  await driver.navigate().to("about:addons");
422
441
  await driver.wait(until.elementLocated(By.name("extension")), 1000).click();
@@ -464,15 +483,13 @@ class Edge {
464
483
 
465
484
  // Based on "node_modules/msedgedriver/install.js", adding a fallback
466
485
  // mechanism when msedgedriver doesn't exist for the latest Edge version.
467
- let platform = `${process.platform}-${process.arch}`;
468
- let buildTypes = {
486
+ let [zip, driver] = {
469
487
  "win32-ia32": ["edgedriver_win32.zip", "msedgedriver.exe"],
470
488
  "win32-x64": ["edgedriver_win64.zip", "msedgedriver.exe"],
471
489
  "linux-x64": ["edgedriver_linux64.zip", "msedgedriver"],
472
490
  "darwin-x64": ["edgedriver_mac64.zip", "msedgedriver"],
473
491
  "darwin-arm64": ["edgedriver_arm64.zip", "msedgedriver"]
474
- };
475
- let [zip, driver] = buildTypes[platform];
492
+ }[platform];
476
493
  let cacheDir = path.join(snapshotsBaseDir, "edge", "cache");
477
494
  let driverBinDir = path.join(process.cwd(), "node_modules", Edge.#DRIVER,
478
495
  "bin");
@@ -498,17 +515,12 @@ class Edge {
498
515
  throw new Error(`msedgedriver was not found for Edge ${version}`);
499
516
 
500
517
  await extractZip(archive, {dir: cacheDir});
518
+ // avoid driver copy failing if the file would be locked
519
+ await killDriverProcess(Edge.#DRIVER);
501
520
  for (let destinationDir of [driverBinDir, driverLibDir]) {
502
521
  await fs.promises.mkdir(destinationDir, {recursive: true});
503
- try {
504
- await fs.promises.copyFile(path.join(cacheDir, driver),
505
- path.join(destinationDir, driver));
506
- }
507
- catch (err) {
508
- // https://gitlab.com/eyeo/developer-experience/get-browser-binary/-/issues/3
509
- if (!err.toString().includes("copyfile"))
510
- throw err;
511
- }
522
+ await fs.promises.copyFile(path.join(cacheDir, driver),
523
+ path.join(destinationDir, driver));
512
524
  }
513
525
  }
514
526
 
@@ -516,9 +528,6 @@ class Edge {
516
528
  static async getDriver(version, {headless = true, extensionPaths = [],
517
529
  incognito = false, insecure = false,
518
530
  extraArgs = []} = {}) {
519
- if (incognito)
520
- throw new Error(ERROR_INCOGNITO_NOT_SUPPORTED);
521
-
522
531
  await Edge.#installDriver();
523
532
 
524
533
  let args = ["no-sandbox", ...extraArgs];
@@ -526,6 +535,8 @@ class Edge {
526
535
  args.push("headless");
527
536
  if (extensionPaths.length > 0)
528
537
  args.push(`load-extension=${extensionPaths.join(",")}`);
538
+ if (incognito)
539
+ args.push("incognito");
529
540
 
530
541
  let builder = new webdriver.Builder();
531
542
  builder.forBrowser("MicrosoftEdge");
@@ -538,6 +549,32 @@ class Edge {
538
549
 
539
550
  return builder.build();
540
551
  }
552
+
553
+ /** @see Browser.enableExtensionInIncognito */
554
+ static async enableExtensionInIncognito(driver, extensionTitle) {
555
+ let version = await getBrowserVersion(driver);
556
+ if (version < 79)
557
+ // The UI workaround needs a chromium based msedgedriver
558
+ throw new Error(`Only supported on Edge >= 79. Current version: ${version}`);
559
+
560
+ await driver.navigate().to("edge://extensions/");
561
+ for (let elem of await driver.findElements(By.css("[role=listitem]"))) {
562
+ let text = await elem.getAttribute("innerHTML");
563
+ if (!text.includes(extensionTitle))
564
+ continue;
565
+
566
+ for (let button of await elem.findElements(By.css("button"))) {
567
+ text = await elem.getAttribute("innerHTML");
568
+ if (!text.includes("Details"))
569
+ continue;
570
+
571
+ await button.click();
572
+ return await driver.findElement(By.id("itemAllowIncognito")).click();
573
+ }
574
+ throw new Error("Details button not found");
575
+ }
576
+ throw new Error(`Extension "${extensionTitle}" not found`);
577
+ }
541
578
  }
542
579
 
543
580
 
package/src/utils.js CHANGED
@@ -25,6 +25,12 @@ import got from "got";
25
25
  import fsExtra from "fs-extra";
26
26
  import dmg from "dmg";
27
27
 
28
+ /**
29
+ * Downloads url resources.
30
+ * @param {string} url - The url of the resource to be downloaded.
31
+ * @param {string} destFile - The destination file path.
32
+ * @throws {TypeError} Invalid URL.
33
+ */
28
34
  export async function download(url, destFile) {
29
35
  let cacheDir = path.dirname(destFile);
30
36
 
@@ -37,7 +43,11 @@ export async function download(url, destFile) {
37
43
  await promisify(pipeline)(got.stream(url), writable);
38
44
  }
39
45
  catch (error) {
40
- await fs.promises.rm(tempDest, {recursive: true});
46
+ try {
47
+ await fs.promises.rm(tempDest, {recursive: true});
48
+ }
49
+ catch (e) {}
50
+
41
51
  throw error;
42
52
  }
43
53
 
@@ -78,3 +88,21 @@ export async function getBrowserVersion(driver) {
78
88
  let version = (await driver.getCapabilities()).getBrowserVersion();
79
89
  return parseInt(version.split(".")[0], 10);
80
90
  }
91
+
92
+ export async function killDriverProcess(driverName) {
93
+ let cmd = `kill $(pgrep ${driverName})`;
94
+ let shell;
95
+ if (process.platform == "win32") {
96
+ cmd = `Get-Process -Name ${driverName} | Stop-Process; Start-Sleep 1`;
97
+ shell = "powershell.exe";
98
+ }
99
+
100
+ try {
101
+ await promisify(exec)(cmd, {shell});
102
+ }
103
+ catch (err) {
104
+ // Command will fail when the driver process is not found
105
+ if (!err.toString().includes("Command failed"))
106
+ throw err;
107
+ }
108
+ }
@@ -18,14 +18,12 @@
18
18
  import fs from "fs";
19
19
  import expect from "expect";
20
20
  import path from "path";
21
- import {exec} from "child_process";
22
- import {promisify} from "util";
23
21
 
24
- import {BROWSERS, snapshotsBaseDir} from "../src/browsers.js";
22
+ import {BROWSERS, snapshotsBaseDir} from "../index.js";
23
+ import {killDriverProcess} from "../src/utils.js";
25
24
 
26
- // Required to start the driver on some platforms (e.g. Windows).
25
+ // Required to set the driver path on Windows
27
26
  import "chromedriver";
28
- import "geckodriver";
29
27
  import "msedgedriver";
30
28
 
31
29
  const VERSIONS = {
@@ -64,44 +62,10 @@ async function getHandle(driver, page) {
64
62
  return handle;
65
63
  }
66
64
 
67
- async function killDriverProcess() {
68
- for (let name of ["chromedriver", "msedgedriver"]) {
69
- let stdout;
70
- if (process.platform == "win32") {
71
- try {
72
- ({stdout} = await promisify(exec)(
73
- `(Get-Process -Name ${name}).Id | Stop-Process`,
74
- {shell: "powershell.exe"}
75
- ));
76
- }
77
- catch (err) {
78
- if (err.toString().includes("Command failed"))
79
- continue; // Command will fail when driver process is not found
80
-
81
- throw err;
82
- }
83
- }
84
- else {
85
- try {
86
- ({stdout} =
87
- await promisify(exec)(`ps -a | grep ${name} | grep -v grep`));
88
- }
89
- catch (err) {
90
- if (err.toString().includes("Command failed"))
91
- continue; // Command will fail when driver process is not found
92
-
93
- throw err;
94
- }
95
- let pid = /\s*(\d*)/.exec(stdout)[1]; // first number after any spaces
96
- await promisify(exec)(`kill ${pid}`);
97
- }
98
- }
99
- }
100
-
101
65
  for (let browser of Object.keys(BROWSERS)) {
102
66
  for (let version of VERSIONS[browser]) {
103
67
  describe(`Browser: ${browser} ${version || "latest"}`, function() {
104
- this.timeout(15000);
68
+ this.timeout(20000);
105
69
 
106
70
  before(async() => {
107
71
  try {
@@ -117,8 +81,9 @@ for (let browser of Object.keys(BROWSERS)) {
117
81
 
118
82
  await driver.quit();
119
83
  driver = null;
120
- // Some platforms don't immediately kill the webdriver process
121
- await killDriverProcess();
84
+ // Some platforms don't immediately kill the chromedriver process
85
+ if (browser == "chromium")
86
+ await killDriverProcess("chromedriver");
122
87
  });
123
88
 
124
89
  it("downloads", async function() {
@@ -163,9 +128,12 @@ for (let browser of Object.keys(BROWSERS)) {
163
128
  });
164
129
 
165
130
  it("loads an extension in incognito mode", async function() {
166
- if (browser != "firefox" || version == "68.0")
131
+ if (browser == "firefox" && version == "68.0")
167
132
  this.skip();
168
133
 
134
+ if (process.platform == "win32")
135
+ this.timeout(30000);
136
+
169
137
  driver = await BROWSERS[browser].getDriver(
170
138
  version, {headless: false, extensionPaths, incognito: true});
171
139
  await BROWSERS[browser].enableExtensionInIncognito(
package/test/utils.js ADDED
@@ -0,0 +1,42 @@
1
+ /*
2
+ * Copyright (c) 2006-present eyeo GmbH
3
+ *
4
+ * This module is free software: you can redistribute it and/or modify
5
+ * it under the terms of the GNU General Public License as published by
6
+ * the Free Software Foundation, either version 3 of the License, or
7
+ * (at your option) any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ * GNU General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ */
17
+
18
+ import fs from "fs";
19
+ import expect from "expect";
20
+ import path from "path";
21
+
22
+ import {snapshotsBaseDir, download} from "../index.js";
23
+
24
+ describe("Utils", () => {
25
+ it("defines a browser snapshots folder", () => expect(snapshotsBaseDir)
26
+ .toBe(path.join(process.cwd(), "browser-snapshots")));
27
+
28
+ let destFile = path.join(snapshotsBaseDir, "download-test.txt");
29
+
30
+ it("downloads resources", async() => {
31
+ let url = "https://gitlab.com/eyeo/developer-experience/get-browser-binary/-/raw/main/package.json";
32
+ await download(url, destFile);
33
+ let contents = await fs.promises.readFile(destFile, {encoding: "utf8"});
34
+ expect(contents).toEqual(
35
+ expect.stringContaining("\"name\": \"@eyeo/get-browser-binary\""));
36
+ });
37
+
38
+ it("does not download invalid resources", async() => {
39
+ expect(download("invalid", destFile)).rejects
40
+ .toThrow("TypeError [ERR_INVALID_URL]: Invalid URL");
41
+ });
42
+ });