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,321 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
require("source-map-support/register");
|
|
6
|
+
|
|
7
|
+
var _appium = require("../lib/appium");
|
|
8
|
+
|
|
9
|
+
var _baseDriver = require("@appium/base-driver");
|
|
10
|
+
|
|
11
|
+
var _fakeDriver = require("@appium/fake-driver");
|
|
12
|
+
|
|
13
|
+
var _helpers = require("./helpers");
|
|
14
|
+
|
|
15
|
+
var _schema = require("../lib/schema/schema");
|
|
16
|
+
|
|
17
|
+
var _lodash = _interopRequireDefault(require("lodash"));
|
|
18
|
+
|
|
19
|
+
var _sinon = _interopRequireDefault(require("sinon"));
|
|
20
|
+
|
|
21
|
+
var _asyncbox = require("asyncbox");
|
|
22
|
+
|
|
23
|
+
var _utils = require("../lib/utils");
|
|
24
|
+
|
|
25
|
+
const SESSION_ID = 1;
|
|
26
|
+
describe('AppiumDriver', function () {
|
|
27
|
+
beforeEach(function () {
|
|
28
|
+
(0, _schema.resetSchema)();
|
|
29
|
+
});
|
|
30
|
+
describe('AppiumDriver', function () {
|
|
31
|
+
function getDriverAndFakeDriver(appiumArgs = {}, DriverClass = _fakeDriver.FakeDriver) {
|
|
32
|
+
const appium = new _appium.AppiumDriver(appiumArgs);
|
|
33
|
+
const fakeDriver = new DriverClass();
|
|
34
|
+
|
|
35
|
+
const mockFakeDriver = _sinon.default.mock(fakeDriver);
|
|
36
|
+
|
|
37
|
+
mockFakeDriver._fakeDriver = fakeDriver;
|
|
38
|
+
|
|
39
|
+
const mockedDriverReturnerClass = function Driver() {
|
|
40
|
+
return fakeDriver;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
appium._findMatchingDriver = function () {
|
|
44
|
+
return {
|
|
45
|
+
driver: mockedDriverReturnerClass,
|
|
46
|
+
version: '1.2.3',
|
|
47
|
+
driverName: 'fake'
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
return [appium, mockFakeDriver];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
describe('createSession', function () {
|
|
55
|
+
let appium;
|
|
56
|
+
let mockFakeDriver;
|
|
57
|
+
beforeEach(function () {
|
|
58
|
+
[appium, mockFakeDriver] = getDriverAndFakeDriver();
|
|
59
|
+
});
|
|
60
|
+
afterEach(async function () {
|
|
61
|
+
mockFakeDriver.restore();
|
|
62
|
+
await appium.deleteSession(SESSION_ID);
|
|
63
|
+
});
|
|
64
|
+
it(`should call inner driver's createSession with desired capabilities`, async function () {
|
|
65
|
+
mockFakeDriver.expects('createSession').once().withExactArgs(null, null, _helpers.W3C_CAPS, []).returns([SESSION_ID, (0, _utils.removeAppiumPrefixes)(_helpers.W3C_PREFIXED_CAPS)]);
|
|
66
|
+
await appium.createSession(null, null, _helpers.W3C_CAPS);
|
|
67
|
+
mockFakeDriver.verify();
|
|
68
|
+
});
|
|
69
|
+
it(`should call inner driver's createSession with desired and default capabilities`, async function () {
|
|
70
|
+
let defaultCaps = {
|
|
71
|
+
'appium:someCap': 'hello'
|
|
72
|
+
};
|
|
73
|
+
let allCaps = { ..._helpers.W3C_CAPS,
|
|
74
|
+
alwaysMatch: { ..._helpers.W3C_CAPS.alwaysMatch,
|
|
75
|
+
...defaultCaps
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
appium.args.defaultCapabilities = defaultCaps;
|
|
79
|
+
mockFakeDriver.expects('createSession').once().withArgs(null, null, allCaps).returns([SESSION_ID, (0, _utils.removeAppiumPrefixes)(allCaps.alwaysMatch)]);
|
|
80
|
+
await appium.createSession(null, null, _helpers.W3C_CAPS);
|
|
81
|
+
mockFakeDriver.verify();
|
|
82
|
+
});
|
|
83
|
+
it(`should call inner driver's createSession with desired and default capabilities without overriding caps`, async function () {
|
|
84
|
+
let defaultCaps = {
|
|
85
|
+
platformName: 'Ersatz'
|
|
86
|
+
};
|
|
87
|
+
appium.args.defaultCapabilities = defaultCaps;
|
|
88
|
+
mockFakeDriver.expects('createSession').once().withArgs(null, null, _helpers.W3C_CAPS).returns([SESSION_ID, (0, _utils.removeAppiumPrefixes)(_helpers.W3C_PREFIXED_CAPS)]);
|
|
89
|
+
await appium.createSession(null, null, _helpers.W3C_CAPS);
|
|
90
|
+
mockFakeDriver.verify();
|
|
91
|
+
});
|
|
92
|
+
it('should kill all other sessions if sessionOverride is on', async function () {
|
|
93
|
+
appium.args.sessionOverride = true;
|
|
94
|
+
let fakeDrivers = [new _fakeDriver.FakeDriver(), new _fakeDriver.FakeDriver(), new _fakeDriver.FakeDriver()];
|
|
95
|
+
|
|
96
|
+
let mockFakeDrivers = _lodash.default.map(fakeDrivers, fd => _sinon.default.mock(fd));
|
|
97
|
+
|
|
98
|
+
mockFakeDrivers[0].expects('deleteSession').once();
|
|
99
|
+
mockFakeDrivers[1].expects('deleteSession').once().throws('Cannot shut down Android driver; it has already shut down');
|
|
100
|
+
mockFakeDrivers[2].expects('deleteSession').once();
|
|
101
|
+
appium.sessions['abc-123-xyz'] = fakeDrivers[0];
|
|
102
|
+
appium.sessions['xyz-321-abc'] = fakeDrivers[1];
|
|
103
|
+
appium.sessions['123-abc-xyz'] = fakeDrivers[2];
|
|
104
|
+
let sessions = await appium.getSessions();
|
|
105
|
+
sessions.should.have.length(3);
|
|
106
|
+
mockFakeDriver.expects('createSession').once().withExactArgs(null, null, _helpers.W3C_CAPS, []).returns([SESSION_ID, (0, _utils.removeAppiumPrefixes)(_helpers.W3C_PREFIXED_CAPS)]);
|
|
107
|
+
await appium.createSession(null, null, _helpers.W3C_CAPS);
|
|
108
|
+
sessions = await appium.getSessions();
|
|
109
|
+
sessions.should.have.length(1);
|
|
110
|
+
|
|
111
|
+
for (let mfd of mockFakeDrivers) {
|
|
112
|
+
mfd.verify();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
mockFakeDriver.verify();
|
|
116
|
+
});
|
|
117
|
+
it('should call "createSession" with W3C capabilities argument, if provided', async function () {
|
|
118
|
+
mockFakeDriver.expects('createSession').once().withArgs(null, undefined, _helpers.W3C_CAPS).returns([SESSION_ID, _helpers.BASE_CAPS]);
|
|
119
|
+
await appium.createSession(undefined, undefined, _helpers.W3C_CAPS);
|
|
120
|
+
mockFakeDriver.verify();
|
|
121
|
+
});
|
|
122
|
+
it('should call "createSession" with W3C capabilities argument with additional provided parameters', async function () {
|
|
123
|
+
let w3cCaps = { ..._helpers.W3C_CAPS,
|
|
124
|
+
alwaysMatch: { ..._helpers.W3C_CAPS.alwaysMatch,
|
|
125
|
+
'appium:someOtherParm': 'someOtherParm'
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
mockFakeDriver.expects('createSession').once().withArgs(null, undefined, {
|
|
129
|
+
alwaysMatch: { ...w3cCaps.alwaysMatch,
|
|
130
|
+
'appium:someOtherParm': 'someOtherParm'
|
|
131
|
+
},
|
|
132
|
+
firstMatch: [{}]
|
|
133
|
+
}).returns([SESSION_ID, (0, _utils.insertAppiumPrefixes)(_helpers.BASE_CAPS)]);
|
|
134
|
+
await appium.createSession(undefined, undefined, w3cCaps);
|
|
135
|
+
mockFakeDriver.verify();
|
|
136
|
+
});
|
|
137
|
+
it('should not call "createSession" with JSONWP capabilities if W3C has incomplete capabilities', async function () {
|
|
138
|
+
const w3cCaps = { ..._helpers.W3C_CAPS,
|
|
139
|
+
alwaysMatch: {
|
|
140
|
+
'appium:someOtherParm': 'someOtherParm'
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
const jsonwpCaps = { ..._helpers.BASE_CAPS,
|
|
144
|
+
automationName: 'Fake',
|
|
145
|
+
someOtherParam: 'someOtherParam'
|
|
146
|
+
};
|
|
147
|
+
mockFakeDriver.expects('createSession').never();
|
|
148
|
+
await appium.createSession(jsonwpCaps, undefined, w3cCaps);
|
|
149
|
+
mockFakeDriver.verify();
|
|
150
|
+
});
|
|
151
|
+
it('should assign args to property `cliArgs`', async function () {
|
|
152
|
+
class ArgsDriver extends _baseDriver.BaseDriver {}
|
|
153
|
+
|
|
154
|
+
const args = {
|
|
155
|
+
driver: {
|
|
156
|
+
fake: {
|
|
157
|
+
randomArg: 1234
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
[appium, mockFakeDriver] = getDriverAndFakeDriver(args, ArgsDriver);
|
|
162
|
+
const {
|
|
163
|
+
value
|
|
164
|
+
} = await appium.createSession(undefined, undefined, _helpers.W3C_CAPS);
|
|
165
|
+
|
|
166
|
+
try {
|
|
167
|
+
mockFakeDriver._fakeDriver.cliArgs.should.eql({
|
|
168
|
+
randomArg: 1234
|
|
169
|
+
});
|
|
170
|
+
} finally {
|
|
171
|
+
await appium.deleteSession(value[0]);
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
describe('deleteSession', function () {
|
|
176
|
+
let appium;
|
|
177
|
+
let mockFakeDriver;
|
|
178
|
+
beforeEach(function () {
|
|
179
|
+
[appium, mockFakeDriver] = getDriverAndFakeDriver();
|
|
180
|
+
});
|
|
181
|
+
afterEach(function () {
|
|
182
|
+
mockFakeDriver.restore();
|
|
183
|
+
});
|
|
184
|
+
it('should remove the session if it is found', async function () {
|
|
185
|
+
let [sessionId] = (await appium.createSession(null, null, _helpers.W3C_CAPS)).value;
|
|
186
|
+
let sessions = await appium.getSessions();
|
|
187
|
+
sessions.should.have.length(1);
|
|
188
|
+
await appium.deleteSession(sessionId);
|
|
189
|
+
sessions = await appium.getSessions();
|
|
190
|
+
sessions.should.have.length(0);
|
|
191
|
+
});
|
|
192
|
+
it('should call inner driver\'s deleteSession method', async function () {
|
|
193
|
+
const [sessionId] = (await appium.createSession(null, null, _helpers.W3C_CAPS)).value;
|
|
194
|
+
mockFakeDriver.expects('deleteSession').once().withExactArgs(sessionId, []).returns();
|
|
195
|
+
await appium.deleteSession(sessionId);
|
|
196
|
+
mockFakeDriver.verify();
|
|
197
|
+
await mockFakeDriver.object.deleteSession();
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
describe('getSessions', function () {
|
|
201
|
+
let appium, mockFakeDriver;
|
|
202
|
+
let sessions;
|
|
203
|
+
before(function () {
|
|
204
|
+
[appium, mockFakeDriver] = getDriverAndFakeDriver();
|
|
205
|
+
});
|
|
206
|
+
afterEach(async function () {
|
|
207
|
+
for (let session of sessions) {
|
|
208
|
+
await appium.deleteSession(session.id);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
mockFakeDriver.restore();
|
|
212
|
+
});
|
|
213
|
+
it('should return an empty array of sessions', async function () {
|
|
214
|
+
sessions = await appium.getSessions();
|
|
215
|
+
sessions.should.be.an('array');
|
|
216
|
+
sessions.should.be.empty;
|
|
217
|
+
});
|
|
218
|
+
it('should return sessions created', async function () {
|
|
219
|
+
let caps1 = {
|
|
220
|
+
alwaysMatch: { ..._helpers.W3C_PREFIXED_CAPS,
|
|
221
|
+
'appium:cap': 'value'
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
let caps2 = {
|
|
225
|
+
alwaysMatch: { ..._helpers.W3C_PREFIXED_CAPS,
|
|
226
|
+
'appium:cap': 'other value'
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
mockFakeDriver.expects('createSession').once().returns(['fake-session-id-1', (0, _utils.removeAppiumPrefixes)(caps1.alwaysMatch)]);
|
|
230
|
+
let [session1Id, session1Caps] = (await appium.createSession(null, null, caps1)).value;
|
|
231
|
+
mockFakeDriver.expects('createSession').once().returns(['fake-session-id-2', (0, _utils.removeAppiumPrefixes)(caps2.alwaysMatch)]);
|
|
232
|
+
let [session2Id, session2Caps] = (await appium.createSession(null, null, caps2)).value;
|
|
233
|
+
sessions = await appium.getSessions();
|
|
234
|
+
sessions.should.be.an('array');
|
|
235
|
+
sessions.should.have.length(2);
|
|
236
|
+
sessions[0].id.should.equal(session1Id);
|
|
237
|
+
(0, _utils.removeAppiumPrefixes)(caps1.alwaysMatch).should.eql(session1Caps);
|
|
238
|
+
sessions[1].id.should.equal(session2Id);
|
|
239
|
+
(0, _utils.removeAppiumPrefixes)(caps2.alwaysMatch).should.eql(session2Caps);
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
describe('getStatus', function () {
|
|
243
|
+
let appium;
|
|
244
|
+
before(function () {
|
|
245
|
+
appium = new _appium.AppiumDriver({});
|
|
246
|
+
});
|
|
247
|
+
it('should return a status', async function () {
|
|
248
|
+
let status = await appium.getStatus();
|
|
249
|
+
status.build.should.exist;
|
|
250
|
+
status.build.version.should.exist;
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
describe('sessionExists', function () {});
|
|
254
|
+
describe('attachUnexpectedShutdownHandler', function () {
|
|
255
|
+
let appium;
|
|
256
|
+
let mockFakeDriver;
|
|
257
|
+
beforeEach(function () {
|
|
258
|
+
[appium, mockFakeDriver] = getDriverAndFakeDriver();
|
|
259
|
+
});
|
|
260
|
+
afterEach(async function () {
|
|
261
|
+
await mockFakeDriver.object.deleteSession();
|
|
262
|
+
mockFakeDriver.restore();
|
|
263
|
+
appium.args.defaultCapabilities = {};
|
|
264
|
+
});
|
|
265
|
+
it('should remove session if inner driver unexpectedly exits with an error', async function () {
|
|
266
|
+
let [sessionId] = (await appium.createSession(null, null, _lodash.default.clone(_helpers.W3C_CAPS))).value;
|
|
267
|
+
|
|
268
|
+
_lodash.default.keys(appium.sessions).should.contain(sessionId);
|
|
269
|
+
|
|
270
|
+
appium.sessions[sessionId].eventEmitter.emit('onUnexpectedShutdown', new Error('Oops'));
|
|
271
|
+
await (0, _asyncbox.sleep)(1);
|
|
272
|
+
|
|
273
|
+
_lodash.default.keys(appium.sessions).should.not.contain(sessionId);
|
|
274
|
+
});
|
|
275
|
+
it('should remove session if inner driver unexpectedly exits with no error', async function () {
|
|
276
|
+
let [sessionId] = (await appium.createSession(null, null, _lodash.default.clone(_helpers.W3C_CAPS))).value;
|
|
277
|
+
|
|
278
|
+
_lodash.default.keys(appium.sessions).should.contain(sessionId);
|
|
279
|
+
|
|
280
|
+
appium.sessions[sessionId].eventEmitter.emit('onUnexpectedShutdown');
|
|
281
|
+
await (0, _asyncbox.sleep)(1);
|
|
282
|
+
|
|
283
|
+
_lodash.default.keys(appium.sessions).should.not.contain(sessionId);
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
describe('#createPluginInstances', function () {
|
|
288
|
+
class NoArgsPlugin {}
|
|
289
|
+
|
|
290
|
+
NoArgsPlugin.pluginName = 'noargs';
|
|
291
|
+
|
|
292
|
+
class ArgsPlugin {}
|
|
293
|
+
|
|
294
|
+
ArgsPlugin.pluginName = 'args';
|
|
295
|
+
it('should not set CLI args if none are sent', function () {
|
|
296
|
+
const appium = new _appium.AppiumDriver({});
|
|
297
|
+
appium.pluginClasses = [NoArgsPlugin, ArgsPlugin];
|
|
298
|
+
|
|
299
|
+
for (const plugin of appium.createPluginInstances()) {
|
|
300
|
+
should.not.exist(plugin.cliArgs);
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
it('should add cliArgs to the plugin once validated', function () {
|
|
304
|
+
const appium = new _appium.AppiumDriver({
|
|
305
|
+
plugin: {
|
|
306
|
+
args: {
|
|
307
|
+
randomArg: 1234
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
appium.pluginClasses = [ArgsPlugin];
|
|
312
|
+
const plugin = appium.createPluginInstances()[0];
|
|
313
|
+
plugin.cliArgs.should.eql({
|
|
314
|
+
randomArg: 1234
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
});require('source-map-support').install();
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvZHJpdmVyLXNwZWNzLmpzIl0sIm5hbWVzIjpbIlNFU1NJT05fSUQiLCJkZXNjcmliZSIsImJlZm9yZUVhY2giLCJnZXREcml2ZXJBbmRGYWtlRHJpdmVyIiwiYXBwaXVtQXJncyIsIkRyaXZlckNsYXNzIiwiRmFrZURyaXZlciIsImFwcGl1bSIsIkFwcGl1bURyaXZlciIsImZha2VEcml2ZXIiLCJtb2NrRmFrZURyaXZlciIsInNpbm9uIiwibW9jayIsIl9mYWtlRHJpdmVyIiwibW9ja2VkRHJpdmVyUmV0dXJuZXJDbGFzcyIsIkRyaXZlciIsIl9maW5kTWF0Y2hpbmdEcml2ZXIiLCJkcml2ZXIiLCJ2ZXJzaW9uIiwiZHJpdmVyTmFtZSIsImFmdGVyRWFjaCIsInJlc3RvcmUiLCJkZWxldGVTZXNzaW9uIiwiaXQiLCJleHBlY3RzIiwib25jZSIsIndpdGhFeGFjdEFyZ3MiLCJXM0NfQ0FQUyIsInJldHVybnMiLCJXM0NfUFJFRklYRURfQ0FQUyIsImNyZWF0ZVNlc3Npb24iLCJ2ZXJpZnkiLCJkZWZhdWx0Q2FwcyIsImFsbENhcHMiLCJhbHdheXNNYXRjaCIsImFyZ3MiLCJkZWZhdWx0Q2FwYWJpbGl0aWVzIiwid2l0aEFyZ3MiLCJwbGF0Zm9ybU5hbWUiLCJzZXNzaW9uT3ZlcnJpZGUiLCJmYWtlRHJpdmVycyIsIm1vY2tGYWtlRHJpdmVycyIsIl8iLCJtYXAiLCJmZCIsInRocm93cyIsInNlc3Npb25zIiwiZ2V0U2Vzc2lvbnMiLCJzaG91bGQiLCJoYXZlIiwibGVuZ3RoIiwibWZkIiwidW5kZWZpbmVkIiwiQkFTRV9DQVBTIiwidzNjQ2FwcyIsImZpcnN0TWF0Y2giLCJqc29ud3BDYXBzIiwiYXV0b21hdGlvbk5hbWUiLCJzb21lT3RoZXJQYXJhbSIsIm5ldmVyIiwiQXJnc0RyaXZlciIsIkJhc2VEcml2ZXIiLCJmYWtlIiwicmFuZG9tQXJnIiwidmFsdWUiLCJjbGlBcmdzIiwiZXFsIiwic2Vzc2lvbklkIiwib2JqZWN0IiwiYmVmb3JlIiwic2Vzc2lvbiIsImlkIiwiYmUiLCJhbiIsImVtcHR5IiwiY2FwczEiLCJjYXBzMiIsInNlc3Npb24xSWQiLCJzZXNzaW9uMUNhcHMiLCJzZXNzaW9uMklkIiwic2Vzc2lvbjJDYXBzIiwiZXF1YWwiLCJzdGF0dXMiLCJnZXRTdGF0dXMiLCJidWlsZCIsImV4aXN0IiwiY2xvbmUiLCJrZXlzIiwiY29udGFpbiIsImV2ZW50RW1pdHRlciIsImVtaXQiLCJFcnJvciIsIm5vdCIsIk5vQXJnc1BsdWdpbiIsInBsdWdpbk5hbWUiLCJBcmdzUGx1Z2luIiwicGx1Z2luQ2xhc3NlcyIsInBsdWdpbiIsImNyZWF0ZVBsdWdpbkluc3RhbmNlcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBR0EsTUFBTUEsVUFBVSxHQUFHLENBQW5CO0FBRUFDLFFBQVEsQ0FBQyxjQUFELEVBQWlCLFlBQVk7QUFDbkNDLEVBQUFBLFVBQVUsQ0FBQyxZQUFZO0FBQ3JCO0FBQ0QsR0FGUyxDQUFWO0FBR0FELEVBQUFBLFFBQVEsQ0FBQyxjQUFELEVBQWlCLFlBQVk7QUFDbkMsYUFBU0Usc0JBQVQsQ0FBaUNDLFVBQVUsR0FBRyxFQUE5QyxFQUFrREMsV0FBVyxHQUFHQyxzQkFBaEUsRUFBNEU7QUFDMUUsWUFBTUMsTUFBTSxHQUFHLElBQUlDLG9CQUFKLENBQWlCSixVQUFqQixDQUFmO0FBQ0EsWUFBTUssVUFBVSxHQUFHLElBQUlKLFdBQUosRUFBbkI7O0FBQ0EsWUFBTUssY0FBYyxHQUFHQyxlQUFNQyxJQUFOLENBQVdILFVBQVgsQ0FBdkI7O0FBQ0FDLE1BQUFBLGNBQWMsQ0FBQ0csV0FBZixHQUE2QkosVUFBN0I7O0FBQ0EsWUFBTUsseUJBQXlCLEdBQUcsU0FBU0MsTUFBVCxHQUFtQjtBQUNuRCxlQUFPTixVQUFQO0FBQ0QsT0FGRDs7QUFJQUYsTUFBQUEsTUFBTSxDQUFDUyxtQkFBUCxHQUE2QixZQUFZO0FBQ3ZDLGVBQU87QUFDTEMs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RUFBRSxDQUFDLDBDQUFELEVBQTZDLFlBQVk7QUFDekQsWUFBTWhCLE1BQU0sR0FBRyxJQUFJQyxvQkFBSixDQUFpQixFQUFqQixDQUFmO0FBQ0FELE1BQUFBLE1BQU0sQ0FBQ3lGLGFBQVAsR0FBdUIsQ0FBQ0gsWUFBRCxFQUFlRSxVQUFmLENBQXZCOztBQUNBLFdBQUssTUFBTUUsTUFBWCxJQUFxQjFGLE1BQU0sQ0FBQzJGLHFCQUFQLEVBQXJCLEVBQXFEO0FBQ25EbEQsUUFBQUEsTUFBTSxDQUFDNEMsR0FBUCxDQUFXUCxLQUFYLENBQWlCWSxNQUFNLENBQUNoQyxPQUF4QjtBQUNEO0FBQ0YsS0FOQyxDQUFGO0FBT0ExQyxJQUFBQSxFQUFFLENBQUMsaURBQUQsRUFBb0QsWUFBWTtBQUNoRSxZQUFNaEIsTUFBTSxHQUFHLElBQUlDLG9CQUFKLENBQWlCO0FBQUN5RixRQUFBQSxNQUFNLEVBQUU7QUFBQzlELFVBQUFBLElBQUksRUFBRTtBQUFDNEIsWUFBQUEsU0FBUyxFQUFFO0FBQVo7QUFBUDtBQUFULE9BQWpCLENBQWY7QUFDQXhELE1BQUFBLE1BQU0sQ0FBQ3lGLGFBQVAsR0FBdUIsQ0FBQ0QsVUFBRCxDQUF2QjtBQUNBLFlBQU1FLE1BQU0sR0FBRzFGLE1BQU0sQ0FBQzJGLHFCQUFQLEdBQStCLENBQS9CLENBQWY7QUFDQUQsTUFBQUEsTUFBTSxDQUFDaEMsT0FBUCxDQUFlakIsTUFBZixDQUFzQmtCLEdBQXRCLENBQTBCO0FBQUNILFFBQUFBLFNBQVMsRUFBRTtBQUFaLE9BQTFCO0FBQ0QsS0FMQyxDQUFGO0FBTUQsR0FwQk8sQ0FBUjtBQXFCRCxDQWhTTyxDQUFSIiwic291cmNlc0NvbnRlbnQiOlsiLy8gdHJhbnNwaWxlOm1vY2hhXG5cbmltcG9ydCB7IEFwcGl1bURyaXZlciB9IGZyb20gJy4uL2xpYi9hcHBpdW0nO1xuaW1wb3J0IHsgQmFzZURyaXZlciB9IGZyb20gJ0BhcHBpdW0vYmFzZS1kcml2ZXInO1xuaW1wb3J0IHsgRmFrZURyaXZlciB9IGZyb20gJ0BhcHBpdW0vZmFrZS1kcml2ZXInO1xuaW1wb3J0IHsgQkFTRV9DQVBTLCBXM0NfQ0FQUywgVzNDX1BSRUZJWEVEX0NBUFMgfSBmcm9tICcuL2hlbHBlcnMnO1xuaW1wb3J0IHtyZXNldFNjaGVtYX0gZnJvbSAnLi4vbGliL3NjaGVtYS9zY2hlbWEnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBzaW5vbiBmcm9tICdzaW5vbic7XG5pbXBvcnQgeyBzbGVlcCB9IGZyb20gJ2FzeW5jYm94JztcbmltcG9ydCB7IGluc2VydEFwcGl1bVByZWZpeGVzLCByZW1vdmVBcHBpdW1QcmVmaXhlcyB9IGZyb20gJy4uL2xpYi91dGlscyc7XG5cblxuY29uc3QgU0VTU0lPTl9JRCA9IDE7XG5cbmRlc2NyaWJlKCdBcHBpdW1Ecml2ZXInLCBmdW5jdGlvbiAoKSB7XG4gIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgIHJlc2V0U2NoZW1hKCk7XG4gIH0pO1xuICBkZXNjcmliZSgnQXBwaXVtRHJpdmVyJywgZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIGdldERyaXZlckFuZEZha2VEcml2ZXIgKGFwcGl1bUFyZ3MgPSB7fSwgRHJpdmVyQ2xhc3MgPSBGYWtlRHJpdmVyKSB7XG4gICAgICBjb25zdCBhcHBpdW0gPSBuZXcgQXBwaXVtRHJpdmVyKGFwcGl1bUFyZ3MpO1xuICAgICAgY29uc3QgZmFrZURyaXZlciA9IG5ldyBEcml2ZXJDbGFzcygpO1xuICAgICAgY29uc3QgbW9ja0Zha2VEcml2ZXIgPSBzaW5vbi5tb2NrKGZha2VEcml2ZXIpO1xuICAgICAgbW9ja0Zha2VEcml2ZXIuX2Zha2VEcml2ZXIgPSBmYWtlRHJpdmVyO1xuICAgICAgY29uc3QgbW9ja2VkRHJpdmVyUmV0dXJuZXJDbGFzcyA9IGZ1bmN0aW9uIERyaXZlciAoKSB7XG4gICAgICAgIHJldHVybiBmYWtlRHJpdmVyO1xuICAgICAgfTtcblxuICAgICAgYXBwaXVtLl9maW5kTWF0Y2hpbmdEcml2ZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZHJpdmVyOiBtb2NrZWREcml2ZXJSZXR1cm5lckNsYXNzLFxuICAgICAgICAgIHZlcnNpb246ICcxLjIuMycsXG4gICAgICAgICAgZHJpdmVyTmFtZTogJ2Zha2UnLFxuICAgICAgICB9O1xuICAgICAgfTtcbiAgICAgIHJldHVybiBbYXBwaXVtLCBtb2NrRmFrZURyaXZlcl07XG4gICAgfVxuICAgIGRlc2NyaWJlKCdjcmVhdGVTZXNzaW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IGFwcGl1bTtcbiAgICAgIGxldCBtb2NrRmFrZURyaXZlcjtcbiAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICBbYXBwaXVtLCBtb2NrRmFrZURyaXZlcl0gPSBnZXREcml2ZXJBbmRGYWtlRHJpdmVyKCk7XG4gICAgICB9KTtcbiAgICAgIGFmdGVyRWFjaChhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIG1vY2tGYWtlRHJpdmVyLnJlc3RvcmUoKTtcbiAgICAgICAgYXdhaXQgYXBwaXVtLmRlbGV0ZVNlc3Npb24oU0VTU0lPTl9JRCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoYHNob3VsZCBjYWxsIGlubmVyIGRyaXZlcidzIGNyZWF0ZVNlc3Npb24gd2l0aCBkZXNpcmVkIGNhcGFiaWxpdGllc2AsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbW9ja0Zha2VEcml2ZXIuZXhwZWN0cygnY3JlYXRlU2Vzc2lvbicpXG4gICAgICAgICAgLm9uY2UoKS53aXRoRXhhY3RBcmdzKG51bGwsIG51bGwsIFczQ19DQVBTLCBbXSlcbiAgICAgICAgICAucmV0dXJucyhbU0VTU0lPTl9JRCwgcmVtb3ZlQXBwaXVtUHJlZml4ZXMoVzNDX1BSRUZJWEVEX0NBUFMpXSk7XG4gICAgICAgIGF3YWl0IGFwcGl1bS5jcmVhdGVTZXNzaW9uKG51bGwsIG51bGwsIFczQ19DQVBTKTtcbiAgICAgICAgbW9ja0Zha2VEcml2ZXIudmVyaWZ5KCk7XG4gICAgICB9KTtcbiAgICAgIGl0KGBzaG91bGQgY2FsbCBpbm5lciBkcml2ZXIncyBjcmVhdGVTZXNzaW9uIHdpdGggZGVzaXJlZCBhbmQgZGVmYXVsdCBjYXBhYmlsaXRpZXNgLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBkZWZhdWx0Q2FwcyA9IHsnYXBwaXVtOnNvbWVDYXAnOiAnaGVsbG8nfTtcbiAgICAgICAgbGV0IGFsbENhcHMgPSB7Li4uVzNDX0NBUFMsIGFsd2F5c01hdGNoOiB7Li4uVzNDX0NBUFMuYWx3YXlzTWF0Y2gsIC4uLmRlZmF1bHRDYXBzfX07XG4gICAgICAgIGFwcGl1bS5hcmdzLmRlZmF1bHRDYXBhYmlsaXRpZXMgPSBkZWZhdWx0Q2FwcztcbiAgICAgICAgbW9ja0Zha2VEcml2ZXIuZXhwZWN0cygnY3JlYXRlU2Vzc2lvbicpXG4gICAgICAgICAgLm9uY2UoKS53aXRoQXJncyhudWxsLCBudWxsLCBhbGxDYXBzKVxuICAgICAgICAgIC5yZXR1cm5zKFtTRVNTSU9OX0lELCByZW1vdmVBcHBpdW1QcmVmaXhlcyhhbGxDYXBzLmFsd2F5c01hdGNoKV0pO1xuICAgICAgICBhd2FpdCBhcHBpdW0uY3JlYXRlU2Vzc2lvbihudWxsLCBudWxsLCBXM0NfQ0FQUyk7XG4gICAgICAgIG1vY2tGYWtlRHJpdmVyLnZlcmlmeSgpO1xuICAgICAgfSk7XG4gICAgICBpdChgc2hvdWxkIGNhbGwgaW5uZXIgZHJpdmVyJ3MgY3JlYXRlU2Vzc2lvbiB3aXRoIGRlc2lyZWQgYW5kIGRlZmF1bHQgY2FwYWJpbGl0aWVzIHdpdGhvdXQgb3ZlcnJpZGluZyBjYXBzYCwgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBhIGRlZmF1bHQgY2FwYWJpbGl0eSB3aXRoIHRoZSBzYW1lIGtleSBhcyBhIGRlc2lyZWQgY2FwYWJpbGl0eVxuICAgICAgICAvLyBzaG91bGQgZG8gbm90aGluZ1xuICAgICAgICBsZXQgZGVmYXVsdENhcHMgPSB7cGxhdGZvcm1OYW1lOiAnRXJzYXR6J307XG4gICAgICAgIGFwcGl1bS5hcmdzLmRlZmF1bHRDYXBhYmlsaXRpZXMgPSBkZWZhdWx0Q2FwcztcbiAgICAgICAgbW9ja0Zha2VEcml2ZXIuZXhwZWN0cygnY3JlYXRlU2Vzc2lvbicpXG4gICAgICAgICAgLm9uY2UoKS53aXRoQXJncyhudWxsLCBudWxsLCBXM0NfQ0FQUylcbiAgICAgICAgICAucmV0dXJucyhbU0VTU0lPTl9JRCwgcmVtb3ZlQXBwaXVtUHJlZml4ZXMoVzNDX1BSRUZJWEVEX0NBUFMpXSk7XG4gICAgICAgIGF3YWl0IGFwcGl1bS5jcmVhdGVTZXNzaW9uKG51bGwsIG51bGwsIFczQ19DQVBTKTtcbiAgICAgICAgbW9ja0Zha2VEcml2ZXIudmVyaWZ5KCk7XG4gICAgICB9KTtcbiAgICAgIGl0KCdzaG91bGQga2lsbCBhbGwgb3RoZXIgc2Vzc2lvbnMgaWYgc2Vzc2lvbk92ZXJyaWRlIGlzIG9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBhcHBpdW0uYXJncy5zZXNzaW9uT3ZlcnJpZGUgPSB0cnVlO1xuXG4gICAgICAgIC8vIG1vY2sgdGhyZWUgc2Vzc2lvbnMgdGhhdCBzaG91bGQgYmUgcmVtb3ZlZCB3aGVuIHRoZSBuZXcgb25lIGlzIGNyZWF0ZWRcbiAgICAgICAgbGV0IGZha2VEcml2ZXJzID0gW1xuICAgICAgICAgIG5ldyBGYWtlRHJpdmVyKCksXG4gICAgICAgICAgbmV3IEZha2VEcml2ZXIoKSxcbiAgICAgICAgICBuZXcgRmFrZURyaXZlcigpLFxuICAgICAgICBdO1xuICAgICAgICBsZXQgbW9ja0Zha2VEcml2ZXJzID0gXy5tYXAoZmFrZURyaXZlcnMsIChmZCkgPT4gc2lub24ubW9jayhmZCkpO1xuICAgICAgICBtb2NrRmFrZURyaXZlcnNbMF0uZXhwZWN0cygnZGVsZXRlU2Vzc2lvbicpXG4gICAgICAgICAgLm9uY2UoKTtcbiAgICAgICAgbW9ja0Zha2VEcml2ZXJzWzFdLmV4cGVjdHMoJ2RlbGV0ZVNlc3Npb24nKVxuICAgICAgICAgIC5vbmNlKClcbiAgICAgICAgICAudGhyb3dzKCdDYW5ub3Qgc2h1dCBkb3duIEFuZHJvaWQgZHJpdmVyOyBpdCBoYXMgYWxyZWFkeSBzaHV0IGRvd24nKTtcbiAgICAgICAgbW9ja0Zha2VEcml2ZXJzWzJdLmV4cGVjdHMoJ2RlbGV0ZVNlc3Npb24nKVxuICAgICAgICAgIC5vbmNlKCk7XG4gICAgICAgIGFwcGl1bS5zZXNzaW9uc1snYWJjLTEyMy14eXonXSA9IGZha2VEcml2ZXJzWzBdO1xuICAgICAgICBhcHBpdW0uc2Vzc2lvbnNbJ3h5ei0zMjEtYWJjJ10gPSBmYWtlRHJpdmVyc1sxXTtcbiAgICAgICAgYXBwaXVtLnNlc3Npb25zWycxMjMtYWJjLXh5eiddID0gZmFrZURyaXZlcnNbMl07XG5cbiAgICAgICAgbGV0IHNlc3Npb25zID0gYXdhaXQgYXBwaXVtLmdldFNlc3Npb25zKCk7XG4gICAgICAgIHNlc3Npb25zLnNob3VsZC5oYXZlLmxlbmd0aCgzKTtcblxuICAgICAgICBtb2NrRmFrZURyaXZlci5leHBlY3RzKCdjcmVhdGVTZXNzaW9uJylcbiAgICAgICAgICAub25jZSgpLndpdGhFeGFjdEFyZ3MobnVsbCwgbnVsbCwgVzNDX0NBUFMsIFtdKVxuICAgICAgICAgIC5yZXR1cm5zKFtTRVNTSU9OX0lELCByZW1vdmVBcHBpdW1QcmVmaXhlcyhXM0NfUFJFRklYRURfQ0FQUyldKTtcbiAgICAgICAgYXdhaXQgYXBwaXVtLmNyZWF0ZVNlc3Npb24obnVsbCwgbnVsbCwgVzNDX0NBUFMpO1xuXG4gICAgICAgIHNlc3Npb25zID0gYXdhaXQgYXBwaXVtLmdldFNlc3Npb25zKCk7XG4gICAgICAgIHNlc3Npb25zLnNob3VsZC5oYXZlLmxlbmd0aCgxKTtcblxuICAgICAgICBmb3IgKGxldCBtZmQgb2YgbW9ja0Zha2VEcml2ZXJzKSB7XG4gICAgICAgICAgbWZkLnZlcmlmeSgpO1xuICAgICAgICB9XG4gICAgICAgIG1vY2tGYWtlRHJpdmVyLnZlcmlmeSgpO1xuICAgICAgfSk7XG4gICAgICBpdCgnc2hvdWxkIGNhbGwgXCJjcmVhdGVTZXNzaW9uXCIgd2l0aCBXM0MgY2FwYWJpbGl0aWVzIGFyZ3VtZW50LCBpZiBwcm92aWRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbW9ja0Zha2VEcml2ZXIuZXhwZWN0cygnY3JlYXRlU2Vzc2lvbicpXG4gICAgICAgICAgLm9uY2UoKS53aXRoQXJncyhudWxsLCB1bmRlZmluZWQsIFczQ19DQVBTKVxuICAgICAgICAgIC5yZXR1cm5zKFtTRVNTSU9OX0lELCBCQVNFX0NBUFNdKTtcbiAgICAgICAgYXdhaXQgYXBwaXVtLmNyZWF0ZVNlc3Npb24odW5kZWZpbmVkLCB1bmRlZmluZWQsIFczQ19DQVBTKTtcbiAgICAgICAgbW9ja0Zha2VEcml2ZXIudmVyaWZ5KCk7XG4gICAgICB9KTtcbiAgICAgIGl0KCdzaG91bGQgY2FsbCBcImNyZWF0ZVNlc3Npb25cIiB3aXRoIFczQyBjYXBhYmlsaXRpZXMgYXJndW1lbnQgd2l0aCBhZGRpdGlvbmFsIHByb3ZpZGVkIHBhcmFtZXRlcnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCB3M2NDYXBzID0ge1xuICAgICAgICAgIC4uLlczQ19DQVBTLFxuICAgICAgICAgIGFsd2F5c01hdGNoOiB7XG4gICAgICAgICAgICAuLi5XM0NfQ0FQUy5hbHdheXNNYXRjaCxcbiAgICAgICAgICAgICdhcHBpdW06c29tZU90aGVyUGFybSc6ICdzb21lT3RoZXJQYXJtJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICBtb2NrRmFrZURyaXZlci5leHBlY3RzKCdjcmVhdGVTZXNzaW9uJylcbiAgICAgICAgICAub25jZSgpLndpdGhBcmdzKG51bGwsIHVuZGVmaW5lZCwge1xuICAgICAgICAgICAgYWx3YXlzTWF0Y2g6IHtcbiAgICAgICAgICAgICAgLi4udzNjQ2Fwcy5hbHdheXNNYXRjaCxcbiAgICAgICAgICAgICAgJ2FwcGl1bTpzb21lT3RoZXJQYXJtJzogJ3NvbWVPdGhlclBhcm0nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGZpcnN0TWF0Y2g6IFt7fV0sXG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmV0dXJucyhbU0VTU0lPTl9JRCwgaW5zZXJ0QXBwaXVtUHJlZml4ZXMoQkFTRV9DQVBTKV0pO1xuXG4gICAgICAgIGF3YWl0IGFwcGl1bS5jcmVhdGVTZXNzaW9uKHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB3M2NDYXBzKTtcbiAgICAgICAgbW9ja0Zha2VEcml2ZXIudmVyaWZ5KCk7XG4gICAgICB9KTtcbiAgICAgIGl0KCdzaG91bGQgbm90IGNhbGwgXCJjcmVhdGVTZXNzaW9uXCIgd2l0aCBKU09OV1AgY2FwYWJpbGl0aWVzIGlmIFczQyBoYXMgaW5jb21wbGV0ZSBjYXBhYmlsaXRpZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHczY0NhcHMgPSB7XG4gICAgICAgICAgLi4uVzNDX0NBUFMsXG4gICAgICAgICAgYWx3YXlzTWF0Y2g6IHtcbiAgICAgICAgICAgICdhcHBpdW06c29tZU90aGVyUGFybSc6ICdzb21lT3RoZXJQYXJtJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGpzb253cENhcHMgPSB7XG4gICAgICAgICAgLi4uQkFTRV9DQVBTLFxuICAgICAgICAgIGF1dG9tYXRpb25OYW1lOiAnRmFrZScsXG4gICAgICAgICAgc29tZU90aGVyUGFyYW06ICdzb21lT3RoZXJQYXJhbScsXG4gICAgICAgIH07XG5cbiAgICAgICAgbW9ja0Zha2VEcml2ZXIuZXhwZWN0cygnY3JlYXRlU2Vzc2lvbicpLm5ldmVyKCk7XG4gICAgICAgIGF3YWl0IGFwcGl1bS5jcmVhdGVTZXNzaW9uKGpzb253cENhcHMsIHVuZGVmaW5lZCwgdzNjQ2Fwcyk7XG4gICAgICAgIG1vY2tGYWtlRHJpdmVyLnZlcmlmeSgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgYXNzaWduIGFyZ3MgdG8gcHJvcGVydHkgYGNsaUFyZ3NgJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjbGFzcyBBcmdzRHJpdmVyIGV4dGVuZHMgQmFzZURyaXZlciB7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXJncyA9IHtkcml2ZXI6IHtmYWtlOiB7cmFuZG9tQXJnOiAxMjM0fX19O1xuICAgICAgICBbYXBwaXVtLCBtb2NrRmFrZURyaXZlcl0gPSBnZXREcml2ZXJBbmRGYWtlRHJpdmVyKGFyZ3MsIEFyZ3NEcml2ZXIpO1xuICAgICAgICBjb25zdCB7dmFsdWV9ID0gYXdhaXQgYXBwaXVtLmNyZWF0ZVNlc3Npb24odW5kZWZpbmVkLCB1bmRlZmluZWQsIFczQ19DQVBTKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBtb2NrRmFrZURyaXZlci5fZmFrZURyaXZlci5jbGlBcmdzLnNob3VsZC5lcWwoe3JhbmRvbUFyZzogMTIzNH0pO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGF3YWl0IGFwcGl1bS5kZWxldGVTZXNzaW9uKHZhbHVlWzBdKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgZGVzY3JpYmUoJ2RlbGV0ZVNlc3Npb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgYXBwaXVtO1xuICAgICAgbGV0IG1vY2tGYWtlRHJpdmVyO1xuICAgICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIFthcHBpdW0sIG1vY2tGYWtlRHJpdmVyXSA9IGdldERyaXZlckFuZEZha2VEcml2ZXIoKTtcbiAgICAgIH0pO1xuICAgICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbW9ja0Zha2VEcml2ZXIucmVzdG9yZSgpO1xuICAgICAgfSk7XG4gICAgICBpdCgnc2hvdWxkIHJlbW92ZSB0aGUgc2Vzc2lvbiBpZiBpdCBpcyBmb3VuZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbGV0IFtzZXNzaW9uSWRdID0gKGF3YWl0IGFwcGl1bS5jcmVhdGVTZXNzaW9uKG51bGwsIG51bGwsIFczQ19DQVBTKSkudmFsdWU7XG4gICAgICAgIGxldCBzZXNzaW9ucyA9IGF3YWl0IGFwcGl1bS5nZXRTZXNzaW9ucygpO1xuICAgICAgICBzZXNzaW9ucy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG4gICAgICAgIGF3YWl0IGFwcGl1bS5kZWxldGVTZXNzaW9uKHNlc3Npb25JZCk7XG4gICAgICAgIHNlc3Npb25zID0gYXdhaXQgYXBwaXVtLmdldFNlc3Npb25zKCk7XG4gICAgICAgIHNlc3Npb25zLnNob3VsZC5oYXZlLmxlbmd0aCgwKTtcbiAgICAgIH0pO1xuICAgICAgaXQoJ3Nob3VsZCBjYWxsIGlubmVyIGRyaXZlclxcJ3MgZGVsZXRlU2Vzc2lvbiBtZXRob2QnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IFtzZXNzaW9uSWRdID0gKGF3YWl0IGFwcGl1bS5jcmVhdGVTZXNzaW9uKG51bGwsIG51bGwsIFczQ19DQVBTKSkudmFsdWU7XG4gICAgICAgIG1vY2tGYWtlRHJpdmVyLmV4cGVjdHMoJ2RlbGV0ZVNlc3Npb24nKVxuICAgICAgICAgIC5vbmNlKCkud2l0aEV4YWN0QXJncyhzZXNzaW9uSWQsIFtdKVxuICAgICAgICAgIC5yZXR1cm5zKCk7XG4gICAgICAgIGF3YWl0IGFwcGl1bS5kZWxldGVTZXNzaW9uKHNlc3Npb25JZCk7XG4gICAgICAgIG1vY2tGYWtlRHJpdmVyLnZlcmlmeSgpO1xuXG4gICAgICAgIC8vIGNsZWFudXAsIHNpbmNlIHdlIGZha2VkIHRoZSBkZWxldGUgc2Vzc2lvbiBjYWxsXG4gICAgICAgIGF3YWl0IG1vY2tGYWtlRHJpdmVyLm9iamVjdC5kZWxldGVTZXNzaW9uKCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBkZXNjcmliZSgnZ2V0U2Vzc2lvbnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgYXBwaXVtLCBtb2NrRmFrZURyaXZlcjtcbiAgICAgIGxldCBzZXNzaW9ucztcbiAgICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIFthcHBpdW0sIG1vY2tGYWtlRHJpdmVyXSA9IGdldERyaXZlckFuZEZha2VEcml2ZXIoKTtcbiAgICAgIH0pO1xuICAgICAgYWZ0ZXJFYWNoKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZm9yIChsZXQgc2Vzc2lvbiBvZiBzZXNzaW9ucykge1xuICAgICAgICAgIGF3YWl0IGFwcGl1bS5kZWxldGVTZXNzaW9uKHNlc3Npb24uaWQpO1xuICAgICAgICB9XG4gICAgICAgIG1vY2tGYWtlRHJpdmVyLnJlc3RvcmUoKTtcbiAgICAgIH0pO1xuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYW4gZW1wdHkgYXJyYXkgb2Ygc2Vzc2lvbnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlc3Npb25zID0gYXdhaXQgYXBwaXVtLmdldFNlc3Npb25zKCk7XG4gICAgICAgIHNlc3Npb25zLnNob3VsZC5iZS5hbignYXJyYXknKTtcbiAgICAgICAgc2Vzc2lvbnMuc2hvdWxkLmJlLmVtcHR5O1xuICAgICAgfSk7XG4gICAgICBpdCgnc2hvdWxkIHJldHVybiBzZXNzaW9ucyBjcmVhdGVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgY2FwczEgPSB7YWx3YXlzTWF0Y2g6IHsuLi5XM0NfUFJFRklYRURfQ0FQUywgJ2FwcGl1bTpjYXAnOiAndmFsdWUnfX07XG4gICAgICAgIGxldCBjYXBzMiA9IHthbHdheXNNYXRjaDogey4uLlczQ19QUkVGSVhFRF9DQVBTLCAnYXBwaXVtOmNhcCc6ICdvdGhlciB2YWx1ZSd9fTtcbiAgICAgICAgbW9ja0Zha2VEcml2ZXIuZXhwZWN0cygnY3JlYXRlU2Vzc2lvbicpLm9uY2UoKVxuICAgICAgICAgIC5yZXR1cm5zKFsnZmFrZS1zZXNzaW9uLWlkLTEnLCByZW1vdmVBcHBpdW1QcmVmaXhlcyhjYXBzMS5hbHdheXNNYXRjaCldKTtcbiAgICAgICAgbGV0IFtzZXNzaW9uMUlkLCBzZXNzaW9uMUNhcHNdID0gKGF3YWl0IGFwcGl1bS5jcmVhdGVTZXNzaW9uKG51bGwsIG51bGwsIGNhcHMxKSkudmFsdWU7XG4gICAgICAgIG1vY2tGYWtlRHJpdmVyLmV4cGVjdHMoJ2NyZWF0ZVNlc3Npb24nKS5vbmNlKClcbiAgICAgICAgICAucmV0dXJucyhbJ2Zha2Utc2Vzc2lvbi1pZC0yJywgcmVtb3ZlQXBwaXVtUHJlZml4ZXMoY2FwczIuYWx3YXlzTWF0Y2gpXSk7XG4gICAgICAgIGxldCBbc2Vzc2lvbjJJZCwgc2Vzc2lvbjJDYXBzXSA9IChhd2FpdCBhcHBpdW0uY3JlYXRlU2Vzc2lvbihudWxsLCBudWxsLCBjYXBzMikpLnZhbHVlO1xuXG4gICAgICAgIHNlc3Npb25zID0gYXdhaXQgYXBwaXVtLmdldFNlc3Npb25zKCk7XG4gICAgICAgIHNlc3Npb25zLnNob3VsZC5iZS5hbignYXJyYXknKTtcbiAgICAgICAgc2Vzc2lvbnMuc2hvdWxkLmhhdmUubGVuZ3RoKDIpO1xuICAgICAgICBzZXNzaW9uc1swXS5pZC5zaG91bGQuZXF1YWwoc2Vzc2lvbjFJZCk7XG4gICAgICAgIHJlbW92ZUFwcGl1bVByZWZpeGVzKGNhcHMxLmFsd2F5c01hdGNoKS5zaG91bGQuZXFsKHNlc3Npb24xQ2Fwcyk7XG4gICAgICAgIHNlc3Npb25zWzFdLmlkLnNob3VsZC5lcXVhbChzZXNzaW9uMklkKTtcbiAgICAgICAgcmVtb3ZlQXBwaXVtUHJlZml4ZXMoY2FwczIuYWx3YXlzTWF0Y2gpLnNob3VsZC5lcWwoc2Vzc2lvbjJDYXBzKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIGRlc2NyaWJlKCdnZXRTdGF0dXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgYXBwaXVtO1xuICAgICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXBwaXVtID0gbmV3IEFwcGl1bURyaXZlcih7fSk7XG4gICAgICB9KTtcbiAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgc3RhdHVzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgc3RhdHVzID0gYXdhaXQgYXBwaXVtLmdldFN0YXR1cygpO1xuICAgICAgICBzdGF0dXMuYnVpbGQuc2hvdWxkLmV4aXN0O1xuICAgICAgICBzdGF0dXMuYnVpbGQudmVyc2lvbi5zaG91bGQuZXhpc3Q7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBkZXNjcmliZSgnc2Vzc2lvbkV4aXN0cycsIGZ1bmN0aW9uICgpIHtcbiAgICB9KTtcbiAgICBkZXNjcmliZSgnYXR0YWNoVW5leHBlY3RlZFNodXRkb3duSGFuZGxlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCBhcHBpdW07XG4gICAgICBsZXQgbW9ja0Zha2VEcml2ZXI7XG4gICAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgW2FwcGl1bSwgbW9ja0Zha2VEcml2ZXJdID0gZ2V0RHJpdmVyQW5kRmFrZURyaXZlcigpO1xuICAgICAgfSk7XG4gICAgICBhZnRlckVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBhd2FpdCBtb2NrRmFrZURyaXZlci5vYmplY3QuZGVsZXRlU2Vzc2lvbigpO1xuICAgICAgICBtb2NrRmFrZURyaXZlci5yZXN0b3JlKCk7XG4gICAgICAgIGFwcGl1bS5hcmdzLmRlZmF1bHRDYXBhYmlsaXRpZXMgPSB7fTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlbW92ZSBzZXNzaW9uIGlmIGlubmVyIGRyaXZlciB1bmV4cGVjdGVkbHkgZXhpdHMgd2l0aCBhbiBlcnJvcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbGV0IFtzZXNzaW9uSWQsXSA9IChhd2FpdCBhcHBpdW0uY3JlYXRlU2Vzc2lvbihudWxsLCBudWxsLCBfLmNsb25lKFczQ19DQVBTKSkpLnZhbHVlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGNvbW1hLXNwYWNpbmdcbiAgICAgICAgXy5rZXlzKGFwcGl1bS5zZXNzaW9ucykuc2hvdWxkLmNvbnRhaW4oc2Vzc2lvbklkKTtcbiAgICAgICAgYXBwaXVtLnNlc3Npb25zW3Nlc3Npb25JZF0uZXZlbnRFbWl0dGVyLmVtaXQoJ29uVW5leHBlY3RlZFNodXRkb3duJywgbmV3IEVycm9yKCdPb3BzJykpO1xuICAgICAgICAvLyBsZXQgZXZlbnQgbG9vcCBzcGluIHNvIHJlamVjdGlvbiBpcyBoYW5kbGVkXG4gICAgICAgIGF3YWl0IHNsZWVwKDEpO1xuICAgICAgICBfLmtleXMoYXBwaXVtLnNlc3Npb25zKS5zaG91bGQubm90LmNvbnRhaW4oc2Vzc2lvbklkKTtcbiAgICAgIH0pO1xuICAgICAgaXQoJ3Nob3VsZCByZW1vdmUgc2Vzc2lvbiBpZiBpbm5lciBkcml2ZXIgdW5leHBlY3RlZGx5IGV4aXRzIHdpdGggbm8gZXJyb3InLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBbc2Vzc2lvbklkLF0gPSAoYXdhaXQgYXBwaXVtLmNyZWF0ZVNlc3Npb24obnVsbCwgbnVsbCwgXy5jbG9uZShXM0NfQ0FQUykpKS52YWx1ZTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjb21tYS1zcGFjaW5nXG4gICAgICAgIF8ua2V5cyhhcHBpdW0uc2Vzc2lvbnMpLnNob3VsZC5jb250YWluKHNlc3Npb25JZCk7XG4gICAgICAgIGFwcGl1bS5zZXNzaW9uc1tzZXNzaW9uSWRdLmV2ZW50RW1pdHRlci5lbWl0KCdvblVuZXhwZWN0ZWRTaHV0ZG93bicpO1xuICAgICAgICAvLyBsZXQgZXZlbnQgbG9vcCBzcGluIHNvIHJlamVjdGlvbiBpcyBoYW5kbGVkXG4gICAgICAgIGF3YWl0IHNsZWVwKDEpO1xuICAgICAgICBfLmtleXMoYXBwaXVtLnNlc3Npb25zKS5zaG91bGQubm90LmNvbnRhaW4oc2Vzc2lvbklkKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbiAgZGVzY3JpYmUoJyNjcmVhdGVQbHVnaW5JbnN0YW5jZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgY2xhc3MgTm9BcmdzUGx1Z2luIHt9XG4gICAgTm9BcmdzUGx1Z2luLnBsdWdpbk5hbWUgPSAnbm9hcmdzJztcblxuICAgIGNsYXNzIEFyZ3NQbHVnaW4ge31cbiAgICBBcmdzUGx1Z2luLnBsdWdpbk5hbWUgPSAnYXJncyc7XG5cbiAgICBpdCgnc2hvdWxkIG5vdCBzZXQgQ0xJIGFyZ3MgaWYgbm9uZSBhcmUgc2VudCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFwcGl1bSA9IG5ldyBBcHBpdW1Ecml2ZXIoe30pO1xuICAgICAgYXBwaXVtLnBsdWdpbkNsYXNzZXMgPSBbTm9BcmdzUGx1Z2luLCBBcmdzUGx1Z2luXTtcbiAgICAgIGZvciAoY29uc3QgcGx1Z2luIG9mIGFwcGl1bS5jcmVhdGVQbHVnaW5JbnN0YW5jZXMoKSkge1xuICAgICAgICBzaG91bGQubm90LmV4aXN0KHBsdWdpbi5jbGlBcmdzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIGFkZCBjbGlBcmdzIHRvIHRoZSBwbHVnaW4gb25jZSB2YWxpZGF0ZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhcHBpdW0gPSBuZXcgQXBwaXVtRHJpdmVyKHtwbHVnaW46IHthcmdzOiB7cmFuZG9tQXJnOiAxMjM0fX19KTtcbiAgICAgIGFwcGl1bS5wbHVnaW5DbGFzc2VzID0gW0FyZ3NQbHVnaW5dO1xuICAgICAgY29uc3QgcGx1Z2luID0gYXBwaXVtLmNyZWF0ZVBsdWdpbkluc3RhbmNlcygpWzBdO1xuICAgICAgcGx1Z2luLmNsaUFyZ3Muc2hvdWxkLmVxbCh7cmFuZG9tQXJnOiAxMjM0fSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXSwiZmlsZSI6InRlc3QvZHJpdmVyLXNwZWNzLmpzIiwic291cmNlUm9vdCI6Ii4uLy4uIn0=
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
require("source-map-support/register");
|
|
6
|
+
|
|
7
|
+
var _fs = require("fs");
|
|
8
|
+
|
|
9
|
+
var _path = _interopRequireDefault(require("path"));
|
|
10
|
+
|
|
11
|
+
var _sinon = _interopRequireDefault(require("sinon"));
|
|
12
|
+
|
|
13
|
+
var _yaml = _interopRequireDefault(require("yaml"));
|
|
14
|
+
|
|
15
|
+
var _helpers = require("./helpers");
|
|
16
|
+
|
|
17
|
+
const expect = chai.expect;
|
|
18
|
+
describe('ExtensionConfigIO', function () {
|
|
19
|
+
let sandbox;
|
|
20
|
+
let yamlFixture;
|
|
21
|
+
before(async function () {
|
|
22
|
+
yamlFixture = await _fs.promises.readFile(_path.default.join(__dirname, 'fixtures', 'extensions.yaml'), 'utf8');
|
|
23
|
+
});
|
|
24
|
+
let getExtConfigIOInstance;
|
|
25
|
+
let mocks;
|
|
26
|
+
beforeEach(function () {
|
|
27
|
+
sandbox = _sinon.default.createSandbox();
|
|
28
|
+
mocks = {
|
|
29
|
+
'@appium/support': {
|
|
30
|
+
fs: {
|
|
31
|
+
readFile: sandbox.stub().resolves(yamlFixture),
|
|
32
|
+
writeFile: sandbox.stub().resolves(true)
|
|
33
|
+
},
|
|
34
|
+
mkdirp: sandbox.stub().resolves()
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
getExtConfigIOInstance = _helpers.rewiremock.proxy('../lib/ext-config-io', mocks).getExtConfigIOInstance;
|
|
38
|
+
});
|
|
39
|
+
afterEach(function () {
|
|
40
|
+
sandbox.restore();
|
|
41
|
+
getExtConfigIOInstance.cache = new Map();
|
|
42
|
+
});
|
|
43
|
+
describe('instantiation', function () {
|
|
44
|
+
describe('when called twice with the same `appiumHome` value', function () {
|
|
45
|
+
it('should return the same object both times', function () {
|
|
46
|
+
const firstInstance = getExtConfigIOInstance('/some/path');
|
|
47
|
+
const secondInstance = getExtConfigIOInstance('/some/path');
|
|
48
|
+
expect(firstInstance).to.equal(secondInstance);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
describe('when called twice with different `appiumHome` values', function () {
|
|
52
|
+
it('should return different objects', function () {
|
|
53
|
+
const firstInstance = getExtConfigIOInstance('/some/path');
|
|
54
|
+
const secondInstance = getExtConfigIOInstance('/some/other/path');
|
|
55
|
+
expect(firstInstance).to.not.equal(secondInstance);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
describe('property', function () {
|
|
60
|
+
describe('filepath', function () {
|
|
61
|
+
it('should not be writable', function () {
|
|
62
|
+
const instance = getExtConfigIOInstance('/some/path');
|
|
63
|
+
expect(() => {
|
|
64
|
+
instance.filepath = '/some/other/path';
|
|
65
|
+
}).to.throw(TypeError);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
describe('read()', function () {
|
|
70
|
+
let io;
|
|
71
|
+
beforeEach(function () {
|
|
72
|
+
io = getExtConfigIOInstance('/some/path');
|
|
73
|
+
});
|
|
74
|
+
describe('when called with a valid extension type', function () {
|
|
75
|
+
describe('when the file does not yet exist', function () {
|
|
76
|
+
beforeEach(async function () {
|
|
77
|
+
const err = new Error();
|
|
78
|
+
err.code = 'ENOENT';
|
|
79
|
+
mocks['@appium/support'].fs.readFile.rejects(err);
|
|
80
|
+
await io.read('driver');
|
|
81
|
+
});
|
|
82
|
+
it('should create a new file', function () {
|
|
83
|
+
expect(mocks['@appium/support'].fs.writeFile).to.be.calledOnceWith(io.filepath, _yaml.default.stringify({
|
|
84
|
+
drivers: {},
|
|
85
|
+
plugins: {},
|
|
86
|
+
schemaRev: 2
|
|
87
|
+
}), 'utf8');
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
describe('when the file already exists', function () {
|
|
91
|
+
beforeEach(async function () {
|
|
92
|
+
await io.read('driver');
|
|
93
|
+
});
|
|
94
|
+
it('should attempt to create the `appiumHome` directory', function () {
|
|
95
|
+
expect(mocks['@appium/support'].mkdirp).to.have.been.calledOnceWith('/some/path');
|
|
96
|
+
});
|
|
97
|
+
it('should attempt to read the file at `filepath`', function () {
|
|
98
|
+
expect(mocks['@appium/support'].fs.readFile).to.have.been.calledOnceWith(io.filepath, 'utf8');
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
describe('when called with an unknown extension type`', function () {
|
|
103
|
+
it('should reject', async function () {
|
|
104
|
+
const promise = io.read('unknown');
|
|
105
|
+
return await expect(promise).to.be.rejectedWith(TypeError, /invalid extension type/i);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
describe('when called twice with the same `extensionType`', function () {
|
|
109
|
+
it('should return the same object both times', async function () {
|
|
110
|
+
const firstInstance = await io.read('driver');
|
|
111
|
+
const secondInstance = await io.read('driver');
|
|
112
|
+
expect(firstInstance).to.equal(secondInstance);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
describe('write()', function () {
|
|
117
|
+
let io;
|
|
118
|
+
let driverData;
|
|
119
|
+
beforeEach(function () {
|
|
120
|
+
io = getExtConfigIOInstance('/some/path');
|
|
121
|
+
});
|
|
122
|
+
describe('when called after `read()`', function () {
|
|
123
|
+
beforeEach(async function () {
|
|
124
|
+
driverData = await io.read('driver');
|
|
125
|
+
});
|
|
126
|
+
describe('when called without modifying the data', function () {
|
|
127
|
+
it('should not write the file', async function () {
|
|
128
|
+
expect(await io.write()).to.be.false;
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
describe('when called after adding a property', function () {
|
|
132
|
+
beforeEach(function () {
|
|
133
|
+
driverData.foo = {
|
|
134
|
+
name: 'foo',
|
|
135
|
+
version: '1.0.0',
|
|
136
|
+
path: '/foo/path'
|
|
137
|
+
};
|
|
138
|
+
});
|
|
139
|
+
it('should write the file', async function () {
|
|
140
|
+
expect(await io.write()).to.be.true;
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
describe('when called after deleting a property', function () {
|
|
144
|
+
beforeEach(function () {
|
|
145
|
+
driverData.foo = {
|
|
146
|
+
name: 'foo',
|
|
147
|
+
version: '1.0.0',
|
|
148
|
+
path: '/foo/path'
|
|
149
|
+
};
|
|
150
|
+
io._dirty = false;
|
|
151
|
+
delete driverData.foo;
|
|
152
|
+
});
|
|
153
|
+
it('should write the file', async function () {
|
|
154
|
+
expect(await io.write()).to.be.true;
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
describe('when the config file could not be written', function () {
|
|
158
|
+
beforeEach(function () {
|
|
159
|
+
mocks['@appium/support'].fs.writeFile = sandbox.stub().rejects(new Error());
|
|
160
|
+
io._dirty = true;
|
|
161
|
+
});
|
|
162
|
+
it('should reject', async function () {
|
|
163
|
+
await expect(io.write()).to.be.rejectedWith(Error, /Appium could not parse or write/i);
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
describe('when called before `read()`', function () {
|
|
168
|
+
it('should return `false`', async function () {
|
|
169
|
+
expect(await io.write()).to.be.false;
|
|
170
|
+
});
|
|
171
|
+
describe('when called with `force: true`', function () {
|
|
172
|
+
it('should reject', async function () {
|
|
173
|
+
await expect(io.write(true)).to.be.rejectedWith(ReferenceError, 'No data to write. Call `read()` first');
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
});require('source-map-support').install();
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvZXh0LWNvbmZpZy1pby1zcGVjcy5qcyJdLCJuYW1lcyI6WyJleHBlY3QiLCJjaGFpIiwiZGVzY3JpYmUiLCJzYW5kYm94IiwieWFtbEZpeHR1cmUiLCJiZWZvcmUiLCJmcyIsInJlYWRGaWxlIiwicGF0aCIsImpvaW4iLCJfX2Rpcm5hbWUiLCJnZXRFeHRDb25maWdJT0luc3RhbmNlIiwibW9ja3MiLCJiZWZvcmVFYWNoIiwic2lub24iLCJjcmVhdGVTYW5kYm94Iiwic3R1YiIsInJlc29sdmVzIiwid3JpdGVGaWxlIiwibWtkaXJwIiwicmV3aXJlbW9jayIsInByb3h5IiwiYWZ0ZXJFYWNoIiwicmVzdG9yZSIsImNhY2hlIiwiTWFwIiwiaXQiLCJmaXJzdEluc3RhbmNlIiwic2Vjb25kSW5zdGFuY2UiLCJ0byIsImVxdWFsIiwibm90IiwiaW5zdGFuY2UiLCJmaWxlcGF0aCIsInRocm93IiwiVHlwZUVycm9yIiwiaW8iLCJlcnIiLCJFcnJvciIsImNvZGUiLCJyZWplY3RzIiwicmVhZCIsImJlIiwiY2FsbGVkT25jZVdpdGgiLCJZQU1MIiwic3RyaW5naWZ5IiwiZHJpdmVycyIsInBsdWdpbnMiLCJzY2hlbWFSZXYiLCJoYXZlIiwiYmVlbiIsInByb21pc2UiLCJyZWplY3RlZFdpdGgiLCJkcml2ZXJEYXRhIiwid3JpdGUiLCJmYWxzZSIsImZvbyIsIm5hbWUiLCJ2ZXJzaW9uIiwidHJ1ZSIsIl9kaXJ0eSIsIlJlZmVyZW5jZUVycm9yIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFFQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQSxNQUFNQSxNQUFNLEdBQUdDLElBQUksQ0FBQ0QsTUFBcEI7QUFFQUUsUUFBUSxDQUFDLG1CQUFELEVBQXNCLFlBQVk7QUFJeEMsTUFBSUMsT0FBSjtBQUdBLE1BQUlDLFdBQUo7QUFFQUMsRUFBQUEsTUFBTSxDQUFDLGtCQUFrQjtBQUN2QkQsSUFBQUEsV0FBVyxHQUFHLE1BQU1FLGFBQUdDLFFBQUgsQ0FDbEJD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QUFzREFwQyxJQUFBQSxRQUFRLENBQUMsNkJBQUQsRUFBZ0MsWUFBWTtBQUNsRHdCLE1BQUFBLEVBQUUsQ0FBQyx1QkFBRCxFQUEwQixrQkFBa0I7QUFDNUMxQixRQUFBQSxNQUFNLENBQUMsTUFBTW9DLEVBQUUsQ0FBQ2tCLEtBQUgsRUFBUCxDQUFOLENBQXlCekIsRUFBekIsQ0FBNEJhLEVBQTVCLENBQStCYSxLQUEvQjtBQUNELE9BRkMsQ0FBRjtBQUlBckQsTUFBQUEsUUFBUSxDQUFDLGdDQUFELEVBQW1DLFlBQVk7QUFDckR3QixRQUFBQSxFQUFFLENBQUMsZUFBRCxFQUFrQixrQkFBa0I7QUFDcEMsZ0JBQU0xQixNQUFNLENBQUNvQyxFQUFFLENBQUNrQixLQUFILENBQVMsSUFBVCxDQUFELENBQU4sQ0FBdUJ6QixFQUF2QixDQUEwQmEsRUFBMUIsQ0FBNkJVLFlBQTdCLENBQTBDUyxjQUExQyxFQUEwRCx1Q0FBMUQsQ0FBTjtBQUNELFNBRkMsQ0FBRjtBQUdELE9BSk8sQ0FBUjtBQUtELEtBVk8sQ0FBUjtBQVdELEdBekVPLENBQVI7QUEwRUQsQ0F2Tk8sQ0FBUiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgeyBwcm9taXNlcyBhcyBmcyB9IGZyb20gJ2ZzJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHNpbm9uIGZyb20gJ3Npbm9uJztcbmltcG9ydCBZQU1MIGZyb20gJ3lhbWwnO1xuaW1wb3J0IHsgcmV3aXJlbW9jayB9IGZyb20gJy4vaGVscGVycyc7XG5jb25zdCBleHBlY3QgPSBjaGFpLmV4cGVjdDtcblxuZGVzY3JpYmUoJ0V4dGVuc2lvbkNvbmZpZ0lPJywgZnVuY3Rpb24gKCkge1xuICAvKipcbiAgICogQHR5cGUge2ltcG9ydCgnc2lub24nKS5TaW5vblNhbmRib3h9XG4gICAqL1xuICBsZXQgc2FuZGJveDtcblxuICAvKiogQHR5cGUge3N0cmluZ30gKi9cbiAgbGV0IHlhbWxGaXh0dXJlO1xuXG4gIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgeWFtbEZpeHR1cmUgPSBhd2FpdCBmcy5yZWFkRmlsZShcbiAgICAgIHBhdGguam9pbihfX2Rpcm5hbWUsICdmaXh0dXJlcycsICdleHRlbnNpb25zLnlhbWwnKSxcbiAgICAgICd1dGY4JyxcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogQHR5cGUge3R5cGVvZiBpbXBvcnQoJy4uL2xpYi9leHQtY29uZmlnLWlvJykuZ2V0RXh0Q29uZmlnSU9JbnN0YW5jZX1cbiAgICovXG4gIGxldCBnZXRFeHRDb25maWdJT0luc3RhbmNlO1xuXG4gIGxldCBtb2NrcztcblxuICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICBzYW5kYm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuICAgIG1vY2tzID0ge1xuICAgICAgJ0BhcHBpdW0vc3VwcG9ydCc6IHtcbiAgICAgICAgZnM6IHtcbiAgICAgICAgICByZWFkRmlsZTogc2FuZGJveC5zdHViKCkucmVzb2x2ZXMoeWFtbEZpeHR1cmUpLFxuICAgICAgICAgIHdyaXRlRmlsZTogc2FuZGJveC5zdHViKCkucmVzb2x2ZXModHJ1ZSksXG4gICAgICAgIH0sXG4gICAgICAgIG1rZGlycDogc2FuZGJveC5zdHViKCkucmVzb2x2ZXMoKSxcbiAgICAgIH0sXG4gICAgfTtcbiAgICBnZXRFeHRDb25maWdJT0luc3RhbmNlID0gcmV3aXJlbW9jay5wcm94eShcbiAgICAgICcuLi9saWIvZXh0LWNvbmZpZy1pbycsXG4gICAgICBtb2NrcyxcbiAgICApLmdldEV4dENvbmZpZ0lPSW5zdGFuY2U7XG4gIH0pO1xuXG4gIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgc2FuZGJveC5yZXN0b3JlKCk7XG4gICAgZ2V0RXh0Q29uZmlnSU9JbnN0YW5jZS5jYWNoZSA9IG5ldyBNYXAoKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2luc3RhbnRpYXRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgZGVzY3JpYmUoJ3doZW4gY2FsbGVkIHR3aWNlIHdpdGggdGhlIHNhbWUgYGFwcGl1bUhvbWVgIHZhbHVlJywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gdGhlIHNhbWUgb2JqZWN0IGJvdGggdGltZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGZpcnN0SW5zdGFuY2UgPSBnZXRFeHRDb25maWdJT0luc3RhbmNlKCcvc29tZS9wYXRoJyk7XG4gICAgICAgIGNvbnN0IHNlY29uZEluc3RhbmNlID0gZ2V0RXh0Q29uZmlnSU9JbnN0YW5jZSgnL3NvbWUvcGF0aCcpO1xuICAgICAgICBleHBlY3QoZmlyc3RJbnN0YW5jZSkudG8uZXF1YWwoc2Vjb25kSW5zdGFuY2UpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnd2hlbiBjYWxsZWQgdHdpY2Ugd2l0aCBkaWZmZXJlbnQgYGFwcGl1bUhvbWVgIHZhbHVlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGRpZmZlcmVudCBvYmplY3RzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBmaXJzdEluc3RhbmNlID0gZ2V0RXh0Q29uZmlnSU9JbnN0YW5jZSgnL3NvbWUvcGF0aCcpO1xuICAgICAgICBjb25zdCBzZWNvbmRJbnN0YW5jZSA9IGdldEV4dENvbmZpZ0lPSW5zdGFuY2UoJy9zb21lL290aGVyL3BhdGgnKTtcbiAgICAgICAgZXhwZWN0KGZpcnN0SW5zdGFuY2UpLnRvLm5vdC5lcXVhbChzZWNvbmRJbnN0YW5jZSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3Byb3BlcnR5JywgZnVuY3Rpb24gKCkge1xuICAgIGRlc2NyaWJlKCdmaWxlcGF0aCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgbm90IGJlIHdyaXRhYmxlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBpbnN0YW5jZSA9IGdldEV4dENvbmZpZ0lPSW5zdGFuY2UoJy9zb21lL3BhdGgnKTtcbiAgICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgaW5zdGFuY2UuZmlsZXBhdGggPSAnL3NvbWUvb3RoZXIvcGF0aCc7XG4gICAgICAgIH0pLnRvLnRocm93KFR5cGVFcnJvcik7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3JlYWQoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAvKiogQHR5cGUge2ltcG9ydCgnLi4vbGliL2V4dC1jb25maWctaW8nKS5FeHRlbnNpb25Db25maWdJT30gKi9cbiAgICBsZXQgaW87XG5cbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGlvID0gZ2V0RXh0Q29uZmlnSU9JbnN0YW5jZSgnL3NvbWUvcGF0aCcpO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3doZW4gY2FsbGVkIHdpdGggYSB2YWxpZCBleHRlbnNpb24gdHlwZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGRlc2NyaWJlKCd3aGVuIHRoZSBmaWxlIGRvZXMgbm90IHlldCBleGlzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYmVmb3JlRWFjaChhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgLyoqIEB0eXBlIHtOb2RlSlMuRXJybm9FeGNlcHRpb259ICovXG4gICAgICAgICAgY29uc3QgZXJyID0gbmV3IEVycm9yKCk7XG4gICAgICAgICAgZXJyLmNvZGUgPSAnRU5PRU5UJztcbiAgICAgICAgICBtb2Nrc1snQGFwcGl1bS9zdXBwb3J0J10uZnMucmVhZEZpbGUucmVqZWN0cyhlcnIpO1xuICAgICAgICAgIGF3YWl0IGlvLnJlYWQoJ2RyaXZlcicpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhIG5ldyBmaWxlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGV4cGVjdChtb2Nrc1snQGFwcGl1bS9zdXBwb3J0J10uZnMud3JpdGVGaWxlKS50by5iZS5jYWxsZWRPbmNlV2l0aChcbiAgICAgICAgICAgIGlvLmZpbGVwYXRoLFxuICAgICAgICAgICAgWUFNTC5zdHJpbmdpZnkoe2RyaXZlcnM6IHt9LCBwbHVnaW5zOiB7fSwgc2NoZW1hUmV2OiAyfSksXG4gICAgICAgICAgICAndXRmOCcsXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ3doZW4gdGhlIGZpbGUgYWxyZWFkeSBleGlzdHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGJlZm9yZUVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGF3YWl0IGlvLnJlYWQoJ2RyaXZlcicpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGF0dGVtcHQgdG8gY3JlYXRlIHRoZSBgYXBwaXVtSG9tZWAgZGlyZWN0b3J5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGV4cGVjdChtb2Nrc1snQGFwcGl1bS9zdXBwb3J0J10ubWtkaXJwKS50by5oYXZlLmJlZW4uY2FsbGVkT25jZVdpdGgoXG4gICAgICAgICAgICAnL3NvbWUvcGF0aCcsXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBhdHRlbXB0IHRvIHJlYWQgdGhlIGZpbGUgYXQgYGZpbGVwYXRoYCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBleHBlY3QoXG4gICAgICAgICAgICBtb2Nrc1snQGFwcGl1bS9zdXBwb3J0J10uZnMucmVhZEZpbGUsXG4gICAgICAgICAgKS50by5oYXZlLmJlZW4uY2FsbGVkT25jZVdpdGgoaW8uZmlsZXBhdGgsICd1dGY4Jyk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnd2hlbiBjYWxsZWQgd2l0aCBhbiB1bmtub3duIGV4dGVuc2lvbiB0eXBlYCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBpby5yZWFkKCd1bmtub3duJyk7XG4gICAgICAgIHJldHVybiBhd2FpdCBleHBlY3QocHJvbWlzZSkudG8uYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgIFR5cGVFcnJvcixcbiAgICAgICAgICAvaW52YWxpZCBleHRlbnNpb24gdHlwZS9pLFxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnd2hlbiBjYWxsZWQgdHdpY2Ugd2l0aCB0aGUgc2FtZSBgZXh0ZW5zaW9uVHlwZWAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIHJldHVybiB0aGUgc2FtZSBvYmplY3QgYm90aCB0aW1lcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgZmlyc3RJbnN0YW5jZSA9IGF3YWl0IGlvLnJlYWQoJ2RyaXZlcicpO1xuICAgICAgICBjb25zdCBzZWNvbmRJbnN0YW5jZSA9IGF3YWl0IGlvLnJlYWQoJ2RyaXZlcicpO1xuICAgICAgICBleHBlY3QoZmlyc3RJbnN0YW5jZSkudG8uZXF1YWwoc2Vjb25kSW5zdGFuY2UpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd3cml0ZSgpJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBpbztcbiAgICBsZXQgZHJpdmVyRGF0YTtcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgaW8gPSBnZXRFeHRDb25maWdJT0luc3RhbmNlKCcvc29tZS9wYXRoJyk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnd2hlbiBjYWxsZWQgYWZ0ZXIgYHJlYWQoKWAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBiZWZvcmVFYWNoKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZHJpdmVyRGF0YSA9IGF3YWl0IGlvLnJlYWQoJ2RyaXZlcicpO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCd3aGVuIGNhbGxlZCB3aXRob3V0IG1vZGlmeWluZyB0aGUgZGF0YScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCBub3Qgd3JpdGUgdGhlIGZpbGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgZXhwZWN0KGF3YWl0IGlvLndyaXRlKCkpLnRvLmJlLmZhbHNlO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnd2hlbiBjYWxsZWQgYWZ0ZXIgYWRkaW5nIGEgcHJvcGVydHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGRyaXZlckRhdGEuZm9vID0ge1xuICAgICAgICAgICAgbmFtZTogJ2ZvbycsXG4gICAgICAgICAgICB2ZXJzaW9uOiAnMS4wLjAnLFxuICAgICAgICAgICAgcGF0aDogJy9mb28vcGF0aCcsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCB3cml0ZSB0aGUgZmlsZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBleHBlY3QoYXdhaXQgaW8ud3JpdGUoKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ3doZW4gY2FsbGVkIGFmdGVyIGRlbGV0aW5nIGEgcHJvcGVydHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGRyaXZlckRhdGEuZm9vID0ge1xuICAgICAgICAgICAgbmFtZTogJ2ZvbycsXG4gICAgICAgICAgICB2ZXJzaW9uOiAnMS4wLjAnLFxuICAgICAgICAgICAgcGF0aDogJy9mb28vcGF0aCcsXG4gICAgICAgICAgfTtcbiAgICAgICAgICBpby5fZGlydHkgPSBmYWxzZTtcbiAgICAgICAgICBkZWxldGUgZHJpdmVyRGF0YS5mb287XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgd3JpdGUgdGhlIGZpbGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgZXhwZWN0KGF3YWl0IGlvLndyaXRlKCkpLnRvLmJlLnRydWU7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCd3aGVuIHRoZSBjb25maWcgZmlsZSBjb3VsZCBub3QgYmUgd3JpdHRlbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgbW9ja3NbJ0BhcHBpdW0vc3VwcG9ydCddLmZzLndyaXRlRmlsZSA9IHNhbmRib3guc3R1YigpLnJlamVjdHMobmV3IEVycm9yKCkpO1xuICAgICAgICAgIGlvLl9kaXJ0eSA9IHRydWU7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmVqZWN0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGF3YWl0IGV4cGVjdChpby53cml0ZSgpKS50by5iZS5yZWplY3RlZFdpdGgoRXJyb3IsIC9BcHBpdW0gY291bGQgbm90IHBhcnNlIG9yIHdyaXRlL2kpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnd2hlbiBjYWxsZWQgYmVmb3JlIGByZWFkKClgJywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYGZhbHNlYCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZXhwZWN0KGF3YWl0IGlvLndyaXRlKCkpLnRvLmJlLmZhbHNlO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCd3aGVuIGNhbGxlZCB3aXRoIGBmb3JjZTogdHJ1ZWAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmVqZWN0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGF3YWl0IGV4cGVjdChpby53cml0ZSh0cnVlKSkudG8uYmUucmVqZWN0ZWRXaXRoKFJlZmVyZW5jZUVycm9yLCAnTm8gZGF0YSB0byB3cml0ZS4gQ2FsbCBgcmVhZCgpYCBmaXJzdCcpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl0sImZpbGUiOiJ0ZXN0L2V4dC1jb25maWctaW8tc3BlY3MuanMiLCJzb3VyY2VSb290IjoiLi4vLi4ifQ==
|