@eyeo/get-browser-binary 0.19.0 → 0.20.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/.mocharc.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "timeout": 80000
2
+ "timeout": 90000
3
3
  }
package/RELEASE_NOTES.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Unreleased
2
2
 
3
+ # 0.20.0
4
+
5
+ - Enable developer mode for incognito tests (!126)
6
+ - Adds support to beta and dev channels for Edge in macOS (!127)
7
+ - Enable developer mode for latest versions of chromium browsers (!128)
8
+
3
9
  # 0.19.0
4
10
 
5
11
  - Fixes an issue starting with Firefox version 135 which prevented the binary to be downloaded (#82)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eyeo/get-browser-binary",
3
- "version": "0.19.0",
3
+ "version": "0.20.0",
4
4
  "description": "Install browser binaries and matching webdrivers",
5
5
  "repository": {
6
6
  "type": "git",
package/src/browser.js CHANGED
@@ -125,7 +125,6 @@ export class Browser {
125
125
  * enables the extension when loaded in incognito.
126
126
  * @param {webdriver} driver The driver controlling the browser.
127
127
  * @param {string} extensionTitle Title of the extension to be enabled.
128
- * @return {webdriver}
129
128
  * @throws {Error} Unsupported browser version, Extension not found, HTML
130
129
  * element not found.
131
130
  */
package/src/chromium.js CHANGED
@@ -19,7 +19,7 @@ import path from "path";
19
19
  import fs from "fs";
20
20
 
21
21
  import got from "got";
22
- import webdriver from "selenium-webdriver";
22
+ import {Builder} from "selenium-webdriver";
23
23
  import chrome from "selenium-webdriver/chrome.js";
24
24
  import extractZip from "extract-zip";
25
25
 
@@ -27,6 +27,20 @@ import {Browser} from "./browser.js";
27
27
  import {download, getMajorVersion, checkVersion, checkPlatform, errMsg,
28
28
  snapshotsBaseDir, platformArch, checkExtensionPaths} from "./utils.js";
29
29
 
30
+ async function enableDeveloperMode(driver) {
31
+ await driver.switchTo().newWindow("window");
32
+ await driver.navigate().to("chrome://extensions");
33
+ await driver.executeScript(() => {
34
+ const devModeToggle = document
35
+ .querySelector("extensions-manager").shadowRoot
36
+ .getElementById("toolbar").shadowRoot
37
+ .querySelector("#toolbar #devMode");
38
+
39
+ if (!devModeToggle.checked)
40
+ devModeToggle.click();
41
+ });
42
+ }
43
+
30
44
  /**
31
45
  * Browser and webdriver functionality for Chromium.
32
46
  * @hideconstructor
@@ -211,8 +225,8 @@ export class Chromium extends Browser {
211
225
  await checkExtensionPaths(extensionPaths);
212
226
  options.addArguments(`load-extension=${extensionPaths.join(",")}`);
213
227
  }
228
+ let majorVersion = getMajorVersion(versionNumber);
214
229
  if (headless) {
215
- let majorVersion = getMajorVersion(versionNumber);
216
230
  // https://www.selenium.dev/blog/2023/headless-is-going-away/
217
231
  if (majorVersion >= 109)
218
232
  options.addArguments("headless=new");
@@ -227,11 +241,18 @@ export class Chromium extends Browser {
227
241
  options.addArguments("incognito");
228
242
  options.setChromeBinaryPath(binary);
229
243
 
230
- let builder = new webdriver.Builder();
244
+ let builder = new Builder();
231
245
  builder.forBrowser("chrome");
232
246
  builder.setChromeOptions(options);
233
247
 
234
- return builder.build();
248
+ const driver = builder.build();
249
+
250
+ // From Chromium 134 on, developer mode needs to be enabled
251
+ // for custom extensions to work properly
252
+ if (majorVersion >= 134)
253
+ await enableDeveloperMode(driver);
254
+
255
+ return driver;
235
256
  }
236
257
 
237
258
  /** @see Browser.enableExtensionInIncognito */
package/src/edge.js CHANGED
@@ -21,7 +21,7 @@ import {promisify} from "util";
21
21
  import fs from "fs";
22
22
 
23
23
  import got from "got";
24
- import webdriver from "selenium-webdriver";
24
+ 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";
@@ -29,9 +29,16 @@ import {download, killDriverProcess, wait, getMajorVersion, checkVersion,
29
29
  checkPlatform, errMsg, snapshotsBaseDir, checkExtensionPaths}
30
30
  from "./utils.js";
31
31
 
32
- let {By} = webdriver;
33
32
  let {platform} = process;
34
33
 
34
+ async function enableDeveloperMode(driver) {
35
+ await driver.navigate().to("edge://extensions/");
36
+ const devModeToggle = driver.findElement(By.id("developer-mode"));
37
+
38
+ if (!devModeToggle.checked)
39
+ devModeToggle.click();
40
+ }
41
+
35
42
  /**
36
43
  * Browser and webdriver functionality for Edge.
37
44
  * @hideconstructor
@@ -83,19 +90,24 @@ export class Edge extends Browser {
83
90
  return {versionNumber, channel};
84
91
  }
85
92
 
86
- static #darwinApp = "Microsoft Edge";
93
+ static #getDarwinApp(channel = "stable") {
94
+ const firstUppercase =
95
+ String(channel).charAt(0).toUpperCase() + String(channel).slice(1);
96
+ return channel === "stable" ? "Microsoft Edge" : `Microsoft Edge ${firstUppercase}`;
97
+ }
87
98
 
88
99
  static #getBinaryPath(channel = "stable") {
89
100
  switch (platform) {
90
101
  case "win32":
91
- let programFiles = process.env["ProgramFiles(x86)"] ?
102
+ const programFiles = process.env["ProgramFiles(x86)"] ?
92
103
  "${Env:ProgramFiles(x86)}" : "${Env:ProgramFiles}";
93
104
  return `${programFiles}\\Microsoft\\Edge\\Application\\msedge.exe`;
94
105
  case "linux":
95
106
  return channel == "stable" ?
96
107
  "/usr/bin/microsoft-edge" : `/usr/bin/microsoft-edge-${channel}`;
97
108
  case "darwin":
98
- return `${process.env.HOME}/Applications/${Edge.#darwinApp}.app/Contents/MacOS/${Edge.#darwinApp}`;
109
+ const darwinApp = Edge.#getDarwinApp(channel);
110
+ return `${process.env.HOME}/Applications/${darwinApp}.app/Contents/MacOS/${darwinApp}`;
99
111
  default:
100
112
  checkPlatform();
101
113
  }
@@ -119,9 +131,8 @@ export class Edge extends Browser {
119
131
  // https://support.microsoft.com/en-us/microsoft-edge/why-can-t-i-uninstall-microsoft-edge-ee150b3b-7d7a-9984-6d83-eb36683d526d
120
132
  throw new Error(`${errMsg.unsupportedPlatform}: ${platform}`);
121
133
 
122
- if (platform == "darwin" && version != "latest")
123
- // Only latest Edge is supported on macOS
124
- throw new Error(`${errMsg.unsupportedVersion}: ${version}. Only "latest" is supported`);
134
+ if (platform == "darwin" && !/latest|beta|dev/.test(version))
135
+ throw new Error(`${errMsg.unsupportedVersion}: ${version}. Only "latest", "beta" or "dev" are supported`);
125
136
 
126
137
  checkVersion(version, Edge.#MIN_VERSION, Edge.#CHANNELS);
127
138
  let {versionNumber, channel} = await Edge.#getVersionForChannel(version);
@@ -143,16 +154,14 @@ export class Edge extends Browser {
143
154
  let url = `https://packages.microsoft.com/repos/edge/pool/main/m/microsoft-edge-${channel}/${filename}`;
144
155
  try {
145
156
  if (platform == "darwin") {
146
- let caskUrl = "https://formulae.brew.sh/api/cask/microsoft-edge.json";
147
- let caskJson;
157
+ const caskFile = channel === "stable" ? "microsoft-edge.json" : `microsoft-edge@${channel}.json`;
158
+ const caskUrl = `https://formulae.brew.sh/api/cask/${caskFile}`;
148
159
  try {
149
- caskJson = await got(caskUrl).json();
160
+ ({url} = await got(caskUrl).json());
150
161
  }
151
162
  catch (err) {
152
163
  throw new Error(`${errMsg.browserVersionCheck}: ${caskUrl}\n${err}`);
153
164
  }
154
- ({url} = process.arch == "arm64" ?
155
- caskJson.variations.arm64_ventura : caskJson);
156
165
  }
157
166
  await download(url, archive, downloadTimeout);
158
167
  }
@@ -164,7 +173,7 @@ export class Edge extends Browser {
164
173
  await promisify(exec)(`dpkg -i ${archive}`);
165
174
  }
166
175
  else if (platform == "darwin") {
167
- await fs.promises.rm(`${process.env.HOME}/Applications/${Edge.#darwinApp}.app`, {force: true, recursive: true});
176
+ await fs.promises.rm(`${process.env.HOME}/Applications/${Edge.#getDarwinApp(channel)}.app`, {force: true, recursive: true});
168
177
  await promisify(exec)(`installer -pkg ${archive} -target CurrentUserHomeDirectory`);
169
178
  }
170
179
 
@@ -213,10 +222,10 @@ export class Edge extends Browser {
213
222
  options.addArguments("inprivate");
214
223
  if (insecure)
215
224
  options.addArguments("ignore-certificate-errors");
216
- if (platform == "linux")
225
+ if (platform === "linux" || platform === "darwin")
217
226
  options.setEdgeChromiumBinaryPath(binary);
218
227
 
219
- let builder = new webdriver.Builder();
228
+ let builder = new Builder();
220
229
  builder.forBrowser("MicrosoftEdge");
221
230
  builder.setEdgeOptions(options);
222
231
 
@@ -235,12 +244,17 @@ export class Edge extends Browser {
235
244
  }
236
245
  }, 30000, `${errMsg.driverStart}: msedgedriver`, 1000);
237
246
 
247
+ // Developer mode needs to be enabled
248
+ // for custom extensions to work properly
249
+ await enableDeveloperMode(driver);
250
+
238
251
  return driver;
239
252
  }
240
253
 
241
254
  /** @see Browser.enableExtensionInIncognito */
242
255
  static async enableExtensionInIncognito(driver, extensionTitle) {
243
256
  await driver.navigate().to("edge://extensions/");
257
+
244
258
  for (let elem of await driver.findElements(By.css("[role=listitem]"))) {
245
259
  let text = await elem.getAttribute("innerHTML");
246
260
  if (!text.includes(extensionTitle))
@@ -252,8 +266,23 @@ export class Edge extends Browser {
252
266
  continue;
253
267
 
254
268
  await button.click();
255
- return await driver.findElement(By.id("itemAllowIncognito")).click();
269
+ await driver.findElement(By.id("itemAllowIncognito")).click();
270
+
271
+ // On Edge 134, extension gets turned off when incognito mode is enabled
272
+ // We need to turn it back on by clicking the toggle
273
+ try {
274
+ await driver.wait(until.elementLocated(
275
+ By.css('[aria-label="Extension on"]:not(:checked)')), 3000).click();
276
+ }
277
+ catch (err) {
278
+ // ignoring timeout errors, as the element is not expected
279
+ // to be present for all Edge versions
280
+ if (err.name !== "TimeoutError")
281
+ throw err;
282
+ }
283
+ return;
256
284
  }
285
+
257
286
  throw new Error(`${errMsg.elemNotFound}: Details button`);
258
287
  }
259
288
  throw new Error(`${errMsg.extensionNotFound}: ${extensionTitle}`);
package/src/firefox.js CHANGED
@@ -21,7 +21,7 @@ import {promisify} from "util";
21
21
  import fs from "fs";
22
22
 
23
23
  import got from "got";
24
- import webdriver from "selenium-webdriver";
24
+ import {until, By, Builder} from "selenium-webdriver";
25
25
  import firefox from "selenium-webdriver/firefox.js";
26
26
  import {Command} from "selenium-webdriver/lib/command.js";
27
27
 
@@ -30,8 +30,6 @@ import {download, extractTar, extractDmg, killDriverProcess, wait,
30
30
  getMajorVersion, checkVersion, checkPlatform, errMsg, snapshotsBaseDir,
31
31
  platformArch, checkExtensionPaths} from "./utils.js";
32
32
 
33
- let {until, By} = webdriver;
34
-
35
33
  /**
36
34
  * Browser and webdriver functionality for Firefox.
37
35
  * @hideconstructor
@@ -221,7 +219,7 @@ export class Firefox extends Browser {
221
219
  // https://github.com/mozilla/geckodriver/issues/1560
222
220
  await wait(async() => {
223
221
  try {
224
- driver = await new webdriver.Builder()
222
+ driver = await new Builder()
225
223
  .forBrowser("firefox")
226
224
  .setFirefoxOptions(options)
227
225
  .build();