webdriver 8.14.6 → 8.15.4

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.
@@ -4,10 +4,4 @@ export declare const REG_EXPS: {
4
4
  commandName: RegExp;
5
5
  execFn: RegExp;
6
6
  };
7
- export declare const SUPPORTED_BROWSERNAMES: {
8
- chrome: string[];
9
- firefox: string[];
10
- edge: string[];
11
- safari: string[];
12
- };
13
7
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAE1C,eAAO,MAAM,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAiJpE,CAAA;AAED,eAAO,MAAM,QAAQ;;;CAGpB,CAAA;AAED,eAAO,MAAM,sBAAsB;;;;;CAKlC,CAAA"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAE1C,eAAO,MAAM,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAiJpE,CAAA;AAED,eAAO,MAAM,QAAQ;;;CAGpB,CAAA"}
@@ -148,9 +148,3 @@ export const REG_EXPS = {
148
148
  commandName: /.*\/session\/[0-9a-f-]+\/(.*)/,
149
149
  execFn: /return \(([\s\S]*)\)\.apply\(null, arguments\)/
150
150
  };
151
- export const SUPPORTED_BROWSERNAMES = {
152
- chrome: ['chrome', 'googlechrome', 'chromium', 'chromium-browser'],
153
- firefox: ['firefox', 'ff', 'mozilla', 'mozilla firefox'],
154
- edge: ['edge', 'microsoftedge', 'msedge'],
155
- safari: ['safari', 'safari technology preview']
156
- };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,aAAa,CAAA;AAExD,OAAO,OAAO,MAAM,cAAc,CAAA;AAGlC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAyB,YAAY,EAAE,kBAAkB,EAAsB,MAAM,YAAY,CAAA;AACxG,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAgB,MAAM,YAAY,CAAA;AAIrE,MAAM,CAAC,OAAO,OAAO,SAAS;WACb,UAAU,CACnB,OAAO,EAAE,OAAO,CAAC,SAAS,EAC1B,QAAQ,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAClC,aAAa,KAAK,EAClB,oBAAoB,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,GAC/C,OAAO,CAAC,MAAM,CAAC;IAyDlB;;OAEG;IACH,MAAM,CAAC,eAAe,CAClB,OAAO,CAAC,EAAE,aAAa,EACvB,QAAQ,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAClC,aAAa,KAAK,EAClB,cAAc,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,GACzC,MAAM;IA0BT;;;;;;OAMG;WACU,aAAa,CAAC,QAAQ,EAAE,MAAM;IAW3C,MAAM,KAAK,SAAS,qBAEnB;CACJ;AAED;;GAEG;AACH,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAA;AAC9D,cAAc,YAAY,CAAA;AAC1B,cAAc,mBAAmB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,aAAa,CAAA;AAExD,OAAO,OAAO,MAAM,cAAc,CAAA;AAElC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAyB,YAAY,EAAE,kBAAkB,EAAsB,MAAM,YAAY,CAAA;AACxG,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAgB,MAAM,YAAY,CAAA;AAIrE,MAAM,CAAC,OAAO,OAAO,SAAS;WACb,UAAU,CACnB,OAAO,EAAE,OAAO,CAAC,SAAS,EAC1B,QAAQ,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAClC,aAAa,KAAK,EAClB,oBAAoB,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,GAC/C,OAAO,CAAC,MAAM,CAAC;IAyDlB;;OAEG;IACH,MAAM,CAAC,eAAe,CAClB,OAAO,CAAC,EAAE,aAAa,EACvB,QAAQ,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAClC,aAAa,KAAK,EAClB,cAAc,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,GACzC,MAAM;IA0BT;;;;;;OAMG;WACU,aAAa,CAAC,QAAQ,EAAE,MAAM;IAW3C,MAAM,KAAK,SAAS,qBAEnB;CACJ;AAED;;GAEG;AACH,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAA;AAC9D,cAAc,YAAY,CAAA;AAC1B,cAAc,mBAAmB,CAAA"}
package/build/index.js CHANGED
@@ -1,9 +1,8 @@
1
1
  import path from 'node:path';
2
2
  import logger from '@wdio/logger';
3
- import { webdriverMonad, sessionEnvironmentDetector } from '@wdio/utils';
3
+ import { webdriverMonad, sessionEnvironmentDetector, startWebDriver } from '@wdio/utils';
4
4
  import { validateConfig } from '@wdio/config';
5
5
  import command from './command.js';
6
- import { startWebDriver } from './driver/index.js';
7
6
  import { BidiHandler } from './bidi/handler.js';
8
7
  import { DEFAULTS } from './constants.js';
9
8
  import { startWebDriverSession, getPrototype, getEnvironmentVars, setupDirectConnect } from './utils.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webdriver",
3
- "version": "8.14.6",
3
+ "version": "8.15.4",
4
4
  "description": "A Node.js bindings implementation for the W3C WebDriver and Mobile JSONWire Protocol",
5
5
  "author": "Christian Bromann <mail@bromann.dev>",
6
6
  "homepage": "https://github.com/webdriverio/webdriverio/tree/main/packages/webdriver",
@@ -36,25 +36,17 @@
36
36
  "url": "https://github.com/webdriverio/webdriverio/issues"
37
37
  },
38
38
  "dependencies": {
39
- "@puppeteer/browsers": "^1.4.6",
40
39
  "@types/node": "^20.1.0",
41
40
  "@types/ws": "^8.5.3",
42
- "@wdio/config": "8.14.6",
41
+ "@wdio/config": "8.15.4",
43
42
  "@wdio/logger": "8.11.0",
44
43
  "@wdio/protocols": "8.14.6",
45
- "@wdio/types": "8.14.0",
46
- "@wdio/utils": "8.14.0",
47
- "chrome-launcher": "^1.0.0",
48
- "decamelize": "^6.0.0",
44
+ "@wdio/types": "8.15.0",
45
+ "@wdio/utils": "8.15.4",
49
46
  "deepmerge-ts": "^5.1.0",
50
- "edgedriver": "^5.3.2",
51
- "geckodriver": "^4.2.0",
52
- "get-port": "^7.0.0",
53
47
  "got": "^ 12.6.1",
54
48
  "ky": "^0.33.0",
55
- "safaridriver": "^0.1.0",
56
- "wait-port": "^1.0.4",
57
49
  "ws": "^8.8.0"
58
50
  },
59
- "gitHead": "84472108356bc234e6765ba9ffd84867aea2df2a"
51
+ "gitHead": "528fe3a1d3d37a44f58882a65170971f38461add"
60
52
  }
@@ -1,19 +0,0 @@
1
- /// <reference types="node" />
2
- import cp from 'node:child_process';
3
- import type { Options } from '@wdio/types';
4
- import { type SafaridriverOptions } from 'safaridriver';
5
- import { type GeckodriverParameters } from 'geckodriver';
6
- import { type EdgedriverParameters } from 'edgedriver';
7
- import { type InstallOptions } from '@puppeteer/browsers';
8
- import type { Capabilities } from '@wdio/types';
9
- export interface ExtendedCapabilities extends Capabilities.Capabilities, WDIODriverOptions {
10
- }
11
- export type ChromedriverOptions = InstallOptions & Omit<EdgedriverParameters, 'port' | 'edgeDriverVersion' | 'customEdgeDriverPath'>;
12
- export interface WDIODriverOptions {
13
- 'wdio:chromedriverOptions'?: ChromedriverOptions;
14
- 'wdio:safaridriverOptions'?: Omit<SafaridriverOptions, 'port'>;
15
- 'wdio:geckodriverOptions'?: Omit<GeckodriverParameters, 'port'>;
16
- 'wdio:edgedriverOptions'?: Omit<EdgedriverParameters, 'port'>;
17
- }
18
- export declare function startWebDriver(options: Options.WebDriver): Promise<cp.ChildProcess | undefined>;
19
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/driver/index.ts"],"names":[],"mappings":";AAIA,OAAO,EAAyB,MAAM,oBAAoB,CAAA;AAO1D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAE1C,OAAO,EAA8B,KAAK,mBAAmB,EAAE,MAAM,cAAc,CAAA;AACnF,OAAO,EAA6B,KAAK,qBAAqB,EAAE,MAAM,aAAa,CAAA;AACnF,OAAO,EAA4B,KAAK,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAChF,OAAO,EAA2C,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAElG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAO/C,MAAM,WAAW,oBAAqB,SAAQ,YAAY,CAAC,YAAY,EAAE,iBAAiB;CAAG;AAC7F,MAAM,MAAM,mBAAmB,GAAG,cAAc,GAAG,IAAI,CAAC,oBAAoB,EAAE,MAAM,GAAG,mBAAmB,GAAG,sBAAsB,CAAC,CAAA;AAEpI,MAAM,WAAW,iBAAiB;IAC9B,0BAA0B,CAAC,EAAE,mBAAmB,CAAA;IAChD,0BAA0B,CAAC,EAAE,IAAI,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAA;IAC9D,yBAAyB,CAAC,EAAE,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAA;IAC/D,wBAAwB,CAAC,EAAE,IAAI,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAA;CAChE;AAED,wBAAsB,cAAc,CAAE,OAAO,EAAE,OAAO,CAAC,SAAS,wCAsK/D"}
@@ -1,172 +0,0 @@
1
- import fs from 'node:fs';
2
- import fsp from 'node:fs/promises';
3
- import os from 'node:os';
4
- import path from 'node:path';
5
- import cp from 'node:child_process';
6
- import got from 'got';
7
- import getPort from 'get-port';
8
- import waitPort from 'wait-port';
9
- import logger from '@wdio/logger';
10
- import { deepmerge } from 'deepmerge-ts';
11
- import { start as startSafaridriver } from 'safaridriver';
12
- import { start as startGeckodriver } from 'geckodriver';
13
- import { start as startEdgedriver } from 'edgedriver';
14
- import { install, computeExecutablePath, Browser } from '@puppeteer/browsers';
15
- import { parseParams, setupChrome, definesRemoteDriver, downloadProgressCallback } from './utils.js';
16
- import { SUPPORTED_BROWSERNAMES } from '../constants.js';
17
- const log = logger('webdriver');
18
- export async function startWebDriver(options) {
19
- /**
20
- * in case we are running unit tests, just return
21
- */
22
- if (process.env.WDIO_SKIP_DRIVER_SETUP) {
23
- options.hostname = '0.0.0.0';
24
- options.port = 4321;
25
- return;
26
- }
27
- /**
28
- * if any of the connection parameter are set, don't start any driver
29
- */
30
- if (definesRemoteDriver(options)) {
31
- log.info(`Connecting to existing driver at ${options.protocol}://${options.hostname}:${options.port}${options.path}`);
32
- return;
33
- }
34
- let driverProcess;
35
- let driver = '';
36
- const start = Date.now();
37
- const caps = options.capabilities.alwaysMatch || options.capabilities;
38
- /**
39
- * session might be a mobile session so don't do anything
40
- */
41
- if (!caps.browserName) {
42
- throw new Error('No "browserName" defined in capabilities nor hostname or port found!\n' +
43
- 'If you like to run a mobile session with Appium, make sure to set "hostname" and "port" in your ' +
44
- 'WebdriverIO options. If you like to run a local browser session make sure to pick from one of ' +
45
- `the following browser names: ${Object.values(SUPPORTED_BROWSERNAMES).flat(Infinity)}`);
46
- }
47
- const port = await getPort();
48
- if (SUPPORTED_BROWSERNAMES.chrome.includes(caps.browserName.toLowerCase())) {
49
- /**
50
- * Chrome
51
- */
52
- caps.browserName = caps.browserName.toLowerCase();
53
- const chromedriverOptions = caps['wdio:chromedriverOptions'] || {};
54
- const cacheDir = chromedriverOptions.cacheDir || options.cacheDir || os.tmpdir();
55
- const exist = await fsp.access(cacheDir).then(() => true, () => false);
56
- if (!exist) {
57
- await fsp.mkdir(cacheDir, { recursive: true });
58
- }
59
- const { executablePath, buildId, platform } = await setupChrome(caps, cacheDir);
60
- let chromedriverBinaryPath = computeExecutablePath({
61
- browser: Browser.CHROMEDRIVER,
62
- buildId,
63
- cacheDir
64
- });
65
- let loggedBuildId = buildId;
66
- const hasChromedriverInstalled = await fsp.access(chromedriverBinaryPath).then(() => true, () => false);
67
- if (!hasChromedriverInstalled) {
68
- log.info(`Downloading Chromedriver v${buildId}`);
69
- const chromedriverInstallOpts = {
70
- ...chromedriverOptions,
71
- cacheDir,
72
- platform,
73
- buildId,
74
- browser: Browser.CHROMEDRIVER,
75
- unpack: true,
76
- downloadProgressCallback: (downloadedBytes, totalBytes) => downloadProgressCallback('Chromedriver', downloadedBytes, totalBytes)
77
- };
78
- try {
79
- await install({ ...chromedriverInstallOpts, buildId });
80
- }
81
- catch (err) {
82
- /**
83
- * in case we detect a Chrome browser installed for which there is no Chromedriver available
84
- * we are falling back to the latest known good version
85
- */
86
- log.warn(`Couldn't download Chromedriver v${buildId}: ${err.message}, trying to find known good version...`);
87
- const majorVersion = buildId.split('.')[0];
88
- const knownGoodVersions = await got('https://googlechromelabs.github.io/chrome-for-testing/known-good-versions.json').json();
89
- const knownGoodVersion = knownGoodVersions.versions.filter(({ version }) => version.startsWith(majorVersion)).pop();
90
- if (!knownGoodVersion) {
91
- throw new Error(`Couldn't find known good version for Chromedriver v${majorVersion}`);
92
- }
93
- loggedBuildId = knownGoodVersion.version;
94
- await install({ ...chromedriverInstallOpts, buildId: loggedBuildId });
95
- chromedriverBinaryPath = computeExecutablePath({
96
- browser: Browser.CHROMEDRIVER,
97
- buildId: loggedBuildId,
98
- cacheDir
99
- });
100
- }
101
- }
102
- else {
103
- log.info(`Using Chromedriver v${buildId} from cache directory ${cacheDir}`);
104
- }
105
- caps['goog:chromeOptions'] = deepmerge({ binary: executablePath }, caps['goog:chromeOptions'] || {});
106
- chromedriverOptions.allowedOrigins = chromedriverOptions.allowedOrigins || ['*'];
107
- chromedriverOptions.allowedIps = chromedriverOptions.allowedIps || [''];
108
- const driverParams = parseParams({ port, ...chromedriverOptions });
109
- driverProcess = cp.spawn(chromedriverBinaryPath, driverParams);
110
- driver = `Chromedriver v${loggedBuildId} with params ${driverParams.join(' ')}`;
111
- }
112
- else if (SUPPORTED_BROWSERNAMES.safari.includes(caps.browserName.toLowerCase())) {
113
- const safaridriverOptions = caps['wdio:safaridriverOptions'] || {};
114
- /**
115
- * Safari
116
- */
117
- driver = 'SafariDriver';
118
- driverProcess = startSafaridriver({
119
- useTechnologyPreview: Boolean(caps.browserName.match(/preview/i)),
120
- ...safaridriverOptions,
121
- port
122
- });
123
- /**
124
- * set "Host" header as it is required by Safaridriver
125
- */
126
- options.headers = deepmerge({ Host: 'localhost' }, (options.headers || {}));
127
- }
128
- else if (SUPPORTED_BROWSERNAMES.firefox.includes(caps.browserName.toLowerCase())) {
129
- /**
130
- * Firefox
131
- */
132
- const geckodriverOptions = caps['wdio:geckodriverOptions'] || {};
133
- const cacheDir = geckodriverOptions.cacheDir || options.cacheDir || os.tmpdir();
134
- driver = 'GeckoDriver';
135
- driverProcess = await startGeckodriver({ ...geckodriverOptions, cacheDir, port });
136
- }
137
- else if (SUPPORTED_BROWSERNAMES.edge.includes(caps.browserName.toLowerCase())) {
138
- /**
139
- * Microsoft Edge
140
- */
141
- const edgedriverOptions = caps['wdio:edgedriverOptions'] || {};
142
- const cacheDir = edgedriverOptions.cacheDir || options.cacheDir || os.tmpdir();
143
- driver = 'EdgeDriver';
144
- driverProcess = await startEdgedriver({ ...edgedriverOptions, cacheDir, port }).catch((err) => {
145
- log.warn(`Couldn't start EdgeDriver: ${err.message}, retry ...`);
146
- return startEdgedriver({ ...edgedriverOptions, cacheDir, port });
147
- });
148
- /**
149
- * Microsoft Edge is very particular when it comes to browser names
150
- */
151
- caps.browserName = 'MicrosoftEdge';
152
- }
153
- else {
154
- throw new Error(`Unknown browser name "${caps.browserName}". Make sure to pick from one of the following ` +
155
- Object.values(SUPPORTED_BROWSERNAMES).flat(Infinity));
156
- }
157
- if (options.outputDir) {
158
- const logIdentifier = driver.split(' ').shift()?.toLowerCase();
159
- const logFileName = process.env.WDIO_WORKER_ID
160
- ? `wdio-${process.env.WDIO_WORKER_ID}-${logIdentifier}.log`
161
- : `wdio-${logIdentifier}-${port}.log`;
162
- const logFile = path.resolve(options.outputDir, logFileName);
163
- const logStream = fs.createWriteStream(logFile, { flags: 'w' });
164
- driverProcess.stdout?.pipe(logStream);
165
- driverProcess.stderr?.pipe(logStream);
166
- }
167
- await waitPort({ port, output: 'silent' });
168
- options.hostname = '0.0.0.0';
169
- options.port = port;
170
- log.info(`Started ${driver} in ${Date.now() - start}ms on port ${port}`);
171
- return driverProcess;
172
- }
@@ -1,18 +0,0 @@
1
- import type { EdgedriverParameters } from 'edgedriver';
2
- import type { Capabilities, Options } from '@wdio/types';
3
- export declare function parseParams(params: EdgedriverParameters): string[];
4
- export declare function getLocalChromePath(): string | undefined;
5
- export declare function getBuildIdByPath(chromePath?: string): string | undefined;
6
- export declare const downloadProgressCallback: (artifact: string, downloadedBytes: number, totalBytes: number) => void;
7
- export declare function setupChrome(caps: Capabilities.Capabilities, cacheDir: string): Promise<{
8
- platform: import("@puppeteer/browsers").BrowserPlatform;
9
- executablePath: string;
10
- buildId: string;
11
- }>;
12
- /**
13
- * helper method to determine if we need to start a browser driver
14
- * which is: whenever the user has set connection options that differ from
15
- * the default, or a port is set
16
- */
17
- export declare function definesRemoteDriver(options: Options.WebDriver): boolean;
18
- //# sourceMappingURL=utils.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/driver/utils.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAOxD,wBAAgB,WAAW,CAAC,MAAM,EAAE,oBAAoB,YAYvD;AAED,wBAAgB,kBAAkB,uBAOjC;AAED,wBAAgB,gBAAgB,CAAC,UAAU,CAAC,EAAE,MAAM,sBAenD;AAGD,eAAO,MAAM,wBAAwB,aAAc,MAAM,mBAAmB,MAAM,cAAc,MAAM,SAOrG,CAAA;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,YAAY,CAAC,YAAY,EAAE,QAAQ,EAAE,MAAM;;;;GA4ClF;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,WAO7D"}
@@ -1,109 +0,0 @@
1
- import os from 'node:os';
2
- import fs from 'node:fs';
3
- import path from 'node:path';
4
- import cp from 'node:child_process';
5
- import decamelize from 'decamelize';
6
- import logger from '@wdio/logger';
7
- import { getChromePath } from 'chrome-launcher';
8
- import { install, canDownload, resolveBuildId, detectBrowserPlatform, Browser, ChromeReleaseChannel, computeExecutablePath } from '@puppeteer/browsers';
9
- import { DEFAULTS } from '../constants.js';
10
- const log = logger('webdriver');
11
- const EXCLUDED_PARAMS = ['version', 'help'];
12
- export function parseParams(params) {
13
- return Object.entries(params)
14
- .filter(([key,]) => !EXCLUDED_PARAMS.includes(key))
15
- .map(([key, val]) => {
16
- if (typeof val === 'boolean' && !val) {
17
- return '';
18
- }
19
- const vals = Array.isArray(val) ? val : [val];
20
- return vals.map((v) => `--${decamelize(key, { separator: '-' })}${typeof v === 'boolean' ? '' : `=${v}`}`);
21
- })
22
- .flat()
23
- .filter(Boolean);
24
- }
25
- export function getLocalChromePath() {
26
- try {
27
- const chromePath = getChromePath();
28
- return chromePath;
29
- }
30
- catch (err) {
31
- return;
32
- }
33
- }
34
- export function getBuildIdByPath(chromePath) {
35
- if (!chromePath) {
36
- return;
37
- }
38
- else if (os.platform() === 'win32') {
39
- const versionPath = path.dirname(chromePath);
40
- const contents = fs.readdirSync(versionPath);
41
- const versions = contents.filter(a => /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/g.test(a));
42
- // returning oldest in case there is an updated version and chrome still hasn't relaunched
43
- const oldest = versions.sort((a, b) => a > b ? -1 : 1)[0];
44
- return oldest;
45
- }
46
- const versionString = cp.execSync(`"${chromePath}" --version`).toString();
47
- return versionString.split(' ').pop()?.trim();
48
- }
49
- let lastTimeCalled = Date.now();
50
- export const downloadProgressCallback = (artifact, downloadedBytes, totalBytes) => {
51
- if (Date.now() - lastTimeCalled < 1000) {
52
- return;
53
- }
54
- const percentage = ((downloadedBytes / totalBytes) * 100).toFixed(2);
55
- log.info(`Downloading ${artifact} ${percentage}%`);
56
- lastTimeCalled = Date.now();
57
- };
58
- export async function setupChrome(caps, cacheDir) {
59
- const platform = detectBrowserPlatform();
60
- if (!platform) {
61
- throw new Error('The current platform is not supported.');
62
- }
63
- if (!caps.browserVersion) {
64
- const executablePath = getLocalChromePath();
65
- const tag = getBuildIdByPath(executablePath);
66
- /**
67
- * verify that we have a valid Chrome browser installed
68
- */
69
- if (tag) {
70
- return {
71
- platform,
72
- executablePath,
73
- buildId: await resolveBuildId(Browser.CHROME, platform, tag)
74
- };
75
- }
76
- }
77
- /**
78
- * otherwise download provided Chrome browser version or "stable"
79
- */
80
- const tag = caps.browserVersion || ChromeReleaseChannel.STABLE;
81
- const buildId = await resolveBuildId(Browser.CHROME, platform, tag);
82
- const installOptions = {
83
- unpack: true,
84
- cacheDir,
85
- platform,
86
- buildId,
87
- browser: Browser.CHROME,
88
- downloadProgressCallback: (downloadedBytes, totalBytes) => downloadProgressCallback('Chrome', downloadedBytes, totalBytes)
89
- };
90
- const isCombinationAvailable = await canDownload(installOptions);
91
- if (!isCombinationAvailable) {
92
- throw new Error(`Couldn't find a matching Chrome browser for tag "${buildId}" on platform "${platform}"`);
93
- }
94
- log.info(`Setting up Chrome v${buildId}`);
95
- await install(installOptions);
96
- const executablePath = computeExecutablePath(installOptions);
97
- return { executablePath, buildId, platform };
98
- }
99
- /**
100
- * helper method to determine if we need to start a browser driver
101
- * which is: whenever the user has set connection options that differ from
102
- * the default, or a port is set
103
- */
104
- export function definesRemoteDriver(options) {
105
- return Boolean((options.protocol && options.protocol !== DEFAULTS.protocol.default) ||
106
- (options.hostname && options.hostname !== DEFAULTS.hostname.default) ||
107
- Boolean(options.port) ||
108
- (options.path && options.path !== DEFAULTS.path.default));
109
- }