appium 2.0.0-beta.25 → 2.0.0-beta.26
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/build/lib/appium-config.schema.json +278 -0
- package/build/lib/appium.js +45 -66
- package/build/lib/cli/args.js +19 -39
- package/build/lib/cli/driver-command.js +5 -9
- package/build/lib/cli/extension-command.js +73 -64
- package/build/lib/cli/extension.js +10 -23
- package/build/lib/cli/parser.js +9 -19
- package/build/lib/cli/plugin-command.js +5 -9
- package/build/lib/cli/utils.js +2 -4
- package/build/lib/config-file.js +2 -4
- package/build/lib/config.js +7 -6
- package/build/lib/constants.js +60 -0
- package/build/lib/extension/driver-config.js +190 -0
- package/build/lib/extension/extension-config.js +297 -0
- package/build/lib/extension/index.js +77 -0
- package/build/lib/extension/manifest.js +246 -0
- package/build/lib/extension/package-changed.js +68 -0
- package/build/lib/extension/plugin-config.js +87 -0
- package/build/lib/grid-register.js +2 -4
- package/build/lib/logger.js +2 -4
- package/build/lib/logsink.js +2 -4
- package/build/lib/main.js +40 -68
- package/build/lib/schema/appium-config-schema.js +2 -4
- package/build/lib/schema/arg-spec.js +11 -14
- package/build/lib/schema/cli-args.js +2 -4
- package/build/lib/schema/cli-transformers.js +2 -4
- package/build/lib/schema/index.js +2 -4
- package/build/lib/schema/keywords.js +2 -4
- package/build/lib/schema/schema.js +55 -37
- package/build/lib/utils.js +1 -32
- package/lib/appium.js +50 -68
- package/lib/cli/args.js +19 -23
- package/lib/cli/driver-command.js +10 -2
- package/lib/cli/extension-command.js +216 -135
- package/lib/cli/extension.js +7 -15
- package/lib/cli/parser.js +6 -14
- package/lib/cli/plugin-command.js +1 -2
- package/lib/config-file.js +3 -3
- package/lib/config.js +5 -4
- package/lib/constants.js +79 -0
- package/lib/extension/driver-config.js +230 -0
- package/lib/extension/extension-config.js +459 -0
- package/lib/extension/index.js +103 -0
- package/lib/extension/manifest.js +590 -0
- package/lib/extension/package-changed.js +64 -0
- package/lib/extension/plugin-config.js +111 -0
- package/lib/grid-register.js +4 -4
- package/lib/main.js +51 -88
- package/lib/schema/arg-spec.js +2 -2
- package/lib/schema/cli-args.js +1 -0
- package/lib/schema/keywords.js +1 -1
- package/lib/schema/schema.js +60 -28
- package/lib/utils.js +2 -32
- package/package.json +29 -21
- package/{postinstall.js → scripts/postinstall.js} +1 -1
- package/types/types.d.ts +70 -31
- package/bin/ios-webkit-debug-proxy-launcher.js +0 -71
- package/build/check-npm-pack-files.js +0 -23
- package/build/commands-yml/parse.js +0 -319
- package/build/commands-yml/validator.js +0 -130
- package/build/index.js +0 -19
- package/build/lib/cli/npm.js +0 -220
- package/build/lib/driver-config.js +0 -100
- package/build/lib/drivers.js +0 -100
- package/build/lib/ext-config-io.js +0 -165
- package/build/lib/extension-config.js +0 -320
- package/build/lib/plugin-config.js +0 -69
- package/build/lib/plugins.js +0 -18
- package/build/postinstall.js +0 -90
- package/build/test/cli/cli-e2e-specs.js +0 -221
- package/build/test/cli/cli-helpers.js +0 -86
- package/build/test/cli/cli-specs.js +0 -71
- package/build/test/cli/fixtures/test-driver/package.json +0 -27
- package/build/test/cli/schema-args-specs.js +0 -48
- package/build/test/cli/schema-e2e-specs.js +0 -47
- package/build/test/config-e2e-specs.js +0 -112
- package/build/test/config-file-e2e-specs.js +0 -191
- package/build/test/config-file-specs.js +0 -281
- package/build/test/config-specs.js +0 -258
- package/build/test/driver-e2e-specs.js +0 -435
- package/build/test/driver-specs.js +0 -386
- package/build/test/ext-config-io-specs.js +0 -181
- package/build/test/extension-config-specs.js +0 -365
- package/build/test/fixtures/allow-feat.txt +0 -5
- package/build/test/fixtures/caps.json +0 -3
- package/build/test/fixtures/config/allow-insecure.txt +0 -3
- package/build/test/fixtures/config/appium.config.bad-nodeconfig.json +0 -5
- package/build/test/fixtures/config/appium.config.bad.json +0 -32
- package/build/test/fixtures/config/appium.config.ext-good.json +0 -9
- package/build/test/fixtures/config/appium.config.ext-unknown-props.json +0 -10
- package/build/test/fixtures/config/appium.config.good.js +0 -40
- package/build/test/fixtures/config/appium.config.good.json +0 -33
- package/build/test/fixtures/config/appium.config.good.yaml +0 -30
- package/build/test/fixtures/config/appium.config.invalid.json +0 -31
- package/build/test/fixtures/config/appium.config.security-array.json +0 -5
- package/build/test/fixtures/config/appium.config.security-delimited.json +0 -5
- package/build/test/fixtures/config/appium.config.security-path.json +0 -5
- package/build/test/fixtures/config/driver-fake.config.json +0 -8
- package/build/test/fixtures/config/nodeconfig.json +0 -3
- package/build/test/fixtures/config/plugin-fake.config.json +0 -0
- package/build/test/fixtures/default-args.js +0 -35
- package/build/test/fixtures/deny-feat.txt +0 -5
- package/build/test/fixtures/driver.schema.js +0 -20
- package/build/test/fixtures/extensions.yaml +0 -27
- package/build/test/fixtures/flattened-schema.js +0 -532
- package/build/test/fixtures/plugin.schema.js +0 -20
- package/build/test/fixtures/schema-with-extensions.js +0 -28
- package/build/test/grid-register-specs.js +0 -74
- package/build/test/helpers.js +0 -75
- package/build/test/logger-specs.js +0 -76
- package/build/test/npm-specs.js +0 -20
- package/build/test/parser-specs.js +0 -319
- package/build/test/plugin-e2e-specs.js +0 -316
- package/build/test/schema/arg-spec-specs.js +0 -70
- package/build/test/schema/cli-args-specs.js +0 -408
- package/build/test/schema/schema-specs.js +0 -407
- package/build/test/utils-specs.js +0 -288
- package/lib/cli/npm.js +0 -251
- package/lib/driver-config.js +0 -101
- package/lib/drivers.js +0 -84
- package/lib/ext-config-io.js +0 -287
- package/lib/extension-config.js +0 -366
- package/lib/plugin-config.js +0 -63
- package/lib/plugins.js +0 -13
|
@@ -1,316 +0,0 @@
|
|
|
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 _webdriverio = require("webdriverio");
|
|
14
|
-
|
|
15
|
-
var _axios = _interopRequireDefault(require("axios"));
|
|
16
|
-
|
|
17
|
-
var _main = require("../lib/main");
|
|
18
|
-
|
|
19
|
-
var _extensionConfig = require("../lib/extension-config");
|
|
20
|
-
|
|
21
|
-
var _helpers = require("./helpers");
|
|
22
|
-
|
|
23
|
-
var _extension = require("../lib/cli/extension");
|
|
24
|
-
|
|
25
|
-
const FAKE_ARGS = {
|
|
26
|
-
sillyWebServerPort: 1234,
|
|
27
|
-
host: 'hey'
|
|
28
|
-
};
|
|
29
|
-
const FAKE_PLUGIN_ARGS = {
|
|
30
|
-
fake: FAKE_ARGS
|
|
31
|
-
};
|
|
32
|
-
const wdOpts = {
|
|
33
|
-
hostname: _helpers.TEST_HOST,
|
|
34
|
-
port: null,
|
|
35
|
-
connectionRetryCount: 0,
|
|
36
|
-
capabilities: _helpers.W3C_PREFIXED_CAPS
|
|
37
|
-
};
|
|
38
|
-
describe('FakePlugin', function () {
|
|
39
|
-
const fakePluginDir = _path.default.join(_helpers.PROJECT_ROOT, 'node_modules', '@appium', 'fake-plugin');
|
|
40
|
-
|
|
41
|
-
const fakeDriverDir = _path.default.join(_helpers.PROJECT_ROOT, 'packages', 'fake-driver');
|
|
42
|
-
|
|
43
|
-
const appiumHome = _extensionConfig.DEFAULT_APPIUM_HOME;
|
|
44
|
-
let baseArgs;
|
|
45
|
-
let testServer;
|
|
46
|
-
let testPort;
|
|
47
|
-
let baseUrl;
|
|
48
|
-
before(async function () {
|
|
49
|
-
wdOpts.port = testPort = await (0, _helpers.getTestPort)();
|
|
50
|
-
testServer = `http://${_helpers.TEST_HOST}:${testPort}`;
|
|
51
|
-
baseUrl = `${testServer}/session`;
|
|
52
|
-
const driverList = await (0, _extension.runExtensionCommand)({
|
|
53
|
-
appiumHome,
|
|
54
|
-
driverCommand: 'list',
|
|
55
|
-
showInstalled: true
|
|
56
|
-
}, _extensionConfig.DRIVER_TYPE);
|
|
57
|
-
|
|
58
|
-
if (!_lodash.default.has(driverList, 'fake')) {
|
|
59
|
-
await (0, _extension.runExtensionCommand)({
|
|
60
|
-
appiumHome,
|
|
61
|
-
driverCommand: 'install',
|
|
62
|
-
driver: fakeDriverDir,
|
|
63
|
-
installType: _extensionConfig.INSTALL_TYPE_LOCAL
|
|
64
|
-
}, _extensionConfig.DRIVER_TYPE);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const pluginList = await (0, _extension.runExtensionCommand)({
|
|
68
|
-
appiumHome,
|
|
69
|
-
pluginCommand: 'list',
|
|
70
|
-
showInstalled: true
|
|
71
|
-
}, _extensionConfig.PLUGIN_TYPE);
|
|
72
|
-
|
|
73
|
-
if (!_lodash.default.has(pluginList, 'fake')) {
|
|
74
|
-
await (0, _extension.runExtensionCommand)({
|
|
75
|
-
appiumHome,
|
|
76
|
-
pluginCommand: 'install',
|
|
77
|
-
plugin: fakePluginDir,
|
|
78
|
-
installType: _extensionConfig.INSTALL_TYPE_LOCAL
|
|
79
|
-
}, _extensionConfig.PLUGIN_TYPE);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
baseArgs = {
|
|
83
|
-
port: testPort,
|
|
84
|
-
host: _helpers.TEST_HOST,
|
|
85
|
-
appiumHome,
|
|
86
|
-
usePlugins: ['fake'],
|
|
87
|
-
useDrivers: ['fake']
|
|
88
|
-
};
|
|
89
|
-
});
|
|
90
|
-
describe('without plugin registered', function () {
|
|
91
|
-
let server = null;
|
|
92
|
-
before(async function () {
|
|
93
|
-
const args = {
|
|
94
|
-
port: testPort,
|
|
95
|
-
host: _helpers.TEST_HOST,
|
|
96
|
-
appiumHome,
|
|
97
|
-
usePlugins: ['other1', 'other2']
|
|
98
|
-
};
|
|
99
|
-
server = await (0, _main.main)(args);
|
|
100
|
-
});
|
|
101
|
-
after(async function () {
|
|
102
|
-
if (server) {
|
|
103
|
-
await server.close();
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
it('should not update the server if plugin is not activated', async function () {
|
|
107
|
-
await _axios.default.post(`http://${_helpers.TEST_HOST}:${testPort}/fake`).should.eventually.be.rejectedWith(/404/);
|
|
108
|
-
});
|
|
109
|
-
it('should not update method map if plugin is not activated', async function () {
|
|
110
|
-
const driver = await (0, _webdriverio.remote)(wdOpts);
|
|
111
|
-
const {
|
|
112
|
-
sessionId
|
|
113
|
-
} = driver;
|
|
114
|
-
|
|
115
|
-
try {
|
|
116
|
-
await _axios.default.post(`${baseUrl}/${sessionId}/fake_data`, {
|
|
117
|
-
data: {
|
|
118
|
-
fake: 'data'
|
|
119
|
-
}
|
|
120
|
-
}).should.eventually.be.rejectedWith(/404/);
|
|
121
|
-
} finally {
|
|
122
|
-
await driver.deleteSession();
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
it('should not handle commands if plugin is not activated', async function () {
|
|
126
|
-
const driver = await (0, _webdriverio.remote)(wdOpts);
|
|
127
|
-
const {
|
|
128
|
-
sessionId
|
|
129
|
-
} = driver;
|
|
130
|
-
|
|
131
|
-
try {
|
|
132
|
-
const el = (await _axios.default.post(`${baseUrl}/${sessionId}/element`, {
|
|
133
|
-
using: 'xpath',
|
|
134
|
-
value: '//MockWebView'
|
|
135
|
-
})).data.value;
|
|
136
|
-
el.should.not.have.property('fake');
|
|
137
|
-
} finally {
|
|
138
|
-
await driver.deleteSession();
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
for (const registrationType of ['explicit', 'all']) {
|
|
144
|
-
describe(`with plugin registered via type ${registrationType}`, function () {
|
|
145
|
-
let server = null;
|
|
146
|
-
before(async function () {
|
|
147
|
-
const usePlugins = registrationType === 'explicit' ? ['fake', 'p2', 'p3'] : ['all'];
|
|
148
|
-
const args = {
|
|
149
|
-
port: testPort,
|
|
150
|
-
host: _helpers.TEST_HOST,
|
|
151
|
-
appiumHome,
|
|
152
|
-
usePlugins,
|
|
153
|
-
useDrivers: ['fake']
|
|
154
|
-
};
|
|
155
|
-
server = await (0, _main.main)(args);
|
|
156
|
-
});
|
|
157
|
-
after(async function () {
|
|
158
|
-
if (server) {
|
|
159
|
-
await server.close();
|
|
160
|
-
}
|
|
161
|
-
});
|
|
162
|
-
it('should update the server', async function () {
|
|
163
|
-
const res = {
|
|
164
|
-
fake: 'fakeResponse'
|
|
165
|
-
};
|
|
166
|
-
(await _axios.default.post(`http://${_helpers.TEST_HOST}:${testPort}/fake`)).data.should.eql(res);
|
|
167
|
-
});
|
|
168
|
-
it('should modify the method map with new commands', async function () {
|
|
169
|
-
const driver = await (0, _webdriverio.remote)(wdOpts);
|
|
170
|
-
const {
|
|
171
|
-
sessionId
|
|
172
|
-
} = driver;
|
|
173
|
-
|
|
174
|
-
try {
|
|
175
|
-
await _axios.default.post(`${baseUrl}/${sessionId}/fake_data`, {
|
|
176
|
-
data: {
|
|
177
|
-
fake: 'data'
|
|
178
|
-
}
|
|
179
|
-
});
|
|
180
|
-
(await _axios.default.get(`${baseUrl}/${sessionId}/fake_data`)).data.value.should.eql({
|
|
181
|
-
fake: 'data'
|
|
182
|
-
});
|
|
183
|
-
} finally {
|
|
184
|
-
await driver.deleteSession();
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
it('should handle commands and not call the original', async function () {
|
|
188
|
-
const driver = await (0, _webdriverio.remote)(wdOpts);
|
|
189
|
-
const {
|
|
190
|
-
sessionId
|
|
191
|
-
} = driver;
|
|
192
|
-
|
|
193
|
-
try {
|
|
194
|
-
await driver.getPageSource().should.eventually.eql(`<Fake>${JSON.stringify([sessionId])}</Fake>`);
|
|
195
|
-
} finally {
|
|
196
|
-
await driver.deleteSession();
|
|
197
|
-
}
|
|
198
|
-
});
|
|
199
|
-
it('should handle commands and call the original if designed', async function () {
|
|
200
|
-
const driver = await (0, _webdriverio.remote)(wdOpts);
|
|
201
|
-
const {
|
|
202
|
-
sessionId
|
|
203
|
-
} = driver;
|
|
204
|
-
|
|
205
|
-
try {
|
|
206
|
-
const el = (await _axios.default.post(`${baseUrl}/${sessionId}/element`, {
|
|
207
|
-
using: 'xpath',
|
|
208
|
-
value: '//MockWebView'
|
|
209
|
-
})).data.value;
|
|
210
|
-
el.should.have.property('fake');
|
|
211
|
-
} finally {
|
|
212
|
-
await driver.deleteSession();
|
|
213
|
-
}
|
|
214
|
-
});
|
|
215
|
-
it('should allow original command to be proxied if supported', async function () {
|
|
216
|
-
const driver = await (0, _webdriverio.remote)(wdOpts);
|
|
217
|
-
const {
|
|
218
|
-
sessionId
|
|
219
|
-
} = driver;
|
|
220
|
-
|
|
221
|
-
try {
|
|
222
|
-
await _axios.default.post(`${baseUrl}/${sessionId}/context`, {
|
|
223
|
-
name: 'PROXY'
|
|
224
|
-
});
|
|
225
|
-
const handle = (await _axios.default.get(`${baseUrl}/${sessionId}/window/handle`)).data.value;
|
|
226
|
-
handle.should.eql('<<proxied via proxyCommand>>');
|
|
227
|
-
} finally {
|
|
228
|
-
await _axios.default.post(`${baseUrl}/${sessionId}/context`, {
|
|
229
|
-
name: 'NATIVE_APP'
|
|
230
|
-
});
|
|
231
|
-
await driver.deleteSession();
|
|
232
|
-
}
|
|
233
|
-
});
|
|
234
|
-
it('should handle unexpected driver shutdown', async function () {
|
|
235
|
-
const newOpts = { ...wdOpts
|
|
236
|
-
};
|
|
237
|
-
newOpts.capabilities['appium:newCommandTimeout'] = 1;
|
|
238
|
-
const driver = await (0, _webdriverio.remote)(wdOpts);
|
|
239
|
-
let shutdownErr;
|
|
240
|
-
|
|
241
|
-
try {
|
|
242
|
-
let res = await _axios.default.get(`http://${_helpers.TEST_HOST}:${testPort}/unexpected`);
|
|
243
|
-
should.not.exist(res.data);
|
|
244
|
-
await _bluebird.default.delay(1500);
|
|
245
|
-
res = await _axios.default.get(`http://${_helpers.TEST_HOST}:${testPort}/unexpected`);
|
|
246
|
-
res.data.should.match(/Session ended/);
|
|
247
|
-
res.data.should.match(/timeout/);
|
|
248
|
-
await driver.deleteSession();
|
|
249
|
-
} catch (e) {
|
|
250
|
-
shutdownErr = e;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
shutdownErr.message.should.match(/either terminated or not started/);
|
|
254
|
-
});
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
describe('cli args handling for plugin args', function () {
|
|
259
|
-
let server = null;
|
|
260
|
-
before(async function () {
|
|
261
|
-
const args = { ...baseArgs,
|
|
262
|
-
plugin: FAKE_PLUGIN_ARGS
|
|
263
|
-
};
|
|
264
|
-
server = await (0, _main.main)(args);
|
|
265
|
-
});
|
|
266
|
-
after(async function () {
|
|
267
|
-
if (server) {
|
|
268
|
-
await server.close();
|
|
269
|
-
}
|
|
270
|
-
});
|
|
271
|
-
it('should receive user cli args for plugin if passed in', async function () {
|
|
272
|
-
const driver = await (0, _webdriverio.remote)(wdOpts);
|
|
273
|
-
const {
|
|
274
|
-
sessionId
|
|
275
|
-
} = driver;
|
|
276
|
-
|
|
277
|
-
try {
|
|
278
|
-
const {
|
|
279
|
-
data
|
|
280
|
-
} = await _axios.default.get(`${baseUrl}/${sessionId}/fakepluginargs`);
|
|
281
|
-
data.value.should.eql(FAKE_ARGS);
|
|
282
|
-
} finally {
|
|
283
|
-
await driver.deleteSession();
|
|
284
|
-
}
|
|
285
|
-
});
|
|
286
|
-
});
|
|
287
|
-
describe('cli args handling for empty plugin args', function () {
|
|
288
|
-
let server = null;
|
|
289
|
-
before(async function () {
|
|
290
|
-
server = await (0, _main.main)(baseArgs);
|
|
291
|
-
});
|
|
292
|
-
after(async function () {
|
|
293
|
-
if (server) {
|
|
294
|
-
await server.close();
|
|
295
|
-
}
|
|
296
|
-
});
|
|
297
|
-
it('should not receive user cli args for plugin if none were passed in', async function () {
|
|
298
|
-
const driver = await (0, _webdriverio.remote)(wdOpts);
|
|
299
|
-
const {
|
|
300
|
-
sessionId
|
|
301
|
-
} = driver;
|
|
302
|
-
|
|
303
|
-
try {
|
|
304
|
-
const {
|
|
305
|
-
data
|
|
306
|
-
} = await _axios.default.get(`${baseUrl}/${sessionId}/fakepluginargs`);
|
|
307
|
-
should.not.exist(data.value);
|
|
308
|
-
} finally {
|
|
309
|
-
await driver.deleteSession();
|
|
310
|
-
}
|
|
311
|
-
});
|
|
312
|
-
});
|
|
313
|
-
});require('source-map-support').install();
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvcGx1Z2luLWUyZS1zcGVjcy5qcyJdLCJuYW1lcyI6WyJGQUtFX0FSR1MiLCJzaWxseVdlYlNlcnZlclBvcnQiLCJob3N0IiwiRkFLRV9QTFVHSU5fQVJHUyIsImZha2UiLCJ3ZE9wdHMiLCJob3N0bmFtZSIsIlRFU1RfSE9TVCIsInBvcnQiLCJjb25uZWN0aW9uUmV0cnlDb3VudCIsImNhcGFiaWxpdGllcyIsIlczQ19QUkVGSVhFRF9DQVBTIiwiZGVzY3JpYmUiLCJmYWtlUGx1Z2luRGlyIiwicGF0aCIsImpvaW4iLCJQUk9KRUNUX1JPT1QiLCJmYWtlRHJpdmVyRGlyIiwiYXBwaXVtSG9tZSIsIkRFRkFVTFRfQVBQSVVNX0hPTUUiLCJiYXNlQXJncyIsInRlc3RTZXJ2ZXIiLCJ0ZXN0UG9ydCIsImJhc2VVcmwiLCJiZWZvcmUiLCJkcml2ZXJMaXN0IiwiZHJpdmVyQ29tbWFuZCIsInNob3dJbnN0YWxsZWQiLCJEUklWRVJfVFlQRSIsIl8iLCJoYXMiLCJkcml2ZXIiLCJpbnN0YWxsVHlwZSIsIklOU1RBTExfVFlQRV9MT0NBTCIsInBsdWdpbkxpc3QiLCJwbHVnaW5Db21tYW5kIiwiUExVR0lOX1RZUEUiLCJwbHVnaW4iLCJ1c2VQbHVnaW5zIiwidXNlRHJpdmVycyIsInNlcnZlciIsImFyZ3MiLCJhZnRlciIsImNsb3NlIiwiaXQiLCJheGlvcyIsInBvc3QiLCJzaG91bGQiLCJldmVudHVhbGx5IiwiYmUiLCJyZWplY3RlZFdpdGgiLCJzZXNzaW9uSWQiLCJkYXRhIiwiZGVsZXRlU2Vzc2lvbiIsImVsIiwidXNpbmciLCJ2YWx1ZSIsIm5vdCIsImhhdmUiLCJwcm9wZXJ0eSIsInJlZ2lzdHJhdGlvblR5cGUiLCJyZXMiLCJlcWwiLCJnZXQiLCJnZXRQYWdlU291cmNlIiwiSlNPTiIsInN0cmluZ2lmeSIsIm5hbWUiLCJoYW5kbGUiLCJuZXdPcHRzIiwic2h1dGRvd25FcnIiLCJleGlzdCIsIkIiLCJkZWxheSIsIm1hdGNoIiwiZSIsIm1lc3Nh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QUNGLEtBVEMsQ0FBRjtBQVVELEdBdEJPLENBQVI7QUF1QkQsQ0FuTk8sQ0FBUiIsInNvdXJjZXNDb250ZW50IjpbIi8vIHRyYW5zcGlsZTptb2NoYVxuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IEIgZnJvbSAnYmx1ZWJpcmQnO1xuaW1wb3J0IHsgcmVtb3RlIGFzIHdkaW8gfSBmcm9tICd3ZWJkcml2ZXJpbyc7XG5pbXBvcnQgYXhpb3MgZnJvbSAnYXhpb3MnO1xuaW1wb3J0IHsgbWFpbiBhcyBhcHBpdW1TZXJ2ZXIgfSBmcm9tICcuLi9saWIvbWFpbic7XG5pbXBvcnQgeyBERUZBVUxUX0FQUElVTV9IT01FLCBJTlNUQUxMX1RZUEVfTE9DQUwsIERSSVZFUl9UWVBFLCBQTFVHSU5fVFlQRSB9IGZyb20gJy4uL2xpYi9leHRlbnNpb24tY29uZmlnJztcbmltcG9ydCB7IFczQ19QUkVGSVhFRF9DQVBTLCBURVNUX0hPU1QsIGdldFRlc3RQb3J0LCBQUk9KRUNUX1JPT1QgfSBmcm9tICcuL2hlbHBlcnMnO1xuaW1wb3J0IHsgcnVuRXh0ZW5zaW9uQ29tbWFuZCB9IGZyb20gJy4uL2xpYi9jbGkvZXh0ZW5zaW9uJztcblxuXG5jb25zdCBGQUtFX0FSR1MgPSB7c2lsbHlXZWJTZXJ2ZXJQb3J0OiAxMjM0LCBob3N0OiAnaGV5J307XG5jb25zdCBGQUtFX1BMVUdJTl9BUkdTID0ge2Zha2U6IEZBS0VfQVJHU307XG5cbmNvbnN0IHdkT3B0cyA9IHtcbiAgaG9zdG5hbWU6IFRFU1RfSE9TVCxcbiAgcG9ydDogbnVsbCxcbiAgY29ubmVjdGlvblJldHJ5Q291bnQ6IDAsXG4gIGNhcGFiaWxpdGllczogVzNDX1BSRUZJWEVEX0NBUFMsXG59O1xuXG5kZXNjcmliZSgnRmFrZVBsdWdpbicsIGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgZmFrZVBsdWdpbkRpciA9IHBhdGguam9pbihQUk9KRUNUX1JPT1QsICdub2RlX21vZHVsZXMnLCAnQGFwcGl1bScsICdmYWtlLXBsdWdpbicpO1xuICBjb25zdCBmYWtlRHJpdmVyRGlyID0gcGF0aC5qb2luKFBST0pFQ1RfUk9PVCwgJ3BhY2thZ2VzJywgJ2Zha2UtZHJpdmVyJyk7XG4gIGNvbnN0IGFwcGl1bUhvbWUgPSBERUZBVUxUX0FQUElVTV9IT01FO1xuICBsZXQgYmFzZUFyZ3M7XG4gIGxldCB0ZXN0U2VydmVyO1xuICBsZXQgdGVzdFBvcnQ7XG4gIGxldCBiYXNlVXJsO1xuXG4gIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgd2RPcHRzLnBvcnQgPSB0ZXN0UG9ydCA9IGF3YWl0IGdldFRlc3RQb3J0KCk7XG4gICAgdGVzdFNlcnZlciA9IGBodHRwOi8vJHtURVNUX0hPU1R9OiR7dGVzdFBvcnR9YDtcbiAgICBiYXNlVXJsID0gYCR7dGVzdFNlcnZlcn0vc2Vzc2lvbmA7XG4gICAgLy8gZmlyc3QgZW5zdXJlIHdlIGhhdmUgZmFrZWRyaXZlciBpbnN0YWxsZWRcbiAgICBjb25zdCBkcml2ZXJMaXN0ID0gYXdhaXQgcnVuRXh0ZW5zaW9uQ29tbWFuZCh7XG4gICAgICBhcHBpdW1Ib21lLFxuICAgICAgZHJpdmVyQ29tbWFuZDogJ2xpc3QnLFxuICAgICAgc2hvd0luc3RhbGxlZDogdHJ1ZSxcbiAgICB9LCBEUklWRVJfVFlQRSk7XG4gICAgaWYgKCFfLmhhcyhkcml2ZXJMaXN0LCAnZmFrZScpKSB7XG4gICAgICBhd2FpdCBydW5FeHRlbnNpb25Db21tYW5kKHtcbiAgICAgICAgYXBwaXVtSG9tZSxcbiAgICAgICAgZHJpdmVyQ29tbWFuZDogJ2luc3RhbGwnLFxuICAgICAgICBkcml2ZXI6IGZha2VEcml2ZXJEaXIsXG4gICAgICAgIGluc3RhbGxUeXBlOiBJTlNUQUxMX1RZUEVfTE9DQUwsXG4gICAgICB9LCBEUklWRVJfVFlQRSk7XG4gICAgfVxuXG4gICAgY29uc3QgcGx1Z2luTGlzdCA9IGF3YWl0IHJ1bkV4dGVuc2lvbkNvbW1hbmQoe1xuICAgICAgYXBwaXVtSG9tZSxcbiAgICAgIHBsdWdpbkNvbW1hbmQ6ICdsaXN0JyxcbiAgICAgIHNob3dJbnN0YWxsZWQ6IHRydWUsXG4gICAgfSwgUExVR0lOX1RZUEUpO1xuICAgIGlmICghXy5oYXMocGx1Z2luTGlzdCwgJ2Zha2UnKSkge1xuICAgICAgYXdhaXQgcnVuRXh0ZW5zaW9uQ29tbWFuZCh7XG4gICAgICAgIGFwcGl1bUhvbWUsXG4gICAgICAgIHBsdWdpbkNvbW1hbmQ6ICdpbnN0YWxsJyxcbiAgICAgICAgcGx1Z2luOiBmYWtlUGx1Z2luRGlyLFxuICAgICAgICBpbnN0YWxsVHlwZTogSU5TVEFMTF9UWVBFX0xPQ0FMLFxuICAgICAgfSwgUExVR0lOX1RZUEUpO1xuICAgIH1cbiAgICBiYXNlQXJncyA9IHtwb3J0OiB0ZXN0UG9ydCwgaG9zdDogVEVTVF9IT1NULCBhcHBpdW1Ib21lLCB1c2VQbHVnaW5zOiBbJ2Zha2UnXSwgdXNlRHJpdmVyczogWydmYWtlJ119O1xuICB9KTtcblxuICBkZXNjcmliZSgnd2l0aG91dCBwbHVnaW4gcmVnaXN0ZXJlZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgc2VydmVyID0gbnVsbDtcbiAgICBiZWZvcmUoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gdGhlbiBzdGFydCBzZXJ2ZXIgaWYgd2UgbmVlZCB0b1xuICAgICAgY29uc3QgYXJncyA9IHtwb3J0OiB0ZXN0UG9ydCwgaG9zdDogVEVTVF9IT1NULCBhcHBpdW1Ib21lLCB1c2VQbHVnaW5zOiBbJ290aGVyMScsICdvdGhlcjInXX07XG4gICAgICBzZXJ2ZXIgPSBhd2FpdCBhcHBpdW1TZXJ2ZXIoYXJncyk7XG4gICAgfSk7XG4gICAgYWZ0ZXIoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKHNlcnZlcikge1xuICAgICAgICBhd2FpdCBzZXJ2ZXIuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIG5vdCB1cGRhdGUgdGhlIHNlcnZlciBpZiBwbHVnaW4gaXMgbm90IGFjdGl2YXRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGF4aW9zLnBvc3QoYGh0dHA6Ly8ke1RFU1RfSE9TVH06JHt0ZXN0UG9ydH0vZmFrZWApLnNob3VsZC5ldmVudHVhbGx5LmJlLnJlamVjdGVkV2l0aCgvNDA0Lyk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBub3QgdXBkYXRlIG1ldGhvZCBtYXAgaWYgcGx1Z2luIGlzIG5vdCBhY3RpdmF0ZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBkcml2ZXIgPSBhd2FpdCB3ZGlvKHdkT3B0cyk7XG4gICAgICBjb25zdCB7c2Vzc2lvbklkfSA9IGRyaXZlcjtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGF4aW9zLnBvc3QoYCR7YmFzZVVybH0vJHtzZXNzaW9uSWR9L2Zha2VfZGF0YWAsIHtkYXRhOiB7ZmFrZTogJ2RhdGEnfX0pLnNob3VsZC5ldmVudHVhbGx5LmJlLnJlamVjdGVkV2l0aCgvNDA0Lyk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBkcml2ZXIuZGVsZXRlU2Vzc2lvbigpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgbm90IGhhbmRsZSBjb21tYW5kcyBpZiBwbHVnaW4gaXMgbm90IGFjdGl2YXRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGRyaXZlciA9IGF3YWl0IHdkaW8od2RPcHRzKTtcbiAgICAgIGNvbnN0IHtzZXNzaW9uSWR9ID0gZHJpdmVyO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZWwgPSAoYXdhaXQgYXhpb3MucG9zdChgJHtiYXNlVXJsfS8ke3Nlc3Npb25JZH0vZWxlbWVudGAsIHt1c2luZzogJ3hwYXRoJywgdmFsdWU6ICcvL01vY2tXZWJWaWV3J30pKS5kYXRhLnZhbHVlO1xuICAgICAgICBlbC5zaG91bGQubm90LmhhdmUucHJvcGVydHkoJ2Zha2UnKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IGRyaXZlci5kZWxldGVTZXNzaW9uKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIGZvciAoY29uc3QgcmVnaXN0cmF0aW9uVHlwZSBvZiBbJ2V4cGxpY2l0JywgJ2FsbCddKSB7XG4gICAgZGVzY3JpYmUoYHdpdGggcGx1Z2luIHJlZ2lzdGVyZWQgdmlhIHR5cGUgJHtyZWdpc3RyYXRpb25UeXBlfWAsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCBzZXJ2ZXIgPSBudWxsO1xuICAgICAgYmVmb3JlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gdGhlbiBzdGFydCBzZXJ2ZXIgaWYgd2UgbmVlZCB0b1xuICAgICAgICBjb25zdCB1c2VQbHVnaW5zID0gcmVnaXN0cmF0aW9uVHlwZSA9PT0gJ2V4cGxpY2l0JyA/IFsnZmFrZScsICdwMicsICdwMyddIDogWydhbGwnXTtcbiAgICAgICAgY29uc3QgYXJncyA9IHtwb3J0OiB0ZXN0UG9ydCwgaG9zdDogVEVTVF9IT1NULCBhcHBpdW1Ib21lLCB1c2VQbHVnaW5zLCB1c2VEcml2ZXJzOiBbJ2Zha2UnXX07XG4gICAgICAgIHNlcnZlciA9IGF3YWl0IGFwcGl1bVNlcnZlcihhcmdzKTtcbiAgICAgIH0pO1xuICAgICAgYWZ0ZXIoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoc2VydmVyKSB7XG4gICAgICAgICAgYXdhaXQgc2VydmVyLmNsb3NlKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaXQoJ3Nob3VsZCB1cGRhdGUgdGhlIHNlcnZlcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcmVzID0ge2Zha2U6ICdmYWtlUmVzcG9uc2UnfTtcbiAgICAgICAgKGF3YWl0IGF4aW9zLnBvc3QoYGh0dHA6Ly8ke1RFU1RfSE9TVH06JHt0ZXN0UG9ydH0vZmFrZWApKS5kYXRhLnNob3VsZC5lcWwocmVzKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIG1vZGlmeSB0aGUgbWV0aG9kIG1hcCB3aXRoIG5ldyBjb21tYW5kcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgZHJpdmVyID0gYXdhaXQgd2Rpbyh3ZE9wdHMpO1xuICAgICAgICBjb25zdCB7c2Vzc2lvbklkfSA9IGRyaXZlcjtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCBheGlvcy5wb3N0KGAke2Jhc2VVcmx9LyR7c2Vzc2lvbklkfS9mYWtlX2RhdGFgLCB7ZGF0YToge2Zha2U6ICdkYXRhJ319KTtcbiAgICAgICAgICAoYXdhaXQgYXhpb3MuZ2V0KGAke2Jhc2VVcmx9LyR7c2Vzc2lvbklkfS9mYWtlX2RhdGFgKSkuZGF0YS52YWx1ZS5zaG91bGQuZXFsKHtmYWtlOiAnZGF0YSd9KTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBhd2FpdCBkcml2ZXIuZGVsZXRlU2Vzc2lvbigpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgY29tbWFuZHMgYW5kIG5vdCBjYWxsIHRoZSBvcmlnaW5hbCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgZHJpdmVyID0gYXdhaXQgd2Rpbyh3ZE9wdHMpO1xuICAgICAgICBjb25zdCB7c2Vzc2lvbklkfSA9IGRyaXZlcjtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCBkcml2ZXIuZ2V0UGFnZVNvdXJjZSgpLnNob3VsZC5ldmVudHVhbGx5LmVxbChgPEZha2U+JHtKU09OLnN0cmluZ2lmeShbc2Vzc2lvbklkXSl9PC9GYWtlPmApO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGF3YWl0IGRyaXZlci5kZWxldGVTZXNzaW9uKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBjb21tYW5kcyBhbmQgY2FsbCB0aGUgb3JpZ2luYWwgaWYgZGVzaWduZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGRyaXZlciA9IGF3YWl0IHdkaW8od2RPcHRzKTtcbiAgICAgICAgY29uc3Qge3Nlc3Npb25JZH0gPSBkcml2ZXI7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgZWwgPSAoYXdhaXQgYXhpb3MucG9zdChgJHtiYXNlVXJsfS8ke3Nlc3Npb25JZH0vZWxlbWVudGAsIHt1c2luZzogJ3hwYXRoJywgdmFsdWU6ICcvL01vY2tXZWJWaWV3J30pKS5kYXRhLnZhbHVlO1xuICAgICAgICAgIGVsLnNob3VsZC5oYXZlLnByb3BlcnR5KCdmYWtlJyk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgYXdhaXQgZHJpdmVyLmRlbGV0ZVNlc3Npb24oKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgYWxsb3cgb3JpZ2luYWwgY29tbWFuZCB0byBiZSBwcm94aWVkIGlmIHN1cHBvcnRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgZHJpdmVyID0gYXdhaXQgd2Rpbyh3ZE9wdHMpO1xuICAgICAgICBjb25zdCB7c2Vzc2lvbklkfSA9IGRyaXZlcjtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCBheGlvcy5wb3N0KGAke2Jhc2VVcmx9LyR7c2Vzc2lvbklkfS9jb250ZXh0YCwge25hbWU6ICdQUk9YWSd9KTtcbiAgICAgICAgICBjb25zdCBoYW5kbGUgPSAoYXdhaXQgYXhpb3MuZ2V0KGAke2Jhc2VVcmx9LyR7c2Vzc2lvbklkfS93aW5kb3cvaGFuZGxlYCkpLmRhdGEudmFsdWU7XG4gICAgICAgICAgaGFuZGxlLnNob3VsZC5lcWwoJzw8cHJveGllZCB2aWEgcHJveHlDb21tYW5kPj4nKTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBhd2FpdCBheGlvcy5wb3N0KGAke2Jhc2VVcmx9LyR7c2Vzc2lvbklkfS9jb250ZXh0YCwge25hbWU6ICdOQVRJVkVfQVBQJ30pO1xuICAgICAgICAgIGF3YWl0IGRyaXZlci5kZWxldGVTZXNzaW9uKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSB1bmV4cGVjdGVkIGRyaXZlciBzaHV0ZG93bicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgbmV3T3B0cyA9IHsuLi53ZE9wdHN9O1xuICAgICAgICBuZXdPcHRzLmNhcGFiaWxpdGllc1snYXBwaXVtOm5ld0NvbW1hbmRUaW1lb3V0J10gPSAxO1xuICAgICAgICBjb25zdCBkcml2ZXIgPSBhd2FpdCB3ZGlvKHdkT3B0cyk7XG4gICAgICAgIGxldCBzaHV0ZG93bkVycjtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBsZXQgcmVzID0gYXdhaXQgYXhpb3MuZ2V0KGBodHRwOi8vJHtURVNUX0hPU1R9OiR7dGVzdFBvcnR9L3VuZXhwZWN0ZWRgKTtcbiAgICAgICAgICBzaG91bGQubm90LmV4aXN0KHJlcy5kYXRhKTtcbiAgICAgICAgICBhd2FpdCBCLmRlbGF5KDE1MDApO1xuICAgICAgICAgIHJlcyA9IGF3YWl0IGF4aW9zLmdldChgaHR0cDovLyR7VEVTVF9IT1NUfToke3Rlc3RQb3J0fS91bmV4cGVjdGVkYCk7XG4gICAgICAgICAgcmVzLmRhdGEuc2hvdWxkLm1hdGNoKC9TZXNzaW9uIGVuZGVkLyk7XG4gICAgICAgICAgcmVzLmRhdGEuc2hvdWxkLm1hdGNoKC90aW1lb3V0Lyk7XG4gICAgICAgICAgYXdhaXQgZHJpdmVyLmRlbGV0ZVNlc3Npb24oKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHNodXRkb3duRXJyID0gZTtcbiAgICAgICAgfVxuICAgICAgICBzaHV0ZG93bkVyci5tZXNzYWdlLnNob3VsZC5tYXRjaCgvZWl0aGVyIHRlcm1pbmF0ZWQgb3Igbm90IHN0YXJ0ZWQvKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG4gIGRlc2NyaWJlKCdjbGkgYXJncyBoYW5kbGluZyBmb3IgcGx1Z2luIGFyZ3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IHNlcnZlciA9IG51bGw7XG4gICAgYmVmb3JlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIHRoZW4gc3RhcnQgc2VydmVyIGlmIHdlIG5lZWQgdG9cbiAgICAgIGNvbnN0IGFyZ3MgPSB7Li4uYmFzZUFyZ3MsIHBsdWdpbjogRkFLRV9QTFVHSU5fQVJHU307XG4gICAgICBzZXJ2ZXIgPSBhd2FpdCBhcHBpdW1TZXJ2ZXIoYXJncyk7XG4gICAgfSk7XG4gICAgYWZ0ZXIoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKHNlcnZlcikge1xuICAgICAgICBhd2FpdCBzZXJ2ZXIuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVjZWl2ZSB1c2VyIGNsaSBhcmdzIGZvciBwbHVnaW4gaWYgcGFzc2VkIGluJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZHJpdmVyID0gYXdhaXQgd2Rpbyh3ZE9wdHMpO1xuICAgICAgY29uc3Qge3Nlc3Npb25JZH0gPSBkcml2ZXI7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCB7ZGF0YX0gPSBhd2FpdCBheGlvcy5nZXQoYCR7YmFzZVVybH0vJHtzZXNzaW9uSWR9L2Zha2VwbHVnaW5hcmdzYCk7XG4gICAgICAgIGRhdGEudmFsdWUuc2hvdWxkLmVxbChGQUtFX0FSR1MpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgYXdhaXQgZHJpdmVyLmRlbGV0ZVNlc3Npb24oKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG4gIGRlc2NyaWJlKCdjbGkgYXJncyBoYW5kbGluZyBmb3IgZW1wdHkgcGx1Z2luIGFyZ3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IHNlcnZlciA9IG51bGw7XG4gICAgYmVmb3JlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIHRoZW4gc3RhcnQgc2VydmVyIGlmIHdlIG5lZWQgdG9cbiAgICAgIHNlcnZlciA9IGF3YWl0IGFwcGl1bVNlcnZlcihiYXNlQXJncyk7XG4gICAgfSk7XG4gICAgYWZ0ZXIoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKHNlcnZlcikge1xuICAgICAgICBhd2FpdCBzZXJ2ZXIuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbm90IHJlY2VpdmUgdXNlciBjbGkgYXJncyBmb3IgcGx1Z2luIGlmIG5vbmUgd2VyZSBwYXNzZWQgaW4nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBkcml2ZXIgPSBhd2FpdCB3ZGlvKHdkT3B0cyk7XG4gICAgICBjb25zdCB7c2Vzc2lvbklkfSA9IGRyaXZlcjtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHtkYXRhfSA9IGF3YWl0IGF4aW9zLmdldChgJHtiYXNlVXJsfS8ke3Nlc3Npb25JZH0vZmFrZXBsdWdpbmFyZ3NgKTtcbiAgICAgICAgc2hvdWxkLm5vdC5leGlzdChkYXRhLnZhbHVlKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IGRyaXZlci5kZWxldGVTZXNzaW9uKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXSwiZmlsZSI6InRlc3QvcGx1Z2luLWUyZS1zcGVjcy5qcyIsInNvdXJjZVJvb3QiOiIuLi8uLiJ9
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
require("source-map-support/register");
|
|
4
|
-
|
|
5
|
-
var _argSpec = require("../../lib/schema/arg-spec");
|
|
6
|
-
|
|
7
|
-
const {
|
|
8
|
-
expect
|
|
9
|
-
} = chai;
|
|
10
|
-
describe('ArgSpec', function () {
|
|
11
|
-
describe('class method', function () {
|
|
12
|
-
describe('create()', function () {
|
|
13
|
-
it('should return a new ArgSpec', function () {
|
|
14
|
-
expect(_argSpec.ArgSpec.create('foo')).to.be.an.instanceof(_argSpec.ArgSpec);
|
|
15
|
-
});
|
|
16
|
-
});
|
|
17
|
-
describe('toSchemaRef()', function () {
|
|
18
|
-
describe('when provided no extension information', function () {
|
|
19
|
-
it('should return a schema ID for a specific argument', function () {
|
|
20
|
-
expect(_argSpec.ArgSpec.toSchemaRef('foo')).to.equal('appium.json#/properties/server/properties/foo');
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
describe('when provided extension information', function () {
|
|
24
|
-
it('should return a schema ID for a specific argument within an extension schema', function () {
|
|
25
|
-
expect(_argSpec.ArgSpec.toSchemaRef('bar', 'driver', 'stuff')).to.equal('driver-stuff.json#/properties/bar');
|
|
26
|
-
});
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
describe('toSchemaBaseRef()', function () {
|
|
30
|
-
describe('when provided no extension information', function () {
|
|
31
|
-
it('should return the base schema ID', function () {
|
|
32
|
-
expect(_argSpec.ArgSpec.toSchemaBaseRef()).to.equal('appium.json');
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
describe('when provided extension information', function () {
|
|
36
|
-
it('should return a schema ID for an extension', function () {
|
|
37
|
-
expect(_argSpec.ArgSpec.toSchemaBaseRef('driver', 'stuff')).to.equal('driver-stuff.json');
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
describe('toArg()', function () {
|
|
42
|
-
describe('when provided no extension information', function () {
|
|
43
|
-
it('should return a bare arg name', function () {
|
|
44
|
-
expect(_argSpec.ArgSpec.toArg('foo')).to.equal('foo');
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
describe('when provided extension information', function () {
|
|
48
|
-
it('should return an extension-specific arg name', function () {
|
|
49
|
-
expect(_argSpec.ArgSpec.toArg('no-oats', 'driver', 'bad-donkey')).to.equal('driver-bad-donkey-no-oats');
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
describe('extensionInfoFromRootSchemaId()', function () {
|
|
54
|
-
describe('when provided the base schema ID', function () {
|
|
55
|
-
it('should return an empty object', function () {
|
|
56
|
-
expect(_argSpec.ArgSpec.extensionInfoFromRootSchemaId('appium.json')).to.be.empty;
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
describe('when provided the schema ID of an extension schema', function () {
|
|
60
|
-
expect(_argSpec.ArgSpec.extensionInfoFromRootSchemaId('driver-stuff.json')).to.eql({
|
|
61
|
-
extType: 'driver',
|
|
62
|
-
normalizedExtName: 'stuff'
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
});require('source-map-support').install();
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3Qvc2NoZW1hL2FyZy1zcGVjLXNwZWNzLmpzIl0sIm5hbWVzIjpbImV4cGVjdCIsImNoYWkiLCJkZXNjcmliZSIsIml0IiwiQXJnU3BlYyIsImNyZWF0ZSIsInRvIiwiYmUiLCJhbiIsImluc3RhbmNlb2YiLCJ0b1NjaGVtYVJlZiIsImVxdWFsIiwidG9TY2hlbWFCYXNlUmVmIiwidG9BcmciLCJleHRlbnNpb25JbmZvRnJvbVJvb3RTY2hlbWFJZCIsImVtcHR5IiwiZXFsIiwiZXh0VHlwZSIsIm5vcm1hbGl6ZWRFeHROYW1lIl0sIm1hcHBpbmdzIjoiOzs7O0FBRUE7O0FBRUEsTUFBTTtBQUFDQSxFQUFBQTtBQUFELElBQVdDLElBQWpCO0FBRUFDLFFBQVEsQ0FBQyxTQUFELEVBQVksWUFBWTtBQUM5QkEsRUFBQUEsUUFBUSxDQUFDLGNBQUQsRUFBaUIsWUFBWTtBQUNuQ0EsSUFBQUEsUUFBUSxDQUFDLFVBQUQsRUFBYSxZQUFZO0FBQy9CQyxNQUFBQSxFQUFFLENBQUMsNkJBQUQsRUFBZ0MsWUFBWTtBQUM1Q0gsUUFBQUEsTUFBTSxDQUFDSSxpQkFBUUMsTUFBUixDQUFlLEtBQWYsQ0FBRCxDQUFOLENBQThCQyxFQUE5QixDQUFpQ0MsRUFBakMsQ0FBb0NDLEVBQXBDLENBQXVDQyxVQUF2QyxDQUFrREwsZ0JBQWxEO0FBQ0QsT0FGQyxDQUFGO0FBR0QsS0FKTyxDQUFSO0FBTUFGLElBQUFBLFFBQVEsQ0FBQyxlQUFELEVBQWtCLFlBQVk7QUFDcENBLE1BQUFBLFFBQVEsQ0FBQyx3Q0FBRCxFQUEyQyxZQUFZO0FBQzdEQyxRQUFBQSxFQUFFLENBQUMsbURBQUQsRUFBc0QsWUFBWTtBQUNsRUgsVUFBQUEsTUFBTSxDQUFDSSxpQkFBUU0sV0FBUixDQUFvQixLQUFwQixDQUFELENBQU4sQ0FBbUNKLEVBQW5DLENBQXNDSyxLQUF0QyxDQUNFLCtDQURGO0FBR0QsU0FKQyxDQUFGO0FBS0QsT0FOTyxDQUFSO0FBUUFULE1BQUFBLFFBQVEsQ0FBQyxxQ0FBRCxFQUF3QyxZQUFZO0FBQzFEQyxRQUFBQSxFQUFFLENBQUMsOEVBQUQsRUFBaUYsWUFBWTtBQUM3RkgsVUFBQUEsTUFBTSxDQUFDSSxpQkFBUU0sV0FBUixDQUFvQixLQUFwQixFQUEyQixRQUEzQixFQUFxQyxPQUFyQyxDQUFELENBQU4sQ0FBc0RKLEVBQXRELENBQXlESyxLQUF6RCxDQUNFLG1DQURGO0FBR0QsU0FKQyxDQUFGO0FBS0QsT0FOTyxDQUFSO0FBT0QsS0FoQk8sQ0FBUjtBQWtCQVQsSUFBQUEsUUFBUSxDQUFDLG1CQUFELEVBQXNCLFlBQVk7QUFDeENBLE1BQUFBLFFBQVEsQ0FBQyx3Q0FBRCxFQUEyQyxZQUFZO0FBQzdEQyxRQUFBQSxFQUFFLENBQUMsa0NBQUQsRUFBcUMsWUFBWTtBQUNqREgsVUFBQUEsTUFBTSxDQUFDSSxpQkFBUVEsZUFBUixFQUFELENBQU4sQ0FBa0NOLEVBQWxDLENBQXFDSyxLQUFyQyxDQUNFLGFBREY7QUFHRCxTQUpDLENBQUY7QUFLRCxPQU5PLENBQVI7QUFRQVQsTUFBQUEsUUFBUSxDQUFDLHFDQUFELEVBQXdDLFlBQVk7QUFDMURDLFFBQUFBLEVBQUUsQ0FBQyw0Q0FBRCxFQUErQyxZQUFZO0FBQzNESCxVQUFBQSxNQUFNLENBQUNJLGlCQUFRUSxlQUFSLENBQXdCLFFBQXhCLEVBQWtDLE9BQWxDLENBQUQsQ0FBTixDQUFtRE4sRUFBbkQsQ0FBc0RLLEtBQXRELENBQ0UsbUJBREY7QUFHRCxTQUpDLENBQUY7QUFLRCxPQU5PLENBQVI7QUFPRCxLQWhCTyxDQUFSO0FBa0JBVCxJQUFBQSxRQUFRLENBQUMsU0FBRCxFQUFZLFlBQVk7QUFDOUJBLE1BQUFBLFFBQVEsQ0FBQyx3Q0FBRCxFQUEyQyxZQUFZO0FBQzdEQyxRQUFBQSxFQUFFLENBQUMsK0JBQUQsRUFBa0MsWUFBWTtBQUM5Q0gsVUFBQUEsTUFBTSxDQUFDSSxpQkFBUVMsS0FBUixDQUFjLEtBQWQsQ0FBRCxDQUFOLENBQTZCUCxFQUE3QixDQUFnQ0ssS0FBaEMsQ0FBc0MsS0FBdEM7QUFDRCxTQUZDLENBQUY7QUFHRCxPQUpPLENBQVI7QUFNQVQsTUFBQUEsUUFBUSxDQUFDLHFDQUFELEVBQXdDLFlBQVk7QUFDMURDLFFBQUFBLEVBQUUsQ0FBQyw4Q0FBRCxFQUFpRCxZQUFZO0FBQzdESCxVQUFBQSxNQUFNLENBQUNJLGlCQUFRUyxLQUFSLENBQWMsU0FBZCxFQUF5QixRQUF6QixFQUFtQyxZQUFuQyxDQUFELENBQU4sQ0FBeURQLEVBQXpELENBQTRESyxLQUE1RCxDQUNFLDJCQURGO0FBR0QsU0FKQyxDQUFGO0FBS0QsT0FOTyxDQUFSO0FBT0QsS0FkTyxDQUFSO0FBZ0JBVCxJQUFBQSxRQUFRLENBQUMsaUNBQUQsRUFBb0MsWUFBWTtBQUN0REEsTUFBQUEsUUFBUSxDQUFDLGtDQUFELEVBQXFDLFlBQVk7QUFDdkRDLFFBQUFBLEVBQUUsQ0FBQywrQkFBRCxFQUFrQyxZQUFZO0FBQzlDSCxVQUFBQSxNQUFNLENBQUNJLGlCQUFRVSw2QkFBUixDQUFzQyxhQUF0QyxDQUFELENBQU4sQ0FBNkRSLEVBQTdELENBQWdFQyxFQUFoRSxDQUNHUSxLQURIO0FBRUQsU0FIQyxDQUFGO0FBSUQsT0FMTyxDQUFSO0FBT0FiLE1BQUFBLFFBQVEsQ0FBQyxvREFBRCxFQUF1RCxZQUFZO0FBQ3pFRixRQUFBQSxNQUFNLENBQ0pJLGlCQUFRVSw2QkFBUixDQUFzQyxtQkFBdEMsQ0FESSxDQUFOLENBRUVSLEVBRkYsQ0FFS1UsR0FGTCxDQUVTO0FBQUNDLFVBQUFBLE9BQU8sRUFBRSxRQUFWO0FBQW9CQyxVQUFBQSxpQkFBaUIsRUFBRTtBQUF2QyxTQUZUO0FBR0QsT0FKTyxDQUFSO0FBS0QsS0FiTyxDQUFSO0FBY0QsR0F6RU8sQ0FBUjtBQTBFRCxDQTNFTyxDQUFSIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCB7QXJnU3BlY30gZnJvbSAnLi4vLi4vbGliL3NjaGVtYS9hcmctc3BlYyc7XG5cbmNvbnN0IHtleHBlY3R9ID0gY2hhaTtcblxuZGVzY3JpYmUoJ0FyZ1NwZWMnLCBmdW5jdGlvbiAoKSB7XG4gIGRlc2NyaWJlKCdjbGFzcyBtZXRob2QnLCBmdW5jdGlvbiAoKSB7XG4gICAgZGVzY3JpYmUoJ2NyZWF0ZSgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYSBuZXcgQXJnU3BlYycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZXhwZWN0KEFyZ1NwZWMuY3JlYXRlKCdmb28nKSkudG8uYmUuYW4uaW5zdGFuY2VvZihBcmdTcGVjKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3RvU2NoZW1hUmVmKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBkZXNjcmliZSgnd2hlbiBwcm92aWRlZCBubyBleHRlbnNpb24gaW5mb3JtYXRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgc2NoZW1hIElEIGZvciBhIHNwZWNpZmljIGFyZ3VtZW50JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGV4cGVjdChBcmdTcGVjLnRvU2NoZW1hUmVmKCdmb28nKSkudG8uZXF1YWwoXG4gICAgICAgICAgICAnYXBwaXVtLmpzb24jL3Byb3BlcnRpZXMvc2VydmVyL3Byb3BlcnRpZXMvZm9vJyxcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnd2hlbiBwcm92aWRlZCBleHRlbnNpb24gaW5mb3JtYXRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgc2NoZW1hIElEIGZvciBhIHNwZWNpZmljIGFyZ3VtZW50IHdpdGhpbiBhbiBleHRlbnNpb24gc2NoZW1hJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGV4cGVjdChBcmdTcGVjLnRvU2NoZW1hUmVmKCdiYXInLCAnZHJpdmVyJywgJ3N0dWZmJykpLnRvLmVxdWFsKFxuICAgICAgICAgICAgJ2RyaXZlci1zdHVmZi5qc29uIy9wcm9wZXJ0aWVzL2JhcicsXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCd0b1NjaGVtYUJhc2VSZWYoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGRlc2NyaWJlKCd3aGVuIHByb3ZpZGVkIG5vIGV4dGVuc2lvbiBpbmZvcm1hdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gdGhlIGJhc2Ugc2NoZW1hIElEJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGV4cGVjdChBcmdTcGVjLnRvU2NoZW1hQmFzZVJlZigpKS50by5lcXVhbChcbiAgICAgICAgICAgICdhcHBpdW0uanNvbicsXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ3doZW4gcHJvdmlkZWQgZXh0ZW5zaW9uIGluZm9ybWF0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBhIHNjaGVtYSBJRCBmb3IgYW4gZXh0ZW5zaW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGV4cGVjdChBcmdTcGVjLnRvU2NoZW1hQmFzZVJlZignZHJpdmVyJywgJ3N0dWZmJykpLnRvLmVxdWFsKFxuICAgICAgICAgICAgJ2RyaXZlci1zdHVmZi5qc29uJyxcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3RvQXJnKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBkZXNjcmliZSgnd2hlbiBwcm92aWRlZCBubyBleHRlbnNpb24gaW5mb3JtYXRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgYmFyZSBhcmcgbmFtZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBleHBlY3QoQXJnU3BlYy50b0FyZygnZm9vJykpLnRvLmVxdWFsKCdmb28nKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ3doZW4gcHJvdmlkZWQgZXh0ZW5zaW9uIGluZm9ybWF0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBhbiBleHRlbnNpb24tc3BlY2lmaWMgYXJnIG5hbWUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgZXhwZWN0KEFyZ1NwZWMudG9BcmcoJ25vLW9hdHMnLCAnZHJpdmVyJywgJ2JhZC1kb25rZXknKSkudG8uZXF1YWwoXG4gICAgICAgICAgICAnZHJpdmVyLWJhZC1kb25rZXktbm8tb2F0cycsXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdleHRlbnNpb25JbmZvRnJvbVJvb3RTY2hlbWFJZCgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgZGVzY3JpYmUoJ3doZW4gcHJvdmlkZWQgdGhlIGJhc2Ugc2NoZW1hIElEJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBhbiBlbXB0eSBvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgZXhwZWN0KEFyZ1NwZWMuZXh0ZW5zaW9uSW5mb0Zyb21Sb290U2NoZW1hSWQoJ2FwcGl1bS5qc29uJykpLnRvLmJlXG4gICAgICAgICAgICAuZW1wdHk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCd3aGVuIHByb3ZpZGVkIHRoZSBzY2hlbWEgSUQgb2YgYW4gZXh0ZW5zaW9uIHNjaGVtYScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZXhwZWN0KFxuICAgICAgICAgIEFyZ1NwZWMuZXh0ZW5zaW9uSW5mb0Zyb21Sb290U2NoZW1hSWQoJ2RyaXZlci1zdHVmZi5qc29uJyksXG4gICAgICAgICkudG8uZXFsKHtleHRUeXBlOiAnZHJpdmVyJywgbm9ybWFsaXplZEV4dE5hbWU6ICdzdHVmZid9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl0sImZpbGUiOiJ0ZXN0L3NjaGVtYS9hcmctc3BlYy1zcGVjcy5qcyIsInNvdXJjZVJvb3QiOiIuLi8uLi8uLiJ9
|