@eyeo/get-browser-binary 0.16.0 → 0.17.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
@@ -27,42 +27,50 @@ test:basic:
27
27
  - npm run lint
28
28
  - npm test -- --grep "Utils"
29
29
 
30
- test:browsers:linux:
30
+ .linux:
31
31
  stage: test
32
32
  image: docker:24.0.5
33
33
  services:
34
34
  - docker:24.0.5-dind
35
35
  before_script:
36
36
  - docker build -f test/docker/Dockerfile -t browsers .
37
+
38
+ test:browsers:linux:
39
+ extends: .linux
37
40
  script:
38
- - docker run --shm-size=512m -t browsers
41
+ - docker run --shm-size=512m -t -e TEST_ARGS="--grep ^.*Browser((?!Version:.dev).)*\$" browsers
39
42
 
40
- test:browsers:windows:
43
+ test:browsers:linux:dev:
44
+ extends: .linux
45
+ script:
46
+ - docker run --shm-size=512m -t -e TEST_ARGS="--grep Version:.dev" browsers
47
+ allow_failure: true
48
+
49
+ .windows:
41
50
  stage: test
42
- variables:
43
- CI_PROJECT_ID_MAINSTREAM: 36688302
44
51
  before_script:
45
- - Invoke-WebRequest
46
- -Uri "${Env:CI_API_V4_URL}/projects/${Env:CI_PROJECT_ID_MAINSTREAM}/packages/generic/microsoft-edge/79.0.309/MicrosoftEdgeEnterpriseX64.msi"
47
- -Headers @{'JOB-TOKEN' = $Env:CI_JOB_TOKEN}
48
- -OutFile 'MicrosoftEdgeEnterpriseX64.msi'
49
- - Start-Process msiexec
50
- -ArgumentList "/i MicrosoftEdgeEnterpriseX64.msi /norestart /qn" -Wait
51
- - choco upgrade -y --no-progress nodejs --version 18.17.1
52
+ - choco install -y microsoft-edge
52
53
  - npm install
54
+ tags:
55
+ - saas-windows-medium-amd64
56
+ cache: {}
57
+
58
+ test:browsers:windows:
59
+ extends: .windows
53
60
  script:
54
61
  # Running Edge tests only on the preinstalled version
55
62
  # https://gitlab.com/eyeo/developer-experience/get-browser-binary/-/issues/29
56
63
  - npm test -- --grep "edge.*latest"
57
- - npm test -- --grep "chromium"
64
+ - npm test -- --grep "^.*chromium((?!Version:.dev).)*$"
58
65
  # Running only a subset of Firefox tests to avoid low OS resources error
59
66
  # https://gitlab.com/eyeo/developer-experience/get-browser-binary/-/issues/2
60
67
  - npm test -- --grep "firefox.*installs"
61
- tags:
62
- - shared-windows
63
- - windows
64
- - windows-1809
65
- cache: {}
68
+
69
+ test:browsers:windows:dev:
70
+ extends: .windows
71
+ script:
72
+ - npm test -- --grep "chromium.*Version:.dev"
73
+ allow_failure: true
66
74
 
67
75
  docs:
68
76
  stage: docs
package/README.md CHANGED
@@ -43,6 +43,22 @@ Edge version is supported.
43
43
  Set the `VERBOSE` environment variable to `"true"` to get verbose logging on
44
44
  download requests.
45
45
 
46
+ ### Offline execution
47
+
48
+ It is possible to run browsers offline as long as they have been previously
49
+ installed. Example:
50
+
51
+ ```javascript
52
+ // Online
53
+ let {binary} = await BROWSERS[browser].installBrowser(version);
54
+ console.log(binary); // keep the browser binary location to use it offline
55
+ let driver = await BROWSERS[browser].getDriver(version); // let the driver binary download
56
+
57
+ // Offline
58
+ let customBrowserBinary = "<browser binary location>";
59
+ let driver = await BROWSERS[browser].getDriver(version, {customBrowserBinary});
60
+ ```
61
+
46
62
  ## Development
47
63
 
48
64
  ### Prerequisites
package/RELEASE_NOTES.md CHANGED
@@ -1,6 +1,16 @@
1
+ # Unreleased
2
+
3
+ # 0.17.0
4
+
5
+ - Stops calling `driver.close()` in `enableExtensionInIncognito()`
6
+ on non-Windows platforms (!114)
7
+ - Add instructions for offline execution (!110)
8
+ - Adds option to setup proxy through PAC file for Firefox (!115)
9
+
1
10
  # 0.16.0
2
11
 
3
- - Starts using selenium's automated driver management (#67)
12
+ - Starts using selenium's automated driver management. That means additional
13
+ `chromedriver` and `msedgedriver` packages are no longer needed (#67)
4
14
  - Loads the extension in Firefox by local path instead of being copied to a
5
15
  temporary folder (!104)
6
16
  - Checks if extensions can be loaded beforehand, by ensuring they contain a
@@ -18,7 +28,9 @@ include parenthesis (#69)
18
28
  ### Notes for integrators
19
29
 
20
30
  - Please make sure that your selenium-webdriver package version is at least
21
- 4.15.0 (the one used in this release) (#67)
31
+ 4.15.0 (the one used in this release). Also make sure that you are not using the
32
+ `chromedriver` nor `msedgedriver` packages, otherwise the automated driver
33
+ management may not work as expected (#67)
22
34
  - If you experience chromedriver issues, try deleting the `/browser-snapshots`
23
35
  cache folder.
24
36
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eyeo/get-browser-binary",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "description": "Install browser binaries and matching webdrivers",
5
5
  "repository": {
6
6
  "type": "git",
package/src/browser.js CHANGED
@@ -95,6 +95,8 @@ export class Browser {
95
95
  * certificates, or not.
96
96
  * @property {Array.<string>} [extraArgs=[]] Additional arguments to start
97
97
  * the browser with.
98
+ * @property {string} [proxy] Only for Firefox, path to network
99
+ * proxy autoconfig url (PAC file).
98
100
  * @property {string} [customBrowserBinary] Path to the browser binary to be
99
101
  * used, instead of the browser installed by installBrowser(). This option
100
102
  * overrides the version parameter in getDriver().
package/src/chromium.js CHANGED
@@ -265,8 +265,9 @@ export class Chromium extends Browser {
265
265
  setTimeout(() => resolve(enable()), 100);
266
266
  });
267
267
  }, extensionTitle, errMsg.extensionNotFound);
268
- if (version >= 115)
269
- // Closing the previously opened new window
268
+ if (version >= 115 && process.platform == "win32")
269
+ // Closing the previously opened new window. Needed on Windows to avoid a
270
+ // further `WebDriverError: disconnected` error
270
271
  await driver.close();
271
272
 
272
273
  await driver.switchTo().window(handle);
package/src/firefox.js CHANGED
@@ -140,9 +140,14 @@ export class Firefox extends Browser {
140
140
  }
141
141
 
142
142
  /** @see Browser.getDriver */
143
+ /** In Firefox you can define url to proxy autoconfig file.
144
+ * Proxy Autoconfig file determine whether web requests should go through
145
+ * a proxy server or connect directly. This allow to use localhost mapped
146
+ * to any url (f.ex testpages.adblockplus.org)
147
+ */
143
148
  static async getDriver(version = "latest", {
144
149
  headless = true, extensionPaths = [], incognito = false, insecure = false,
145
- extraArgs = [], customBrowserBinary
150
+ extraArgs = [], customBrowserBinary, proxy
146
151
  } = {}, downloadTimeout = 0) {
147
152
  let binary;
148
153
  let versionNumber;
@@ -163,6 +168,10 @@ export class Firefox extends Browser {
163
168
  // Enabled by default on Firefox > 68
164
169
  if (versionNumber && getMajorVersion(versionNumber) == 68)
165
170
  options.setPreference("dom.promise_rejection_events.enabled", true);
171
+ if (proxy) {
172
+ options.setPreference("network.proxy.type", 2);
173
+ options.setPreference("network.proxy.autoconfig_url", proxy);
174
+ }
166
175
 
167
176
  options.setBinary(customBrowserBinary || binary);
168
177
 
package/test/browsers.js CHANGED
@@ -31,6 +31,7 @@ const VERSIONS = {
31
31
  edge: ["latest", "95.0.1020.40", "beta", "dev"]
32
32
  };
33
33
  const TEST_URL_BASIC = `${TEST_SERVER_URL}/basic.html`;
34
+ const PROXY_URL_BASIC = "http://testpages.adblockplus.org/basic.html";
34
35
  const TEST_URL_LONG = `${TEST_SERVER_URL}/long.html`;
35
36
 
36
37
  async function switchToHandle(driver, testFn) {
@@ -106,7 +107,8 @@ function getExtension(browser, version) {
106
107
 
107
108
  async function getInstallFileCTime(browser) {
108
109
  // Browsers installed at OS level are not tested
109
- if (browser == "edge" && process.platform == "win32")
110
+ if (browser == "edge" && (process.platform == "win32" ||
111
+ process.platform == "darwin"))
110
112
  return null;
111
113
 
112
114
  const installTypes = [".zip", ".dmg", ".bz2", ".deb", ".exe"];
@@ -141,6 +143,14 @@ function addVersionToTitle(ctx, version) {
141
143
  ctx.test.title = `${ctx.test.title} [v${version}]`;
142
144
  }
143
145
 
146
+ function isOldHeadlessMode(browser, version) {
147
+ // Chromium's old headless mode doesn't support loading extensions
148
+ return browser != "firefox" && (
149
+ !["latest", "beta", "dev"].includes(version) ||
150
+ // Edge on the Windows CI is v79, that is old headless
151
+ (browser == "edge" && process.platform == "win32"));
152
+ }
153
+
144
154
  for (let browser of Object.keys(BROWSERS)) {
145
155
  describe(`Browser: ${browser}`, () => {
146
156
  before(async() => {
@@ -168,6 +178,12 @@ for (let browser of Object.keys(BROWSERS)) {
168
178
  await killDriverProcess("chromedriver");
169
179
  else if (browser == "firefox")
170
180
  await killDriverProcess("geckodriver");
181
+
182
+ // https://gitlab.com/eyeo/developer-experience/get-browser-binary/-/issues/77
183
+ if (process.platform == "win32" && browser == "chromium")
184
+ await killDriverProcess("chrome");
185
+ else if (process.platform == "win32" && browser == "edge")
186
+ await killDriverProcess("msedge");
171
187
  }
172
188
 
173
189
  beforeEach(function() {
@@ -258,6 +274,22 @@ for (let browser of Object.keys(BROWSERS)) {
258
274
  expect(sizeSmall).toMeasureLessThan(sizeDefault);
259
275
  });
260
276
 
277
+ it("supports proxy", async function() {
278
+ if (browser != "firefox")
279
+ this.skip();
280
+
281
+ let headless = true;
282
+ let proxy = "http://localhost:3000/proxy-config.pac";
283
+ let extraArgs = [];
284
+ driver = await BROWSERS[browser].getDriver(
285
+ version, {headless, extraArgs, proxy});
286
+ await driver.navigate().to(PROXY_URL_BASIC);
287
+
288
+ let text = await driver.findElement(By.id("basic")).getText();
289
+ expect(text).toEqual("Test server basic page");
290
+ await quitDriver();
291
+ });
292
+
261
293
  it("takes a full page screenshot", async() => {
262
294
  driver = await BROWSERS[browser].getDriver(version);
263
295
  await driver.navigate().to(TEST_URL_LONG);
@@ -277,9 +309,7 @@ for (let browser of Object.keys(BROWSERS)) {
277
309
  // Selenium's automated driver download should be able to manage it.
278
310
  // https://gitlab.com/eyeo/developer-experience/get-browser-binary/-/issues/44
279
311
  it("loads an extension", async() => {
280
- // Chromium's old headless mode doesn't support loading extensions
281
- let headless = browser == "firefox" || (browser == "chromium" &&
282
- ["latest", "beta", "dev"].includes(version));
312
+ let headless = !isOldHeadlessMode(browser, version);
283
313
  let {extensionPaths} = getExtension(browser, version);
284
314
 
285
315
  driver = await BROWSERS[browser].getDriver(
@@ -299,6 +329,29 @@ for (let browser of Object.keys(BROWSERS)) {
299
329
  );
300
330
  await getHandle(driver, "/index.html");
301
331
  });
332
+
333
+ it("updates an extension", async() => {
334
+ let headless = !isOldHeadlessMode(browser, version);
335
+ let {extensionPaths, manifest} = getExtension(browser, version);
336
+
337
+ let tmpExtensionDir = path.join(snapshotsBaseDir, "extension");
338
+ await fs.promises.rm(tmpExtensionDir, {recursive: true, force: true});
339
+ await fs.promises.cp(extensionPaths[0], tmpExtensionDir,
340
+ {recursive: true});
341
+
342
+ driver = await BROWSERS[browser].getDriver(
343
+ version, {headless, extensionPaths: [tmpExtensionDir]});
344
+ await getHandle(driver, "/index.html");
345
+ let text = await driver.findElement(By.id("title")).getText();
346
+ expect(text).toEqual(`Browser test extension - ${manifest}`);
347
+
348
+ // The page is modified and reloaded to emulate an extension update
349
+ await fs.promises.cp(path.join(tmpExtensionDir, "update.html"),
350
+ path.join(tmpExtensionDir, "index.html"));
351
+ await driver.navigate().refresh();
352
+ text = await driver.findElement(By.id("title")).getText();
353
+ expect(text).toEqual(`Updated test extension - ${manifest}`);
354
+ });
302
355
  });
303
356
  }
304
357
 
@@ -1 +1 @@
1
- <h1>Browser test extension - mv2</h1>
1
+ <h1 id="title">Browser test extension - mv2</h1>
@@ -0,0 +1 @@
1
+ <h1 id="title">Updated test extension - mv2</h1>
@@ -1 +1 @@
1
- <h1>Browser test extension - mv3</h1>
1
+ <h1 id="title">Browser test extension - mv3</h1>
@@ -0,0 +1 @@
1
+ <h1 id="title">Updated test extension - mv3</h1>
@@ -0,0 +1,7 @@
1
+
2
+ function FindProxyForURL(url, host) {
3
+ if (host === "testpages.adblockplus.org")
4
+ return "PROXY http://localhost:3000";
5
+
6
+ return "DIRECT";
7
+ }