appium 2.0.0-beta.2 → 2.0.0-beta.23
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/README.md +9 -9
- package/build/check-npm-pack-files.js +23 -0
- package/build/commands-yml/parse.js +319 -0
- package/build/commands-yml/validator.js +130 -0
- package/build/index.js +19 -0
- package/build/lib/appium-config.schema.json +0 -0
- package/build/lib/appium.js +160 -53
- package/build/lib/cli/args.js +115 -279
- package/build/lib/cli/driver-command.js +11 -1
- package/build/lib/cli/extension-command.js +60 -8
- package/build/lib/cli/extension.js +30 -7
- package/build/lib/cli/npm.js +43 -29
- package/build/lib/cli/parser.js +156 -89
- package/build/lib/cli/plugin-command.js +11 -1
- package/build/lib/cli/utils.js +29 -3
- package/build/lib/config-file.js +141 -0
- package/build/lib/config.js +53 -65
- package/build/lib/driver-config.js +42 -19
- package/build/lib/drivers.js +8 -4
- package/build/lib/ext-config-io.js +165 -0
- package/build/lib/extension-config.js +130 -61
- package/build/lib/grid-register.js +22 -24
- package/build/lib/logger.js +3 -3
- package/build/lib/logsink.js +11 -13
- package/build/lib/main.js +197 -77
- package/build/lib/plugin-config.js +21 -11
- package/build/lib/plugins.js +4 -2
- package/build/lib/schema/appium-config-schema.js +253 -0
- package/build/lib/schema/arg-spec.js +120 -0
- package/build/lib/schema/cli-args.js +188 -0
- package/build/lib/schema/cli-transformers.js +76 -0
- package/build/lib/schema/index.js +36 -0
- package/build/lib/schema/keywords.js +72 -0
- package/build/lib/schema/schema.js +357 -0
- package/build/lib/utils.js +44 -99
- package/build/postinstall.js +90 -0
- package/build/test/cli/cli-e2e-specs.js +221 -0
- package/build/test/cli/cli-helpers.js +86 -0
- package/build/test/cli/cli-specs.js +71 -0
- package/build/test/cli/fixtures/test-driver/package.json +27 -0
- package/build/test/cli/schema-args-specs.js +48 -0
- package/build/test/cli/schema-e2e-specs.js +47 -0
- package/build/test/config-e2e-specs.js +112 -0
- package/build/test/config-file-e2e-specs.js +209 -0
- package/build/test/config-file-specs.js +281 -0
- package/build/test/config-specs.js +159 -0
- package/build/test/driver-e2e-specs.js +435 -0
- package/build/test/driver-specs.js +321 -0
- package/build/test/ext-config-io-specs.js +181 -0
- package/build/test/extension-config-specs.js +365 -0
- package/build/test/fixtures/allow-feat.txt +5 -0
- package/build/test/fixtures/caps.json +3 -0
- package/build/test/fixtures/config/allow-insecure.txt +3 -0
- package/build/test/fixtures/config/appium.config.bad-nodeconfig.json +5 -0
- package/build/test/fixtures/config/appium.config.bad.json +32 -0
- package/build/test/fixtures/config/appium.config.ext-good.json +9 -0
- package/build/test/fixtures/config/appium.config.ext-unknown-props.json +10 -0
- package/build/test/fixtures/config/appium.config.good.js +40 -0
- package/build/test/fixtures/config/appium.config.good.json +33 -0
- package/build/test/fixtures/config/appium.config.good.yaml +30 -0
- package/build/test/fixtures/config/appium.config.invalid.json +31 -0
- package/build/test/fixtures/config/appium.config.security-array.json +5 -0
- package/build/test/fixtures/config/appium.config.security-delimited.json +5 -0
- package/build/test/fixtures/config/appium.config.security-path.json +5 -0
- package/build/test/fixtures/config/driver-fake.config.json +8 -0
- package/build/test/fixtures/config/nodeconfig.json +3 -0
- package/build/test/fixtures/config/plugin-fake.config.json +0 -0
- package/build/test/fixtures/default-args.js +35 -0
- package/build/test/fixtures/deny-feat.txt +5 -0
- package/build/test/fixtures/driver.schema.js +20 -0
- package/build/test/fixtures/extensions.yaml +27 -0
- package/build/test/fixtures/flattened-schema.js +504 -0
- package/build/test/fixtures/plugin.schema.js +20 -0
- package/build/test/fixtures/schema-with-extensions.js +28 -0
- package/build/test/grid-register-specs.js +74 -0
- package/build/test/helpers.js +75 -0
- package/build/test/logger-specs.js +76 -0
- package/build/test/npm-specs.js +20 -0
- package/build/test/parser-specs.js +314 -0
- package/build/test/plugin-e2e-specs.js +316 -0
- package/build/test/schema/arg-spec-specs.js +70 -0
- package/build/test/schema/cli-args-specs.js +431 -0
- package/build/test/schema/schema-specs.js +389 -0
- package/build/test/utils-specs.js +266 -0
- package/index.js +11 -0
- package/lib/appium-config.schema.json +278 -0
- package/lib/appium.js +207 -65
- package/lib/cli/args.js +174 -375
- package/lib/cli/driver-command.js +4 -0
- package/lib/cli/extension-command.js +70 -5
- package/lib/cli/extension.js +25 -5
- package/lib/cli/npm.js +86 -18
- package/lib/cli/parser.js +257 -79
- package/lib/cli/plugin-command.js +4 -0
- package/lib/cli/utils.js +21 -1
- package/lib/config-file.js +227 -0
- package/lib/config.js +84 -63
- package/lib/driver-config.js +66 -11
- package/lib/drivers.js +4 -1
- package/lib/ext-config-io.js +287 -0
- package/lib/extension-config.js +225 -67
- package/lib/grid-register.js +27 -24
- package/lib/logger.js +1 -1
- package/lib/logsink.js +10 -7
- package/lib/main.js +214 -77
- package/lib/plugin-config.js +35 -6
- package/lib/plugins.js +1 -0
- package/lib/schema/appium-config-schema.js +287 -0
- package/lib/schema/arg-spec.js +222 -0
- package/lib/schema/cli-args.js +285 -0
- package/lib/schema/cli-transformers.js +123 -0
- package/lib/schema/index.js +2 -0
- package/lib/schema/keywords.js +135 -0
- package/lib/schema/schema.js +577 -0
- package/lib/utils.js +42 -88
- package/package.json +55 -84
- package/postinstall.js +71 -0
- package/types/appium-config.d.ts +197 -0
- package/types/types.d.ts +201 -0
- package/CHANGELOG.md +0 -3515
- package/build/lib/cli/parser-helpers.js +0 -82
- package/lib/cli/parser-helpers.js +0 -79
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
require("source-map-support/register");
|
|
6
|
+
|
|
7
|
+
var _lodash = _interopRequireDefault(require("lodash"));
|
|
8
|
+
|
|
9
|
+
var _path = _interopRequireDefault(require("path"));
|
|
10
|
+
|
|
11
|
+
var _bluebird = _interopRequireDefault(require("bluebird"));
|
|
12
|
+
|
|
13
|
+
var _axios = _interopRequireDefault(require("axios"));
|
|
14
|
+
|
|
15
|
+
var _webdriverio = require("webdriverio");
|
|
16
|
+
|
|
17
|
+
var _main = require("../lib/main");
|
|
18
|
+
|
|
19
|
+
var _extensionConfig = require("../lib/extension-config");
|
|
20
|
+
|
|
21
|
+
var _helpers = require("./helpers");
|
|
22
|
+
|
|
23
|
+
var _baseDriver = require("@appium/base-driver");
|
|
24
|
+
|
|
25
|
+
var _driverConfig = _interopRequireDefault(require("../lib/driver-config"));
|
|
26
|
+
|
|
27
|
+
var _extension = require("../lib/cli/extension");
|
|
28
|
+
|
|
29
|
+
var _utils = require("../lib/utils");
|
|
30
|
+
|
|
31
|
+
var _sinon = _interopRequireDefault(require("sinon"));
|
|
32
|
+
|
|
33
|
+
let TEST_SERVER;
|
|
34
|
+
let TEST_PORT;
|
|
35
|
+
const sillyWebServerPort = 1234;
|
|
36
|
+
const sillyWebServerHost = 'hey';
|
|
37
|
+
const FAKE_ARGS = {
|
|
38
|
+
sillyWebServerPort,
|
|
39
|
+
sillyWebServerHost
|
|
40
|
+
};
|
|
41
|
+
const FAKE_DRIVER_ARGS = {
|
|
42
|
+
driver: {
|
|
43
|
+
fake: FAKE_ARGS
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
const shouldStartServer = process.env.USE_RUNNING_SERVER !== '0';
|
|
47
|
+
const caps = _helpers.W3C_PREFIXED_CAPS;
|
|
48
|
+
const wdOpts = {
|
|
49
|
+
hostname: _helpers.TEST_HOST,
|
|
50
|
+
port: null,
|
|
51
|
+
connectionRetryCount: 0
|
|
52
|
+
};
|
|
53
|
+
describe('FakeDriver - via HTTP', function () {
|
|
54
|
+
let server = null;
|
|
55
|
+
const appiumHome = _extensionConfig.DEFAULT_APPIUM_HOME;
|
|
56
|
+
let FakeDriver = null;
|
|
57
|
+
let baseUrl;
|
|
58
|
+
|
|
59
|
+
const FAKE_DRIVER_DIR = _path.default.join(_helpers.PROJECT_ROOT, 'packages', 'fake-driver');
|
|
60
|
+
|
|
61
|
+
before(async function () {
|
|
62
|
+
wdOpts.port = TEST_PORT = await (0, _helpers.getTestPort)();
|
|
63
|
+
TEST_SERVER = `http://${_helpers.TEST_HOST}:${TEST_PORT}`;
|
|
64
|
+
baseUrl = `${TEST_SERVER}/session`;
|
|
65
|
+
const driverList = await (0, _extension.runExtensionCommand)({
|
|
66
|
+
appiumHome,
|
|
67
|
+
driverCommand: 'list',
|
|
68
|
+
showInstalled: true
|
|
69
|
+
}, _extensionConfig.DRIVER_TYPE);
|
|
70
|
+
|
|
71
|
+
if (!_lodash.default.has(driverList, 'fake')) {
|
|
72
|
+
await (0, _extension.runExtensionCommand)({
|
|
73
|
+
appiumHome,
|
|
74
|
+
driverCommand: 'install',
|
|
75
|
+
driver: FAKE_DRIVER_DIR,
|
|
76
|
+
installType: _extensionConfig.INSTALL_TYPE_LOCAL
|
|
77
|
+
}, _extensionConfig.DRIVER_TYPE);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const config = _driverConfig.default.getInstance(appiumHome);
|
|
81
|
+
|
|
82
|
+
FakeDriver = config.require('fake');
|
|
83
|
+
await serverStart();
|
|
84
|
+
});
|
|
85
|
+
after(async function () {
|
|
86
|
+
await serverClose();
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
async function serverStart(args = {}) {
|
|
90
|
+
args = {
|
|
91
|
+
port: TEST_PORT,
|
|
92
|
+
host: _helpers.TEST_HOST,
|
|
93
|
+
appiumHome,
|
|
94
|
+
...args
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
if (shouldStartServer) {
|
|
98
|
+
server = await (0, _main.main)(args);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async function serverClose() {
|
|
103
|
+
if (server) {
|
|
104
|
+
await server.close();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
describe('server updating', function () {
|
|
109
|
+
it('should allow drivers to update the server in arbitrary ways', async function () {
|
|
110
|
+
const {
|
|
111
|
+
data
|
|
112
|
+
} = await _axios.default.get(`${TEST_SERVER}/fakedriver`);
|
|
113
|
+
data.should.eql({
|
|
114
|
+
fakedriver: 'fakeResponse'
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
describe('cli args handling for empty args', function () {
|
|
119
|
+
it('should not recieve user cli args if none passed in', async function () {
|
|
120
|
+
let driver = await (0, _webdriverio.remote)({ ...wdOpts,
|
|
121
|
+
capabilities: caps
|
|
122
|
+
});
|
|
123
|
+
const {
|
|
124
|
+
sessionId
|
|
125
|
+
} = driver;
|
|
126
|
+
|
|
127
|
+
try {
|
|
128
|
+
const {
|
|
129
|
+
data
|
|
130
|
+
} = await _axios.default.get(`${baseUrl}/${sessionId}/fakedriverargs`);
|
|
131
|
+
should.not.exist(data.value.sillyWebServerPort);
|
|
132
|
+
should.not.exist(data.value.sillyWebServerHost);
|
|
133
|
+
} finally {
|
|
134
|
+
await driver.deleteSession();
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
describe('cli args handling for passed in args', function () {
|
|
139
|
+
before(async function () {
|
|
140
|
+
await serverClose();
|
|
141
|
+
await serverStart(FAKE_DRIVER_ARGS);
|
|
142
|
+
});
|
|
143
|
+
after(async function () {
|
|
144
|
+
await serverClose();
|
|
145
|
+
await serverStart();
|
|
146
|
+
});
|
|
147
|
+
it('should receive user cli args from a driver if arguments were passed in', async function () {
|
|
148
|
+
let driver = await (0, _webdriverio.remote)({ ...wdOpts,
|
|
149
|
+
capabilities: caps
|
|
150
|
+
});
|
|
151
|
+
const {
|
|
152
|
+
sessionId
|
|
153
|
+
} = driver;
|
|
154
|
+
|
|
155
|
+
try {
|
|
156
|
+
const {
|
|
157
|
+
data
|
|
158
|
+
} = await _axios.default.get(`${baseUrl}/${sessionId}/fakedriverargs`);
|
|
159
|
+
data.value.sillyWebServerPort.should.eql(sillyWebServerPort);
|
|
160
|
+
data.value.sillyWebServerHost.should.eql(sillyWebServerHost);
|
|
161
|
+
} finally {
|
|
162
|
+
await driver.deleteSession();
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
describe('session handling', function () {
|
|
167
|
+
it('should start and stop a session and not allow commands after session stopped', async function () {
|
|
168
|
+
let driver = await (0, _webdriverio.remote)({ ...wdOpts,
|
|
169
|
+
capabilities: caps
|
|
170
|
+
});
|
|
171
|
+
should.exist(driver.sessionId);
|
|
172
|
+
driver.sessionId.should.be.a('string');
|
|
173
|
+
await driver.deleteSession();
|
|
174
|
+
await driver.getTitle().should.eventually.be.rejectedWith(/terminated/);
|
|
175
|
+
});
|
|
176
|
+
it('should be able to run two FakeDriver sessions simultaneously', async function () {
|
|
177
|
+
let driver1 = await (0, _webdriverio.remote)({ ...wdOpts,
|
|
178
|
+
capabilities: caps
|
|
179
|
+
});
|
|
180
|
+
should.exist(driver1.sessionId);
|
|
181
|
+
driver1.sessionId.should.be.a('string');
|
|
182
|
+
let driver2 = await (0, _webdriverio.remote)({ ...wdOpts,
|
|
183
|
+
capabilities: caps
|
|
184
|
+
});
|
|
185
|
+
should.exist(driver2.sessionId);
|
|
186
|
+
driver2.sessionId.should.be.a('string');
|
|
187
|
+
driver2.sessionId.should.not.equal(driver1.sessionId);
|
|
188
|
+
await driver1.deleteSession();
|
|
189
|
+
await driver2.deleteSession();
|
|
190
|
+
});
|
|
191
|
+
it('should not be able to run two FakeDriver sessions simultaneously when one is unique', async function () {
|
|
192
|
+
let uniqueCaps = _lodash.default.clone(caps);
|
|
193
|
+
|
|
194
|
+
uniqueCaps['appium:uniqueApp'] = true;
|
|
195
|
+
let driver1 = await (0, _webdriverio.remote)({ ...wdOpts,
|
|
196
|
+
capabilities: uniqueCaps
|
|
197
|
+
});
|
|
198
|
+
should.exist(driver1.sessionId);
|
|
199
|
+
driver1.sessionId.should.be.a('string');
|
|
200
|
+
await (0, _webdriverio.remote)({ ...wdOpts,
|
|
201
|
+
capabilities: caps
|
|
202
|
+
}).should.eventually.be.rejected;
|
|
203
|
+
await driver1.deleteSession();
|
|
204
|
+
});
|
|
205
|
+
it('should use the newCommandTimeout of the inner Driver on session creation', async function () {
|
|
206
|
+
let localCaps = Object.assign({
|
|
207
|
+
'appium:newCommandTimeout': 0.25
|
|
208
|
+
}, caps);
|
|
209
|
+
let driver = await (0, _webdriverio.remote)({ ...wdOpts,
|
|
210
|
+
capabilities: localCaps
|
|
211
|
+
});
|
|
212
|
+
should.exist(driver.sessionId);
|
|
213
|
+
await _bluebird.default.delay(250);
|
|
214
|
+
await driver.getPageSource().should.eventually.be.rejectedWith(/terminated/);
|
|
215
|
+
});
|
|
216
|
+
it('should accept valid W3C capabilities and start a W3C session', async function () {
|
|
217
|
+
const w3cCaps = {
|
|
218
|
+
capabilities: {
|
|
219
|
+
alwaysMatch: {
|
|
220
|
+
'appium:automationName': 'Fake',
|
|
221
|
+
platformName: 'Fake'
|
|
222
|
+
},
|
|
223
|
+
firstMatch: [{
|
|
224
|
+
'appium:deviceName': 'Fake',
|
|
225
|
+
'appium:app': _helpers.TEST_FAKE_APP
|
|
226
|
+
}]
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
const {
|
|
230
|
+
status,
|
|
231
|
+
value,
|
|
232
|
+
sessionId
|
|
233
|
+
} = (await _axios.default.post(baseUrl, w3cCaps)).data;
|
|
234
|
+
|
|
235
|
+
try {
|
|
236
|
+
should.not.exist(status);
|
|
237
|
+
should.not.exist(sessionId);
|
|
238
|
+
value.sessionId.should.be.a.string;
|
|
239
|
+
value.should.exist;
|
|
240
|
+
value.capabilities.should.deep.equal({
|
|
241
|
+
automationName: 'Fake',
|
|
242
|
+
platformName: 'Fake',
|
|
243
|
+
deviceName: 'Fake',
|
|
244
|
+
app: _helpers.TEST_FAKE_APP
|
|
245
|
+
});
|
|
246
|
+
const {
|
|
247
|
+
status: screenshotStatus,
|
|
248
|
+
value: screenshotValue
|
|
249
|
+
} = (await (0, _axios.default)({
|
|
250
|
+
url: `${baseUrl}/${value.sessionId}/screenshot`
|
|
251
|
+
})).data;
|
|
252
|
+
should.not.exist(screenshotStatus);
|
|
253
|
+
screenshotValue.should.match(/^iVBOR/);
|
|
254
|
+
await _axios.default.post(`${baseUrl}/${value.sessionId}/execute/async`, {
|
|
255
|
+
script: '',
|
|
256
|
+
args: ['a']
|
|
257
|
+
}).should.eventually.be.rejectedWith(/405/);
|
|
258
|
+
} finally {
|
|
259
|
+
await _axios.default.delete(`${baseUrl}/${value.sessionId}`);
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
it('should reject invalid W3C capabilities and respond with a 400 Bad Parameters error', async function () {
|
|
263
|
+
const badW3Ccaps = {
|
|
264
|
+
capabilities: {
|
|
265
|
+
alwaysMatch: {},
|
|
266
|
+
firstMatch: [{
|
|
267
|
+
'appium:deviceName': 'Fake',
|
|
268
|
+
'appium:app': _helpers.TEST_FAKE_APP
|
|
269
|
+
}]
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
await _axios.default.post(baseUrl, badW3Ccaps).should.eventually.be.rejectedWith(/400/);
|
|
273
|
+
});
|
|
274
|
+
it('should accept a combo of W3C and JSONWP capabilities but completely ignore JSONWP', async function () {
|
|
275
|
+
const combinedCaps = {
|
|
276
|
+
'desiredCapabilities': { ...caps,
|
|
277
|
+
jsonwpParam: 'jsonwpParam'
|
|
278
|
+
},
|
|
279
|
+
'capabilities': {
|
|
280
|
+
'alwaysMatch': { ...caps
|
|
281
|
+
},
|
|
282
|
+
'firstMatch': [{
|
|
283
|
+
'appium:w3cParam': 'w3cParam'
|
|
284
|
+
}]
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
const {
|
|
288
|
+
status,
|
|
289
|
+
value,
|
|
290
|
+
sessionId
|
|
291
|
+
} = (await _axios.default.post(baseUrl, combinedCaps)).data;
|
|
292
|
+
|
|
293
|
+
try {
|
|
294
|
+
should.not.exist(status);
|
|
295
|
+
should.not.exist(sessionId);
|
|
296
|
+
value.sessionId.should.exist;
|
|
297
|
+
value.capabilities.should.deep.equal({ ...(0, _utils.removeAppiumPrefixes)(caps),
|
|
298
|
+
w3cParam: 'w3cParam'
|
|
299
|
+
});
|
|
300
|
+
} finally {
|
|
301
|
+
await _axios.default.delete(`${baseUrl}/${value.sessionId}`);
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
it('should reject bad automation name with an appropriate error', async function () {
|
|
305
|
+
const w3cCaps = {
|
|
306
|
+
capabilities: {
|
|
307
|
+
alwaysMatch: { ...caps,
|
|
308
|
+
'appium:automationName': 'BadAutomationName'
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
await _axios.default.post(baseUrl, w3cCaps).should.eventually.be.rejectedWith(/500/);
|
|
313
|
+
});
|
|
314
|
+
it('should accept capabilities that are provided in the firstMatch array', async function () {
|
|
315
|
+
const w3cCaps = {
|
|
316
|
+
capabilities: {
|
|
317
|
+
alwaysMatch: {},
|
|
318
|
+
firstMatch: [{}, { ...caps
|
|
319
|
+
}]
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
const {
|
|
323
|
+
value,
|
|
324
|
+
sessionId,
|
|
325
|
+
status
|
|
326
|
+
} = (await _axios.default.post(baseUrl, w3cCaps)).data;
|
|
327
|
+
|
|
328
|
+
try {
|
|
329
|
+
should.not.exist(status);
|
|
330
|
+
should.not.exist(sessionId);
|
|
331
|
+
value.capabilities.should.deep.equal((0, _utils.removeAppiumPrefixes)(caps));
|
|
332
|
+
} finally {
|
|
333
|
+
await _axios.default.delete(`${baseUrl}/${value.sessionId}`);
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
it('should not fall back to MJSONWP if w3c caps are invalid', async function () {
|
|
337
|
+
const combinedCaps = {
|
|
338
|
+
desiredCapabilities: { ...caps
|
|
339
|
+
},
|
|
340
|
+
capabilities: {
|
|
341
|
+
alwaysMatch: {},
|
|
342
|
+
firstMatch: [{}, { ...caps,
|
|
343
|
+
platformName: null,
|
|
344
|
+
'appium:automationName': null,
|
|
345
|
+
'appium:deviceName': null
|
|
346
|
+
}]
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
const res = await _axios.default.post(baseUrl, combinedCaps, {
|
|
350
|
+
validateStatus: null
|
|
351
|
+
});
|
|
352
|
+
res.status.should.eql(400);
|
|
353
|
+
res.data.value.error.should.match(/invalid argument/);
|
|
354
|
+
});
|
|
355
|
+
it('should not fall back to MJSONWP even if Inner Driver is not ready for W3C', async function () {
|
|
356
|
+
const combinedCaps = {
|
|
357
|
+
desiredCapabilities: { ...caps
|
|
358
|
+
},
|
|
359
|
+
capabilities: {
|
|
360
|
+
alwaysMatch: { ...caps,
|
|
361
|
+
'appium:deviceName': 'Fake'
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
const createSessionStub = _sinon.default.stub(FakeDriver.prototype, 'createSession').callsFake(async function (jsonwpCaps) {
|
|
367
|
+
const res = await _baseDriver.BaseDriver.prototype.createSession.call(this, jsonwpCaps);
|
|
368
|
+
this.protocol.should.equal('MJSONWP');
|
|
369
|
+
return res;
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
const res = await _axios.default.post(baseUrl, combinedCaps, {
|
|
373
|
+
validateStatus: null
|
|
374
|
+
});
|
|
375
|
+
const {
|
|
376
|
+
data,
|
|
377
|
+
status
|
|
378
|
+
} = res;
|
|
379
|
+
status.should.eql(500);
|
|
380
|
+
data.value.message.should.match(/older capabilities/);
|
|
381
|
+
createSessionStub.restore();
|
|
382
|
+
});
|
|
383
|
+
it('should allow drivers to update the method map with new routes and commands', async function () {
|
|
384
|
+
let driver = await (0, _webdriverio.remote)({ ...wdOpts,
|
|
385
|
+
capabilities: caps
|
|
386
|
+
});
|
|
387
|
+
const {
|
|
388
|
+
sessionId
|
|
389
|
+
} = driver;
|
|
390
|
+
|
|
391
|
+
try {
|
|
392
|
+
await _axios.default.post(`${baseUrl}/${sessionId}/fakedriver`, {
|
|
393
|
+
thing: {
|
|
394
|
+
yes: 'lolno'
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
(await _axios.default.get(`${baseUrl}/${sessionId}/fakedriver`)).data.value.should.eql({
|
|
398
|
+
yes: 'lolno'
|
|
399
|
+
});
|
|
400
|
+
} finally {
|
|
401
|
+
await driver.deleteSession();
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
});
|
|
405
|
+
});
|
|
406
|
+
describe.skip('Logsink', function () {
|
|
407
|
+
let server = null;
|
|
408
|
+
let logs = [];
|
|
409
|
+
|
|
410
|
+
let logHandler = function (level, message) {
|
|
411
|
+
logs.push([level, message]);
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
let args = {
|
|
415
|
+
port: TEST_PORT,
|
|
416
|
+
host: _helpers.TEST_HOST,
|
|
417
|
+
appiumHome: _extensionConfig.DEFAULT_APPIUM_HOME,
|
|
418
|
+
logHandler
|
|
419
|
+
};
|
|
420
|
+
before(async function () {
|
|
421
|
+
server = await (0, _main.main)(args);
|
|
422
|
+
});
|
|
423
|
+
after(async function () {
|
|
424
|
+
await server.close();
|
|
425
|
+
});
|
|
426
|
+
it('should send logs to a logHandler passed in by a parent package', function () {
|
|
427
|
+
logs.length.should.be.above(1);
|
|
428
|
+
let welcomeIndex = logs[0][1].includes('versions of node') ? 1 : 0;
|
|
429
|
+
logs[welcomeIndex].length.should.equal(2);
|
|
430
|
+
logs[welcomeIndex][1].should.include('Welcome to Appium');
|
|
431
|
+
});
|
|
432
|
+
});require('source-map-support').install();
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvZHJpdmVyLWUyZS1zcGVjcy5qcyJdLCJuYW1lcyI6WyJURVNUX1NFUlZFUiIsIlRFU1RfUE9SVCIsInNpbGx5V2ViU2VydmVyUG9ydCIsInNpbGx5V2ViU2VydmVySG9zdCIsIkZBS0VfQVJHUyIsIkZBS0VfRFJJVkVSX0FSR1MiLCJkcml2ZXIiLCJmYWtlIiwic2hvdWxkU3RhcnRTZXJ2ZXIiLCJwcm9jZXNzIiwiZW52IiwiVVNFX1JVTk5JTkdfU0VSVkVSIiwiY2FwcyIsIlczQ19QUkVGSVhFRF9DQVBTIiwid2RPcHRzIiwiaG9zdG5hbWUiLCJURVNUX0hPU1QiLCJwb3J0IiwiY29ubmVjdGlvblJldHJ5Q291bnQiLCJkZXNjcmliZSIsInNlcnZlciIsImFwcGl1bUhvbWUiLCJERUZBVUxUX0FQUElVTV9IT01FIiwiRmFrZURyaXZlciIsImJhc2VVcmwiLCJGQUtFX0RSSVZFUl9ESVIiLCJwYXRoIiwiam9pbiIsIlBST0pFQ1RfUk9PVCIsImJlZm9yZSIsImRyaXZlckxpc3QiLCJkcml2ZXJDb21tYW5kIiwic2hvd0luc3RhbGxlZCIsIkRSSVZFUl9UWVBFIiwiXyIsImhhcyIsImluc3RhbGxUeXBlIiwiSU5TVEFMTF9UWVBFX0xPQ0FMIiwiY29uZmlnIiwiRHJpdmVyQ29uZmlnIiwiZ2V0SW5zdGFuY2UiLCJyZXF1aXJlIiwic2VydmVyU3RhcnQiLCJhZnRlciIsInNlcnZlckNsb3NlIiwiYXJncyIsImhvc3QiLCJjbG9zZSIsIml0IiwiZGF0YSIsImF4aW9zIiwiZ2V0Iiwic2hvdWxkIiwiZXFsIiwiZmFrZWRyaXZlciIsImNhcGFiaWxpdGllcyIsInNlc3Npb25JZCIsIm5vdCIsImV4aXN0IiwidmFsdWUiLCJkZWxldGVTZXNzaW9uIiwiYmUiLCJhIiwiZ2V0VGl0bGUiLCJldmVudHVhbGx5IiwicmVqZWN0ZWRXaXRoIiwiZHJpdmVyMSIsImRyaXZlcjIiLCJlcXVhbCIsInVuaXF1ZUNhcHMiLCJjbG9uZSIsInJlamVjdGVkIiwibG9jYWxDYXBzIiwiT2JqZWN0IiwiYXNzaWduIiwiQiIsImRlbGF5IiwiZ2V0UGFnZVNvdXJjZSIsInczY0NhcHMiLCJhbHdheXNNYXRjaCIsInBsYXRmb3JtTmFtZSIsImZpcnN0TWF0Y2giLCJURVNUX0ZBS0VfQVBQIiwic3RhdHVzIiwicG9zdCIsInN0cmluZyIsImRlZXAiLCJhdXRvbWF0aW9uTmFtZSIsImRldmljZU5hbWUiLCJhcHAiLCJzY3JlZW5zaG90U3RhdHVzIiwic2NyZWVuc2hvdFZhbHVlIiwidXJsIiwibWF0Y2giLCJzY3JpcHQiLCJkZWxldGUiLCJiYWRXM0NjYXBzIiwiY29tYmluZWRDYXBzIiwianNvbndwUGFyYW0iLCJ3M2NQYXJhbSIsImRlc2lyZWRDYXBhYmlsaXRpZXMiLCJyZXMiLCJ2YWxpZGF0ZVN0YXR1cyIsImVycm9yIiwiY3JlYXRlU2Vzc2lvblN0dWIiLCJzaW5vbiIsInN0dWIiLCJwcm90b3R5cGUiLCJjYWxsc0Zha2UiLCJqc29ud3BDYXBzIiwiQmFzZURyaXZlciIsImNyZWF0ZVNlc3Npb24iLCJjYWxsIiwicHJvdG9jb2wiLCJtZXNzYWdlIiwicmVzdG9yZSIsInRoaW5nIiwieWVzIiwic2tpcCIsImxvZ3MiLCJsb2dIYW5kbGVyIiwibGV2ZWwiLCJwdXNoIiwibGVuZ3RoIiwiYWJvdmUiLCJ3ZWxjb21lSW5kZXgiLCJpbmNsdWRlcyIsImluY2x1ZGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUVBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUdBLElBQUlBLFdBQUo7QUFDQSxJQUFJQyxTQUFKO0FBQ0EsTUFBTUMsa0JBQWtCLEdBQUcsSUFBM0I7QUFDQSxNQUFNQyxrQkFBa0IsR0FBRyxLQUEzQjtBQUNBLE1BQU1DLFNBQVMsR0FBRztBQUFDRixFQUFBQSxrQkFBRDtBQUFxQkMsRUFBQUE7QUFBckIsQ0FBbEI7QUFDQSxNQUFNRSxnQkFBZ0IsR0FBRztBQUFDQyxFQUFBQSxNQUFN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Q0QsR0FMQyxDQUFGO0FBTUQsQ0EzQkQiLCJzb3VyY2VzQ29udGVudCI6WyIvLyB0cmFuc3BpbGU6bW9jaGFcblxuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IEIgZnJvbSAnYmx1ZWJpcmQnO1xuaW1wb3J0IGF4aW9zIGZyb20gJ2F4aW9zJztcbmltcG9ydCB7IHJlbW90ZSBhcyB3ZGlvIH0gZnJvbSAnd2ViZHJpdmVyaW8nO1xuaW1wb3J0IHsgbWFpbiBhcyBhcHBpdW1TZXJ2ZXIgfSBmcm9tICcuLi9saWIvbWFpbic7XG5pbXBvcnQgeyBERUZBVUxUX0FQUElVTV9IT01FLCBJTlNUQUxMX1RZUEVfTE9DQUwsIERSSVZFUl9UWVBFIH0gZnJvbSAnLi4vbGliL2V4dGVuc2lvbi1jb25maWcnO1xuaW1wb3J0IHsgVzNDX1BSRUZJWEVEX0NBUFMsIFRFU1RfRkFLRV9BUFAsIFRFU1RfSE9TVCwgZ2V0VGVzdFBvcnQsIFBST0pFQ1RfUk9PVCB9IGZyb20gJy4vaGVscGVycyc7XG5pbXBvcnQgeyBCYXNlRHJpdmVyIH0gZnJvbSAnQGFwcGl1bS9iYXNlLWRyaXZlcic7XG5pbXBvcnQgRHJpdmVyQ29uZmlnIGZyb20gJy4uL2xpYi9kcml2ZXItY29uZmlnJztcbmltcG9ydCB7IHJ1bkV4dGVuc2lvbkNvbW1hbmQgfSBmcm9tICcuLi9saWIvY2xpL2V4dGVuc2lvbic7XG5pbXBvcnQgeyByZW1vdmVBcHBpdW1QcmVmaXhlcyB9IGZyb20gJy4uL2xpYi91dGlscyc7XG5pbXBvcnQgc2lub24gZnJvbSAnc2lub24nO1xuXG5cbmxldCBURVNUX1NFUlZFUjtcbmxldCBURVNUX1BPUlQ7XG5jb25zdCBzaWxseVdlYlNlcnZlclBvcnQgPSAxMjM0O1xuY29uc3Qgc2lsbHlXZWJTZXJ2ZXJIb3N0ID0gJ2hleSc7XG5jb25zdCBGQUtFX0FSR1MgPSB7c2lsbHlXZWJTZXJ2ZXJQb3J0LCBzaWxseVdlYlNlcnZlckhvc3R9O1xuY29uc3QgRkFLRV9EUklWRVJfQVJHUyA9IHtkcml2ZXI6IHtmYWtlOiBGQUtFX0FSR1N9fTtcbmNvbnN0IHNob3VsZFN0YXJ0U2VydmVyID0gcHJvY2Vzcy5lbnYuVVNFX1JVTk5JTkdfU0VSVkVSICE9PSAnMCc7XG5jb25zdCBjYXBzID0gVzNDX1BSRUZJWEVEX0NBUFM7XG5jb25zdCB3ZE9wdHMgPSB7XG4gIGhvc3RuYW1lOiBURVNUX0hPU1QsXG4gIHBvcnQ6IG51bGwsXG4gIGNvbm5lY3Rpb25SZXRyeUNvdW50OiAwLFxufTtcblxuZGVzY3JpYmUoJ0Zha2VEcml2ZXIgLSB2aWEgSFRUUCcsIGZ1bmN0aW9uICgpIHtcbiAgbGV0IHNlcnZlciA9IG51bGw7XG4gIGNvbnN0IGFwcGl1bUhvbWUgPSBERUZBVUxUX0FQUElVTV9IT01FO1xuICAvLyBzaW5jZSB3ZSB1cGRhdGUgdGhlIEZha2VEcml2ZXIucHJvdG90eXBlIGJlbG93LCBtYWtlIHN1cmUgd2UgdXBkYXRlIHRoZSBGYWtlRHJpdmVyIHdoaWNoIGlzXG4gIC8vIGFjdHVhbGx5IGdvaW5nIHRvIGJlIHJlcXVpcmVkIGJ5IEFwcGl1bVxuICBsZXQgRmFrZURyaXZlciA9IG51bGw7XG4gIGxldCBiYXNlVXJsO1xuICBjb25zdCBGQUtFX0RSSVZFUl9ESVIgPSBwYXRoLmpvaW4oUFJPSkVDVF9ST09ULCAncGFja2FnZXMnLCAnZmFrZS1kcml2ZXInKTtcbiAgYmVmb3JlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICB3ZE9wdHMucG9ydCA9IFRFU1RfUE9SVCA9IGF3YWl0IGdldFRlc3RQb3J0KCk7XG4gICAgVEVTVF9TRVJWRVIgPSBgaHR0cDovLyR7VEVTVF9IT1NUfToke1RFU1RfUE9SVH1gO1xuICAgIGJhc2VVcmwgPSBgJHtURVNUX1NFUlZFUn0vc2Vzc2lvbmA7XG4gICAgLy8gZmlyc3QgZW5zdXJlIHdlIGhhdmUgZmFrZWRyaXZlciBpbnN0YWxsZWRcbiAgICBjb25zdCBkcml2ZXJMaXN0ID0gYXdhaXQgcnVuRXh0ZW5zaW9uQ29tbWFuZCh7XG4gICAgICBhcHBpdW1Ib21lLFxuICAgICAgZHJpdmVyQ29tbWFuZDogJ2xpc3QnLFxuICAgICAgc2hvd0luc3RhbGxlZDogdHJ1ZSxcbiAgICB9LCBEUklWRVJfVFlQRSk7XG4gICAgaWYgKCFfLmhhcyhkcml2ZXJMaXN0LCAnZmFrZScpKSB7XG4gICAgICBhd2FpdCBydW5FeHRlbnNpb25Db21tYW5kKHtcbiAgICAgICAgYXBwaXVtSG9tZSxcbiAgICAgICAgZHJpdmVyQ29tbWFuZDogJ2luc3RhbGwnLFxuICAgICAgICBkcml2ZXI6IEZBS0VfRFJJVkVSX0RJUixcbiAgICAgICAgaW5zdGFsbFR5cGU6IElOU1RBTExfVFlQRV9MT0NBTCxcbiAgICAgIH0sIERSSVZFUl9UWVBFKTtcbiAgICB9XG5cbiAgICBjb25zdCBjb25maWcgPSBEcml2ZXJDb25maWcuZ2V0SW5zdGFuY2UoYXBwaXVtSG9tZSk7XG4gICAgRmFrZURyaXZlciA9IGNvbmZpZy5yZXF1aXJlKCdmYWtlJyk7XG4gICAgLy8gdGhlbiBzdGFydCBzZXJ2ZXIgaWYgd2UgbmVlZCB0b1xuICAgIGF3YWl0IHNlcnZlclN0YXJ0KCk7XG4gIH0pO1xuXG4gIGFmdGVyKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBhd2FpdCBzZXJ2ZXJDbG9zZSgpO1xuICB9KTtcblxuICBhc3luYyBmdW5jdGlvbiBzZXJ2ZXJTdGFydCAoYXJncyA9IHt9KSB7XG4gICAgYXJncyA9IHtwb3J0OiBURVNUX1BPUlQsIGhvc3Q6IFRFU1RfSE9TVCwgYXBwaXVtSG9tZSwgLi4uYXJnc307XG4gICAgaWYgKHNob3VsZFN0YXJ0U2VydmVyKSB7XG4gICAgICBzZXJ2ZXIgPSBhd2FpdCBhcHBpdW1TZXJ2ZXIoYXJncyk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gc2VydmVyQ2xvc2UgKCkge1xuICAgIGlmIChzZXJ2ZXIpIHtcbiAgICAgIGF3YWl0IHNlcnZlci5jbG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIGRlc2NyaWJlKCdzZXJ2ZXIgdXBkYXRpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBhbGxvdyBkcml2ZXJzIHRvIHVwZGF0ZSB0aGUgc2VydmVyIGluIGFyYml0cmFyeSB3YXlzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qge2RhdGF9ID0gYXdhaXQgYXhpb3MuZ2V0KGAke1RFU1RfU0VSVkVSfS9mYWtlZHJpdmVyYCk7XG4gICAgICBkYXRhLnNob3VsZC5lcWwoe2Zha2Vkcml2ZXI6ICdmYWtlUmVzcG9uc2UnfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdjbGkgYXJncyBoYW5kbGluZyBmb3IgZW1wdHkgYXJncycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIG5vdCByZWNpZXZlIHVzZXIgY2xpIGFyZ3MgaWYgbm9uZSBwYXNzZWQgaW4nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgZHJpdmVyID0gYXdhaXQgd2Rpbyh7Li4ud2RPcHRzLCBjYXBhYmlsaXRpZXM6IGNhcHN9KTtcbiAgICAgIGNvbnN0IHtzZXNzaW9uSWR9ID0gZHJpdmVyO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3Qge2RhdGF9ID0gYXdhaXQgYXhpb3MuZ2V0KGAke2Jhc2VVcmx9LyR7c2Vzc2lvbklkfS9mYWtlZHJpdmVyYXJnc2ApO1xuICAgICAgICBzaG91bGQubm90LmV4aXN0KGRhdGEudmFsdWUuc2lsbHlXZWJTZXJ2ZXJQb3J0KTtcbiAgICAgICAgc2hvdWxkLm5vdC5leGlzdChkYXRhLnZhbHVlLnNpbGx5V2ViU2VydmVySG9zdCk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBkcml2ZXIuZGVsZXRlU2Vzc2lvbigpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnY2xpIGFyZ3MgaGFuZGxpbmcgZm9yIHBhc3NlZCBpbiBhcmdzJywgZnVuY3Rpb24gKCkge1xuICAgIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBzZXJ2ZXJDbG9zZSgpO1xuICAgICAgYXdhaXQgc2VydmVyU3RhcnQoRkFLRV9EUklWRVJfQVJHUyk7XG4gICAgfSk7XG4gICAgYWZ0ZXIoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgc2VydmVyQ2xvc2UoKTtcbiAgICAgIGF3YWl0IHNlcnZlclN0YXJ0KCk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCByZWNlaXZlIHVzZXIgY2xpIGFyZ3MgZnJvbSBhIGRyaXZlciBpZiBhcmd1bWVudHMgd2VyZSBwYXNzZWQgaW4nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgZHJpdmVyID0gYXdhaXQgd2Rpbyh7Li4ud2RPcHRzLCBjYXBhYmlsaXRpZXM6IGNhcHN9KTtcbiAgICAgIGNvbnN0IHtzZXNzaW9uSWR9ID0gZHJpdmVyO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3Qge2RhdGF9ID0gYXdhaXQgYXhpb3MuZ2V0KGAke2Jhc2VVcmx9LyR7c2Vzc2lvbklkfS9mYWtlZHJpdmVyYXJnc2ApO1xuICAgICAgICBkYXRhLnZhbHVlLnNpbGx5V2ViU2VydmVyUG9ydC5zaG91bGQuZXFsKHNpbGx5V2ViU2VydmVyUG9ydCk7XG4gICAgICAgIGRhdGEudmFsdWUuc2lsbHlXZWJTZXJ2ZXJIb3N0LnNob3VsZC5lcWwoc2lsbHlXZWJTZXJ2ZXJIb3N0KTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IGRyaXZlci5kZWxldGVTZXNzaW9uKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdzZXNzaW9uIGhhbmRsaW5nJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgc3RhcnQgYW5kIHN0b3AgYSBzZXNzaW9uIGFuZCBub3QgYWxsb3cgY29tbWFuZHMgYWZ0ZXIgc2Vzc2lvbiBzdG9wcGVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IGRyaXZlciA9IGF3YWl0IHdkaW8oey4uLndkT3B0cywgY2FwYWJpbGl0aWVzOiBjYXBzfSk7XG4gICAgICBzaG91bGQuZXhpc3QoZHJpdmVyLnNlc3Npb25JZCk7XG4gICAgICBkcml2ZXIuc2Vzc2lvbklkLnNob3VsZC5iZS5hKCdzdHJpbmcnKTtcbiAgICAgIGF3YWl0IGRyaXZlci5kZWxldGVTZXNzaW9uKCk7XG4gICAgICBhd2FpdCBkcml2ZXIuZ2V0VGl0bGUoKS5zaG91bGQuZXZlbnR1YWxseS5iZS5yZWplY3RlZFdpdGgoL3Rlcm1pbmF0ZWQvKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYmUgYWJsZSB0byBydW4gdHdvIEZha2VEcml2ZXIgc2Vzc2lvbnMgc2ltdWx0YW5lb3VzbHknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgZHJpdmVyMSA9IGF3YWl0IHdkaW8oey4uLndkT3B0cywgY2FwYWJpbGl0aWVzOiBjYXBzfSk7XG4gICAgICBzaG91bGQuZXhpc3QoZHJpdmVyMS5zZXNzaW9uSWQpO1xuICAgICAgZHJpdmVyMS5zZXNzaW9uSWQuc2hvdWxkLmJlLmEoJ3N0cmluZycpO1xuICAgICAgbGV0IGRyaXZlcjIgPSBhd2FpdCB3ZGlvKHsuLi53ZE9wdHMsIGNhcGFiaWxpdGllczogY2Fwc30pO1xuICAgICAgc2hvdWxkLmV4aXN0KGRyaXZlcjIuc2Vzc2lvbklkKTtcbiAgICAgIGRyaXZlcjIuc2Vzc2lvbklkLnNob3VsZC5iZS5hKCdzdHJpbmcnKTtcbiAgICAgIGRyaXZlcjIuc2Vzc2lvbklkLnNob3VsZC5ub3QuZXF1YWwoZHJpdmVyMS5zZXNzaW9uSWQpO1xuICAgICAgYXdhaXQgZHJpdmVyMS5kZWxldGVTZXNzaW9uKCk7XG4gICAgICBhd2FpdCBkcml2ZXIyLmRlbGV0ZVNlc3Npb24oKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbm90IGJlIGFibGUgdG8gcnVuIHR3byBGYWtlRHJpdmVyIHNlc3Npb25zIHNpbXVsdGFuZW91c2x5IHdoZW4gb25lIGlzIHVuaXF1ZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCB1bmlxdWVDYXBzID0gXy5jbG9uZShjYXBzKTtcbiAgICAgIHVuaXF1ZUNhcHNbJ2FwcGl1bTp1bmlxdWVBcHAnXSA9IHRydWU7XG4gICAgICBsZXQgZHJpdmVyMSA9IGF3YWl0IHdkaW8oey4uLndkT3B0cywgY2FwYWJpbGl0aWVzOiB1bmlxdWVDYXBzfSk7XG4gICAgICBzaG91bGQuZXhpc3QoZHJpdmVyMS5zZXNzaW9uSWQpO1xuICAgICAgZHJpdmVyMS5zZXNzaW9uSWQuc2hvdWxkLmJlLmEoJ3N0cmluZycpO1xuICAgICAgYXdhaXQgd2Rpbyh7Li4ud2RPcHRzLCBjYXBhYmlsaXRpZXM6IGNhcHN9KS5zaG91bGQuZXZlbnR1YWxseS5iZS5yZWplY3RlZDtcbiAgICAgIGF3YWl0IGRyaXZlcjEuZGVsZXRlU2Vzc2lvbigpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB1c2UgdGhlIG5ld0NvbW1hbmRUaW1lb3V0IG9mIHRoZSBpbm5lciBEcml2ZXIgb24gc2Vzc2lvbiBjcmVhdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCBsb2NhbENhcHMgPSBPYmplY3QuYXNzaWduKHtcbiAgICAgICAgJ2FwcGl1bTpuZXdDb21tYW5kVGltZW91dCc6IDAuMjUsXG4gICAgICB9LCBjYXBzKTtcbiAgICAgIGxldCBkcml2ZXIgPSBhd2FpdCB3ZGlvKHsuLi53ZE9wdHMsIGNhcGFiaWxpdGllczogbG9jYWxDYXBzfSk7XG4gICAgICBzaG91bGQuZXhpc3QoZHJpdmVyLnNlc3Npb25JZCk7XG5cbiAgICAgIGF3YWl0IEIuZGVsYXkoMjUwKTtcbiAgICAgIGF3YWl0IGRyaXZlci5nZXRQYWdlU291cmNlKCkuc2hvdWxkLmV2ZW50dWFsbHkuYmUucmVqZWN0ZWRXaXRoKC90ZXJtaW5hdGVkLyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGFjY2VwdCB2YWxpZCBXM0MgY2FwYWJpbGl0aWVzIGFuZCBzdGFydCBhIFczQyBzZXNzaW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gVHJ5IHdpdGggdmFsaWQgY2FwYWJpbGl0aWVzIGFuZCBjaGVjayB0aGF0IGl0IHJldHVybnMgYSBzZXNzaW9uIElEXG4gICAgICBjb25zdCB3M2NDYXBzID0ge1xuICAgICAgICBjYXBhYmlsaXRpZXM6IHtcbiAgICAgICAgICBhbHdheXNNYXRjaDogeydhcHBpdW06YXV0b21hdGlvbk5hbWUnOiAnRmFrZScsIHBsYXRmb3JtTmFtZTogJ0Zha2UnfSxcbiAgICAgICAgICBmaXJzdE1hdGNoOiBbeydhcHBpdW06ZGV2aWNlTmFtZSc6ICdGYWtlJywgJ2FwcGl1bTphcHAnOiBURVNUX0ZBS0VfQVBQfV0sXG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIC8vIENyZWF0ZSB0aGUgc2Vzc2lvblxuICAgICAgY29uc3Qge3N0YXR1cywgdmFsdWUsIHNlc3Npb25JZH0gPSAoYXdhaXQgYXhpb3MucG9zdChiYXNlVXJsLCB3M2NDYXBzKSkuZGF0YTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHNob3VsZC5ub3QuZXhpc3Qoc3RhdHVzKTsgLy8gVGVzdCB0aGF0IGl0J3MgYSBXM0Mgc2Vzc2lvbiBieSBjaGVja2luZyB0aGF0ICdzdGF0dXMnIGlzIG5vdCBpbiB0aGUgcmVzcG9uc2VcbiAgICAgICAgc2hvdWxkLm5vdC5leGlzdChzZXNzaW9uSWQpO1xuICAgICAgICB2YWx1ZS5zZXNzaW9uSWQuc2hvdWxkLmJlLmEuc3RyaW5nO1xuICAgICAgICB2YWx1ZS5zaG91bGQuZXhpc3Q7XG4gICAgICAgIHZhbHVlLmNhcGFiaWxpdGllcy5zaG91bGQuZGVlcC5lcXVhbCh7XG4gICAgICAgICAgYXV0b21hdGlvbk5hbWU6ICdGYWtlJyxcbiAgICAgICAgICBwbGF0Zm9ybU5hbWU6ICdGYWtlJyxcbiAgICAgICAgICBkZXZpY2VOYW1lOiAnRmFrZScsXG4gICAgICAgICAgYXBwOiBURVNUX0ZBS0VfQVBQLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBOb3cgdXNlIHRoYXQgc2Vzc2lvbklkIHRvIGNhbGwgL3NjcmVlbnNob3RcbiAgICAgICAgY29uc3Qge3N0YXR1czogc2NyZWVuc2hvdFN0YXR1cywgdmFsdWU6IHNjcmVlbnNob3RWYWx1ZX0gPSAoYXdhaXQgYXhpb3Moe3VybDogYCR7YmFzZVVybH0vJHt2YWx1ZS5zZXNzaW9uSWR9L3NjcmVlbnNob3RgfSkpLmRhdGE7XG4gICAgICAgIHNob3VsZC5ub3QuZXhpc3Qoc2NyZWVuc2hvdFN0YXR1cyk7XG4gICAgICAgIHNjcmVlbnNob3RWYWx1ZS5zaG91bGQubWF0Y2goL15pVkJPUi8pOyAvLyBzaG91bGQgYmUgYSBwbmdcblxuICAgICAgICAvLyBOb3cgdXNlIHRoYXQgc2Vzc2lvbklEIHRvIGNhbGwgYW4gYXJiaXRyYXJ5IFczQy1vbmx5IGVuZHBvaW50IHRoYXQgaXNuJ3QgaW1wbGVtZW50ZWQgdG8gc2VlIGlmIGl0IHJlc3BvbmRzIHdpdGggY29ycmVjdCBlcnJvclxuICAgICAgICBhd2FpdCBheGlvcy5wb3N0KFxuICAgICAgICAgIGAke2Jhc2VVcmx9LyR7dmFsdWUuc2Vzc2lvbklkfS9leGVjdXRlL2FzeW5jYCxcbiAgICAgICAgICB7c2NyaXB0OiAnJywgYXJnczogWydhJ119KS5zaG91bGQuZXZlbnR1YWxseS5iZS5yZWplY3RlZFdpdGgoLzQwNS8pO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgLy8gRW5kIHNlc3Npb25cbiAgICAgICAgYXdhaXQgYXhpb3MuZGVsZXRlKGAke2Jhc2VVcmx9LyR7dmFsdWUuc2Vzc2lvbklkfWApO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgaW52YWxpZCBXM0MgY2FwYWJpbGl0aWVzIGFuZCByZXNwb25kIHdpdGggYSA0MDAgQmFkIFBhcmFtZXRlcnMgZXJyb3InLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiYWRXM0NjYXBzID0ge1xuICAgICAgICBjYXBhYmlsaXRpZXM6IHtcbiAgICAgICAgICBhbHdheXNNYXRjaDoge30sXG4gICAgICAgICAgZmlyc3RNYXRjaDogW3snYXBwaXVtOmRldmljZU5hbWUnOiAnRmFrZScsICdhcHBpdW06YXBwJzogVEVTVF9GQUtFX0FQUH1dLFxuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBhd2FpdCBheGlvcy5wb3N0KGJhc2VVcmwsIGJhZFczQ2NhcHMpLnNob3VsZC5ldmVudHVhbGx5LmJlLnJlamVjdGVkV2l0aCgvNDAwLyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGFjY2VwdCBhIGNvbWJvIG9mIFczQyBhbmQgSlNPTldQIGNhcGFiaWxpdGllcyBidXQgY29tcGxldGVseSBpZ25vcmUgSlNPTldQJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29tYmluZWRDYXBzID0ge1xuICAgICAgICAnZGVzaXJlZENhcGFiaWxpdGllcyc6IHtcbiAgICAgICAgICAuLi5jYXBzLFxuICAgICAgICAgIGpzb253cFBhcmFtOiAnanNvbndwUGFyYW0nLFxuICAgICAgICB9LFxuICAgICAgICAnY2FwYWJpbGl0aWVzJzoge1xuICAgICAgICAgICdhbHdheXNNYXRjaCc6IHsuLi5jYXBzfSxcbiAgICAgICAgICAnZmlyc3RNYXRjaCc6IFt7XG4gICAgICAgICAgICAnYXBwaXVtOnczY1BhcmFtJzogJ3czY1BhcmFtJyxcbiAgICAgICAgICB9XSxcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgY29uc3Qge3N0YXR1cywgdmFsdWUsIHNlc3Npb25JZH0gPSAoYXdhaXQgYXhpb3MucG9zdChiYXNlVXJsLCBjb21iaW5lZENhcHMpKS5kYXRhO1xuICAgICAgdHJ5IHtcbiAgICAgICAgc2hvdWxkLm5vdC5leGlzdChzdGF0dXMpOyAvLyBJZiBpdCdzIGEgVzNDIHNlc3Npb24sIHNob3VsZCBub3QgcmVzcG9uZCB3aXRoICdzdGF0dXMnXG4gICAgICAgIHNob3VsZC5ub3QuZXhpc3Qoc2Vzc2lvbklkKTtcbiAgICAgICAgdmFsdWUuc2Vzc2lvbklkLnNob3VsZC5leGlzdDtcbiAgICAgICAgdmFsdWUuY2FwYWJpbGl0aWVzLnNob3VsZC5kZWVwLmVxdWFsKHtcbiAgICAgICAgICAuLi5yZW1vdmVBcHBpdW1QcmVmaXhlcyhjYXBzKSxcbiAgICAgICAgICB3M2NQYXJhbTogJ3czY1BhcmFtJyxcbiAgICAgICAgfSk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICAvLyBFbmQgc2Vzc2lvblxuICAgICAgICBhd2FpdCBheGlvcy5kZWxldGUoYCR7YmFzZVVybH0vJHt2YWx1ZS5zZXNzaW9uSWR9YCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBiYWQgYXV0b21hdGlvbiBuYW1lIHdpdGggYW4gYXBwcm9wcmlhdGUgZXJyb3InLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3M2NDYXBzID0ge1xuICAgICAgICBjYXBhYmlsaXRpZXM6IHtcbiAgICAgICAgICBhbHdheXNNYXRjaDoge1xuICAgICAgICAgICAgLi4uY2FwcyxcbiAgICAgICAgICAgICdhcHBpdW06YXV0b21hdGlvbk5hbWUnOiAnQmFkQXV0b21hdGlvbk5hbWUnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgYXdhaXQgYXhpb3MucG9zdChiYXNlVXJsLCB3M2NDYXBzKS5zaG91bGQuZXZlbnR1YWxseS5iZS5yZWplY3RlZFdpdGgoLzUwMC8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBhY2NlcHQgY2FwYWJpbGl0aWVzIHRoYXQgYXJlIHByb3ZpZGVkIGluIHRoZSBmaXJzdE1hdGNoIGFycmF5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdzNjQ2FwcyA9IHtcbiAgICAgICAgY2FwYWJpbGl0aWVzOiB7XG4gICAgICAgICAgYWx3YXlzTWF0Y2g6IHt9LFxuICAgICAgICAgIGZpcnN0TWF0Y2g6IFt7fSwge1xuICAgICAgICAgICAgLi4uY2Fwc1xuICAgICAgICAgIH1dLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHt2YWx1ZSwgc2Vzc2lvbklkLCBzdGF0dXN9ID0gKGF3YWl0IGF4aW9zLnBvc3QoYmFzZVVybCwgdzNjQ2FwcykpLmRhdGE7XG4gICAgICB0cnkge1xuICAgICAgICBzaG91bGQubm90LmV4aXN0KHN0YXR1cyk7XG4gICAgICAgIHNob3VsZC5ub3QuZXhpc3Qoc2Vzc2lvbklkKTtcbiAgICAgICAgdmFsdWUuY2FwYWJpbGl0aWVzLnNob3VsZC5kZWVwLmVxdWFsKHJlbW92ZUFwcGl1bVByZWZpeGVzKGNhcHMpKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIC8vIEVuZCBzZXNzaW9uXG4gICAgICAgIGF3YWl0IGF4aW9zLmRlbGV0ZShgJHtiYXNlVXJsfS8ke3ZhbHVlLnNlc3Npb25JZH1gKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbm90IGZhbGwgYmFjayB0byBNSlNPTldQIGlmIHczYyBjYXBzIGFyZSBpbnZhbGlkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29tYmluZWRDYXBzID0ge1xuICAgICAgICBkZXNpcmVkQ2FwYWJpbGl0aWVzOiB7XG4gICAgICAgICAgLi4uY2FwcyxcbiAgICAgICAgfSxcbiAgICAgICAgY2FwYWJpbGl0aWVzOiB7XG4gICAgICAgICAgYWx3YXlzTWF0Y2g6IHt9LFxuICAgICAgICAgIGZpcnN0TWF0Y2g6IFt7fSwge1xuICAgICAgICAgICAgLi4uY2FwcyxcbiAgICAgICAgICAgIHBsYXRmb3JtTmFtZTogbnVsbCxcbiAgICAgICAgICAgICdhcHBpdW06YXV0b21hdGlvbk5hbWUnOiBudWxsLFxuICAgICAgICAgICAgJ2FwcGl1bTpkZXZpY2VOYW1lJzogbnVsbCxcbiAgICAgICAgICB9XSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBjb25zdCByZXMgPSAoYXdhaXQgYXhpb3MucG9zdChiYXNlVXJsLCBjb21iaW5lZENhcHMsIHt2YWxpZGF0ZVN0YXR1czogbnVsbH0pKTtcbiAgICAgIHJlcy5zdGF0dXMuc2hvdWxkLmVxbCg0MDApO1xuICAgICAgcmVzLmRhdGEudmFsdWUuZXJyb3Iuc2hvdWxkLm1hdGNoKC9pbnZhbGlkIGFyZ3VtZW50Lyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG5vdCBmYWxsIGJhY2sgdG8gTUpTT05XUCBldmVuIGlmIElubmVyIERyaXZlciBpcyBub3QgcmVhZHkgZm9yIFczQycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvbWJpbmVkQ2FwcyA9IHtcbiAgICAgICAgZGVzaXJlZENhcGFiaWxpdGllczoge1xuICAgICAgICAgIC4uLmNhcHMsXG4gICAgICAgIH0sXG4gICAgICAgIGNhcGFiaWxpdGllczoge1xuICAgICAgICAgIGFsd2F5c01hdGNoOiB7XG4gICAgICAgICAgICAuLi5jYXBzLFxuICAgICAgICAgICAgJ2FwcGl1bTpkZXZpY2VOYW1lJzogJ0Zha2UnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgY29uc3QgY3JlYXRlU2Vzc2lvblN0dWIgPSBzaW5vbi5zdHViKEZha2VEcml2ZXIucHJvdG90eXBlLCAnY3JlYXRlU2Vzc2lvbicpLmNhbGxzRmFrZShhc3luYyBmdW5jdGlvbiAoanNvbndwQ2Fwcykge1xuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBCYXNlRHJpdmVyLnByb3RvdHlwZS5jcmVhdGVTZXNzaW9uLmNhbGwodGhpcywganNvbndwQ2Fwcyk7XG4gICAgICAgIHRoaXMucHJvdG9jb2wuc2hvdWxkLmVxdWFsKCdNSlNPTldQJyk7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcmVzID0gKGF3YWl0IGF4aW9zLnBvc3QoYmFzZVVybCwgY29tYmluZWRDYXBzLCB7dmFsaWRhdGVTdGF0dXM6IG51bGx9KSk7XG4gICAgICBjb25zdCB7ZGF0YSwgc3RhdHVzfSA9IHJlcztcbiAgICAgIHN0YXR1cy5zaG91bGQuZXFsKDUwMCk7XG4gICAgICBkYXRhLnZhbHVlLm1lc3NhZ2Uuc2hvdWxkLm1hdGNoKC9vbGRlciBjYXBhYmlsaXRpZXMvKTtcblxuICAgICAgY3JlYXRlU2Vzc2lvblN0dWIucmVzdG9yZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBhbGxvdyBkcml2ZXJzIHRvIHVwZGF0ZSB0aGUgbWV0aG9kIG1hcCB3aXRoIG5ldyByb3V0ZXMgYW5kIGNvbW1hbmRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IGRyaXZlciA9IGF3YWl0IHdkaW8oey4uLndkT3B0cywgY2FwYWJpbGl0aWVzOiBjYXBzfSk7XG4gICAgICBjb25zdCB7c2Vzc2lvbklkfSA9IGRyaXZlcjtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGF4aW9zLnBvc3QoYCR7YmFzZVVybH0vJHtzZXNzaW9uSWR9L2Zha2Vkcml2ZXJgLCB7dGhpbmc6IHt5ZXM6ICdsb2xubyd9fSk7XG4gICAgICAgIChhd2FpdCBheGlvcy5nZXQoYCR7YmFzZVVybH0vJHtzZXNzaW9uSWR9L2Zha2Vkcml2ZXJgKSkuZGF0YS52YWx1ZS5zaG91bGQuZXFsKHt5ZXM6ICdsb2xubyd9KTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IGRyaXZlci5kZWxldGVTZXNzaW9uKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufSk7XG5cbi8vIFRPRE8gdGhpcyB0ZXN0IG9ubHkgd29ya3MgaWYgdGhlIGxvZyBoYXMgbm90IHByZXZpb3VzbHkgYmVlbiBpbml0aWFsaXplZCBpbiB0aGUgc2FtZSBwcm9jZXNzLlxuLy8gdGhlcmUgc2VlbXMgdG8gYmUgc29tZSBnbG9iYWwgc3RhdGUgdGhhdCBpcyBub3QgY2xlYW5lZCB1cCBiZXR3ZWVuIHRlc3RzLlxuZGVzY3JpYmUuc2tpcCgnTG9nc2luaycsIGZ1bmN0aW9uICgpIHtcbiAgbGV0IHNlcnZlciA9IG51bGw7XG4gIGxldCBsb2dzID0gW107XG4gIGxldCBsb2dIYW5kbGVyID0gZnVuY3Rpb24gKGxldmVsLCBtZXNzYWdlKSB7XG4gICAgbG9ncy5wdXNoKFtsZXZlbCwgbWVzc2FnZV0pO1xuICB9O1xuICBsZXQgYXJncyA9IHtcbiAgICBwb3J0OiBURVNUX1BPUlQsXG4gICAgaG9zdDogVEVTVF9IT1NULFxuICAgIGFwcGl1bUhvbWU6IERFRkFVTFRfQVBQSVVNX0hPTUUsXG4gICAgbG9nSGFuZGxlcixcbiAgfTtcblxuICBiZWZvcmUoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIHNlcnZlciA9IGF3YWl0IGFwcGl1bVNlcnZlcihhcmdzKTtcbiAgfSk7XG5cbiAgYWZ0ZXIoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGF3YWl0IHNlcnZlci5jbG9zZSgpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHNlbmQgbG9ncyB0byBhIGxvZ0hhbmRsZXIgcGFzc2VkIGluIGJ5IGEgcGFyZW50IHBhY2thZ2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgbG9ncy5sZW5ndGguc2hvdWxkLmJlLmFib3ZlKDEpO1xuICAgIGxldCB3ZWxjb21lSW5kZXggPSBsb2dzWzBdWzFdLmluY2x1ZGVzKCd2ZXJzaW9ucyBvZiBub2RlJykgPyAxIDogMDtcbiAgICBsb2dzW3dlbGNvbWVJbmRleF0ubGVuZ3RoLnNob3VsZC5lcXVhbCgyKTtcbiAgICBsb2dzW3dlbGNvbWVJbmRleF1bMV0uc2hvdWxkLmluY2x1ZGUoJ1dlbGNvbWUgdG8gQXBwaXVtJyk7XG4gIH0pO1xufSk7XG4iXSwiZmlsZSI6InRlc3QvZHJpdmVyLWUyZS1zcGVjcy5qcyIsInNvdXJjZVJvb3QiOiIuLi8uLiJ9
|