appium-chromedriver 5.5.3 → 5.6.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/CHANGELOG.md +7 -0
- package/README.md +14 -0
- package/build/lib/chromedriver.d.ts +1 -1
- package/build/lib/chromedriver.d.ts.map +1 -1
- package/build/lib/chromedriver.js +4 -4
- package/build/lib/chromedriver.js.map +1 -1
- package/build/lib/constants.d.ts +19 -0
- package/build/lib/constants.d.ts.map +1 -0
- package/build/lib/constants.js +26 -0
- package/build/lib/constants.js.map +1 -0
- package/build/lib/index.d.ts +1 -1
- package/build/lib/index.d.ts.map +1 -1
- package/build/lib/index.js +1 -1
- package/build/lib/index.js.map +1 -1
- package/build/lib/install.d.ts.map +1 -1
- package/build/lib/install.js +23 -8
- package/build/lib/install.js.map +1 -1
- package/build/lib/storage-client/chromelabs.d.ts +22 -0
- package/build/lib/storage-client/chromelabs.d.ts.map +1 -0
- package/build/lib/storage-client/chromelabs.js +148 -0
- package/build/lib/storage-client/chromelabs.js.map +1 -0
- package/build/lib/storage-client/googleapis.d.ts +32 -0
- package/build/lib/storage-client/googleapis.d.ts.map +1 -0
- package/build/lib/storage-client/googleapis.js +188 -0
- package/build/lib/storage-client/googleapis.js.map +1 -0
- package/build/lib/{storage-client.d.ts → storage-client/storage-client.d.ts} +14 -36
- package/build/lib/storage-client/storage-client.d.ts.map +1 -0
- package/build/lib/{storage-client.js → storage-client/storage-client.js} +105 -181
- package/build/lib/storage-client/storage-client.js.map +1 -0
- package/build/lib/types.d.ts +9 -3
- package/build/lib/types.d.ts.map +1 -1
- package/build/lib/utils.d.ts +6 -9
- package/build/lib/utils.d.ts.map +1 -1
- package/build/lib/utils.js +20 -21
- package/build/lib/utils.js.map +1 -1
- package/lib/chromedriver.js +4 -5
- package/lib/constants.js +24 -0
- package/lib/index.ts +1 -1
- package/lib/install.js +27 -10
- package/lib/storage-client/chromelabs.js +141 -0
- package/lib/storage-client/googleapis.js +209 -0
- package/lib/{storage-client.js → storage-client/storage-client.js} +124 -213
- package/lib/types.ts +9 -3
- package/lib/utils.js +20 -20
- package/package.json +1 -1
- package/build/lib/storage-client.d.ts.map +0 -1
- package/build/lib/storage-client.js.map +0 -1
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parseGoogleapiStorageXml = exports.parseNotes = exports.findChildNode = void 0;
|
|
7
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
8
|
+
const xpath_1 = __importDefault(require("xpath"));
|
|
9
|
+
const support_1 = require("@appium/support");
|
|
10
|
+
const utils_1 = require("../utils");
|
|
11
|
+
const bluebird_1 = __importDefault(require("bluebird"));
|
|
12
|
+
const constants_1 = require("../constants");
|
|
13
|
+
const xmldom_1 = require("@xmldom/xmldom");
|
|
14
|
+
const path_1 = __importDefault(require("path"));
|
|
15
|
+
const log = support_1.logger.getLogger('ChromedriverGoogleapisStorageClient');
|
|
16
|
+
const MAX_PARALLEL_DOWNLOADS = 5;
|
|
17
|
+
/**
|
|
18
|
+
*
|
|
19
|
+
* @param {Node|Attr} parent
|
|
20
|
+
* @param {string?} childName
|
|
21
|
+
* @param {string?} text
|
|
22
|
+
* @returns
|
|
23
|
+
*/
|
|
24
|
+
function findChildNode(parent, childName = null, text = null) {
|
|
25
|
+
if (!childName && !text) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
if (!parent.hasChildNodes()) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
for (let childNodeIdx = 0; childNodeIdx < parent.childNodes.length; childNodeIdx++) {
|
|
32
|
+
const childNode = /** @type {Element|Attr} */ (parent.childNodes[childNodeIdx]);
|
|
33
|
+
if (childName && !text && childName === childNode.localName) {
|
|
34
|
+
return childNode;
|
|
35
|
+
}
|
|
36
|
+
if (text) {
|
|
37
|
+
const childText = extractNodeText(childNode);
|
|
38
|
+
if (!childText) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (childName && childName === childNode.localName && text === childText) {
|
|
42
|
+
return childNode;
|
|
43
|
+
}
|
|
44
|
+
if (!childName && text === childText) {
|
|
45
|
+
return childNode;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
exports.findChildNode = findChildNode;
|
|
52
|
+
/**
|
|
53
|
+
*
|
|
54
|
+
* @param {Node?} node
|
|
55
|
+
* @returns
|
|
56
|
+
*/
|
|
57
|
+
function extractNodeText(node) {
|
|
58
|
+
return !node || !node.firstChild || !support_1.util.hasValue(node.firstChild.nodeValue)
|
|
59
|
+
? null
|
|
60
|
+
: node.firstChild.nodeValue;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Gets additional chromedriver details from chromedriver
|
|
64
|
+
* release notes
|
|
65
|
+
*
|
|
66
|
+
* @param {string} content - Release notes of the corresponding chromedriver
|
|
67
|
+
* @returns {import('../types').AdditionalDriverDetails}
|
|
68
|
+
*/
|
|
69
|
+
function parseNotes(content) {
|
|
70
|
+
const result = {};
|
|
71
|
+
const versionMatch = /^\s*[-]+ChromeDriver[\D]+([\d.]+)/im.exec(content);
|
|
72
|
+
if (versionMatch) {
|
|
73
|
+
result.version = versionMatch[1];
|
|
74
|
+
}
|
|
75
|
+
const minBrowserVersionMatch = /^\s*Supports Chrome[\D]+(\d+)/im.exec(content);
|
|
76
|
+
if (minBrowserVersionMatch) {
|
|
77
|
+
result.minBrowserVersion = minBrowserVersionMatch[1];
|
|
78
|
+
}
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
exports.parseNotes = parseNotes;
|
|
82
|
+
/**
|
|
83
|
+
* Parses chromedriver storage XML and returns
|
|
84
|
+
* the parsed results
|
|
85
|
+
*
|
|
86
|
+
* @param {string} xml - The chromedriver storage XML
|
|
87
|
+
* @param {boolean} shouldParseNotes [true] - If set to `true`
|
|
88
|
+
* then additional drivers information is going to be parsed
|
|
89
|
+
* and assigned to `this.mapping`
|
|
90
|
+
* @returns {Promise<ChromedriverDetailsMapping>}
|
|
91
|
+
*/
|
|
92
|
+
async function parseGoogleapiStorageXml(xml, shouldParseNotes = true) {
|
|
93
|
+
const doc = new xmldom_1.DOMParser().parseFromString(xml);
|
|
94
|
+
const driverNodes = /** @type {Array<Node|Attr>} */ (xpath_1.default.select(`//*[local-name(.)='Contents']`, doc));
|
|
95
|
+
log.debug(`Parsed ${driverNodes.length} entries from storage XML`);
|
|
96
|
+
if (lodash_1.default.isEmpty(driverNodes)) {
|
|
97
|
+
throw new Error('Cannot retrieve any valid Chromedriver entries from the storage config');
|
|
98
|
+
}
|
|
99
|
+
const promises = [];
|
|
100
|
+
const chunk = [];
|
|
101
|
+
/** @type {ChromedriverDetailsMapping} */
|
|
102
|
+
const mapping = {};
|
|
103
|
+
for (const driverNode of driverNodes) {
|
|
104
|
+
const k = extractNodeText(findChildNode(driverNode, 'Key'));
|
|
105
|
+
if (!lodash_1.default.includes(k, '/chromedriver_')) {
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
const key = String(k);
|
|
109
|
+
const etag = extractNodeText(findChildNode(driverNode, 'ETag'));
|
|
110
|
+
if (!etag) {
|
|
111
|
+
log.debug(`The entry '${key}' does not contain the checksum. Skipping it`);
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
const filename = path_1.default.basename(key);
|
|
115
|
+
const osNameMatch = /_([a-z]+)/i.exec(filename);
|
|
116
|
+
if (!osNameMatch) {
|
|
117
|
+
log.debug(`The entry '${key}' does not contain valid OS name. Skipping it`);
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
/** @type {ChromedriverDetails} */
|
|
121
|
+
const cdInfo = {
|
|
122
|
+
url: `${constants_1.GOOGLEAPIS_CDN}/${key}`,
|
|
123
|
+
etag: lodash_1.default.trim(etag, '"'),
|
|
124
|
+
version: /** @type {string} */ (lodash_1.default.first(key.split('/'))),
|
|
125
|
+
minBrowserVersion: null,
|
|
126
|
+
os: {
|
|
127
|
+
name: osNameMatch[1],
|
|
128
|
+
arch: filename.includes(constants_1.ARCH.X64) ? constants_1.ARCH.X64 : constants_1.ARCH.X86,
|
|
129
|
+
cpu: constants_1.APPLE_ARM_SUFFIXES.some((suffix) => filename.includes(suffix)) ? constants_1.CPU.ARM : constants_1.CPU.INTEL,
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
mapping[key] = cdInfo;
|
|
133
|
+
const notesPath = `${cdInfo.version}/notes.txt`;
|
|
134
|
+
const isNotesPresent = !!driverNodes.reduce((acc, node) => Boolean(acc || findChildNode(node, 'Key', notesPath)), false);
|
|
135
|
+
if (!isNotesPresent) {
|
|
136
|
+
cdInfo.minBrowserVersion = null;
|
|
137
|
+
if (shouldParseNotes) {
|
|
138
|
+
log.info(`The entry '${key}' does not contain any notes. Skipping it`);
|
|
139
|
+
}
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
else if (!shouldParseNotes) {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
const promise = bluebird_1.default.resolve(retrieveAdditionalDriverInfo(key, `${constants_1.GOOGLEAPIS_CDN}/${notesPath}`, cdInfo));
|
|
146
|
+
promises.push(promise);
|
|
147
|
+
chunk.push(promise);
|
|
148
|
+
if (chunk.length >= MAX_PARALLEL_DOWNLOADS) {
|
|
149
|
+
await bluebird_1.default.any(chunk);
|
|
150
|
+
}
|
|
151
|
+
lodash_1.default.remove(chunk, (p) => p.isFulfilled());
|
|
152
|
+
}
|
|
153
|
+
await bluebird_1.default.all(promises);
|
|
154
|
+
log.info(`The total count of entries in the mapping: ${lodash_1.default.size(mapping)}`);
|
|
155
|
+
return mapping;
|
|
156
|
+
}
|
|
157
|
+
exports.parseGoogleapiStorageXml = parseGoogleapiStorageXml;
|
|
158
|
+
/**
|
|
159
|
+
* Downloads chromedriver release notes and puts them
|
|
160
|
+
* into the dictionary argument
|
|
161
|
+
*
|
|
162
|
+
* The method call mutates by merging `AdditionalDriverDetails`
|
|
163
|
+
* @param {string} driverKey - Driver version plus archive name
|
|
164
|
+
* @param {string} notesUrl - The URL of chromedriver notes
|
|
165
|
+
* @param {ChromedriverDetails} infoDict - The dictionary containing driver info.
|
|
166
|
+
* @param {number} timeout
|
|
167
|
+
* @throws {Error} if the release notes cannot be downloaded
|
|
168
|
+
*/
|
|
169
|
+
async function retrieveAdditionalDriverInfo(driverKey, notesUrl, infoDict, timeout = constants_1.STORAGE_REQ_TIMEOUT_MS) {
|
|
170
|
+
const notes = await (0, utils_1.retrieveData)(notesUrl, {
|
|
171
|
+
'user-agent': 'appium',
|
|
172
|
+
accept: '*/*',
|
|
173
|
+
}, { timeout });
|
|
174
|
+
const { minBrowserVersion } = parseNotes(notes);
|
|
175
|
+
if (!minBrowserVersion) {
|
|
176
|
+
log.debug(`The driver '${driverKey}' does not contain valid release notes at ${notesUrl}. ` +
|
|
177
|
+
`Skipping it`);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
infoDict.minBrowserVersion = minBrowserVersion;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* @typedef {import('../types').SyncOptions} SyncOptions
|
|
184
|
+
* @typedef {import('../types').OSInfo} OSInfo
|
|
185
|
+
* @typedef {import('../types').ChromedriverDetails} ChromedriverDetails
|
|
186
|
+
* @typedef {import('../types').ChromedriverDetailsMapping} ChromedriverDetailsMapping
|
|
187
|
+
*/
|
|
188
|
+
//# sourceMappingURL=googleapis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"googleapis.js","sourceRoot":"","sources":["../../../lib/storage-client/googleapis.js"],"names":[],"mappings":"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"}
|
|
@@ -1,43 +1,13 @@
|
|
|
1
1
|
export class ChromedriverStorageClient {
|
|
2
2
|
/**
|
|
3
3
|
*
|
|
4
|
-
* @param {import('
|
|
4
|
+
* @param {import('../types').ChromedriverStorageClientOpts} args
|
|
5
5
|
*/
|
|
6
|
-
constructor(args?: import('
|
|
6
|
+
constructor(args?: import('../types').ChromedriverStorageClientOpts);
|
|
7
7
|
chromedriverDir: string;
|
|
8
8
|
timeout: number;
|
|
9
9
|
/** @type {ChromedriverDetailsMapping} */
|
|
10
10
|
mapping: ChromedriverDetailsMapping;
|
|
11
|
-
/**
|
|
12
|
-
* Gets additional chromedriver details from chromedriver
|
|
13
|
-
* release notes
|
|
14
|
-
*
|
|
15
|
-
* @param {string} content - Release notes of the corresponding chromedriver
|
|
16
|
-
* @returns {import('./types').AdditionalDriverDetails}
|
|
17
|
-
*/
|
|
18
|
-
parseNotes(content: string): import('./types').AdditionalDriverDetails;
|
|
19
|
-
/**
|
|
20
|
-
* Downloads chromedriver release notes and puts them
|
|
21
|
-
* into the dictionary argument
|
|
22
|
-
*
|
|
23
|
-
* The method call mutates by merging `AdditionalDriverDetails`
|
|
24
|
-
* @param {string} driverKey - Driver version plus archive name
|
|
25
|
-
* @param {string} notesUrl - The URL of chromedriver notes
|
|
26
|
-
* @param {ChromedriverDetails} infoDict - The dictionary containing driver info.
|
|
27
|
-
* @throws {Error} if the release notes cannot be downloaded
|
|
28
|
-
*/
|
|
29
|
-
retrieveAdditionalDriverInfo(driverKey: string, notesUrl: string, infoDict: ChromedriverDetails): Promise<void>;
|
|
30
|
-
/**
|
|
31
|
-
* Parses chromedriver storage XML and stores
|
|
32
|
-
* the parsed results into `this.mapping`
|
|
33
|
-
*
|
|
34
|
-
* @param {Document} doc - The DOM representation
|
|
35
|
-
* of the chromedriver storage XML
|
|
36
|
-
* @param {boolean} shouldParseNotes [true] - If set to `true`
|
|
37
|
-
* then additional drivers information is going to be parsed
|
|
38
|
-
* and assigned to `this.mapping`
|
|
39
|
-
*/
|
|
40
|
-
parseStorageXml(doc: Document, shouldParseNotes?: boolean): Promise<void>;
|
|
41
11
|
/**
|
|
42
12
|
* Retrieves chromedriver mapping from the storage
|
|
43
13
|
*
|
|
@@ -66,6 +36,14 @@ export class ChromedriverStorageClient {
|
|
|
66
36
|
* entry names (version/archive name)
|
|
67
37
|
*/
|
|
68
38
|
selectMatchingDrivers(osInfo: OSInfo, opts?: SyncOptions): Array<string>;
|
|
39
|
+
/**
|
|
40
|
+
* Checks whether the given chromedriver matches the operating system to run on
|
|
41
|
+
*
|
|
42
|
+
* @param {string} cdName
|
|
43
|
+
* @param {OSInfo} osInfo
|
|
44
|
+
* @returns {boolean}
|
|
45
|
+
*/
|
|
46
|
+
doesMatchForOsInfo(cdName: string, { name, arch, cpu }: OSInfo): boolean;
|
|
69
47
|
/**
|
|
70
48
|
* Retrieves the given chromedriver from the storage
|
|
71
49
|
* and unpacks it into `this.chromedriverDir` folder
|
|
@@ -94,8 +72,8 @@ export class ChromedriverStorageClient {
|
|
|
94
72
|
syncDrivers(opts?: SyncOptions): Promise<string[]>;
|
|
95
73
|
}
|
|
96
74
|
export default ChromedriverStorageClient;
|
|
97
|
-
export type SyncOptions = import('
|
|
98
|
-
export type OSInfo = import('
|
|
99
|
-
export type ChromedriverDetails = import('
|
|
100
|
-
export type ChromedriverDetailsMapping = import('
|
|
75
|
+
export type SyncOptions = import('../types').SyncOptions;
|
|
76
|
+
export type OSInfo = import('../types').OSInfo;
|
|
77
|
+
export type ChromedriverDetails = import('../types').ChromedriverDetails;
|
|
78
|
+
export type ChromedriverDetailsMapping = import('../types').ChromedriverDetailsMapping;
|
|
101
79
|
//# sourceMappingURL=storage-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-client.d.ts","sourceRoot":"","sources":["../../../lib/storage-client/storage-client.js"],"names":[],"mappings":"AAwCA;IACE;;;OAGG;IACH,mBAFW,OAAO,UAAU,EAAE,6BAA6B,EAQ1D;IAJC,wBAAsC;IACtC,gBAAsB;IACtB,yCAAyC;IACzC,SADW,0BAA0B,CACpB;IAGnB;;;;;;;OAOG;IACH,mCALW,OAAO,GAGL,QAAQ,0BAA0B,CAAC,CAiB/C;IAED;;;;;;OAMG;IACH,iBAHW,MAAM,OACN,MAAM,iBAwBhB;IAED;;;;;;;;;OASG;IACH,8BALW,MAAM,SACN,WAAW,GACT,aAAa,CAyHzB;IAED;;;;;;OAMG;IACH,2BAJW,MAAM,uBACN,MAAM,GACJ,OAAO,CAgBnB;IAED;;;;;;;;;;;;;;OAcG;IACH,sBAXW,MAAM,aACN,MAAM,gBACN,MAAM,aAEN,OAAO,GAIL,QAAQ,OAAO,CAAC,CA4C5B;IAED;;;;;;;;OAQG;IACH,mBALW,WAAW,GAGT,QAAQ,MAAM,EAAE,CAAC,CAwD7B;CACF;;0BAKY,OAAO,UAAU,EAAE,WAAW;qBAC9B,OAAO,UAAU,EAAE,MAAM;kCACzB,OAAO,UAAU,EAAE,mBAAmB;yCACtC,OAAO,UAAU,EAAE,0BAA0B"}
|
|
@@ -4,15 +4,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.ChromedriverStorageClient = void 0;
|
|
7
|
-
const utils_1 = require("
|
|
7
|
+
const utils_1 = require("../utils");
|
|
8
8
|
const lodash_1 = __importDefault(require("lodash"));
|
|
9
|
-
const xpath_1 = __importDefault(require("xpath"));
|
|
10
|
-
const xmldom_1 = require("@xmldom/xmldom");
|
|
11
9
|
const bluebird_1 = __importDefault(require("bluebird"));
|
|
12
10
|
const path_1 = __importDefault(require("path"));
|
|
13
|
-
const os_1 = __importDefault(require("os"));
|
|
14
11
|
const support_1 = require("@appium/support");
|
|
15
|
-
const
|
|
12
|
+
const constants_1 = require("../constants");
|
|
13
|
+
const googleapis_1 = require("./googleapis");
|
|
14
|
+
const chromelabs_1 = require("./chromelabs");
|
|
15
|
+
const compare_versions_1 = require("compare-versions");
|
|
16
|
+
const semver_1 = __importDefault(require("semver"));
|
|
16
17
|
const MAX_PARALLEL_DOWNLOADS = 5;
|
|
17
18
|
const log = support_1.logger.getLogger('ChromedriverStorageClient');
|
|
18
19
|
/**
|
|
@@ -25,160 +26,18 @@ async function isCrcOk(src, checksum) {
|
|
|
25
26
|
const md5 = await support_1.fs.hash(src, 'md5');
|
|
26
27
|
return lodash_1.default.toLower(md5) === lodash_1.default.toLower(checksum);
|
|
27
28
|
}
|
|
28
|
-
/**
|
|
29
|
-
*
|
|
30
|
-
* @param {Node|Attr} parent
|
|
31
|
-
* @param {string?} childName
|
|
32
|
-
* @param {string?} text
|
|
33
|
-
* @returns
|
|
34
|
-
*/
|
|
35
|
-
function findChildNode(parent, childName = null, text = null) {
|
|
36
|
-
if (!childName && !text) {
|
|
37
|
-
return null;
|
|
38
|
-
}
|
|
39
|
-
if (!parent.hasChildNodes()) {
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
for (let childNodeIdx = 0; childNodeIdx < parent.childNodes.length; childNodeIdx++) {
|
|
43
|
-
const childNode = /** @type {Element|Attr} */ (parent.childNodes[childNodeIdx]);
|
|
44
|
-
if (childName && !text && childName === childNode.localName) {
|
|
45
|
-
return childNode;
|
|
46
|
-
}
|
|
47
|
-
if (text) {
|
|
48
|
-
const childText = extractNodeText(childNode);
|
|
49
|
-
if (!childText) {
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
if (childName && childName === childNode.localName && text === childText) {
|
|
53
|
-
return childNode;
|
|
54
|
-
}
|
|
55
|
-
if (!childName && text === childText) {
|
|
56
|
-
return childNode;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return null;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
*
|
|
64
|
-
* @param {Node?} node
|
|
65
|
-
* @returns
|
|
66
|
-
*/
|
|
67
|
-
function extractNodeText(node) {
|
|
68
|
-
return !node || !node.firstChild || !support_1.util.hasValue(node.firstChild.nodeValue)
|
|
69
|
-
? null
|
|
70
|
-
: node.firstChild.nodeValue;
|
|
71
|
-
}
|
|
72
29
|
class ChromedriverStorageClient {
|
|
73
30
|
/**
|
|
74
31
|
*
|
|
75
|
-
* @param {import('
|
|
32
|
+
* @param {import('../types').ChromedriverStorageClientOpts} args
|
|
76
33
|
*/
|
|
77
34
|
constructor(args = {}) {
|
|
78
|
-
const { chromedriverDir = (0, utils_1.getChromedriverDir)(), timeout =
|
|
35
|
+
const { chromedriverDir = (0, utils_1.getChromedriverDir)(), timeout = constants_1.STORAGE_REQ_TIMEOUT_MS } = args;
|
|
79
36
|
this.chromedriverDir = chromedriverDir;
|
|
80
37
|
this.timeout = timeout;
|
|
81
38
|
/** @type {ChromedriverDetailsMapping} */
|
|
82
39
|
this.mapping = {};
|
|
83
40
|
}
|
|
84
|
-
/**
|
|
85
|
-
* Gets additional chromedriver details from chromedriver
|
|
86
|
-
* release notes
|
|
87
|
-
*
|
|
88
|
-
* @param {string} content - Release notes of the corresponding chromedriver
|
|
89
|
-
* @returns {import('./types').AdditionalDriverDetails}
|
|
90
|
-
*/
|
|
91
|
-
parseNotes(content) {
|
|
92
|
-
const result = {};
|
|
93
|
-
const versionMatch = /^\s*[-]+ChromeDriver[\D]+([\d.]+)/im.exec(content);
|
|
94
|
-
if (versionMatch) {
|
|
95
|
-
result.version = versionMatch[1];
|
|
96
|
-
}
|
|
97
|
-
const minBrowserVersionMatch = /^\s*Supports Chrome[\D]+(\d+)/im.exec(content);
|
|
98
|
-
if (minBrowserVersionMatch) {
|
|
99
|
-
result.minBrowserVersion = minBrowserVersionMatch[1];
|
|
100
|
-
}
|
|
101
|
-
return result;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Downloads chromedriver release notes and puts them
|
|
105
|
-
* into the dictionary argument
|
|
106
|
-
*
|
|
107
|
-
* The method call mutates by merging `AdditionalDriverDetails`
|
|
108
|
-
* @param {string} driverKey - Driver version plus archive name
|
|
109
|
-
* @param {string} notesUrl - The URL of chromedriver notes
|
|
110
|
-
* @param {ChromedriverDetails} infoDict - The dictionary containing driver info.
|
|
111
|
-
* @throws {Error} if the release notes cannot be downloaded
|
|
112
|
-
*/
|
|
113
|
-
async retrieveAdditionalDriverInfo(driverKey, notesUrl, infoDict) {
|
|
114
|
-
const notes = await (0, utils_1.retrieveData)(notesUrl, {
|
|
115
|
-
'user-agent': 'appium',
|
|
116
|
-
accept: '*/*',
|
|
117
|
-
}, { timeout: this.timeout });
|
|
118
|
-
const { minBrowserVersion } = this.parseNotes(notes);
|
|
119
|
-
if (!minBrowserVersion) {
|
|
120
|
-
log.debug(`The driver '${driverKey}' does not contain valid release notes at ${notesUrl}. ` +
|
|
121
|
-
`Skipping it`);
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
infoDict.minBrowserVersion = minBrowserVersion;
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Parses chromedriver storage XML and stores
|
|
128
|
-
* the parsed results into `this.mapping`
|
|
129
|
-
*
|
|
130
|
-
* @param {Document} doc - The DOM representation
|
|
131
|
-
* of the chromedriver storage XML
|
|
132
|
-
* @param {boolean} shouldParseNotes [true] - If set to `true`
|
|
133
|
-
* then additional drivers information is going to be parsed
|
|
134
|
-
* and assigned to `this.mapping`
|
|
135
|
-
*/
|
|
136
|
-
async parseStorageXml(doc, shouldParseNotes = true) {
|
|
137
|
-
const driverNodes = /** @type {Array<Node|Attr>} */ (xpath_1.default.select(`//*[local-name(.)='Contents']`, doc));
|
|
138
|
-
log.debug(`Parsed ${driverNodes.length} entries from storage XML`);
|
|
139
|
-
if (lodash_1.default.isEmpty(driverNodes)) {
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
const promises = [];
|
|
143
|
-
for (const driverNode of driverNodes) {
|
|
144
|
-
const k = extractNodeText(findChildNode(driverNode, 'Key'));
|
|
145
|
-
if (!lodash_1.default.includes(k, '/chromedriver_')) {
|
|
146
|
-
continue;
|
|
147
|
-
}
|
|
148
|
-
const key = String(k);
|
|
149
|
-
const etag = extractNodeText(findChildNode(driverNode, 'ETag'));
|
|
150
|
-
if (!etag) {
|
|
151
|
-
log.debug(`The entry '${key}' does not contain the checksum. Skipping it`);
|
|
152
|
-
continue;
|
|
153
|
-
}
|
|
154
|
-
/** @type {ChromedriverDetails} */
|
|
155
|
-
const cdInfo = {
|
|
156
|
-
url: `${utils_1.CD_CDN}/${key}`,
|
|
157
|
-
etag: lodash_1.default.trim(etag, '"'),
|
|
158
|
-
version: /** @type {string} */ (lodash_1.default.first(key.split('/'))),
|
|
159
|
-
minBrowserVersion: null,
|
|
160
|
-
};
|
|
161
|
-
this.mapping[key] = cdInfo;
|
|
162
|
-
const notesPath = `${cdInfo.version}/notes.txt`;
|
|
163
|
-
const isNotesPresent = !!driverNodes.reduce((acc, node) => Boolean(acc || findChildNode(node, 'Key', notesPath)), false);
|
|
164
|
-
if (!isNotesPresent) {
|
|
165
|
-
cdInfo.minBrowserVersion = null;
|
|
166
|
-
if (shouldParseNotes) {
|
|
167
|
-
log.info(`The entry '${key}' does not contain any notes. Skipping it`);
|
|
168
|
-
}
|
|
169
|
-
continue;
|
|
170
|
-
}
|
|
171
|
-
else if (!shouldParseNotes) {
|
|
172
|
-
continue;
|
|
173
|
-
}
|
|
174
|
-
promises.push(this.retrieveAdditionalDriverInfo(key, `${utils_1.CD_CDN}/${notesPath}`, cdInfo));
|
|
175
|
-
if (promises.length % MAX_PARALLEL_DOWNLOADS === 0) {
|
|
176
|
-
await bluebird_1.default.all(promises);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
await bluebird_1.default.all(promises);
|
|
180
|
-
log.info(`The total count of entries in the mapping: ${lodash_1.default.size(this.mapping)}`);
|
|
181
|
-
}
|
|
182
41
|
/**
|
|
183
42
|
* Retrieves chromedriver mapping from the storage
|
|
184
43
|
*
|
|
@@ -188,13 +47,19 @@ class ChromedriverStorageClient {
|
|
|
188
47
|
* @returns {Promise<ChromedriverDetailsMapping>}
|
|
189
48
|
*/
|
|
190
49
|
async retrieveMapping(shouldParseNotes = true) {
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
50
|
+
const [xmlStr, jsonStr] = await bluebird_1.default.all([
|
|
51
|
+
[constants_1.GOOGLEAPIS_CDN, 'application/xml'],
|
|
52
|
+
[`${constants_1.CHROMELABS_URL}/chrome-for-testing/known-good-versions-with-downloads.json`, 'application/json'],
|
|
53
|
+
]
|
|
54
|
+
.map(([url, contentType]) => url
|
|
55
|
+
? (0, utils_1.retrieveData)(url, {
|
|
56
|
+
'user-agent': constants_1.USER_AGENT,
|
|
57
|
+
accept: `${contentType}, */*`,
|
|
58
|
+
}, { timeout: this.timeout })
|
|
59
|
+
: bluebird_1.default.resolve()));
|
|
60
|
+
this.mapping = xmlStr ? await (0, googleapis_1.parseGoogleapiStorageXml)(xmlStr, shouldParseNotes) : {};
|
|
61
|
+
Object.assign(this.mapping, (0, chromelabs_1.parseKnownGoodVersionsWithDownloadsJson)(jsonStr));
|
|
62
|
+
return this.mapping;
|
|
198
63
|
}
|
|
199
64
|
/**
|
|
200
65
|
* Extracts downloaded chromedriver archive
|
|
@@ -267,28 +132,83 @@ class ChromedriverStorageClient {
|
|
|
267
132
|
}
|
|
268
133
|
if (!lodash_1.default.isEmpty(osInfo)) {
|
|
269
134
|
// Filter out drivers for unsupported system architectures
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
135
|
+
const { name, arch, cpu = (0, utils_1.getCpuType)() } = osInfo;
|
|
136
|
+
log.debug(`Selecting chromedrivers whose platform matches to ${name}:${cpu}${arch}`);
|
|
137
|
+
let result = driversToSync.filter((cdName) => this.doesMatchForOsInfo(cdName, osInfo));
|
|
138
|
+
if (lodash_1.default.isEmpty(result) && arch === constants_1.ARCH.X64 && cpu === constants_1.CPU.INTEL) {
|
|
139
|
+
// Fallback to X86 if X64 architecture is not available for this driver
|
|
140
|
+
result = driversToSync.filter((cdName) => this.doesMatchForOsInfo(cdName, {
|
|
141
|
+
name, arch: constants_1.ARCH.X86, cpu
|
|
142
|
+
}));
|
|
274
143
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
arch = armSuffix;
|
|
281
|
-
break;
|
|
282
|
-
}
|
|
283
|
-
}
|
|
144
|
+
if (lodash_1.default.isEmpty(result) && name === constants_1.OS.MAC && cpu === constants_1.CPU.ARM) {
|
|
145
|
+
// Fallback to Intel/Rosetta if ARM architecture is not available for this driver
|
|
146
|
+
result = driversToSync.filter((cdName) => this.doesMatchForOsInfo(cdName, {
|
|
147
|
+
name, arch, cpu: constants_1.CPU.INTEL
|
|
148
|
+
}));
|
|
284
149
|
}
|
|
285
|
-
|
|
286
|
-
const platformRe = new RegExp(`(\\b|_)${name}${arch}\\b`);
|
|
287
|
-
driversToSync = driversToSync.filter((cdName) => platformRe.test(cdName));
|
|
150
|
+
driversToSync = result;
|
|
288
151
|
log.debug(`Got ${support_1.util.pluralize('item', driversToSync.length, true)}`);
|
|
289
152
|
}
|
|
153
|
+
if (!lodash_1.default.isEmpty(driversToSync)) {
|
|
154
|
+
log.debug('Excluding older patches if present');
|
|
155
|
+
/** @type {{[key: string]: string[]}} */
|
|
156
|
+
const patchesMap = {};
|
|
157
|
+
// Older chromedrivers must not be excluded as they follow a different
|
|
158
|
+
// versioning pattern
|
|
159
|
+
const versionWithPatchPattern = /\d+\.\d+\.\d+\.\d+/;
|
|
160
|
+
const selectedVersions = new Set();
|
|
161
|
+
for (const cdName of driversToSync) {
|
|
162
|
+
const cdVersion = this.mapping[cdName].version;
|
|
163
|
+
if (!versionWithPatchPattern.test(cdVersion)) {
|
|
164
|
+
selectedVersions.add(cdVersion);
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
const verObj = semver_1.default.parse(cdVersion, { loose: true });
|
|
168
|
+
if (!verObj) {
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
if (!lodash_1.default.isArray(patchesMap[verObj.major])) {
|
|
172
|
+
patchesMap[verObj.major] = [];
|
|
173
|
+
}
|
|
174
|
+
patchesMap[verObj.major].push(cdVersion);
|
|
175
|
+
}
|
|
176
|
+
for (const majorVersion of lodash_1.default.keys(patchesMap)) {
|
|
177
|
+
if (patchesMap[majorVersion].length <= 1) {
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
patchesMap[majorVersion].sort((/** @type {string} */ a, /** @type {string}} */ b) => (0, compare_versions_1.compareVersions)(b, a));
|
|
181
|
+
}
|
|
182
|
+
if (!lodash_1.default.isEmpty(patchesMap)) {
|
|
183
|
+
log.debug('Versions mapping: ' + JSON.stringify(patchesMap, null, 2));
|
|
184
|
+
for (const sortedVersions of lodash_1.default.values(patchesMap)) {
|
|
185
|
+
selectedVersions.add(sortedVersions[0]);
|
|
186
|
+
}
|
|
187
|
+
driversToSync = driversToSync.filter((cdName) => selectedVersions.has(this.mapping[cdName].version));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
290
190
|
return driversToSync;
|
|
291
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* Checks whether the given chromedriver matches the operating system to run on
|
|
194
|
+
*
|
|
195
|
+
* @param {string} cdName
|
|
196
|
+
* @param {OSInfo} osInfo
|
|
197
|
+
* @returns {boolean}
|
|
198
|
+
*/
|
|
199
|
+
doesMatchForOsInfo(cdName, { name, arch, cpu }) {
|
|
200
|
+
const cdInfo = this.mapping[cdName];
|
|
201
|
+
if (!cdInfo) {
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
if (cdInfo.os.name !== name || cdInfo.os.arch !== arch) {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
if (cpu && cdInfo.os.cpu && this.mapping[cdName].os.cpu !== cpu) {
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
292
212
|
/**
|
|
293
213
|
* Retrieves the given chromedriver from the storage
|
|
294
214
|
* and unpacks it into `this.chromedriverDir` folder
|
|
@@ -311,7 +231,7 @@ class ChromedriverStorageClient {
|
|
|
311
231
|
try {
|
|
312
232
|
await support_1.net.downloadFile(url, archivePath, {
|
|
313
233
|
isMetered: false,
|
|
314
|
-
timeout:
|
|
234
|
+
timeout: constants_1.STORAGE_REQ_TIMEOUT_MS,
|
|
315
235
|
});
|
|
316
236
|
}
|
|
317
237
|
catch (e) {
|
|
@@ -323,7 +243,7 @@ class ChromedriverStorageClient {
|
|
|
323
243
|
log.error(msg);
|
|
324
244
|
return false;
|
|
325
245
|
}
|
|
326
|
-
if (!(await isCrcOk(archivePath, etag))) {
|
|
246
|
+
if (etag && !(await isCrcOk(archivePath, etag))) {
|
|
327
247
|
const msg = `The checksum for the downloaded chromedriver '${driverKey}' did not match`;
|
|
328
248
|
if (isStrict) {
|
|
329
249
|
throw new Error(msg);
|
|
@@ -376,17 +296,21 @@ class ChromedriverStorageClient {
|
|
|
376
296
|
*/
|
|
377
297
|
const synchronizedDrivers = [];
|
|
378
298
|
const promises = [];
|
|
299
|
+
const chunk = [];
|
|
379
300
|
const archivesRoot = await support_1.tempDir.openDir();
|
|
380
301
|
try {
|
|
381
302
|
for (const [idx, driverKey] of driversToSync.entries()) {
|
|
382
|
-
|
|
303
|
+
const promise = bluebird_1.default.resolve((async () => {
|
|
383
304
|
if (await this.retrieveDriver(idx, driverKey, archivesRoot, !lodash_1.default.isEmpty(opts))) {
|
|
384
305
|
synchronizedDrivers.push(driverKey);
|
|
385
306
|
}
|
|
386
307
|
})());
|
|
387
|
-
|
|
388
|
-
|
|
308
|
+
promises.push(promise);
|
|
309
|
+
chunk.push(promise);
|
|
310
|
+
if (chunk.length >= MAX_PARALLEL_DOWNLOADS) {
|
|
311
|
+
await bluebird_1.default.any(chunk);
|
|
389
312
|
}
|
|
313
|
+
lodash_1.default.remove(chunk, (p) => p.isFulfilled());
|
|
390
314
|
}
|
|
391
315
|
await bluebird_1.default.all(promises);
|
|
392
316
|
}
|
|
@@ -406,9 +330,9 @@ class ChromedriverStorageClient {
|
|
|
406
330
|
exports.ChromedriverStorageClient = ChromedriverStorageClient;
|
|
407
331
|
exports.default = ChromedriverStorageClient;
|
|
408
332
|
/**
|
|
409
|
-
* @typedef {import('
|
|
410
|
-
* @typedef {import('
|
|
411
|
-
* @typedef {import('
|
|
412
|
-
* @typedef {import('
|
|
333
|
+
* @typedef {import('../types').SyncOptions} SyncOptions
|
|
334
|
+
* @typedef {import('../types').OSInfo} OSInfo
|
|
335
|
+
* @typedef {import('../types').ChromedriverDetails} ChromedriverDetails
|
|
336
|
+
* @typedef {import('../types').ChromedriverDetailsMapping} ChromedriverDetailsMapping
|
|
413
337
|
*/
|
|
414
338
|
//# sourceMappingURL=storage-client.js.map
|