appium-webdriveragent 5.6.2 → 5.7.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/build/index.js +39 -36
- package/build/lib/check-dependencies.d.ts +3 -0
- package/build/lib/check-dependencies.d.ts.map +1 -0
- package/build/lib/check-dependencies.js +38 -32
- package/build/lib/check-dependencies.js.map +1 -1
- package/build/lib/constants.d.ts +12 -0
- package/build/lib/constants.d.ts.map +1 -0
- package/build/lib/constants.js +8 -10
- package/build/lib/constants.js.map +1 -1
- package/build/lib/logger.d.ts +3 -0
- package/build/lib/logger.d.ts.map +1 -0
- package/build/lib/logger.js +5 -11
- package/build/lib/logger.js.map +1 -1
- package/build/lib/no-session-proxy.d.ts +6 -0
- package/build/lib/no-session-proxy.d.ts.map +1 -0
- package/build/lib/no-session-proxy.js +22 -26
- package/build/lib/no-session-proxy.js.map +1 -1
- package/build/lib/utils.d.ts +127 -0
- package/build/lib/utils.d.ts.map +1 -0
- package/build/lib/utils.js +347 -211
- package/build/lib/utils.js.map +1 -1
- package/build/lib/webdriveragent.d.ts +145 -0
- package/build/lib/webdriveragent.d.ts.map +1 -0
- package/build/lib/webdriveragent.js +478 -367
- package/build/lib/webdriveragent.js.map +1 -1
- package/build/lib/xcodebuild.d.ts +58 -0
- package/build/lib/xcodebuild.d.ts.map +1 -0
- package/build/lib/xcodebuild.js +367 -289
- package/build/lib/xcodebuild.js.map +1 -1
- package/lib/check-dependencies.js +3 -4
- package/lib/utils.js +10 -7
- package/lib/webdriveragent.js +14 -9
- package/lib/xcodebuild.js +39 -7
- package/package.json +28 -18
|
@@ -1,404 +1,515 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
require("
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
var _appiumIosDevice = require("appium-ios-device");
|
|
24
|
-
var _strongbox = require("@appium/strongbox");
|
|
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.WebDriverAgent = void 0;
|
|
7
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const url_1 = __importDefault(require("url"));
|
|
10
|
+
const bluebird_1 = __importDefault(require("bluebird"));
|
|
11
|
+
const base_driver_1 = require("@appium/base-driver");
|
|
12
|
+
const support_1 = require("@appium/support");
|
|
13
|
+
const logger_1 = __importDefault(require("./logger"));
|
|
14
|
+
const no_session_proxy_1 = require("./no-session-proxy");
|
|
15
|
+
const utils_1 = require("./utils");
|
|
16
|
+
const xcodebuild_1 = __importDefault(require("./xcodebuild"));
|
|
17
|
+
const async_lock_1 = __importDefault(require("async-lock"));
|
|
18
|
+
const teen_process_1 = require("teen_process");
|
|
19
|
+
const check_dependencies_1 = require("./check-dependencies");
|
|
20
|
+
const constants_1 = require("./constants");
|
|
21
|
+
const appium_ios_device_1 = require("appium-ios-device");
|
|
22
|
+
const strongbox_1 = require("@appium/strongbox");
|
|
25
23
|
const WDA_LAUNCH_TIMEOUT = 60 * 1000;
|
|
26
24
|
const WDA_AGENT_PORT = 8100;
|
|
27
25
|
const WDA_CF_BUNDLE_NAME = 'WebDriverAgentRunner-Runner';
|
|
28
|
-
const SHARED_RESOURCES_GUARD = new
|
|
26
|
+
const SHARED_RESOURCES_GUARD = new async_lock_1.default();
|
|
29
27
|
const RECENT_MODULE_VERSION_ITEM_NAME = 'recentWdaModuleVersion';
|
|
30
28
|
class WebDriverAgent {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
return this.updatedWDABundleId ? `${this.updatedWDABundleId}.xctrunner` : _constants.WDA_RUNNER_BUNDLE_ID_FOR_XCTEST;
|
|
89
|
-
}
|
|
90
|
-
setWDAPaths(bootstrapPath, agentPath) {
|
|
91
|
-
this.bootstrapPath = bootstrapPath || _utils.BOOTSTRAP_PATH;
|
|
92
|
-
this.log.info(`Using WDA path: '${this.bootstrapPath}'`);
|
|
93
|
-
this.agentPath = agentPath || _path.default.resolve(this.bootstrapPath, 'WebDriverAgent.xcodeproj');
|
|
94
|
-
this.log.info(`Using WDA agent: '${this.agentPath}'`);
|
|
95
|
-
}
|
|
96
|
-
async cleanupObsoleteProcesses() {
|
|
97
|
-
const obsoletePids = await (0, _utils.getPIDsListeningOnPort)(this.url.port, cmdLine => cmdLine.includes('/WebDriverAgentRunner') && !cmdLine.toLowerCase().includes(this.device.udid.toLowerCase()));
|
|
98
|
-
if (_lodash.default.isEmpty(obsoletePids)) {
|
|
99
|
-
this.log.debug(`No obsolete cached processes from previous WDA sessions ` + `listening on port ${this.url.port} have been found`);
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
this.log.info(`Detected ${obsoletePids.length} obsolete cached process${obsoletePids.length === 1 ? '' : 'es'} ` + `from previous WDA sessions. Cleaning them up`);
|
|
103
|
-
try {
|
|
104
|
-
await (0, _teen_process.exec)('kill', obsoletePids);
|
|
105
|
-
} catch (e) {
|
|
106
|
-
this.log.warn(`Failed to kill obsolete cached process${obsoletePids.length === 1 ? '' : 'es'} '${obsoletePids}'. ` + `Original error: ${e.message}`);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
async isRunning() {
|
|
110
|
-
return !!(await this.getStatus());
|
|
111
|
-
}
|
|
112
|
-
get basePath() {
|
|
113
|
-
if (this.url.path === '/') {
|
|
114
|
-
return '';
|
|
29
|
+
constructor(xcodeVersion, args = {}, log = null) {
|
|
30
|
+
this.xcodeVersion = xcodeVersion;
|
|
31
|
+
this.args = lodash_1.default.clone(args);
|
|
32
|
+
this.log = log ?? logger_1.default;
|
|
33
|
+
this.device = args.device;
|
|
34
|
+
this.platformVersion = args.platformVersion;
|
|
35
|
+
this.platformName = args.platformName;
|
|
36
|
+
this.iosSdkVersion = args.iosSdkVersion;
|
|
37
|
+
this.host = args.host;
|
|
38
|
+
this.isRealDevice = !!args.realDevice;
|
|
39
|
+
this.idb = (args.device || {}).idb;
|
|
40
|
+
this.wdaBundlePath = args.wdaBundlePath;
|
|
41
|
+
this.setWDAPaths(args.bootstrapPath, args.agentPath);
|
|
42
|
+
this.wdaLocalPort = args.wdaLocalPort;
|
|
43
|
+
this.wdaRemotePort = args.wdaLocalPort || WDA_AGENT_PORT;
|
|
44
|
+
this.wdaBaseUrl = args.wdaBaseUrl || constants_1.WDA_BASE_URL;
|
|
45
|
+
this.prebuildWDA = args.prebuildWDA;
|
|
46
|
+
// this.args.webDriverAgentUrl guiarantees the capabilities acually
|
|
47
|
+
// gave 'appium:webDriverAgentUrl' but 'this.webDriverAgentUrl'
|
|
48
|
+
// could be used for caching WDA with xcodebuild.
|
|
49
|
+
this.webDriverAgentUrl = args.webDriverAgentUrl;
|
|
50
|
+
this.started = false;
|
|
51
|
+
this.wdaConnectionTimeout = args.wdaConnectionTimeout;
|
|
52
|
+
this.useXctestrunFile = args.useXctestrunFile;
|
|
53
|
+
this.usePrebuiltWDA = args.usePrebuiltWDA;
|
|
54
|
+
this.derivedDataPath = args.derivedDataPath;
|
|
55
|
+
this.mjpegServerPort = args.mjpegServerPort;
|
|
56
|
+
this.updatedWDABundleId = args.updatedWDABundleId;
|
|
57
|
+
this.usePreinstalledWDA = args.usePreinstalledWDA;
|
|
58
|
+
this.xctestApiClient = null;
|
|
59
|
+
this.xcodebuild = this.canSkipXcodebuild
|
|
60
|
+
? null
|
|
61
|
+
: new xcodebuild_1.default(this.xcodeVersion, this.device, {
|
|
62
|
+
platformVersion: this.platformVersion,
|
|
63
|
+
platformName: this.platformName,
|
|
64
|
+
iosSdkVersion: this.iosSdkVersion,
|
|
65
|
+
agentPath: this.agentPath,
|
|
66
|
+
bootstrapPath: this.bootstrapPath,
|
|
67
|
+
realDevice: this.isRealDevice,
|
|
68
|
+
showXcodeLog: args.showXcodeLog,
|
|
69
|
+
xcodeConfigFile: args.xcodeConfigFile,
|
|
70
|
+
xcodeOrgId: args.xcodeOrgId,
|
|
71
|
+
xcodeSigningId: args.xcodeSigningId,
|
|
72
|
+
keychainPath: args.keychainPath,
|
|
73
|
+
keychainPassword: args.keychainPassword,
|
|
74
|
+
useSimpleBuildTest: args.useSimpleBuildTest,
|
|
75
|
+
usePrebuiltWDA: args.usePrebuiltWDA,
|
|
76
|
+
updatedWDABundleId: this.updatedWDABundleId,
|
|
77
|
+
launchTimeout: args.wdaLaunchTimeout || WDA_LAUNCH_TIMEOUT,
|
|
78
|
+
wdaRemotePort: this.wdaRemotePort,
|
|
79
|
+
useXctestrunFile: this.useXctestrunFile,
|
|
80
|
+
derivedDataPath: args.derivedDataPath,
|
|
81
|
+
mjpegServerPort: this.mjpegServerPort,
|
|
82
|
+
allowProvisioningDeviceRegistration: args.allowProvisioningDeviceRegistration,
|
|
83
|
+
resultBundlePath: args.resultBundlePath,
|
|
84
|
+
resultBundleVersion: args.resultBundleVersion,
|
|
85
|
+
}, this.log);
|
|
115
86
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
});
|
|
125
|
-
try {
|
|
126
|
-
return await noSessionProxy.command('/status', 'GET');
|
|
127
|
-
} catch (err) {
|
|
128
|
-
this.log.debug(`WDA is not listening at '${this.url.href}'`);
|
|
129
|
-
return null;
|
|
87
|
+
/**
|
|
88
|
+
* Return true if the session does not need xcodebuild.
|
|
89
|
+
* @returns {boolean} Whether the session needs/has xcodebuild.
|
|
90
|
+
*/
|
|
91
|
+
get canSkipXcodebuild() {
|
|
92
|
+
// Use this.args.webDriverAgentUrl to guarantee
|
|
93
|
+
// the capabilities set gave the `appium:webDriverAgentUrl`.
|
|
94
|
+
return this.usePreinstalledWDA || this.args.webDriverAgentUrl;
|
|
130
95
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
this.
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
this.log.debug(`Uninstalling WDAs: '${bundleIds}'`);
|
|
140
|
-
for (const bundleId of bundleIds) {
|
|
141
|
-
await this.device.removeApp(bundleId);
|
|
142
|
-
}
|
|
143
|
-
} catch (e) {
|
|
144
|
-
this.log.debug(e);
|
|
145
|
-
this.log.warn(`WebDriverAgent uninstall failed. Perhaps, it is already uninstalled? ` + `Original error: ${e.message}`);
|
|
96
|
+
/**
|
|
97
|
+
*
|
|
98
|
+
* @returns {string} Bundle ID for Xctest.
|
|
99
|
+
*/
|
|
100
|
+
get bundleIdForXctest() {
|
|
101
|
+
return this.updatedWDABundleId ? `${this.updatedWDABundleId}.xctrunner` : constants_1.WDA_RUNNER_BUNDLE_ID_FOR_XCTEST;
|
|
146
102
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
103
|
+
setWDAPaths(bootstrapPath, agentPath) {
|
|
104
|
+
// allow the user to specify a place for WDA. This is undocumented and
|
|
105
|
+
// only here for the purposes of testing development of WDA
|
|
106
|
+
this.bootstrapPath = bootstrapPath || utils_1.BOOTSTRAP_PATH;
|
|
107
|
+
this.log.info(`Using WDA path: '${this.bootstrapPath}'`);
|
|
108
|
+
// for backward compatibility we need to be able to specify agentPath too
|
|
109
|
+
this.agentPath = agentPath || path_1.default.resolve(this.bootstrapPath, 'WebDriverAgent.xcodeproj');
|
|
110
|
+
this.log.info(`Using WDA agent: '${this.agentPath}'`);
|
|
151
111
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
boxItem = await box.createItemWithValue(RECENT_MODULE_VERSION_ITEM_NAME, '5.0.0');
|
|
160
|
-
} catch (e) {
|
|
161
|
-
this.log.warn(`The actual module version cannot be persisted: ${e.message}`);
|
|
162
|
-
return;
|
|
112
|
+
async cleanupObsoleteProcesses() {
|
|
113
|
+
const obsoletePids = await (0, utils_1.getPIDsListeningOnPort)(this.url.port, (cmdLine) => cmdLine.includes('/WebDriverAgentRunner') &&
|
|
114
|
+
!cmdLine.toLowerCase().includes(this.device.udid.toLowerCase()));
|
|
115
|
+
if (lodash_1.default.isEmpty(obsoletePids)) {
|
|
116
|
+
this.log.debug(`No obsolete cached processes from previous WDA sessions ` +
|
|
117
|
+
`listening on port ${this.url.port} have been found`);
|
|
118
|
+
return;
|
|
163
119
|
}
|
|
164
|
-
|
|
165
|
-
|
|
120
|
+
this.log.info(`Detected ${obsoletePids.length} obsolete cached process${obsoletePids.length === 1 ? '' : 'es'} ` +
|
|
121
|
+
`from previous WDA sessions. Cleaning them up`);
|
|
166
122
|
try {
|
|
167
|
-
|
|
168
|
-
}
|
|
169
|
-
|
|
123
|
+
await (0, teen_process_1.exec)('kill', obsoletePids);
|
|
124
|
+
}
|
|
125
|
+
catch (e) {
|
|
126
|
+
this.log.warn(`Failed to kill obsolete cached process${obsoletePids.length === 1 ? '' : 'es'} '${obsoletePids}'. ` +
|
|
127
|
+
`Original error: ${e.message}`);
|
|
170
128
|
}
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
let recentModuleVersion = await boxItem.read();
|
|
175
|
-
try {
|
|
176
|
-
recentModuleVersion = _support.util.coerceVersion(recentModuleVersion, true);
|
|
177
|
-
} catch (e) {
|
|
178
|
-
this.log.warn(`The persisted module version string has been damaged: ${e.message}`);
|
|
179
|
-
this.log.info(`Updating it to '${packageInfo.version}' assuming the project clenup is not needed`);
|
|
180
|
-
await boxItem.write(packageInfo.version);
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
if (_support.util.compareVersions(recentModuleVersion, '>=', packageInfo.version)) {
|
|
184
|
-
this.log.info(`WebDriverAgent does not need a cleanup. The project sources are up to date ` + `(${recentModuleVersion} >= ${packageInfo.version})`);
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
this.log.info(`Cleaning up the WebDriverAgent project after the module upgrade has happened ` + `(${recentModuleVersion} < ${packageInfo.version})`);
|
|
188
|
-
try {
|
|
189
|
-
await this.xcodebuild.cleanProject();
|
|
190
|
-
await boxItem.write(packageInfo.version);
|
|
191
|
-
} catch (e) {
|
|
192
|
-
this.log.warn(`Cannot perform WebDriverAgent project cleanup. Original error: ${e.message}`);
|
|
193
129
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
xctestEnv.MJPEG_SERVER_PORT = this.mjpegServerPort;
|
|
130
|
+
/**
|
|
131
|
+
* Return boolean if WDA is running or not
|
|
132
|
+
* @return {Promise<boolean>} True if WDA is running
|
|
133
|
+
* @throws {Error} If there was invalid response code or body
|
|
134
|
+
*/
|
|
135
|
+
async isRunning() {
|
|
136
|
+
return !!(await this.getStatus());
|
|
202
137
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
this.setupProxies(sessionId);
|
|
209
|
-
const status = await this.getStatus();
|
|
210
|
-
this.started = true;
|
|
211
|
-
return status;
|
|
212
|
-
}
|
|
213
|
-
async launch(sessionId) {
|
|
214
|
-
if (this.webDriverAgentUrl) {
|
|
215
|
-
this.log.info(`Using provided WebdriverAgent at '${this.webDriverAgentUrl}'`);
|
|
216
|
-
this.url = this.webDriverAgentUrl;
|
|
217
|
-
this.setupProxies(sessionId);
|
|
218
|
-
return await this.getStatus();
|
|
138
|
+
get basePath() {
|
|
139
|
+
if (this.url.path === '/') {
|
|
140
|
+
return '';
|
|
141
|
+
}
|
|
142
|
+
return this.url.path || '';
|
|
219
143
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
144
|
+
/**
|
|
145
|
+
* Return current running WDA's status like below
|
|
146
|
+
* {
|
|
147
|
+
* "state": "success",
|
|
148
|
+
* "os": {
|
|
149
|
+
* "name": "iOS",
|
|
150
|
+
* "version": "11.4",
|
|
151
|
+
* "sdkVersion": "11.3"
|
|
152
|
+
* },
|
|
153
|
+
* "ios": {
|
|
154
|
+
* "simulatorVersion": "11.4",
|
|
155
|
+
* "ip": "172.254.99.34"
|
|
156
|
+
* },
|
|
157
|
+
* "build": {
|
|
158
|
+
* "time": "Jun 24 2018 17:08:21",
|
|
159
|
+
* "productBundleIdentifier": "com.facebook.WebDriverAgentRunner"
|
|
160
|
+
* }
|
|
161
|
+
* }
|
|
162
|
+
*
|
|
163
|
+
* @return {Promise<any?>} State Object
|
|
164
|
+
* @throws {Error} If there was invalid response code or body
|
|
165
|
+
*/
|
|
166
|
+
async getStatus() {
|
|
167
|
+
const noSessionProxy = new no_session_proxy_1.NoSessionProxy({
|
|
168
|
+
server: this.url.hostname,
|
|
169
|
+
port: this.url.port,
|
|
170
|
+
base: this.basePath,
|
|
171
|
+
timeout: 3000,
|
|
172
|
+
});
|
|
173
|
+
try {
|
|
174
|
+
return await noSessionProxy.command('/status', 'GET');
|
|
175
|
+
}
|
|
176
|
+
catch (err) {
|
|
177
|
+
this.log.debug(`WDA is not listening at '${this.url.href}'`);
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
225
180
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
181
|
+
/**
|
|
182
|
+
* Uninstall WDAs from the test device.
|
|
183
|
+
* Over Xcode 11, multiple WDA can be in the device since Xcode 11 generates different WDA.
|
|
184
|
+
* Appium does not expect multiple WDAs are running on a device.
|
|
185
|
+
*/
|
|
186
|
+
async uninstall() {
|
|
187
|
+
try {
|
|
188
|
+
const bundleIds = await this.device.getUserInstalledBundleIdsByBundleName(WDA_CF_BUNDLE_NAME);
|
|
189
|
+
if (lodash_1.default.isEmpty(bundleIds)) {
|
|
190
|
+
this.log.debug('No WDAs on the device.');
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
this.log.debug(`Uninstalling WDAs: '${bundleIds}'`);
|
|
194
|
+
for (const bundleId of bundleIds) {
|
|
195
|
+
await this.device.removeApp(bundleId);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
catch (e) {
|
|
199
|
+
this.log.debug(e);
|
|
200
|
+
this.log.warn(`WebDriverAgent uninstall failed. Perhaps, it is already uninstalled? ` +
|
|
201
|
+
`Original error: ${e.message}`);
|
|
202
|
+
}
|
|
230
203
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
204
|
+
async _cleanupProjectIfFresh() {
|
|
205
|
+
if (this.canSkipXcodebuild) {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
const packageInfo = JSON.parse(await support_1.fs.readFile(path_1.default.join(utils_1.BOOTSTRAP_PATH, 'package.json'), 'utf8'));
|
|
209
|
+
const box = (0, strongbox_1.strongbox)(packageInfo.name);
|
|
210
|
+
let boxItem = box.getItem(RECENT_MODULE_VERSION_ITEM_NAME);
|
|
211
|
+
if (!boxItem) {
|
|
212
|
+
const timestampPath = path_1.default.resolve(process.env.HOME ?? '', constants_1.WDA_UPGRADE_TIMESTAMP_PATH);
|
|
213
|
+
if (await support_1.fs.exists(timestampPath)) {
|
|
214
|
+
// TODO: It is probably a bit ugly to hardcode the recent version string,
|
|
215
|
+
// TODO: hovewer it should do the job as a temporary transition trick
|
|
216
|
+
// TODO: to switch from a hardcoded file path to the strongbox usage.
|
|
217
|
+
try {
|
|
218
|
+
boxItem = await box.createItemWithValue(RECENT_MODULE_VERSION_ITEM_NAME, '5.0.0');
|
|
219
|
+
}
|
|
220
|
+
catch (e) {
|
|
221
|
+
this.log.warn(`The actual module version cannot be persisted: ${e.message}`);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
this.log.info('There is no need to perform the project cleanup. A fresh install has been detected');
|
|
227
|
+
try {
|
|
228
|
+
await box.createItemWithValue(RECENT_MODULE_VERSION_ITEM_NAME, packageInfo.version);
|
|
229
|
+
}
|
|
230
|
+
catch (e) {
|
|
231
|
+
this.log.warn(`The actual module version cannot be persisted: ${e.message}`);
|
|
232
|
+
}
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
let recentModuleVersion = await boxItem.read();
|
|
237
|
+
try {
|
|
238
|
+
recentModuleVersion = support_1.util.coerceVersion(recentModuleVersion, true);
|
|
239
|
+
}
|
|
240
|
+
catch (e) {
|
|
241
|
+
this.log.warn(`The persisted module version string has been damaged: ${e.message}`);
|
|
242
|
+
this.log.info(`Updating it to '${packageInfo.version}' assuming the project clenup is not needed`);
|
|
243
|
+
await boxItem.write(packageInfo.version);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
if (support_1.util.compareVersions(recentModuleVersion, '>=', packageInfo.version)) {
|
|
247
|
+
this.log.info(`WebDriverAgent does not need a cleanup. The project sources are up to date ` +
|
|
248
|
+
`(${recentModuleVersion} >= ${packageInfo.version})`);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
this.log.info(`Cleaning up the WebDriverAgent project after the module upgrade has happened ` +
|
|
252
|
+
`(${recentModuleVersion} < ${packageInfo.version})`);
|
|
253
|
+
try {
|
|
254
|
+
// @ts-ignore xcodebuild should be set
|
|
255
|
+
await this.xcodebuild.cleanProject();
|
|
256
|
+
await boxItem.write(packageInfo.version);
|
|
257
|
+
}
|
|
258
|
+
catch (e) {
|
|
259
|
+
this.log.warn(`Cannot perform WebDriverAgent project cleanup. Original error: ${e.message}`);
|
|
260
|
+
}
|
|
236
261
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
262
|
+
/**
|
|
263
|
+
* Launch WDA with preinstalled package without xcodebuild.
|
|
264
|
+
* @param {string} sessionId Launch WDA and establish the session with this sessionId
|
|
265
|
+
* @return {Promise<any?>} State Object
|
|
266
|
+
*/
|
|
267
|
+
async launchWithPreinstalledWDA(sessionId) {
|
|
268
|
+
const xctestEnv = {
|
|
269
|
+
USE_PORT: this.wdaLocalPort || WDA_AGENT_PORT,
|
|
270
|
+
WDA_PRODUCT_BUNDLE_IDENTIFIER: this.bundleIdForXctest
|
|
271
|
+
};
|
|
272
|
+
if (this.mjpegServerPort) {
|
|
273
|
+
xctestEnv.MJPEG_SERVER_PORT = this.mjpegServerPort;
|
|
274
|
+
}
|
|
275
|
+
this.log.info('Launching WebDriverAgent on the device without xcodebuild');
|
|
276
|
+
this.xctestApiClient = new appium_ios_device_1.Xctest(this.device.udid, this.bundleIdForXctest, null, { env: xctestEnv });
|
|
277
|
+
await this.xctestApiClient.start();
|
|
278
|
+
this.setupProxies(sessionId);
|
|
279
|
+
const status = await this.getStatus();
|
|
280
|
+
this.started = true;
|
|
281
|
+
return status;
|
|
240
282
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
283
|
+
/**
|
|
284
|
+
* Return current running WDA's status like below after launching WDA
|
|
285
|
+
* {
|
|
286
|
+
* "state": "success",
|
|
287
|
+
* "os": {
|
|
288
|
+
* "name": "iOS",
|
|
289
|
+
* "version": "11.4",
|
|
290
|
+
* "sdkVersion": "11.3"
|
|
291
|
+
* },
|
|
292
|
+
* "ios": {
|
|
293
|
+
* "simulatorVersion": "11.4",
|
|
294
|
+
* "ip": "172.254.99.34"
|
|
295
|
+
* },
|
|
296
|
+
* "build": {
|
|
297
|
+
* "time": "Jun 24 2018 17:08:21",
|
|
298
|
+
* "productBundleIdentifier": "com.facebook.WebDriverAgentRunner"
|
|
299
|
+
* }
|
|
300
|
+
* }
|
|
301
|
+
*
|
|
302
|
+
* @param {string} sessionId Launch WDA and establish the session with this sessionId
|
|
303
|
+
* @return {Promise<any?>} State Object
|
|
304
|
+
* @throws {Error} If there was invalid response code or body
|
|
305
|
+
*/
|
|
306
|
+
async launch(sessionId) {
|
|
307
|
+
if (this.webDriverAgentUrl) {
|
|
308
|
+
this.log.info(`Using provided WebdriverAgent at '${this.webDriverAgentUrl}'`);
|
|
309
|
+
this.url = this.webDriverAgentUrl;
|
|
310
|
+
this.setupProxies(sessionId);
|
|
311
|
+
return await this.getStatus();
|
|
312
|
+
}
|
|
313
|
+
if (this.usePreinstalledWDA) {
|
|
314
|
+
if (this.isRealDevice) {
|
|
315
|
+
return await this.launchWithPreinstalledWDA(sessionId);
|
|
316
|
+
}
|
|
317
|
+
throw new Error('usePreinstalledWDA is available only for a real device.');
|
|
318
|
+
}
|
|
319
|
+
this.log.info('Launching WebDriverAgent on the device');
|
|
320
|
+
this.setupProxies(sessionId);
|
|
321
|
+
if (!this.useXctestrunFile && !await support_1.fs.exists(this.agentPath)) {
|
|
322
|
+
throw new Error(`Trying to use WebDriverAgent project at '${this.agentPath}' but the ` +
|
|
323
|
+
'file does not exist');
|
|
324
|
+
}
|
|
325
|
+
// useXctestrunFile and usePrebuiltWDA use existing dependencies
|
|
326
|
+
// It depends on user side
|
|
327
|
+
if (this.idb || this.useXctestrunFile || (this.derivedDataPath && this.usePrebuiltWDA)) {
|
|
328
|
+
this.log.info('Skipped WDA project cleanup according to the provided capabilities');
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
const synchronizationKey = path_1.default.normalize(this.bootstrapPath);
|
|
332
|
+
await SHARED_RESOURCES_GUARD.acquire(synchronizationKey, async () => await this._cleanupProjectIfFresh());
|
|
333
|
+
}
|
|
334
|
+
// We need to provide WDA local port, because it might be occupied
|
|
335
|
+
await (0, utils_1.resetTestProcesses)(this.device.udid, !this.isRealDevice);
|
|
336
|
+
if (this.idb) {
|
|
337
|
+
return await this.startWithIDB();
|
|
338
|
+
}
|
|
339
|
+
// @ts-ignore xcodebuild should be set
|
|
340
|
+
await this.xcodebuild.init(this.noSessionProxy);
|
|
341
|
+
// Start the xcodebuild process
|
|
342
|
+
if (this.prebuildWDA) {
|
|
343
|
+
// @ts-ignore xcodebuild should be set
|
|
344
|
+
await this.xcodebuild.prebuild();
|
|
345
|
+
}
|
|
346
|
+
// @ts-ignore xcodebuild should be set
|
|
347
|
+
return await this.xcodebuild.start();
|
|
244
348
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
};
|
|
257
|
-
if (this.mjpegServerPort) {
|
|
258
|
-
env.MJPEG_SERVER_PORT = this.mjpegServerPort;
|
|
349
|
+
async startWithIDB() {
|
|
350
|
+
this.log.info('Will launch WDA with idb instead of xcodebuild since the corresponding flag is enabled');
|
|
351
|
+
const { wdaBundleId, testBundleId } = await this.prepareWDA();
|
|
352
|
+
const env = {
|
|
353
|
+
USE_PORT: this.wdaRemotePort,
|
|
354
|
+
WDA_PRODUCT_BUNDLE_IDENTIFIER: this.updatedWDABundleId,
|
|
355
|
+
};
|
|
356
|
+
if (this.mjpegServerPort) {
|
|
357
|
+
env.MJPEG_SERVER_PORT = this.mjpegServerPort;
|
|
358
|
+
}
|
|
359
|
+
return await this.idb.runXCUITest(wdaBundleId, wdaBundleId, testBundleId, { env });
|
|
259
360
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
if (!infoPlist.CFBundleIdentifier) {
|
|
268
|
-
throw new Error(`Could not find bundle id in '${infoPlistPath}'`);
|
|
361
|
+
async parseBundleId(wdaBundlePath) {
|
|
362
|
+
const infoPlistPath = path_1.default.join(wdaBundlePath, 'Info.plist');
|
|
363
|
+
const infoPlist = await support_1.plist.parsePlist(await support_1.fs.readFile(infoPlistPath));
|
|
364
|
+
if (!infoPlist.CFBundleIdentifier) {
|
|
365
|
+
throw new Error(`Could not find bundle id in '${infoPlistPath}'`);
|
|
366
|
+
}
|
|
367
|
+
return infoPlist.CFBundleIdentifier;
|
|
269
368
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
369
|
+
async prepareWDA() {
|
|
370
|
+
const wdaBundlePath = this.wdaBundlePath || await this.fetchWDABundle();
|
|
371
|
+
const wdaBundleId = await this.parseBundleId(wdaBundlePath);
|
|
372
|
+
if (!await this.device.isAppInstalled(wdaBundleId)) {
|
|
373
|
+
await this.device.installApp(wdaBundlePath);
|
|
374
|
+
}
|
|
375
|
+
const testBundleId = await this.idb.installXCTestBundle(path_1.default.join(wdaBundlePath, 'PlugIns', 'WebDriverAgentRunner.xctest'));
|
|
376
|
+
return { wdaBundleId, testBundleId, wdaBundlePath };
|
|
277
377
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
378
|
+
async fetchWDABundle() {
|
|
379
|
+
if (!this.derivedDataPath) {
|
|
380
|
+
return await (0, check_dependencies_1.bundleWDASim)(this.xcodebuild);
|
|
381
|
+
}
|
|
382
|
+
const wdaBundlePaths = await support_1.fs.glob(`${this.derivedDataPath}/**/*${constants_1.WDA_RUNNER_APP}/`, {
|
|
383
|
+
absolute: true,
|
|
384
|
+
});
|
|
385
|
+
if (lodash_1.default.isEmpty(wdaBundlePaths)) {
|
|
386
|
+
throw new Error(`Could not find the WDA bundle in '${this.derivedDataPath}'`);
|
|
387
|
+
}
|
|
388
|
+
return wdaBundlePaths[0];
|
|
288
389
|
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
390
|
+
async isSourceFresh() {
|
|
391
|
+
const existsPromises = [
|
|
392
|
+
'Resources',
|
|
393
|
+
`Resources${path_1.default.sep}WebDriverAgent.bundle`,
|
|
394
|
+
].map((subPath) => support_1.fs.exists(path_1.default.resolve(this.bootstrapPath, subPath)));
|
|
395
|
+
return (await bluebird_1.default.all(existsPromises)).some((v) => v === false);
|
|
294
396
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
keepAlive: true
|
|
309
|
-
};
|
|
310
|
-
this.jwproxy = new _baseDriver.JWProxy(proxyOpts);
|
|
311
|
-
this.jwproxy.sessionId = sessionId;
|
|
312
|
-
this.proxyReqRes = this.jwproxy.proxyReqRes.bind(this.jwproxy);
|
|
313
|
-
this.noSessionProxy = new _noSessionProxy.NoSessionProxy(proxyOpts);
|
|
314
|
-
}
|
|
315
|
-
async quit() {
|
|
316
|
-
if (this.usePreinstalledWDA) {
|
|
317
|
-
if (this.xctestApiClient) {
|
|
318
|
-
this.log.info('Stopping the XCTest session');
|
|
319
|
-
this.xctestApiClient.stop();
|
|
320
|
-
this.xctestApiClient = null;
|
|
321
|
-
}
|
|
322
|
-
} else if (!this.args.webDriverAgentUrl) {
|
|
323
|
-
this.log.info('Shutting down sub-processes');
|
|
324
|
-
await this.xcodebuild.quit();
|
|
325
|
-
await this.xcodebuild.reset();
|
|
326
|
-
} else {
|
|
327
|
-
this.log.debug('Do not stop xcodebuild nor XCTest session ' + 'since the WDA session is managed by outside this driver.');
|
|
397
|
+
setupProxies(sessionId) {
|
|
398
|
+
const proxyOpts = {
|
|
399
|
+
log: this.log,
|
|
400
|
+
server: this.url.hostname,
|
|
401
|
+
port: this.url.port,
|
|
402
|
+
base: this.basePath,
|
|
403
|
+
timeout: this.wdaConnectionTimeout,
|
|
404
|
+
keepAlive: true,
|
|
405
|
+
};
|
|
406
|
+
this.jwproxy = new base_driver_1.JWProxy(proxyOpts);
|
|
407
|
+
this.jwproxy.sessionId = sessionId;
|
|
408
|
+
this.proxyReqRes = this.jwproxy.proxyReqRes.bind(this.jwproxy);
|
|
409
|
+
this.noSessionProxy = new no_session_proxy_1.NoSessionProxy(proxyOpts);
|
|
328
410
|
}
|
|
329
|
-
|
|
330
|
-
|
|
411
|
+
async quit() {
|
|
412
|
+
if (this.usePreinstalledWDA) {
|
|
413
|
+
if (this.xctestApiClient) {
|
|
414
|
+
this.log.info('Stopping the XCTest session');
|
|
415
|
+
this.xctestApiClient.stop();
|
|
416
|
+
this.xctestApiClient = null;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
else if (!this.args.webDriverAgentUrl) {
|
|
420
|
+
this.log.info('Shutting down sub-processes');
|
|
421
|
+
// @ts-ignore xcodebuild should be set
|
|
422
|
+
await this.xcodebuild.quit();
|
|
423
|
+
// @ts-ignore xcodebuild should be set
|
|
424
|
+
await this.xcodebuild.reset();
|
|
425
|
+
}
|
|
426
|
+
else {
|
|
427
|
+
this.log.debug('Do not stop xcodebuild nor XCTest session ' +
|
|
428
|
+
'since the WDA session is managed by outside this driver.');
|
|
429
|
+
}
|
|
430
|
+
if (this.jwproxy) {
|
|
431
|
+
this.jwproxy.sessionId = null;
|
|
432
|
+
}
|
|
433
|
+
this.started = false;
|
|
434
|
+
if (!this.args.webDriverAgentUrl) {
|
|
435
|
+
// if we populated the url ourselves (during `setupCaching` call, for instance)
|
|
436
|
+
// then clean that up. If the url was supplied, we want to keep it
|
|
437
|
+
this.webDriverAgentUrl = null;
|
|
438
|
+
}
|
|
331
439
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
440
|
+
get url() {
|
|
441
|
+
if (!this._url) {
|
|
442
|
+
if (this.webDriverAgentUrl) {
|
|
443
|
+
this._url = url_1.default.parse(this.webDriverAgentUrl);
|
|
444
|
+
}
|
|
445
|
+
else {
|
|
446
|
+
const port = this.wdaLocalPort || WDA_AGENT_PORT;
|
|
447
|
+
const { protocol, hostname } = url_1.default.parse(this.wdaBaseUrl || constants_1.WDA_BASE_URL);
|
|
448
|
+
this._url = url_1.default.parse(`${protocol}//${hostname}:${port}`);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
return this._url;
|
|
335
452
|
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
if (!this._url) {
|
|
339
|
-
if (this.webDriverAgentUrl) {
|
|
340
|
-
this._url = _url2.default.parse(this.webDriverAgentUrl);
|
|
341
|
-
} else {
|
|
342
|
-
const port = this.wdaLocalPort || WDA_AGENT_PORT;
|
|
343
|
-
const {
|
|
344
|
-
protocol,
|
|
345
|
-
hostname
|
|
346
|
-
} = _url2.default.parse(this.wdaBaseUrl || _constants.WDA_BASE_URL);
|
|
347
|
-
this._url = _url2.default.parse(`${protocol}//${hostname}:${port}`);
|
|
348
|
-
}
|
|
453
|
+
set url(_url) {
|
|
454
|
+
this._url = url_1.default.parse(_url);
|
|
349
455
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
set url(_url) {
|
|
353
|
-
this._url = _url2.default.parse(_url);
|
|
354
|
-
}
|
|
355
|
-
get fullyStarted() {
|
|
356
|
-
return this.started;
|
|
357
|
-
}
|
|
358
|
-
set fullyStarted(started = false) {
|
|
359
|
-
this.started = started;
|
|
360
|
-
}
|
|
361
|
-
async retrieveDerivedDataPath() {
|
|
362
|
-
if (this.canSkipXcodebuild) {
|
|
363
|
-
return;
|
|
456
|
+
get fullyStarted() {
|
|
457
|
+
return this.started;
|
|
364
458
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
async setupCaching() {
|
|
368
|
-
const status = await this.getStatus();
|
|
369
|
-
if (!status || !status.build) {
|
|
370
|
-
this.log.debug('WDA is currently not running. There is nothing to cache');
|
|
371
|
-
return;
|
|
459
|
+
set fullyStarted(started) {
|
|
460
|
+
this.started = started ?? false;
|
|
372
461
|
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
return await this.uninstall();
|
|
462
|
+
async retrieveDerivedDataPath() {
|
|
463
|
+
if (this.canSkipXcodebuild) {
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
// @ts-ignore xcodebuild should be set
|
|
467
|
+
return await this.xcodebuild.retrieveDerivedDataPath();
|
|
380
468
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
469
|
+
/**
|
|
470
|
+
* Reuse running WDA if it has the same bundle id with updatedWDABundleId.
|
|
471
|
+
* Or reuse it if it has the default id without updatedWDABundleId.
|
|
472
|
+
* Uninstall it if the method faces an exception for the above situation.
|
|
473
|
+
*/
|
|
474
|
+
async setupCaching() {
|
|
475
|
+
const status = await this.getStatus();
|
|
476
|
+
if (!status || !status.build) {
|
|
477
|
+
this.log.debug('WDA is currently not running. There is nothing to cache');
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
const { productBundleIdentifier, upgradedAt, } = status.build;
|
|
481
|
+
// for real device
|
|
482
|
+
if (support_1.util.hasValue(productBundleIdentifier) && support_1.util.hasValue(this.updatedWDABundleId) && this.updatedWDABundleId !== productBundleIdentifier) {
|
|
483
|
+
this.log.info(`Will uninstall running WDA since it has different bundle id. The actual value is '${productBundleIdentifier}'.`);
|
|
484
|
+
return await this.uninstall();
|
|
485
|
+
}
|
|
486
|
+
// for simulator
|
|
487
|
+
if (support_1.util.hasValue(productBundleIdentifier) && !support_1.util.hasValue(this.updatedWDABundleId) && constants_1.WDA_RUNNER_BUNDLE_ID !== productBundleIdentifier) {
|
|
488
|
+
this.log.info(`Will uninstall running WDA since its bundle id is not equal to the default value ${constants_1.WDA_RUNNER_BUNDLE_ID}`);
|
|
489
|
+
return await this.uninstall();
|
|
490
|
+
}
|
|
491
|
+
const actualUpgradeTimestamp = await (0, utils_1.getWDAUpgradeTimestamp)();
|
|
492
|
+
this.log.debug(`Upgrade timestamp of the currently bundled WDA: ${actualUpgradeTimestamp}`);
|
|
493
|
+
this.log.debug(`Upgrade timestamp of the WDA on the device: ${upgradedAt}`);
|
|
494
|
+
if (actualUpgradeTimestamp && upgradedAt && lodash_1.default.toLower(`${actualUpgradeTimestamp}`) !== lodash_1.default.toLower(`${upgradedAt}`)) {
|
|
495
|
+
this.log.info('Will uninstall running WDA since it has different version in comparison to the one ' +
|
|
496
|
+
`which is bundled with appium-xcuitest-driver module (${actualUpgradeTimestamp} != ${upgradedAt})`);
|
|
497
|
+
return await this.uninstall();
|
|
498
|
+
}
|
|
499
|
+
const message = support_1.util.hasValue(productBundleIdentifier)
|
|
500
|
+
? `Will reuse previously cached WDA instance at '${this.url.href}' with '${productBundleIdentifier}'`
|
|
501
|
+
: `Will reuse previously cached WDA instance at '${this.url.href}'`;
|
|
502
|
+
this.log.info(`${message}. Set the wdaLocalPort capability to a value different from ${this.url.port} if this is an undesired behavior.`);
|
|
503
|
+
this.webDriverAgentUrl = this.url.href;
|
|
384
504
|
}
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
505
|
+
/**
|
|
506
|
+
* Quit and uninstall running WDA.
|
|
507
|
+
*/
|
|
508
|
+
async quitAndUninstall() {
|
|
509
|
+
await this.quit();
|
|
510
|
+
await this.uninstall();
|
|
391
511
|
}
|
|
392
|
-
const message = _support.util.hasValue(productBundleIdentifier) ? `Will reuse previously cached WDA instance at '${this.url.href}' with '${productBundleIdentifier}'` : `Will reuse previously cached WDA instance at '${this.url.href}'`;
|
|
393
|
-
this.log.info(`${message}. Set the wdaLocalPort capability to a value different from ${this.url.port} if this is an undesired behavior.`);
|
|
394
|
-
this.webDriverAgentUrl = this.url.href;
|
|
395
|
-
}
|
|
396
|
-
async quitAndUninstall() {
|
|
397
|
-
await this.quit();
|
|
398
|
-
await this.uninstall();
|
|
399
|
-
}
|
|
400
512
|
}
|
|
401
513
|
exports.WebDriverAgent = WebDriverAgent;
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbG9kYXNoIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfcGF0aCIsIl91cmwyIiwiX2JsdWViaXJkIiwiX2Jhc2VEcml2ZXIiLCJfc3VwcG9ydCIsIl9sb2dnZXIiLCJfbm9TZXNzaW9uUHJveHkiLCJfdXRpbHMiLCJfeGNvZGVidWlsZCIsIl9hc3luY0xvY2siLCJfdGVlbl9wcm9jZXNzIiwiX2NoZWNrRGVwZW5kZW5jaWVzIiwiX2NvbnN0YW50cyIsIl9hcHBpdW1Jb3NEZXZpY2UiLCJfc3Ryb25nYm94IiwiV0RBX0xBVU5DSF9USU1FT1VUIiwiV0RBX0FHRU5UX1BPUlQiLCJXREFfQ0ZfQlVORExFX05BTUUiLCJTSEFSRURfUkVTT1VSQ0VTX0dVQVJEIiwiQXN5bmNMb2NrIiwiUkVDRU5UX01PRFVMRV9WRVJTSU9OX0lURU1fTkFNRSIsIldlYkRyaXZlckFnZW50IiwiY29uc3RydWN0b3IiLCJ4Y29kZVZlcnNpb24iLCJhcmdzIiwibG9nIiwiXyIsImNsb25lIiwiZGVmYXVsdExvZ2dlciIsImRldmljZSIsInBsYXRmb3JtVmVyc2lvbiIsInBsYXRmb3JtTmFtZSIsImlvc1Nka1ZlcnNpb24iLCJob3N0IiwiaXNSZWFsRGV2aWNlIiwicmVhbERldmljZSIsImlkYiIsIndkYUJ1bmRsZVBhdGgiLCJzZXRXREFQYXRocyIsImJvb3RzdHJhcFBhdGgiLCJhZ2VudFBhdGgiLCJ3ZGFMb2NhbFBvcnQiLCJ3ZGFSZW1vdGVQb3J0Iiwid2RhQmFzZVVybCIsIldEQV9CQVNFX1VSTCIsInByZWJ1aWxkV0RBIiwid2ViRHJpdmVyQWdlbnRVcmwiLCJzdGFydGVkIiwid2RhQ29ubmVjdGlvblRpbWVvdXQiLCJ1c2VYY3Rlc3RydW5GaWxlIiwidXNlUHJlYnVpbHRXREEiLCJkZXJpdmVkRGF0YVBhdGgiLCJtanBlZ1NlcnZlclBvcnQiLCJ1cGRhdGVkV0RBQnVuZGxlSWQiLCJ1c2VQcmVpbnN0YWxsZWRXREEiLCJ4Y3Rlc3RBcGlDbGllbnQiLCJ4Y29kZWJ1aWxkIiwiY2FuU2tpcFhjb2RlYnVpbGQiLCJYY29kZUJ1aWxkIiwic2hvd1hjb2RlTG9nIiwieGNvZGVDb25maWdGaWxlIiwieGNvZGVPcmdJZCIsInhjb2RlU2lnbmluZ0lkIiwia2V5Y2hhaW5QYXRoIiwia2V5Y2hhaW5QYXNzd29yZCIsInVzZVNpbXBsZUJ1aWxkVGVzdCIsImxhdW5jaFRpbWVvdXQiLCJ3ZGFMYXVuY2hUaW1lb3V0IiwiYWxsb3dQcm92aXNpb25pbmdEZXZpY2VSZWdpc3RyYXRpb24iLCJyZXN1bHRCdW5kbGVQYXRoIiwicmVzdWx0QnVuZGxlVmVyc2lvbiIsImJ1bmRsZUlkRm9yWGN0ZXN0IiwiV0RBX1JVTk5FUl9CVU5ETEVfSURfRk9SX1hDVEVTVCIsIkJPT1RTVFJBUF9QQVRIIiwiaW5mbyIsInBhdGgiLCJyZXNvbHZlIiwiY2xlYW51cE9ic29sZXRlUHJvY2Vzc2VzIiwib2Jzb2xldGVQaWRzIiwiZ2V0UElEc0xpc3RlbmluZ09uUG9ydCIsInVybCIsInBvcnQiLCJjbWRMaW5lIiwiaW5jbHVkZXMiLCJ0b0xvd2VyQ2FzZSIsInVkaWQiLCJpc0VtcHR5IiwiZGVidWciLCJsZW5ndGgiLCJleGVjIiwiZSIsIndhcm4iLCJtZXNzYWdlIiwiaXNSdW5uaW5nIiwiZ2V0U3RhdHVzIiwiYmFzZVBhdGgiLCJub1Nlc3Npb25Qcm94eSIsIk5vU2Vzc2lvblByb3h5Iiwic2VydmVyIiwiaG9zdG5hbWUiLCJiYXNlIiwidGltZW91dCIsImNvbW1hbmQiLCJlcnIiLCJocmVmIiwidW5pbnN0YWxsIiwiYnVuZGxlSWRzIiwiZ2V0VXNlckluc3RhbGxlZEJ1bmRsZUlkc0J5QnVuZGxlTmFtZSIsImJ1bmRsZUlkIiwicmVtb3ZlQXBwIiwiX2NsZWFudXBQcm9qZWN0SWZGcmVzaCIsInBhY2thZ2VJbmZvIiwiSlNPTiIsInBhcnNlIiwiZnMiLCJyZWFkRmlsZSIsImpvaW4iLCJib3giLCJzdHJvbmdib3giLCJuYW1lIiwiYm94SXRlbSIsImdldEl0ZW0iLCJ0aW1lc3RhbXBQYXRoIiwicHJvY2VzcyIsImVudiIsIkhPTUUiLCJXREFfVVBHUkFERV9USU1FU1RBTVBfUEFUSCIsImV4aXN0cyIsImNyZWF0ZUl0ZW1XaXRoVmFsdWUiLCJ2ZXJzaW9uIiwicmVjZW50TW9kdWxlVmVyc2lvbiIsInJlYWQiLCJ1dGlsIiwiY29lcmNlVmVyc2lvbiIsIndyaXRlIiwiY29tcGFyZVZlcnNpb25zIiwiY2xlYW5Qcm9qZWN0IiwibGF1bmNoV2l0aFByZWluc3RhbGxlZFdEQSIsInNlc3Npb25JZCIsInhjdGVzdEVudiIsIlVTRV9QT1JUIiwiV0RBX1BST0RVQ1RfQlVORExFX0lERU5USUZJRVIiLCJNSlBFR19TRVJWRVJfUE9SVCIsIlhjdGVzdCIsInN0YXJ0Iiwic2V0dXBQcm94aWVzIiwic3RhdHVzIiwibGF1bmNoIiwiRXJyb3IiLCJzeW5jaHJvbml6YXRpb25LZXkiLCJub3JtYWxpemUiLCJhY3F1aXJlIiwicmVzZXRUZXN0UHJvY2Vzc2VzIiwic3RhcnRXaXRoSURCIiwiaW5pdCIsInByZWJ1aWxkIiwid2RhQnVuZGxlSWQiLCJ0ZXN0QnVuZGxlSWQiLCJwcmVwYXJlV0RBIiwicnVuWENVSVRlc3QiLCJwYXJzZUJ1bmRsZUlkIiwiaW5mb1BsaXN0UGF0aCIsImluZm9QbGlzdCIsInBsaXN0IiwicGFyc2VQbGlzdCIsIkNGQnVuZGxlSWRlbnRpZmllciIsImZldGNoV0RBQnVuZGxlIiwiaXNBcHBJbnN0YWxsZWQiLCJpbnN0YWxsQXBwIiwiaW5zdGFsbFhDVGVzdEJ1bmRsZSIsImJ1bmRsZVdEQVNpbSIsIndkYUJ1bmRsZVBhdGhzIiwiZ2xvYiIsIldEQV9SVU5ORVJfQVBQIiwiYWJzb2x1dGUiLCJpc1NvdXJjZUZyZXNoIiwiZXhpc3RzUHJvbWlzZXMiLCJzZXAiLCJtYXAiLCJzdWJQYXRoIiwiQiIsImFsbCIsInNvbWUiLCJ2IiwicHJveHlPcHRzIiwia2VlcEFsaXZlIiwiandwcm94eSIsIkpXUHJveHkiLCJwcm94eVJlcVJlcyIsImJpbmQiLCJxdWl0Iiwic3RvcCIsInJlc2V0IiwiX3VybCIsInByb3RvY29sIiwiZnVsbHlTdGFydGVkIiwicmV0cmlldmVEZXJpdmVkRGF0YVBhdGgiLCJzZXR1cENhY2hpbmciLCJidWlsZCIsInByb2R1Y3RCdW5kbGVJZGVudGlmaWVyIiwidXBncmFkZWRBdCIsImhhc1ZhbHVlIiwiV0RBX1JVTk5FUl9CVU5ETEVfSUQiLCJhY3R1YWxVcGdyYWRlVGltZXN0YW1wIiwiZ2V0V0RBVXBncmFkZVRpbWVzdGFtcCIsInRvTG93ZXIiLCJxdWl0QW5kVW5pbnN0YWxsIiwiZXhwb3J0cyIsIl9kZWZhdWx0IiwiZGVmYXVsdCJdLCJzb3VyY2VzIjpbIi4uLy4uL2xpYi93ZWJkcml2ZXJhZ2VudC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgdXJsIGZyb20gJ3VybCc7XG5pbXBvcnQgQiBmcm9tICdibHVlYmlyZCc7XG5pbXBvcnQgeyBKV1Byb3h5IH0gZnJvbSAnQGFwcGl1bS9iYXNlLWRyaXZlcic7XG5pbXBvcnQgeyBmcywgdXRpbCwgcGxpc3QgfSBmcm9tICdAYXBwaXVtL3N1cHBvcnQnO1xuaW1wb3J0IGRlZmF1bHRMb2dnZXIgZnJvbSAnLi9sb2dnZXInO1xuaW1wb3J0IHsgTm9TZXNzaW9uUHJveHkgfSBmcm9tICcuL25vLXNlc3Npb24tcHJveHknO1xuaW1wb3J0IHtcbiAgZ2V0V0RBVXBncmFkZVRpbWVzdGFtcCwgcmVzZXRUZXN0UHJvY2Vzc2VzLCBnZXRQSURzTGlzdGVuaW5nT25Qb3J0LCBCT09UU1RSQVBfUEFUSFxufSBmcm9tICcuL3V0aWxzJztcbmltcG9ydCBYY29kZUJ1aWxkIGZyb20gJy4veGNvZGVidWlsZCc7XG5pbXBvcnQgQXN5bmNMb2NrIGZyb20gJ2FzeW5jLWxvY2snO1xuaW1wb3J0IHsgZXhlYyB9IGZyb20gJ3RlZW5fcHJvY2Vzcyc7XG5pbXBvcnQgeyBidW5kbGVXREFTaW0gfSBmcm9tICcuL2NoZWNrLWRlcGVuZGVuY2llcyc7XG5pbXBvcnQge1xuICBXREFfUlVOTkVSX0JVTkRMRV9JRCwgV0RBX1JVTk5FUl9CVU5ETEVfSURfRk9SX1hDVEVTVCwgV0RBX1JVTk5FUl9BUFAsXG4gIFdEQV9CQVNFX1VSTCwgV0RBX1VQR1JBREVfVElNRVNUQU1QX1BBVEhcbn0gZnJvbSAnLi9jb25zdGFudHMnO1xuaW1wb3J0IHtYY3Rlc3R9IGZyb20gJ2FwcGl1bS1pb3MtZGV2aWNlJztcbmltcG9ydCB7c3Ryb25nYm94fSBmcm9tICdAYXBwaXVtL3N0cm9uZ2JveCc7XG5cbmNvbnN0IFdEQV9MQVVOQ0hfVElNRU9VVCA9IDYwICogMTAwMDtcbmNvbnN0IFdEQV9BR0VOVF9QT1JUID0gODEwMDtcbmNvbnN0IFdEQV9DRl9CVU5ETEVfTkFNRSA9ICdXZWJEcml2ZXJBZ2VudFJ1bm5lci1SdW5uZXInO1xuY29uc3QgU0hBUkVEX1JFU09VUkNFU19HVUFSRCA9IG5ldyBBc3luY0xvY2soKTtcbmNvbnN0IFJFQ0VOVF9NT0RVTEVfVkVSU0lPTl9JVEVNX05BTUUgPSAncmVjZW50V2RhTW9kdWxlVmVyc2lvbic7XG5cbmNsYXNzIFdlYkRyaXZlckFnZW50IHtcbiAgY29uc3RydWN0b3IgKHhjb2RlVmVyc2lvbiwgYXJncyA9IHt9LCBsb2cgPSBudWxsKSB7XG4gICAgdGhpcy54Y29kZVZlcnNpb24gPSB4Y29kZVZlcnNpb247XG5cbiAgICB0aGlzLmFyZ3MgPSBfLmNsb25lKGFyZ3MpO1xuICAgIHRoaXMubG9nID0gbG9nID8/IGRlZmF1bHRMb2dnZXI7XG5cbiAgICB0aGlzLmRldmljZSA9IGFyZ3MuZGV2aWNlO1xuICAgIHRoaXMucGxhdGZvcm1WZXJzaW9uID0gYXJncy5wbGF0Zm9ybVZlcnNpb247XG4gICAgdGhpcy5wbGF0Zm9ybU5hbWUgPSBhcmdzLnBsYXRmb3JtTmFtZTtcbiAgICB0aGlzLmlvc1Nka1ZlcnNpb24gPSBhcmdzLmlvc1Nka1ZlcnNpb247XG4gICAgdGhpcy5ob3N0ID0gYXJncy5ob3N0O1xuICAgIHRoaXMuaXNSZWFsRGV2aWNlID0gISFhcmdzLnJlYWxEZXZpY2U7XG4gICAgdGhpcy5pZGIgPSAoYXJncy5kZXZpY2UgfHwge30pLmlkYjtcbiAgICB0aGlzLndkYUJ1bmRsZVBhdGggPSBhcmdzLndkYUJ1bmRsZVBhdGg7XG5cbiAgICB0aGlzLnNldFdEQVBhdGhzKGFyZ3MuYm9vdHN0cmFwUGF0aCwgYXJncy5hZ2VudFBhdGgpO1xuXG4gICAgdGhpcy53ZGFMb2NhbFBvcnQgPSBhcmdzLndkYUxvY2FsUG9ydDtcbiAgICB0aGlzLndkYVJlbW90ZVBvcnQgPSBhcmdzLndkYUxvY2FsUG9ydCB8fCBXREFfQUdFTlRfUE9SVDtcbiAgICB0aGlzLndkYUJhc2VVcmwgPSBhcmdzLndkYUJhc2VVcmwgfHwgV0RBX0JBU0VfVVJMO1xuXG4gICAgdGhpcy5wcmVidWlsZFdEQSA9IGFyZ3MucHJlYnVpbGRXREE7XG5cbiAgICAvLyB0aGlzLmFyZ3Mud2ViRHJpdmVyQWdlbnRVcmwgZ3VpYXJhbnRlZXMgdGhlIGNhcGFiaWxpdGllcyBhY3VhbGx5XG4gICAgLy8gZ2F2ZSAnYXBwaXVtOndlYkRyaXZlckFnZW50VXJsJyBidXQgJ3RoaXMud2ViRHJpdmVyQWdlbnRVcmwnXG4gICAgLy8gY291bGQgYmUgdXNlZCBmb3IgY2FjaGluZyBXREEgd2l0aCB4Y29kZWJ1aWxkLlxuICAgIHRoaXMud2ViRHJpdmVyQWdlbnRVcmwgPSBhcmdzLndlYkRyaXZlckFnZW50VXJsO1xuXG4gICAgdGhpcy5zdGFydGVkID0gZmFsc2U7XG5cbiAgICB0aGlzLndkYUNvbm5lY3Rpb25UaW1lb3V0ID0gYXJncy53ZGFDb25uZWN0aW9uVGltZW91dDtcblxuICAgIHRoaXMudXNlWGN0ZXN0cnVuRmlsZSA9IGFyZ3MudXNlWGN0ZXN0cnVuRmlsZTtcbiAgICB0aGlzLnVzZVByZWJ1aWx0V0RBID0gYXJncy51c2VQcmVidWlsdFdEQTtcbiAgICB0aGlzLmRlcml2ZWREYXRhUGF0aCA9IGFyZ3MuZGVyaXZlZERhdGFQYXRoO1xuICAgIHRoaXMubWpwZWdTZXJ2ZXJQb3J0ID0gYXJncy5tanBlZ1NlcnZlclBvcnQ7XG5cbiAgICB0aGlzLnVwZGF0ZWRXREFCdW5kbGVJZCA9IGFyZ3MudXBkYXRlZFdEQUJ1bmRsZUlkO1xuXG4gICAgdGhpcy51c2VQcmVpbnN0YWxsZWRXREEgPSBhcmdzLnVzZVByZWluc3RhbGxlZFdEQTtcbiAgICB0aGlzLnhjdGVzdEFwaUNsaWVudCA9IG51bGw7XG5cbiAgICB0aGlzLnhjb2RlYnVpbGQgPSB0aGlzLmNhblNraXBYY29kZWJ1aWxkXG4gICAgPyBudWxsXG4gICAgOiBuZXcgWGNvZGVCdWlsZCh0aGlzLnhjb2RlVmVyc2lvbiwgdGhpcy5kZXZpY2UsIHtcbiAgICAgICAgcGxhdGZvcm1WZXJzaW9uOiB0aGlzLnBsYXRmb3JtVmVyc2lvbixcbiAgICAgICAgcGxhdGZvcm1OYW1lOiB0aGlzLnBsYXRmb3JtTmFtZSxcbiAgICAgICAgaW9zU2RrVmVyc2lvbjogdGhpcy5pb3NTZGtWZXJzaW9uLFxuICAgICAgICBhZ2VudFBhdGg6IHRoaXMuYWdlbnRQYXRoLFxuICAgICAgICBib290c3RyYXBQYXRoOiB0aGlzLmJvb3RzdHJhcFBhdGgsXG4gICAgICAgIHJlYWxEZXZpY2U6IHRoaXMuaXNSZWFsRGV2aWNlLFxuICAgICAgICBzaG93WGNvZGVMb2c6IGFyZ3Muc2hvd1hjb2RlTG9nLFxuICAgICAgICB4Y29kZUNvbmZpZ0ZpbGU6IGFyZ3MueGNvZGVDb25maWdGaWxlLFxuICAgICAgICB4Y29kZU9yZ0lkOiBhcmdzLnhjb2RlT3JnSWQsXG4gICAgICAgIHhjb2RlU2lnbmluZ0lkOiBhcmdzLnhjb2RlU2lnbmluZ0lkLFxuICAgICAgICBrZXljaGFpblBhdGg6IGFyZ3Mua2V5Y2hhaW5QYXRoLFxuICAgICAgICBrZXljaGFpblBhc3N3b3JkOiBhcmdzLmtleWNoYWluUGFzc3dvcmQsXG4gICAgICAgIHVzZVNpbXBsZUJ1aWxkVGVzdDogYXJncy51c2VTaW1wbGVCdWlsZFRlc3QsXG4gICAgICAgIHVzZVByZWJ1aWx0V0RBOiBhcmdzLnVzZVByZWJ1aWx0V0RBLFxuICAgICAgICB1cGRhdGVkV0RBQnVuZGxlSWQ6IHRoaXMudXBkYXRlZFdEQUJ1bmRsZUlkLFxuICAgICAgICBsYXVuY2hUaW1lb3V0OiBhcmdzLndkYUxhdW5jaFRpbWVvdXQgfHwgV0RBX0xBVU5DSF9USU1FT1VULFxuICAgICAgICB3ZGFSZW1vdGVQb3J0OiB0aGlzLndkYVJlbW90ZVBvcnQsXG4gICAgICAgIHVzZVhjdGVzdHJ1bkZpbGU6IHRoaXMudXNlWGN0ZXN0cnVuRmlsZSxcbiAgICAgICAgZGVyaXZlZERhdGFQYXRoOiBhcmdzLmRlcml2ZWREYXRhUGF0aCxcbiAgICAgICAgbWpwZWdTZXJ2ZXJQb3J0OiB0aGlzLm1qcGVnU2VydmVyUG9ydCxcbiAgICAgICAgYWxsb3dQcm92aXNpb25pbmdEZXZpY2VSZWdpc3RyYXRpb246IGFyZ3MuYWxsb3dQcm92aXNpb25pbmdEZXZpY2VSZWdpc3RyYXRpb24sXG4gICAgICAgIHJlc3VsdEJ1bmRsZVBhdGg6IGFyZ3MucmVzdWx0QnVuZGxlUGF0aCxcbiAgICAgICAgcmVzdWx0QnVuZGxlVmVyc2lvbjogYXJncy5yZXN1bHRCdW5kbGVWZXJzaW9uLFxuICAgICAgfSwgdGhpcy5sb2cpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiB0cnVlIGlmIHRoZSBzZXNzaW9uIGRvZXMgbm90IG5lZWQgeGNvZGVidWlsZC5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgdGhlIHNlc3Npb24gbmVlZHMvaGFzIHhjb2RlYnVpbGQuXG4gICAqL1xuICBnZXQgY2FuU2tpcFhjb2RlYnVpbGQgKCkge1xuICAgIC8vIFVzZSB0aGlzLmFyZ3Mud2ViRHJpdmVyQWdlbnRVcmwgdG8gZ3VhcmFudGVlXG4gICAgLy8gdGhlIGNhcGFiaWxpdGllcyBzZXQgZ2F2ZSB0aGUgYGFwcGl1bTp3ZWJEcml2ZXJBZ2VudFVybGAuXG4gICAgcmV0dXJuIHRoaXMudXNlUHJlaW5zdGFsbGVkV0RBIHx8IHRoaXMuYXJncy53ZWJEcml2ZXJBZ2VudFVybDtcbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBCdW5kbGUgSUQgZm9yIFhjdGVzdC5cbiAgICovXG4gIGdldCBidW5kbGVJZEZvclhjdGVzdCAoKSB7XG4gICAgcmV0dXJuIHRoaXMudXBkYXRlZFdEQUJ1bmRsZUlkID8gYCR7dGhpcy51cGRhdGVkV0RBQnVuZGxlSWR9LnhjdHJ1bm5lcmAgOiBXREFfUlVOTkVSX0JVTkRMRV9JRF9GT1JfWENURVNUO1xuICB9XG5cbiAgc2V0V0RBUGF0aHMgKGJvb3RzdHJhcFBhdGgsIGFnZW50UGF0aCkge1xuICAgIC8vIGFsbG93IHRoZSB1c2VyIHRvIHNwZWNpZnkgYSBwbGFjZSBmb3IgV0RBLiBUaGlzIGlzIHVuZG9jdW1lbnRlZCBhbmRcbiAgICAvLyBvbmx5IGhlcmUgZm9yIHRoZSBwdXJwb3NlcyBvZiB0ZXN0aW5nIGRldmVsb3BtZW50IG9mIFdEQVxuICAgIHRoaXMuYm9vdHN0cmFwUGF0aCA9IGJvb3RzdHJhcFBhdGggfHwgQk9PVFNUUkFQX1BBVEg7XG4gICAgdGhpcy5sb2cuaW5mbyhgVXNpbmcgV0RBIHBhdGg6ICcke3RoaXMuYm9vdHN0cmFwUGF0aH0nYCk7XG5cbiAgICAvLyBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSB3ZSBuZWVkIHRvIGJlIGFibGUgdG8gc3BlY2lmeSBhZ2VudFBhdGggdG9vXG4gICAgdGhpcy5hZ2VudFBhdGggPSBhZ2VudFBhdGggfHwgcGF0aC5yZXNvbHZlKHRoaXMuYm9vdHN0cmFwUGF0aCwgJ1dlYkRyaXZlckFnZW50Lnhjb2RlcHJvaicpO1xuICAgIHRoaXMubG9nLmluZm8oYFVzaW5nIFdEQSBhZ2VudDogJyR7dGhpcy5hZ2VudFBhdGh9J2ApO1xuICB9XG5cbiAgYXN5bmMgY2xlYW51cE9ic29sZXRlUHJvY2Vzc2VzICgpIHtcbiAgICBjb25zdCBvYnNvbGV0ZVBpZHMgPSBhd2FpdCBnZXRQSURzTGlzdGVuaW5nT25Qb3J0KHRoaXMudXJsLnBvcnQsXG4gICAgICAoY21kTGluZSkgPT4gY21kTGluZS5pbmNsdWRlcygnL1dlYkRyaXZlckFnZW50UnVubmVyJykgJiZcbiAgICAgICAgIWNtZExpbmUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyh0aGlzLmRldmljZS51ZGlkLnRvTG93ZXJDYXNlKCkpKTtcblxuICAgIGlmIChfLmlzRW1wdHkob2Jzb2xldGVQaWRzKSkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYE5vIG9ic29sZXRlIGNhY2hlZCBwcm9jZXNzZXMgZnJvbSBwcmV2aW91cyBXREEgc2Vzc2lvbnMgYCArXG4gICAgICAgIGBsaXN0ZW5pbmcgb24gcG9ydCAke3RoaXMudXJsLnBvcnR9IGhhdmUgYmVlbiBmb3VuZGApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMubG9nLmluZm8oYERldGVjdGVkICR7b2Jzb2xldGVQaWRzLmxlbmd0aH0gb2Jzb2xldGUgY2FjaGVkIHByb2Nlc3Mke29ic29sZXRlUGlkcy5sZW5ndGggPT09IDEgPyAnJyA6ICdlcyd9IGAgK1xuICAgICAgYGZyb20gcHJldmlvdXMgV0RBIHNlc3Npb25zLiBDbGVhbmluZyB0aGVtIHVwYCk7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGV4ZWMoJ2tpbGwnLCBvYnNvbGV0ZVBpZHMpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMubG9nLndhcm4oYEZhaWxlZCB0byBraWxsIG9ic29sZXRlIGNhY2hlZCBwcm9jZXNzJHtvYnNvbGV0ZVBpZHMubGVuZ3RoID09PSAxID8gJycgOiAnZXMnfSAnJHtvYnNvbGV0ZVBpZHN9Jy4gYCArXG4gICAgICAgIGBPcmlnaW5hbCBlcnJvcjogJHtlLm1lc3NhZ2V9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBib29sZWFuIGlmIFdEQSBpcyBydW5uaW5nIG9yIG5vdFxuICAgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIFdEQSBpcyBydW5uaW5nXG4gICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGVyZSB3YXMgaW52YWxpZCByZXNwb25zZSBjb2RlIG9yIGJvZHlcbiAgICovXG4gIGFzeW5jIGlzUnVubmluZyAoKSB7XG4gICAgcmV0dXJuICEhKGF3YWl0IHRoaXMuZ2V0U3RhdHVzKCkpO1xuICB9XG5cbiAgZ2V0IGJhc2VQYXRoICgpIHtcbiAgICBpZiAodGhpcy51cmwucGF0aCA9PT0gJy8nKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnVybC5wYXRoIHx8ICcnO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBjdXJyZW50IHJ1bm5pbmcgV0RBJ3Mgc3RhdHVzIGxpa2UgYmVsb3dcbiAgICoge1xuICAgKiAgIFwic3RhdGVcIjogXCJzdWNjZXNzXCIsXG4gICAqICAgXCJvc1wiOiB7XG4gICAqICAgICBcIm5hbWVcIjogXCJpT1NcIixcbiAgICogICAgIFwidmVyc2lvblwiOiBcIjExLjRcIixcbiAgICogICAgIFwic2RrVmVyc2lvblwiOiBcIjExLjNcIlxuICAgKiAgIH0sXG4gICAqICAgXCJpb3NcIjoge1xuICAgKiAgICAgXCJzaW11bGF0b3JWZXJzaW9uXCI6IFwiMTEuNFwiLFxuICAgKiAgICAgXCJpcFwiOiBcIjE3Mi4yNTQuOTkuMzRcIlxuICAgKiAgIH0sXG4gICAqICAgXCJidWlsZFwiOiB7XG4gICAqICAgICBcInRpbWVcIjogXCJKdW4gMjQgMjAxOCAxNzowODoyMVwiLFxuICAgKiAgICAgXCJwcm9kdWN0QnVuZGxlSWRlbnRpZmllclwiOiBcImNvbS5mYWNlYm9vay5XZWJEcml2ZXJBZ2VudFJ1bm5lclwiXG4gICAqICAgfVxuICAgKiB9XG4gICAqXG4gICAqIEByZXR1cm4gez9vYmplY3R9IFN0YXRlIE9iamVjdFxuICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlcmUgd2FzIGludmFsaWQgcmVzcG9uc2UgY29kZSBvciBib2R5XG4gICAqL1xuICBhc3luYyBnZXRTdGF0dXMgKCkge1xuICAgIGNvbnN0IG5vU2Vzc2lvblByb3h5ID0gbmV3IE5vU2Vzc2lvblByb3h5KHtcbiAgICAgIHNlcnZlcjogdGhpcy51cmwuaG9zdG5hbWUsXG4gICAgICBwb3J0OiB0aGlzLnVybC5wb3J0LFxuICAgICAgYmFzZTogdGhpcy5iYXNlUGF0aCxcbiAgICAgIHRpbWVvdXQ6IDMwMDAsXG4gICAgfSk7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCBub1Nlc3Npb25Qcm94eS5jb21tYW5kKCcvc3RhdHVzJywgJ0dFVCcpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYFdEQSBpcyBub3QgbGlzdGVuaW5nIGF0ICcke3RoaXMudXJsLmhyZWZ9J2ApO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFVuaW5zdGFsbCBXREFzIGZyb20gdGhlIHRlc3QgZGV2aWNlLlxuICAgKiBPdmVyIFhjb2RlIDExLCBtdWx0aXBsZSBXREEgY2FuIGJlIGluIHRoZSBkZXZpY2Ugc2luY2UgWGNvZGUgMTEgZ2VuZXJhdGVzIGRpZmZlcmVudCBXREEuXG4gICAqIEFwcGl1bSBkb2VzIG5vdCBleHBlY3QgbXVsdGlwbGUgV0RBcyBhcmUgcnVubmluZyBvbiBhIGRldmljZS5cbiAgICovXG4gIGFzeW5jIHVuaW5zdGFsbCAoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGJ1bmRsZUlkcyA9IGF3YWl0IHRoaXMuZGV2aWNlLmdldFVzZXJJbnN0YWxsZWRCdW5kbGVJZHNCeUJ1bmRsZU5hbWUoV0RBX0NGX0JVTkRMRV9OQU1FKTtcbiAgICAgIGlmIChfLmlzRW1wdHkoYnVuZGxlSWRzKSkge1xuICAgICAgICB0aGlzLmxvZy5kZWJ1ZygnTm8gV0RBcyBvbiB0aGUgZGV2aWNlLicpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRoaXMubG9nLmRlYnVnKGBVbmluc3RhbGxpbmcgV0RBczogJyR7YnVuZGxlSWRzfSdgKTtcbiAgICAgIGZvciAoY29uc3QgYnVuZGxlSWQgb2YgYnVuZGxlSWRzKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuZGV2aWNlLnJlbW92ZUFwcChidW5kbGVJZCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoZSk7XG4gICAgICB0aGlzLmxvZy53YXJuKGBXZWJEcml2ZXJBZ2VudCB1bmluc3RhbGwgZmFpbGVkLiBQZXJoYXBzLCBpdCBpcyBhbHJlYWR5IHVuaW5zdGFsbGVkPyBgICtcbiAgICAgICAgYE9yaWdpbmFsIGVycm9yOiAke2UubWVzc2FnZX1gKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBfY2xlYW51cFByb2plY3RJZkZyZXNoICgpIHtcbiAgICBpZiAodGhpcy5jYW5Ta2lwWGNvZGVidWlsZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHBhY2thZ2VJbmZvID0gSlNPTi5wYXJzZShhd2FpdCBmcy5yZWFkRmlsZShwYXRoLmpvaW4oQk9PVFNUUkFQX1BBVEgsICdwYWNrYWdlLmpzb24nKSwgJ3V0ZjgnKSk7XG4gICAgY29uc3QgYm94ID0gc3Ryb25nYm94KHBhY2thZ2VJbmZvLm5hbWUpO1xuICAgIGxldCBib3hJdGVtID0gYm94LmdldEl0ZW0oUkVDRU5UX01PRFVMRV9WRVJTSU9OX0lURU1fTkFNRSk7XG4gICAgaWYgKCFib3hJdGVtKSB7XG4gICAgICBjb25zdCB0aW1lc3RhbXBQYXRoID0gcGF0aC5yZXNvbHZlKHByb2Nlc3MuZW52LkhPTUUsIFdEQV9VUEdSQURFX1RJTUVTVEFNUF9QQVRIKTtcbiAgICAgIGlmIChhd2FpdCBmcy5leGlzdHModGltZXN0YW1wUGF0aCkpIHtcbiAgICAgICAgLy8gVE9ETzogSXQgaXMgcHJvYmFibHkgYSBiaXQgdWdseSB0byBoYXJkY29kZSB0aGUgcmVjZW50IHZlcnNpb24gc3RyaW5nLFxuICAgICAgICAvLyBUT0RPOiBob3Zld2VyIGl0IHNob3VsZCBkbyB0aGUgam9iIGFzIGEgdGVtcG9yYXJ5IHRyYW5zaXRpb24gdHJpY2tcbiAgICAgICAgLy8gVE9ETzogdG8gc3dpdGNoIGZyb20gYSBoYXJkY29kZWQgZmlsZSBwYXRoIHRvIHRoZSBzdHJvbmdib3ggdXNhZ2UuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYm94SXRlbSA9IGF3YWl0IGJveC5jcmVhdGVJdGVtV2l0aFZhbHVlKFJFQ0VOVF9NT0RVTEVfVkVSU0lPTl9JVEVNX05BTUUsICc1LjAuMCcpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgdGhpcy5sb2cud2FybihgVGhlIGFjdHVhbCBtb2R1bGUgdmVyc2lvbiBjYW5ub3QgYmUgcGVyc2lzdGVkOiAke2UubWVzc2FnZX1gKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubG9nLmluZm8oJ1RoZXJlIGlzIG5vIG5lZWQgdG8gcGVyZm9ybSB0aGUgcHJvamVjdCBjbGVhbnVwLiBBIGZyZXNoIGluc3RhbGwgaGFzIGJlZW4gZGV0ZWN0ZWQnKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCBib3guY3JlYXRlSXRlbVdpdGhWYWx1ZShSRUNFTlRfTU9EVUxFX1ZFUlNJT05fSVRFTV9OQU1FLCBwYWNrYWdlSW5mby52ZXJzaW9uKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHRoaXMubG9nLndhcm4oYFRoZSBhY3R1YWwgbW9kdWxlIHZlcnNpb24gY2Fubm90IGJlIHBlcnNpc3RlZDogJHtlLm1lc3NhZ2V9YCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIGxldCByZWNlbnRNb2R1bGVWZXJzaW9uID0gYXdhaXQgYm94SXRlbS5yZWFkKCk7XG4gICAgdHJ5IHtcbiAgICAgIHJlY2VudE1vZHVsZVZlcnNpb24gPSB1dGlsLmNvZXJjZVZlcnNpb24ocmVjZW50TW9kdWxlVmVyc2lvbiwgdHJ1ZSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhpcy5sb2cud2FybihgVGhlIHBlcnNpc3RlZCBtb2R1bGUgdmVyc2lvbiBzdHJpbmcgaGFzIGJlZW4gZGFtYWdlZDogJHtlLm1lc3NhZ2V9YCk7XG4gICAgICB0aGlzLmxvZy5pbmZvKGBVcGRhdGluZyBpdCB0byAnJHtwYWNrYWdlSW5mby52ZXJzaW9ufScgYXNzdW1pbmcgdGhlIHByb2plY3QgY2xlbnVwIGlzIG5vdCBuZWVkZWRgKTtcbiAgICAgIGF3YWl0IGJveEl0ZW0ud3JpdGUocGFja2FnZUluZm8udmVyc2lvbik7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHV0aWwuY29tcGFyZVZlcnNpb25zKHJlY2VudE1vZHVsZVZlcnNpb24sICc+PScsIHBhY2thZ2VJbmZvLnZlcnNpb24pKSB7XG4gICAgICB0aGlzLmxvZy5pbmZvKFxuICAgICAgICBgV2ViRHJpdmVyQWdlbnQgZG9lcyBub3QgbmVlZCBhIGNsZWFudXAuIFRoZSBwcm9qZWN0IHNvdXJjZXMgYXJlIHVwIHRvIGRhdGUgYCArXG4gICAgICAgIGAoJHtyZWNlbnRNb2R1bGVWZXJzaW9ufSA+PSAke3BhY2thZ2VJbmZvLnZlcnNpb259KWBcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5sb2cuaW5mbyhcbiAgICAgIGBDbGVhbmluZyB1cCB0aGUgV2ViRHJpdmVyQWdlbnQgcHJvamVjdCBhZnRlciB0aGUgbW9kdWxlIHVwZ3JhZGUgaGFzIGhhcHBlbmVkIGAgK1xuICAgICAgYCgke3JlY2VudE1vZHVsZVZlcnNpb259IDwgJHtwYWNrYWdlSW5mby52ZXJzaW9ufSlgXG4gICAgKTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy54Y29kZWJ1aWxkLmNsZWFuUHJvamVjdCgpO1xuICAgICAgYXdhaXQgYm94SXRlbS53cml0ZShwYWNrYWdlSW5mby52ZXJzaW9uKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLmxvZy53YXJuKGBDYW5ub3QgcGVyZm9ybSBXZWJEcml2ZXJBZ2VudCBwcm9qZWN0IGNsZWFudXAuIE9yaWdpbmFsIGVycm9yOiAke2UubWVzc2FnZX1gKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTGF1bmNoIFdEQSB3aXRoIHByZWluc3RhbGxlZCBwYWNrYWdlIHdpdGhvdXQgeGNvZGVidWlsZC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHNlc3Npb25JZCBMYXVuY2ggV0RBIGFuZCBlc3RhYmxpc2ggdGhlIHNlc3Npb24gd2l0aCB0aGlzIHNlc3Npb25JZFxuICAgKiBAcmV0dXJuIHs/b2JqZWN0fSBTdGF0ZSBPYmplY3RcbiAgICovXG4gIGFzeW5jIGxhdW5jaFdpdGhQcmVpbnN0YWxsZWRXREEoc2Vzc2lvbklkKSB7XG4gICAgY29uc3QgeGN0ZXN0RW52ID0ge1xuICAgICAgVVNFX1BPUlQ6IHRoaXMud2RhTG9jYWxQb3J0IHx8IFdEQV9BR0VOVF9QT1JULFxuICAgICAgV0RBX1BST0RVQ1RfQlVORExFX0lERU5USUZJRVI6IHRoaXMuYnVuZGxlSWRGb3JYY3Rlc3RcbiAgICB9O1xuICAgIGlmICh0aGlzLm1qcGVnU2VydmVyUG9ydCkge1xuICAgICAgeGN0ZXN0RW52Lk1KUEVHX1NFUlZFUl9QT1JUID0gdGhpcy5tanBlZ1NlcnZlclBvcnQ7XG4gICAgfVxuICAgIHRoaXMubG9nLmluZm8oJ0xhdW5jaGluZyBXZWJEcml2ZXJBZ2VudCBvbiB0aGUgZGV2aWNlIHdpdGhvdXQgeGNvZGVidWlsZCcpO1xuICAgIHRoaXMueGN0ZXN0QXBpQ2xpZW50ID0gbmV3IFhjdGVzdCh0aGlzLmRldmljZS51ZGlkLCB0aGlzLmJ1bmRsZUlkRm9yWGN0ZXN0LCBudWxsLCB7ZW52OiB4Y3Rlc3RFbnZ9KTtcblxuICAgIGF3YWl0IHRoaXMueGN0ZXN0QXBpQ2xpZW50LnN0YXJ0KCk7XG5cbiAgICB0aGlzLnNldHVwUHJveGllcyhzZXNzaW9uSWQpO1xuICAgIGNvbnN0IHN0YXR1cyA9IGF3YWl0IHRoaXMuZ2V0U3RhdHVzKCk7XG4gICAgdGhpcy5zdGFydGVkID0gdHJ1ZTtcbiAgICByZXR1cm4gc3RhdHVzO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBjdXJyZW50IHJ1bm5pbmcgV0RBJ3Mgc3RhdHVzIGxpa2UgYmVsb3cgYWZ0ZXIgbGF1bmNoaW5nIFdEQVxuICAgKiB7XG4gICAqICAgXCJzdGF0ZVwiOiBcInN1Y2Nlc3NcIixcbiAgICogICBcIm9zXCI6IHtcbiAgICogICAgIFwibmFtZVwiOiBcImlPU1wiLFxuICAgKiAgICAgXCJ2ZXJzaW9uXCI6IFwiMTEuNFwiLFxuICAgKiAgICAgXCJzZGtWZXJzaW9uXCI6IFwiMTEuM1wiXG4gICAqICAgfSxcbiAgICogICBcImlvc1wiOiB7XG4gICAqICAgICBcInNpbXVsYXRvclZlcnNpb25cIjogXCIxMS40XCIsXG4gICAqICAgICBcImlwXCI6IFwiMTcyLjI1NC45OS4zNFwiXG4gICAqICAgfSxcbiAgICogICBcImJ1aWxkXCI6IHtcbiAgICogICAgIFwidGltZVwiOiBcIkp1biAyNCAyMDE4IDE3OjA4OjIxXCIsXG4gICAqICAgICBcInByb2R1Y3RCdW5kbGVJZGVudGlmaWVyXCI6IFwiY29tLmZhY2Vib29rLldlYkRyaXZlckFnZW50UnVubmVyXCJcbiAgICogICB9XG4gICAqIH1cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHNlc3Npb25JZCBMYXVuY2ggV0RBIGFuZCBlc3RhYmxpc2ggdGhlIHNlc3Npb24gd2l0aCB0aGlzIHNlc3Npb25JZFxuICAgKiBAcmV0dXJuIHs/b2JqZWN0fSBTdGF0ZSBPYmplY3RcbiAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZXJlIHdhcyBpbnZhbGlkIHJlc3BvbnNlIGNvZGUgb3IgYm9keVxuICAgKi9cbiAgYXN5bmMgbGF1bmNoIChzZXNzaW9uSWQpIHtcbiAgICBpZiAodGhpcy53ZWJEcml2ZXJBZ2VudFVybCkge1xuICAgICAgdGhpcy5sb2cuaW5mbyhgVXNpbmcgcHJvdmlkZWQgV2ViZHJpdmVyQWdlbnQgYXQgJyR7dGhpcy53ZWJEcml2ZXJBZ2VudFVybH0nYCk7XG4gICAgICB0aGlzLnVybCA9IHRoaXMud2ViRHJpdmVyQWdlbnRVcmw7XG4gICAgICB0aGlzLnNldHVwUHJveGllcyhzZXNzaW9uSWQpO1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZ2V0U3RhdHVzKCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudXNlUHJlaW5zdGFsbGVkV0RBKSB7XG4gICAgICBpZiAodGhpcy5pc1JlYWxEZXZpY2UpIHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMubGF1bmNoV2l0aFByZWluc3RhbGxlZFdEQShzZXNzaW9uSWQpO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1c2VQcmVpbnN0YWxsZWRXREEgaXMgYXZhaWxhYmxlIG9ubHkgZm9yIGEgcmVhbCBkZXZpY2UuJyk7XG4gICAgfVxuXG4gICAgdGhpcy5sb2cuaW5mbygnTGF1bmNoaW5nIFdlYkRyaXZlckFnZW50IG9uIHRoZSBkZXZpY2UnKTtcblxuICAgIHRoaXMuc2V0dXBQcm94aWVzKHNlc3Npb25JZCk7XG5cbiAgICBpZiAoIXRoaXMudXNlWGN0ZXN0cnVuRmlsZSAmJiAhYXdhaXQgZnMuZXhpc3RzKHRoaXMuYWdlbnRQYXRoKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBUcnlpbmcgdG8gdXNlIFdlYkRyaXZlckFnZW50IHByb2plY3QgYXQgJyR7dGhpcy5hZ2VudFBhdGh9JyBidXQgdGhlIGAgK1xuICAgICAgICAgICAgICAgICAgICAgICdmaWxlIGRvZXMgbm90IGV4aXN0Jyk7XG4gICAgfVxuXG4gICAgLy8gdXNlWGN0ZXN0cnVuRmlsZSBhbmQgdXNlUHJlYnVpbHRXREEgdXNlIGV4aXN0aW5nIGRlcGVuZGVuY2llc1xuICAgIC8vIEl0IGRlcGVuZHMgb24gdXNlciBzaWRlXG4gICAgaWYgKHRoaXMuaWRiIHx8IHRoaXMudXNlWGN0ZXN0cnVuRmlsZSB8fCAodGhpcy5kZXJpdmVkRGF0YVBhdGggJiYgdGhpcy51c2VQcmVidWlsdFdEQSkpIHtcbiAgICAgIHRoaXMubG9nLmluZm8oJ1NraXBwZWQgV0RBIHByb2plY3QgY2xlYW51cCBhY2NvcmRpbmcgdG8gdGhlIHByb3ZpZGVkIGNhcGFiaWxpdGllcycpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBzeW5jaHJvbml6YXRpb25LZXkgPSBwYXRoLm5vcm1hbGl6ZSh0aGlzLmJvb3RzdHJhcFBhdGgpO1xuICAgICAgYXdhaXQgU0hBUkVEX1JFU09VUkNFU19HVUFSRC5hY3F1aXJlKHN5bmNocm9uaXphdGlvbktleSxcbiAgICAgICAgYXN5bmMgKCkgPT4gYXdhaXQgdGhpcy5fY2xlYW51cFByb2plY3RJZkZyZXNoKCkpO1xuICAgIH1cblxuICAgIC8vIFdlIG5lZWQgdG8gcHJvdmlkZSBXREEgbG9jYWwgcG9ydCwgYmVjYXVzZSBpdCBtaWdodCBiZSBvY2N1cGllZFxuICAgIGF3YWl0IHJlc2V0VGVzdFByb2Nlc3Nlcyh0aGlzLmRldmljZS51ZGlkLCAhdGhpcy5pc1JlYWxEZXZpY2UpO1xuXG4gICAgaWYgKHRoaXMuaWRiKSB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zdGFydFdpdGhJREIoKTtcbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLnhjb2RlYnVpbGQuaW5pdCh0aGlzLm5vU2Vzc2lvblByb3h5KTtcblxuICAgIC8vIFN0YXJ0IHRoZSB4Y29kZWJ1aWxkIHByb2Nlc3NcbiAgICBpZiAodGhpcy5wcmVidWlsZFdEQSkge1xuICAgICAgYXdhaXQgdGhpcy54Y29kZWJ1aWxkLnByZWJ1aWxkKCk7XG4gICAgfVxuICAgIHJldHVybiBhd2FpdCB0aGlzLnhjb2RlYnVpbGQuc3RhcnQoKTtcbiAgfVxuXG4gIGFzeW5jIHN0YXJ0V2l0aElEQiAoKSB7XG4gICAgdGhpcy5sb2cuaW5mbygnV2lsbCBsYXVuY2ggV0RBIHdpdGggaWRiIGluc3RlYWQgb2YgeGNvZGVidWlsZCBzaW5jZSB0aGUgY29ycmVzcG9uZGluZyBmbGFnIGlzIGVuYWJsZWQnKTtcbiAgICBjb25zdCB7d2RhQnVuZGxlSWQsIHRlc3RCdW5kbGVJZH0gPSBhd2FpdCB0aGlzLnByZXBhcmVXREEoKTtcbiAgICBjb25zdCBlbnYgPSB7XG4gICAgICBVU0VfUE9SVDogdGhpcy53ZGFSZW1vdGVQb3J0LFxuICAgICAgV0RBX1BST0RVQ1RfQlVORExFX0lERU5USUZJRVI6IHRoaXMudXBkYXRlZFdEQUJ1bmRsZUlkLFxuICAgIH07XG4gICAgaWYgKHRoaXMubWpwZWdTZXJ2ZXJQb3J0KSB7XG4gICAgICBlbnYuTUpQRUdfU0VSVkVSX1BPUlQgPSB0aGlzLm1qcGVnU2VydmVyUG9ydDtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5pZGIucnVuWENVSVRlc3Qod2RhQnVuZGxlSWQsIHdkYUJ1bmRsZUlkLCB0ZXN0QnVuZGxlSWQsIHtlbnZ9KTtcbiAgfVxuXG4gIGFzeW5jIHBhcnNlQnVuZGxlSWQgKHdkYUJ1bmRsZVBhdGgpIHtcbiAgICBjb25zdCBpbmZvUGxpc3RQYXRoID0gcGF0aC5qb2luKHdkYUJ1bmRsZVBhdGgsICdJbmZvLnBsaXN0Jyk7XG4gICAgY29uc3QgaW5mb1BsaXN0ID0gYXdhaXQgcGxpc3QucGFyc2VQbGlzdChhd2FpdCBmcy5yZWFkRmlsZShpbmZvUGxpc3RQYXRoKSk7XG4gICAgaWYgKCFpbmZvUGxpc3QuQ0ZCdW5kbGVJZGVudGlmaWVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvdWxkIG5vdCBmaW5kIGJ1bmRsZSBpZCBpbiAnJHtpbmZvUGxpc3RQYXRofSdgKTtcbiAgICB9XG4gICAgcmV0dXJuIGluZm9QbGlzdC5DRkJ1bmRsZUlkZW50aWZpZXI7XG4gIH1cblxuICBhc3luYyBwcmVwYXJlV0RBICgpIHtcbiAgICBjb25zdCB3ZGFCdW5kbGVQYXRoID0gdGhpcy53ZGFCdW5kbGVQYXRoIHx8IGF3YWl0IHRoaXMuZmV0Y2hXREFCdW5kbGUoKTtcbiAgICBjb25zdCB3ZGFCdW5kbGVJZCA9IGF3YWl0IHRoaXMucGFyc2VCdW5kbGVJZCh3ZGFCdW5kbGVQYXRoKTtcbiAgICBpZiAoIWF3YWl0IHRoaXMuZGV2aWNlLmlzQXBwSW5zdGFsbGVkKHdkYUJ1bmRsZUlkKSkge1xuICAgICAgYXdhaXQgdGhpcy5kZXZpY2UuaW5zdGFsbEFwcCh3ZGFCdW5kbGVQYXRoKTtcbiAgICB9XG4gICAgY29uc3QgdGVzdEJ1bmRsZUlkID0gYXdhaXQgdGhpcy5pZGIuaW5zdGFsbFhDVGVzdEJ1bmRsZShwYXRoLmpvaW4od2RhQnVuZGxlUGF0aCwgJ1BsdWdJbnMnLCAnV2ViRHJpdmVyQWdlbnRSdW5uZXIueGN0ZXN0JykpO1xuICAgIHJldHVybiB7d2RhQnVuZGxlSWQsIHRlc3RCdW5kbGVJZCwgd2RhQnVuZGxlUGF0aH07XG4gIH1cblxuICBhc3luYyBmZXRjaFdEQUJ1bmRsZSAoKSB7XG4gICAgaWYgKCF0aGlzLmRlcml2ZWREYXRhUGF0aCkge1xuICAgICAgcmV0dXJuIGF3YWl0IGJ1bmRsZVdEQVNpbSh0aGlzLnhjb2RlYnVpbGQpO1xuICAgIH1cbiAgICBjb25zdCB3ZGFCdW5kbGVQYXRocyA9IGF3YWl0IGZzLmdsb2IoYCR7dGhpcy5kZXJpdmVkRGF0YVBhdGh9LyoqLyoke1dEQV9SVU5ORVJfQVBQfS9gLCB7XG4gICAgICBhYnNvbHV0ZTogdHJ1ZSxcbiAgICB9KTtcbiAgICBpZiAoXy5pc0VtcHR5KHdkYUJ1bmRsZVBhdGhzKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDb3VsZCBub3QgZmluZCB0aGUgV0RBIGJ1bmRsZSBpbiAnJHt0aGlzLmRlcml2ZWREYXRhUGF0aH0nYCk7XG4gICAgfVxuICAgIHJldHVybiB3ZGFCdW5kbGVQYXRoc1swXTtcbiAgfVxuXG4gIGFzeW5jIGlzU291cmNlRnJlc2ggKCkge1xuICAgIGNvbnN0IGV4aXN0c1Byb21pc2VzID0gW1xuICAgICAgJ1Jlc291cmNlcycsXG4gICAgICBgUmVzb3VyY2VzJHtwYXRoLnNlcH1XZWJEcml2ZXJBZ2VudC5idW5kbGVgLFxuICAgIF0ubWFwKChzdWJQYXRoKSA9PiBmcy5leGlzdHMocGF0aC5yZXNvbHZlKHRoaXMuYm9vdHN0cmFwUGF0aCwgc3ViUGF0aCkpKTtcbiAgICByZXR1cm4gKGF3YWl0IEIuYWxsKGV4aXN0c1Byb21pc2VzKSkuc29tZSgodikgPT4gdiA9PT0gZmFsc2UpO1xuICB9XG5cbiAgc2V0dXBQcm94aWVzIChzZXNzaW9uSWQpIHtcbiAgICBjb25zdCBwcm94eU9wdHMgPSB7XG4gICAgICBsb2c6IHRoaXMubG9nLFxuICAgICAgc2VydmVyOiB0aGlzLnVybC5ob3N0bmFtZSxcbiAgICAgIHBvcnQ6IHRoaXMudXJsLnBvcnQsXG4gICAgICBiYXNlOiB0aGlzLmJhc2VQYXRoLFxuICAgICAgdGltZW91dDogdGhpcy53ZGFDb25uZWN0aW9uVGltZW91dCxcbiAgICAgIGtlZXBBbGl2ZTogdHJ1ZSxcbiAgICB9O1xuXG4gICAgdGhpcy5qd3Byb3h5ID0gbmV3IEpXUHJveHkocHJveHlPcHRzKTtcbiAgICB0aGlzLmp3cHJveHkuc2Vzc2lvbklkID0gc2Vzc2lvbklkO1xuICAgIHRoaXMucHJveHlSZXFSZXMgPSB0aGlzLmp3cHJveHkucHJveHlSZXFSZXMuYmluZCh0aGlzLmp3cHJveHkpO1xuXG4gICAgdGhpcy5ub1Nlc3Npb25Qcm94eSA9IG5ldyBOb1Nlc3Npb25Qcm94eShwcm94eU9wdHMpO1xuICB9XG5cbiAgYXN5bmMgcXVpdCAoKSB7XG4gICAgaWYgKHRoaXMudXNlUHJlaW5zdGFsbGVkV0RBKSB7XG4gICAgICBpZiAodGhpcy54Y3Rlc3RBcGlDbGllbnQpIHtcbiAgICAgICAgdGhpcy5sb2cuaW5mbygnU3RvcHBpbmcgdGhlIFhDVGVzdCBzZXNzaW9uJyk7XG4gICAgICAgIHRoaXMueGN0ZXN0QXBpQ2xpZW50LnN0b3AoKTtcbiAgICAgICAgdGhpcy54Y3Rlc3RBcGlDbGllbnQgPSBudWxsO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIXRoaXMuYXJncy53ZWJEcml2ZXJBZ2VudFVybCkge1xuICAgICAgdGhpcy5sb2cuaW5mbygnU2h1dHRpbmcgZG93biBzdWItcHJvY2Vzc2VzJyk7XG4gICAgICBhd2FpdCB0aGlzLnhjb2RlYnVpbGQucXVpdCgpO1xuICAgICAgYXdhaXQgdGhpcy54Y29kZWJ1aWxkLnJlc2V0KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubG9nLmRlYnVnKCdEbyBub3Qgc3RvcCB4Y29kZWJ1aWxkIG5vciBYQ1Rlc3Qgc2Vzc2lvbiAnICtcbiAgICAgICAgJ3NpbmNlIHRoZSBXREEgc2Vzc2lvbiBpcyBtYW5hZ2VkIGJ5IG91dHNpZGUgdGhpcyBkcml2ZXIuJyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuandwcm94eSkge1xuICAgICAgdGhpcy5qd3Byb3h5LnNlc3Npb25JZCA9IG51bGw7XG4gICAgfVxuXG4gICAgdGhpcy5zdGFydGVkID0gZmFsc2U7XG5cbiAgICBpZiAoIXRoaXMuYXJncy53ZWJEcml2ZXJBZ2VudFVybCkge1xuICAgICAgLy8gaWYgd2UgcG9wdWxhdGVkIHRoZSB1cmwgb3Vyc2VsdmVzIChkdXJpbmcgYHNldHVwQ2FjaGluZ2AgY2FsbCwgZm9yIGluc3RhbmNlKVxuICAgICAgLy8gdGhlbiBjbGVhbiB0aGF0IHVwLiBJZiB0aGUgdXJsIHdhcyBzdXBwbGllZCwgd2Ugd2FudCB0byBrZWVwIGl0XG4gICAgICB0aGlzLndlYkRyaXZlckFnZW50VXJsID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBnZXQgdXJsICgpIHtcbiAgICBpZiAoIXRoaXMuX3VybCkge1xuICAgICAgaWYgKHRoaXMud2ViRHJpdmVyQWdlbnRVcmwpIHtcbiAgICAgICAgdGhpcy5fdXJsID0gdXJsLnBhcnNlKHRoaXMud2ViRHJpdmVyQWdlbnRVcmwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgcG9ydCA9IHRoaXMud2RhTG9jYWxQb3J0IHx8IFdEQV9BR0VOVF9QT1JUO1xuICAgICAgICBjb25zdCB7cHJvdG9jb2wsIGhvc3RuYW1lfSA9IHVybC5wYXJzZSh0aGlzLndkYUJhc2VVcmwgfHwgV0RBX0JBU0VfVVJMKTtcbiAgICAgICAgdGhpcy5fdXJsID0gdXJsLnBhcnNlKGAke3Byb3RvY29sfS8vJHtob3N0bmFtZX06JHtwb3J0fWApO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fdXJsO1xuICB9XG5cbiAgc2V0IHVybCAoX3VybCkge1xuICAgIHRoaXMuX3VybCA9IHVybC5wYXJzZShfdXJsKTtcbiAgfVxuXG4gIGdldCBmdWxseVN0YXJ0ZWQgKCkge1xuICAgIHJldHVybiB0aGlzLnN0YXJ0ZWQ7XG4gIH1cblxuICBzZXQgZnVsbHlTdGFydGVkIChzdGFydGVkID0gZmFsc2UpIHtcbiAgICB0aGlzLnN0YXJ0ZWQgPSBzdGFydGVkO1xuICB9XG5cbiAgYXN5bmMgcmV0cmlldmVEZXJpdmVkRGF0YVBhdGggKCkge1xuICAgIGlmICh0aGlzLmNhblNraXBYY29kZWJ1aWxkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHJldHVybiBhd2FpdCB0aGlzLnhjb2RlYnVpbGQucmV0cmlldmVEZXJpdmVkRGF0YVBhdGgoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXVzZSBydW5uaW5nIFdEQSBpZiBpdCBoYXMgdGhlIHNhbWUgYnVuZGxlIGlkIHdpdGggdXBkYXRlZFdEQUJ1bmRsZUlkLlxuICAgKiBPciByZXVzZSBpdCBpZiBpdCBoYXMgdGhlIGRlZmF1bHQgaWQgd2l0aG91dCB1cGRhdGVkV0RBQnVuZGxlSWQuXG4gICAqIFVuaW5zdGFsbCBpdCBpZiB0aGUgbWV0aG9kIGZhY2VzIGFuIGV4Y2VwdGlvbiBmb3IgdGhlIGFib3ZlIHNpdHVhdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHVwZGF0ZWRXREFCdW5kbGVJZCBCdW5kbGVJZCB5b3UnZCBsaWtlIHRvIHVzZVxuICAgKi9cbiAgYXN5bmMgc2V0dXBDYWNoaW5nICgpIHtcbiAgICBjb25zdCBzdGF0dXMgPSBhd2FpdCB0aGlzLmdldFN0YXR1cygpO1xuICAgIGlmICghc3RhdHVzIHx8ICFzdGF0dXMuYnVpbGQpIHtcbiAgICAgIHRoaXMubG9nLmRlYnVnKCdXREEgaXMgY3VycmVudGx5IG5vdCBydW5uaW5nLiBUaGVyZSBpcyBub3RoaW5nIHRvIGNhY2hlJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qge1xuICAgICAgcHJvZHVjdEJ1bmRsZUlkZW50aWZpZXIsXG4gICAgICB1cGdyYWRlZEF0LFxuICAgIH0gPSBzdGF0dXMuYnVpbGQ7XG4gICAgLy8gZm9yIHJlYWwgZGV2aWNlXG4gICAgaWYgKHV0aWwuaGFzVmFsdWUocHJvZHVjdEJ1bmRsZUlkZW50aWZpZXIpICYmIHV0aWwuaGFzVmFsdWUodGhpcy51cGRhdGVkV0RBQnVuZGxlSWQpICYmIHRoaXMudXBkYXRlZFdEQUJ1bmRsZUlkICE9PSBwcm9kdWN0QnVuZGxlSWRlbnRpZmllcikge1xuICAgICAgdGhpcy5sb2cuaW5mbyhgV2lsbCB1bmluc3RhbGwgcnVubmluZyBXREEgc2luY2UgaXQgaGFzIGRpZmZlcmVudCBidW5kbGUgaWQuIFRoZSBhY3R1YWwgdmFsdWUgaXMgJyR7cHJvZHVjdEJ1bmRsZUlkZW50aWZpZXJ9Jy5gKTtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnVuaW5zdGFsbCgpO1xuICAgIH1cbiAgICAvLyBmb3Igc2ltdWxhdG9yXG4gICAgaWYgKHV0aWwuaGFzVmFsdWUocHJvZHVjdEJ1bmRsZUlkZW50aWZpZXIpICYmICF1dGlsLmhhc1ZhbHVlKHRoaXMudXBkYXRlZFdEQUJ1bmRsZUlkKSAmJiBXREFfUlVOTkVSX0JVTkRMRV9JRCAhPT0gcHJvZHVjdEJ1bmRsZUlkZW50aWZpZXIpIHtcbiAgICAgIHRoaXMubG9nLmluZm8oYFdpbGwgdW5pbnN0YWxsIHJ1bm5pbmcgV0RBIHNpbmNlIGl0cyBidW5kbGUgaWQgaXMgbm90IGVxdWFsIHRvIHRoZSBkZWZhdWx0IHZhbHVlICR7V0RBX1JVTk5FUl9CVU5ETEVfSUR9YCk7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy51bmluc3RhbGwoKTtcbiAgICB9XG5cbiAgICBjb25zdCBhY3R1YWxVcGdyYWRlVGltZXN0YW1wID0gYXdhaXQgZ2V0V0RBVXBncmFkZVRpbWVzdGFtcCgpO1xuICAgIHRoaXMubG9nLmRlYnVnKGBVcGdyYWRlIHRpbWVzdGFtcCBvZiB0aGUgY3VycmVudGx5IGJ1bmRsZWQgV0RBOiAke2FjdHVhbFVwZ3JhZGVUaW1lc3RhbXB9YCk7XG4gICAgdGhpcy5sb2cuZGVidWcoYFVwZ3JhZGUgdGltZXN0YW1wIG9mIHRoZSBXREEgb24gdGhlIGRldmljZTogJHt1cGdyYWRlZEF0fWApO1xuICAgIGlmIChhY3R1YWxVcGdyYWRlVGltZXN0YW1wICYmIHVwZ3JhZGVkQXQgJiYgXy50b0xvd2VyKGAke2FjdHVhbFVwZ3JhZGVUaW1lc3RhbXB9YCkgIT09IF8udG9Mb3dlcihgJHt1cGdyYWRlZEF0fWApKSB7XG4gICAgICB0aGlzLmxvZy5pbmZvKCdXaWxsIHVuaW5zdGFsbCBydW5uaW5nIFdEQSBzaW5jZSBpdCBoYXMgZGlmZmVyZW50IHZlcnNpb24gaW4gY29tcGFyaXNvbiB0byB0aGUgb25lICcgK1xuICAgICAgICBgd2hpY2ggaXMgYnVuZGxlZCB3aXRoIGFwcGl1bS14Y3VpdGVzdC1kcml2ZXIgbW9kdWxlICgke2FjdHVhbFVwZ3JhZGVUaW1lc3RhbXB9ICE9ICR7dXBncmFkZWRBdH0pYCk7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy51bmluc3RhbGwoKTtcbiAgICB9XG5cbiAgICBjb25zdCBtZXNzYWdlID0gdXRpbC5oYXNWYWx1ZShwcm9kdWN0QnVuZGxlSWRlbnRpZmllcilcbiAgICAgID8gYFdpbGwgcmV1c2UgcHJldmlvdXNseSBjYWNoZWQgV0RBIGluc3RhbmNlIGF0ICcke3RoaXMudXJsLmhyZWZ9JyB3aXRoICcke3Byb2R1Y3RCdW5kbGVJZGVudGlmaWVyfSdgXG4gICAgICA6IGBXaWxsIHJldXNlIHByZXZpb3VzbHkgY2FjaGVkIFdEQSBpbnN0YW5jZSBhdCAnJHt0aGlzLnVybC5ocmVmfSdgO1xuICAgIHRoaXMubG9nLmluZm8oYCR7bWVzc2FnZX0uIFNldCB0aGUgd2RhTG9jYWxQb3J0IGNhcGFiaWxpdHkgdG8gYSB2YWx1ZSBkaWZmZXJlbnQgZnJvbSAke3RoaXMudXJsLnBvcnR9IGlmIHRoaXMgaXMgYW4gdW5kZXNpcmVkIGJlaGF2aW9yLmApO1xuICAgIHRoaXMud2ViRHJpdmVyQWdlbnRVcmwgPSB0aGlzLnVybC5ocmVmO1xuICB9XG5cbiAgLyoqXG4gICAqIFF1aXQgYW5kIHVuaW5zdGFsbCBydW5uaW5nIFdEQS5cbiAgICovXG4gIGFzeW5jIHF1aXRBbmRVbmluc3RhbGwgKCkge1xuICAgIGF3YWl0IHRoaXMucXVpdCgpO1xuICAgIGF3YWl0IHRoaXMudW5pbnN0YWxsKCk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgV2ViRHJpdmVyQWdlbnQ7XG5leHBvcnQgeyBXZWJEcml2ZXJBZ2VudCB9O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUFBLElBQUFBLE9BQUEsR0FBQUMsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFDLEtBQUEsR0FBQUYsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFFLEtBQUEsR0FBQUgsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFHLFNBQUEsR0FBQUosc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFJLFdBQUEsR0FBQUosT0FBQTtBQUNBLElBQUFLLFFBQUEsR0FBQUwsT0FBQTtBQUNBLElBQUFNLE9BQUEsR0FBQVAsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFPLGVBQUEsR0FBQVAsT0FBQTtBQUNBLElBQUFRLE1BQUEsR0FBQVIsT0FBQTtBQUdBLElBQUFTLFdBQUEsR0FBQVYsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFVLFVBQUEsR0FBQVgsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFXLGFBQUEsR0FBQVgsT0FBQTtBQUNBLElBQUFZLGtCQUFBLEdBQUFaLE9BQUE7QUFDQSxJQUFBYSxVQUFBLEdBQUFiLE9BQUE7QUFJQSxJQUFBYyxnQkFBQSxHQUFBZCxPQUFBO0FBQ0EsSUFBQWUsVUFBQSxHQUFBZixPQUFBO0FBRUEsTUFBTWdCLGtCQUFrQixHQUFHLEVBQUUsR0FBRyxJQUFJO0FBQ3BDLE1B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
|
|
514
|
+
exports.default = WebDriverAgent;
|
|
515
|
+
//# sourceMappingURL=webdriveragent.js.map
|