@appium/driver-test-support 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,389 +1,417 @@
1
1
  "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
- Object.defineProperty(exports, "__esModule", {
6
- value: true
7
- });
8
- exports.createSessionHelpers = createSessionHelpers;
9
- exports.driverE2ETestSuite = driverE2ETestSuite;
10
-
11
- require("source-map-support/register");
12
-
13
- var _lodash = _interopRequireDefault(require("lodash"));
14
-
15
- var _driver = require("appium/driver");
16
-
17
- var _axios = _interopRequireDefault(require("axios"));
18
-
19
- var _bluebird = _interopRequireDefault(require("bluebird"));
20
-
21
- var _helpers = require("./helpers");
22
-
23
- var _chai = _interopRequireDefault(require("chai"));
24
-
25
- var _sinon = _interopRequireDefault(require("sinon"));
26
-
27
- const should = _chai.default.should();
28
-
29
- function createSessionHelpers(port, address = _helpers.TEST_HOST) {
30
- const createAppiumTestURL = (0, _helpers.createAppiumURL)(address, port);
31
- const createSessionURL = createAppiumTestURL(_lodash.default, '');
32
- const newSessionURL = createAppiumTestURL('', 'session');
33
- return {
34
- newSessionURL,
35
- createAppiumTestURL,
36
- postCommand: async (sessionId, cmdName, data = {}, config = {}) => {
37
- var _response$data;
38
-
39
- const url = createAppiumTestURL(sessionId, cmdName);
40
- const response = await _axios.default.post(url, data, config);
41
- return (_response$data = response.data) === null || _response$data === void 0 ? void 0 : _response$data.value;
42
- },
43
- getCommand: async (sessionIdOrCmdName, cmdNameOrConfig, config = {}) => {
44
- var _response$data2;
45
-
46
- if (!_lodash.default.isString(cmdNameOrConfig)) {
47
- config = cmdNameOrConfig;
48
- cmdNameOrConfig = sessionIdOrCmdName;
49
- sessionIdOrCmdName = '';
50
- }
51
-
52
- const response = await (0, _axios.default)({
53
- url: createAppiumTestURL(sessionIdOrCmdName, cmdNameOrConfig),
54
- validateStatus: null,
55
- ...config
56
- });
57
- return (_response$data2 = response.data) === null || _response$data2 === void 0 ? void 0 : _response$data2.value;
58
- },
59
- startSession: async (data, config = {}) => {
60
- var _response$data3;
61
-
62
- data = _lodash.default.defaultsDeep(data, {
63
- capabilities: {
64
- alwaysMatch: {},
65
- firstMatch: [{}]
66
- }
67
- });
68
- const response = await _axios.default.post(newSessionURL, data, config);
69
- return (_response$data3 = response.data) === null || _response$data3 === void 0 ? void 0 : _response$data3.value;
70
- },
71
- endSession: async sessionId => await _axios.default.delete(createSessionURL(sessionId), {
72
- validateStatus: null
73
- }),
74
- getSession: async sessionId => {
75
- var _response$data4;
76
-
77
- const response = await (0, _axios.default)({
78
- url: createSessionURL(sessionId),
79
- validateStatus: null
80
- });
81
- return (_response$data4 = response.data) === null || _response$data4 === void 0 ? void 0 : _response$data4.value;
82
- }
83
- };
84
- }
85
-
86
- function driverE2ETestSuite(DriverClass, defaultCaps = {}) {
87
- let address = defaultCaps['appium:address'] ?? _helpers.TEST_HOST;
88
- let port = defaultCaps['appium:port'];
89
- const className = DriverClass.name || '(unknown driver)';
90
- describe(`BaseDriver E2E (as ${className})`, function () {
91
- let baseServer;
92
- let d;
93
- let newSessionURL;
94
- let startSession;
95
- let getSession;
96
- let endSession;
97
- let getCommand;
98
- let postCommand;
99
- before(async function () {
100
- port = port ?? (await (0, _helpers.getTestPort)());
101
- defaultCaps = { ...defaultCaps,
102
- 'appium:port': port
103
- };
104
- d = new DriverClass({
105
- port,
106
- address
107
- });
108
- baseServer = await (0, _driver.server)({
109
- routeConfiguringFunction: (0, _driver.routeConfiguringFunction)(d),
110
- port,
111
- hostname: address,
112
- cliArgs: {}
113
- });
114
- ({
115
- startSession,
116
- getSession,
117
- endSession,
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.driverE2ETestSuite = exports.createSessionHelpers = void 0;
7
+ const lodash_1 = __importDefault(require("lodash"));
8
+ const driver_1 = require("appium/driver");
9
+ const axios_1 = __importDefault(require("axios"));
10
+ const bluebird_1 = __importDefault(require("bluebird"));
11
+ const helpers_1 = require("./helpers");
12
+ const chai_1 = __importDefault(require("chai"));
13
+ const sinon_1 = __importDefault(require("sinon"));
14
+ const should = chai_1.default.should();
15
+ /**
16
+ * Creates some helper functions for E2E tests to manage sessions.
17
+ * @template [CommandData=unknown]
18
+ * @template [ResponseData=any]
19
+ * @param {number} port - Port on which the server is running. Typically this will be retrieved via `get-port` beforehand
20
+ * @param {string} [address] - Address/host on which the server is running. Defaults to {@linkcode TEST_HOST}
21
+ * @returns {SessionHelpers<CommandData, ResponseData>}
22
+ */
23
+ function createSessionHelpers(port, address = helpers_1.TEST_HOST) {
24
+ const createAppiumTestURL =
25
+ /** @type {import('lodash').CurriedFunction2<string,string,string>} */ ((0, helpers_1.createAppiumURL)(address, port));
26
+ const createSessionURL = createAppiumTestURL(lodash_1.default, '');
27
+ const newSessionURL = createAppiumTestURL('', 'session');
28
+ return /** @type {SessionHelpers<CommandData, ResponseData>} */ ({
118
29
  newSessionURL,
119
- getCommand,
120
- postCommand
121
- } = createSessionHelpers(port, address));
122
- });
123
- after(async function () {
124
- await baseServer.close();
125
- });
126
- describe('session handling', function () {
127
- it('should handle idempotency while creating sessions', async function () {
128
- const sessionIds = [];
129
- let times = 0;
130
-
131
- do {
132
- const {
133
- sessionId
134
- } = await startSession({
135
- capabilities: {
136
- alwaysMatch: defaultCaps
30
+ createAppiumTestURL,
31
+ /**
32
+ *
33
+ * @param {string} sessionId
34
+ * @param {string} cmdName
35
+ * @param {any} [data]
36
+ * @param {AxiosRequestConfig} [config]
37
+ * @returns {Promise<any>}
38
+ */
39
+ postCommand: async (sessionId, cmdName, data = {}, config = {}) => {
40
+ const url = createAppiumTestURL(sessionId, cmdName);
41
+ const response = await axios_1.default.post(url, data, config);
42
+ return response.data?.value;
43
+ },
44
+ /**
45
+ *
46
+ * @param {string} sessionIdOrCmdName
47
+ * @param {string|AxiosRequestConfig} cmdNameOrConfig
48
+ * @param {AxiosRequestConfig} [config]
49
+ * @returns {Promise<any>}
50
+ */
51
+ getCommand: async (sessionIdOrCmdName, cmdNameOrConfig, config = {}) => {
52
+ if (!lodash_1.default.isString(cmdNameOrConfig)) {
53
+ config = cmdNameOrConfig;
54
+ cmdNameOrConfig = sessionIdOrCmdName;
55
+ sessionIdOrCmdName = '';
137
56
  }
138
- }, {
139
- headers: {
140
- 'X-Idempotency-Key': '123456'
141
- },
142
- simple: false,
143
- resolveWithFullResponse: true
144
- });
145
- sessionIds.push(sessionId);
146
- times++;
147
- } while (times < 2);
148
-
149
- _lodash.default.uniq(sessionIds).length.should.equal(1);
150
-
151
- const {
152
- status,
153
- data
154
- } = await endSession(sessionIds[0]);
155
- status.should.equal(200);
156
- should.equal(data.value, null);
157
- });
158
- it('should handle idempotency while creating parallel sessions', async function () {
159
- const reqs = [];
160
- let times = 0;
161
-
162
- do {
163
- reqs.push(startSession({
164
- capabilities: {
165
- alwaysMatch: defaultCaps
166
- }
167
- }, {
168
- headers: {
169
- 'X-Idempotency-Key': '12345'
170
- }
171
- }));
172
- times++;
173
- } while (times < 2);
174
-
175
- const sessionIds = _lodash.default.map(await _bluebird.default.all(reqs), 'sessionId');
176
-
177
- _lodash.default.uniq(sessionIds).length.should.equal(1);
178
-
179
- const {
180
- status,
181
- data
182
- } = await endSession(sessionIds[0]);
183
- status.should.equal(200);
184
- should.equal(data.value, null);
185
- });
186
- it('should create session and retrieve a session id, then delete it', async function () {
187
- let {
188
- status,
189
- data
190
- } = await _axios.default.post(newSessionURL, {
191
- capabilities: {
192
- alwaysMatch: defaultCaps
193
- }
194
- });
195
- status.should.equal(200);
196
- should.exist(data.value.sessionId);
197
- data.value.capabilities.platformName.should.equal(defaultCaps.platformName);
198
- data.value.capabilities.deviceName.should.equal(defaultCaps['appium:deviceName']);
199
- ({
200
- status,
201
- data
202
- } = await endSession(d.sessionId));
203
- status.should.equal(200);
204
- should.equal(data.value, null);
205
- should.equal(d.sessionId, null);
206
- });
57
+ const response = await (0, axios_1.default)({
58
+ url: createAppiumTestURL(sessionIdOrCmdName, cmdNameOrConfig),
59
+ validateStatus: null,
60
+ ...config,
61
+ });
62
+ return response.data?.value;
63
+ },
64
+ /**
65
+ *
66
+ * @param {NewSessionData} data
67
+ * @param {AxiosRequestConfig} [config]
68
+ */
69
+ startSession: async (data, config = {}) => {
70
+ data = lodash_1.default.defaultsDeep(data, {
71
+ capabilities: {
72
+ alwaysMatch: {},
73
+ firstMatch: [{}],
74
+ },
75
+ });
76
+ const response = await axios_1.default.post(newSessionURL, data, config);
77
+ return response.data?.value;
78
+ },
79
+ /**
80
+ *
81
+ * @param {string} sessionId
82
+ */
83
+ endSession: async (sessionId) => await axios_1.default.delete(createSessionURL(sessionId), {
84
+ validateStatus: null,
85
+ }),
86
+ /**
87
+ * @param {string} sessionId
88
+ * @returns {Promise<any>}
89
+ */
90
+ getSession: async (sessionId) => {
91
+ const response = await (0, axios_1.default)({
92
+ url: createSessionURL(sessionId),
93
+ validateStatus: null,
94
+ });
95
+ return response.data?.value;
96
+ },
207
97
  });
208
- it.skip('should throw NYI for commands not implemented', async function () {});
209
- describe('command timeouts', function () {
210
- let originalFindElement, originalFindElements;
211
-
212
- async function startTimeoutSession(timeout) {
213
- const caps = _lodash.default.cloneDeep(defaultCaps);
214
-
215
- caps['appium:newCommandTimeout'] = timeout;
216
- return await startSession({
217
- capabilities: {
218
- alwaysMatch: caps
219
- }
220
- });
221
- }
222
-
223
- before(function () {
224
- originalFindElement = d.findElement;
225
-
226
- d.findElement = function () {
227
- return 'foo';
228
- }.bind(d);
229
-
230
- originalFindElements = d.findElements;
231
-
232
- d.findElements = async function () {
233
- await _bluebird.default.delay(200);
234
- return ['foo'];
235
- }.bind(d);
236
- });
237
- after(function () {
238
- d.findElement = originalFindElement;
239
- d.findElements = originalFindElements;
240
- });
241
- it('should set a default commandTimeout', async function () {
242
- let newSession = await startTimeoutSession();
243
- d.newCommandTimeoutMs.should.be.above(0);
244
- await endSession(newSession.sessionId);
245
- });
246
- it('should timeout on commands using commandTimeout cap', async function () {
247
- let newSession = await startTimeoutSession(0.25);
248
- const sessionId = d.sessionId;
249
- await postCommand(sessionId, 'element', {
250
- using: 'name',
251
- value: 'foo'
252
- });
253
- await _bluebird.default.delay(400);
254
- const value = await getSession(sessionId);
255
- should.equal(value.error, 'invalid session id');
256
- should.equal(d.sessionId, null);
257
- const resp = (await endSession(newSession.sessionId)).data.value;
258
- should.equal(resp === null || resp === void 0 ? void 0 : resp.error, 'invalid session id');
259
- });
260
- it('should not timeout with commandTimeout of false', async function () {
261
- let newSession = await startTimeoutSession(0.1);
262
- let start = Date.now();
263
- const value = await postCommand(d.sessionId, 'elements', {
264
- using: 'name',
265
- value: 'foo'
266
- });
267
- (Date.now() - start).should.be.above(150);
268
- value.should.eql(['foo']);
269
- await endSession(newSession.sessionId);
270
- });
271
- it('should not timeout with commandTimeout of 0', async function () {
272
- var _value$platformName;
273
-
274
- d.newCommandTimeoutMs = 2;
275
- let newSession = await startTimeoutSession(0);
276
- await postCommand(d.sessionId, 'element', {
277
- using: 'name',
278
- value: 'foo'
279
- });
280
- await _bluebird.default.delay(400);
281
- const value = await getSession(d.sessionId);
282
- (_value$platformName = value.platformName) === null || _value$platformName === void 0 ? void 0 : _value$platformName.should.equal(defaultCaps.platformName);
283
- const resp = (await endSession(newSession.sessionId)).data.value;
284
- should.equal(resp, null);
285
- d.newCommandTimeoutMs = 60 * 1000;
286
- });
287
- it('should not timeout if its just the command taking awhile', async function () {
288
- let newSession = await startTimeoutSession(0.25);
289
- const {
290
- sessionId
291
- } = d;
292
- await postCommand(d.sessionId, 'element', {
293
- using: 'name',
294
- value: 'foo'
98
+ }
99
+ exports.createSessionHelpers = createSessionHelpers;
100
+ /**
101
+ * Creates E2E test suites for a driver.
102
+ * @template {Driver} P
103
+ * @param {DriverClass<P>} DriverClass
104
+ * @param {Partial<BaseNSCapabilities>} [defaultCaps]
105
+ */
106
+ function driverE2ETestSuite(DriverClass, defaultCaps = {}) {
107
+ let address = defaultCaps['appium:address'] ?? helpers_1.TEST_HOST;
108
+ let port = defaultCaps['appium:port'];
109
+ const className = DriverClass.name || '(unknown driver)';
110
+ describe(`BaseDriver E2E (as ${className})`, function () {
111
+ let baseServer;
112
+ /** @type {P} */
113
+ let d;
114
+ /**
115
+ * This URL creates a new session
116
+ * @type {string}
117
+ **/
118
+ let newSessionURL;
119
+ /** @type {SessionHelpers['startSession']} */
120
+ let startSession;
121
+ /** @type {SessionHelpers['getSession']} */
122
+ let getSession;
123
+ /** @type {SessionHelpers['endSession']} */
124
+ let endSession;
125
+ /** @type {SessionHelpers['getCommand']} */
126
+ let getCommand;
127
+ /** @type {SessionHelpers['postCommand']} */
128
+ let postCommand;
129
+ before(async function () {
130
+ port = port ?? (await (0, helpers_1.getTestPort)());
131
+ defaultCaps = { ...defaultCaps };
132
+ d = new DriverClass({ port, address });
133
+ baseServer = await (0, driver_1.server)({
134
+ routeConfiguringFunction: (0, driver_1.routeConfiguringFunction)(d),
135
+ port,
136
+ hostname: address,
137
+ // @ts-expect-error
138
+ cliArgs: {},
139
+ });
140
+ ({ startSession, getSession, endSession, newSessionURL, getCommand, postCommand } =
141
+ createSessionHelpers(port, address));
295
142
  });
296
- await _bluebird.default.delay(400);
297
- const value = await getSession(sessionId);
298
- value.error.should.equal('invalid session id');
299
- should.equal(d.sessionId, null);
300
- const resp = (await endSession(newSession.sessionId)).data.value;
301
- resp.error.should.equal('invalid session id');
302
- });
303
- it('should not have a timer running before or after a session', async function () {
304
- should.not.exist(d.noCommandTimer);
305
- let newSession = await startTimeoutSession(0.25);
306
- newSession.sessionId.should.equal(d.sessionId);
307
- should.exist(d.noCommandTimer);
308
- await endSession(newSession.sessionId);
309
- should.not.exist(d.noCommandTimer);
310
- });
311
- });
312
- describe('settings api', function () {
313
- before(function () {
314
- d.settings = new _driver.DeviceSettings({
315
- ignoreUnimportantViews: false
143
+ after(async function () {
144
+ await baseServer.close();
316
145
  });
317
- });
318
- it('should be able to get settings object', function () {
319
- d.settings.getSettings().ignoreUnimportantViews.should.be.false;
320
- });
321
- it('should not reject when `updateSettings` method is not provided', async function () {
322
- await d.settings.update({
323
- ignoreUnimportantViews: true
324
- }).should.not.be.rejected;
325
- });
326
- it('should reject for invalid update object', async function () {
327
- await d.settings.update('invalid json').should.be.rejectedWith('JSON');
328
- });
329
- });
330
- describe('unexpected exits', function () {
331
- let sandbox;
332
- beforeEach(function () {
333
- sandbox = _sinon.default.createSandbox();
334
- });
335
- afterEach(function () {
336
- sandbox.restore();
337
- });
338
- it('should reject a current command when the driver crashes', async function () {
339
- sandbox.stub(d, 'getStatus').callsFake(async function () {
340
- await _bluebird.default.delay(5000);
146
+ describe('session handling', function () {
147
+ it('should handle idempotency while creating sessions', async function () {
148
+ const sessionIds = [];
149
+ let times = 0;
150
+ do {
151
+ const { sessionId } = await startSession({
152
+ capabilities: { alwaysMatch: defaultCaps },
153
+ }, {
154
+ headers: {
155
+ 'X-Idempotency-Key': '123456',
156
+ },
157
+ // XXX: I'm not sure what these are, as they are not documented axios options,
158
+ // nor are they mentioned in our source
159
+ // @ts-expect-error
160
+ simple: false,
161
+ resolveWithFullResponse: true,
162
+ });
163
+ sessionIds.push(sessionId);
164
+ times++;
165
+ } while (times < 2);
166
+ lodash_1.default.uniq(sessionIds).length.should.equal(1);
167
+ const { status, data } = await endSession(sessionIds[0]);
168
+ status.should.equal(200);
169
+ should.equal(data.value, null);
170
+ });
171
+ it('should handle idempotency while creating parallel sessions', async function () {
172
+ const reqs = [];
173
+ let times = 0;
174
+ do {
175
+ reqs.push(startSession({
176
+ capabilities: {
177
+ alwaysMatch: defaultCaps,
178
+ },
179
+ }, {
180
+ headers: {
181
+ 'X-Idempotency-Key': '12345',
182
+ },
183
+ }));
184
+ times++;
185
+ } while (times < 2);
186
+ const sessionIds = lodash_1.default.map(await bluebird_1.default.all(reqs), 'sessionId');
187
+ lodash_1.default.uniq(sessionIds).length.should.equal(1);
188
+ const { status, data } = await endSession(sessionIds[0]);
189
+ status.should.equal(200);
190
+ should.equal(data.value, null);
191
+ });
192
+ it('should create session and retrieve a session id, then delete it', async function () {
193
+ let { status, data } = await axios_1.default.post(newSessionURL, {
194
+ capabilities: {
195
+ alwaysMatch: defaultCaps,
196
+ },
197
+ });
198
+ status.should.equal(200);
199
+ should.exist(data.value.sessionId);
200
+ data.value.capabilities.platformName.should.equal(defaultCaps.platformName);
201
+ data.value.capabilities.deviceName.should.equal(defaultCaps['appium:deviceName']);
202
+ ({ status, data } = await endSession(/** @type {string} */ (d.sessionId)));
203
+ status.should.equal(200);
204
+ should.equal(data.value, null);
205
+ should.equal(d.sessionId, null);
206
+ });
341
207
  });
342
- const reqPromise = getCommand('status', {
343
- validateStatus: null
208
+ it.skip('should throw NYI for commands not implemented', async function () { });
209
+ describe('command timeouts', function () {
210
+ let originalFindElement, originalFindElements;
211
+ /**
212
+ * @param {number} [timeout]
213
+ */
214
+ async function startTimeoutSession(timeout) {
215
+ const caps = lodash_1.default.cloneDeep(defaultCaps);
216
+ caps['appium:newCommandTimeout'] = timeout;
217
+ return await startSession({ capabilities: { alwaysMatch: caps } });
218
+ }
219
+ before(function () {
220
+ originalFindElement = d.findElement;
221
+ d.findElement = function () {
222
+ return 'foo';
223
+ }.bind(d);
224
+ originalFindElements = d.findElements;
225
+ d.findElements = async function () {
226
+ await bluebird_1.default.delay(200);
227
+ return ['foo'];
228
+ }.bind(d);
229
+ });
230
+ after(function () {
231
+ d.findElement = originalFindElement;
232
+ d.findElements = originalFindElements;
233
+ });
234
+ it('should set a default commandTimeout', async function () {
235
+ let newSession = await startTimeoutSession();
236
+ d.newCommandTimeoutMs.should.be.above(0);
237
+ await endSession(newSession.sessionId);
238
+ });
239
+ it('should timeout on commands using commandTimeout cap', async function () {
240
+ let newSession = await startTimeoutSession(0.25);
241
+ const sessionId = /** @type {string} */ (d.sessionId);
242
+ await postCommand(sessionId, 'element', {
243
+ using: 'name',
244
+ value: 'foo',
245
+ });
246
+ await bluebird_1.default.delay(400);
247
+ const value = await getSession(sessionId);
248
+ should.equal(value.error, 'invalid session id');
249
+ should.equal(d.sessionId, null);
250
+ const resp = (await endSession(newSession.sessionId)).data.value;
251
+ should.equal(resp?.error, 'invalid session id');
252
+ });
253
+ it('should not timeout with commandTimeout of false', async function () {
254
+ let newSession = await startTimeoutSession(0.1);
255
+ let start = Date.now();
256
+ const value = await postCommand(/** @type {string} */ (d.sessionId), 'elements', {
257
+ using: 'name',
258
+ value: 'foo',
259
+ });
260
+ (Date.now() - start).should.be.above(150);
261
+ value.should.eql(['foo']);
262
+ await endSession(newSession.sessionId);
263
+ });
264
+ it('should not timeout with commandTimeout of 0', async function () {
265
+ d.newCommandTimeoutMs = 2;
266
+ let newSession = await startTimeoutSession(0);
267
+ await postCommand(/** @type {string} */ (d.sessionId), 'element', {
268
+ using: 'name',
269
+ value: 'foo',
270
+ });
271
+ await bluebird_1.default.delay(400);
272
+ const value = await getSession(/** @type {string} */ (d.sessionId));
273
+ value.platformName?.should.equal(defaultCaps.platformName);
274
+ const resp = (await endSession(newSession.sessionId)).data.value;
275
+ should.equal(resp, null);
276
+ d.newCommandTimeoutMs = 60 * 1000;
277
+ });
278
+ it('should not timeout if its just the command taking awhile', async function () {
279
+ let newSession = await startTimeoutSession(0.25);
280
+ // XXX: race condition: we must build this URL before ...something happens...
281
+ // which causes `d.sessionId` to be missing
282
+ const { sessionId } = d;
283
+ await postCommand(/** @type {string} */ (d.sessionId), 'element', {
284
+ using: 'name',
285
+ value: 'foo',
286
+ });
287
+ await bluebird_1.default.delay(400);
288
+ const value = await getSession(/** @type {string} */ (sessionId));
289
+ /** @type {string} */ (value.error).should.equal('invalid session id');
290
+ should.equal(d.sessionId, null);
291
+ const resp = (await endSession(newSession.sessionId)).data.value;
292
+ /** @type {string} */ ( /** @type { {error: string} } */(resp).error).should.equal('invalid session id');
293
+ });
294
+ it('should not have a timer running before or after a session', async function () {
295
+ // @ts-expect-error
296
+ should.not.exist(d.noCommandTimer);
297
+ let newSession = await startTimeoutSession(0.25);
298
+ newSession.sessionId.should.equal(d.sessionId);
299
+ // @ts-expect-error
300
+ should.exist(d.noCommandTimer);
301
+ await endSession(newSession.sessionId);
302
+ // @ts-expect-error
303
+ should.not.exist(d.noCommandTimer);
304
+ });
344
305
  });
345
- await _bluebird.default.delay(100);
346
- const shutdownEventPromise = new _bluebird.default((resolve, reject) => {
347
- setTimeout(() => reject(new Error('onUnexpectedShutdown event is expected to be fired within 5 seconds timeout')), 5000);
348
- d.onUnexpectedShutdown(resolve);
306
+ describe('settings api', function () {
307
+ before(function () {
308
+ d.settings = new driver_1.DeviceSettings({ ignoreUnimportantViews: false });
309
+ });
310
+ it('should be able to get settings object', function () {
311
+ d.settings.getSettings().ignoreUnimportantViews.should.be.false;
312
+ });
313
+ it('should not reject when `updateSettings` method is not provided', async function () {
314
+ await d.settings.update({ ignoreUnimportantViews: true }).should.not.be.rejected;
315
+ });
316
+ it('should reject for invalid update object', async function () {
317
+ await d.settings
318
+ // @ts-expect-error
319
+ .update('invalid json')
320
+ .should.be.rejectedWith('JSON');
321
+ });
349
322
  });
350
- d.startUnexpectedShutdown(new Error('Crashytimes'));
351
- const value = await reqPromise;
352
- value.message.should.contain('Crashytimes');
353
- await shutdownEventPromise;
354
- });
355
- });
356
- describe('event timings', function () {
357
- it('should not add timings if not using opt-in cap', async function () {
358
- const session = await startSession({
359
- capabilities: {
360
- alwaysMatch: defaultCaps
361
- }
323
+ describe('unexpected exits', function () {
324
+ /** @type {import('sinon').SinonSandbox} */
325
+ let sandbox;
326
+ beforeEach(function () {
327
+ sandbox = sinon_1.default.createSandbox();
328
+ });
329
+ afterEach(function () {
330
+ sandbox.restore();
331
+ });
332
+ it('should reject a current command when the driver crashes', async function () {
333
+ sandbox.stub(d, 'getStatus').callsFake(async function () {
334
+ await bluebird_1.default.delay(5000);
335
+ });
336
+ const reqPromise = getCommand('status', { validateStatus: null });
337
+ // make sure that the request gets to the server before our shutdown
338
+ await bluebird_1.default.delay(100);
339
+ const shutdownEventPromise = new bluebird_1.default((resolve, reject) => {
340
+ setTimeout(() => reject(new Error('onUnexpectedShutdown event is expected to be fired within 5 seconds timeout')), 5000);
341
+ d.onUnexpectedShutdown(resolve);
342
+ });
343
+ d.startUnexpectedShutdown(new Error('Crashytimes'));
344
+ const value = await reqPromise;
345
+ value.message.should.contain('Crashytimes');
346
+ await shutdownEventPromise;
347
+ });
362
348
  });
363
- const res = await getSession(session.sessionId);
364
- should.not.exist(res.events);
365
- await endSession(session.sessionId);
366
- });
367
- it('should add start session timings', async function () {
368
- var _res$events, _res$events2, _res$events3, _res$events4;
369
-
370
- const caps = { ...defaultCaps,
371
- 'appium:eventTimings': true
372
- };
373
- const session = await startSession({
374
- capabilities: {
375
- alwaysMatch: caps
376
- }
349
+ describe('event timings', function () {
350
+ it('should not add timings if not using opt-in cap', async function () {
351
+ const session = await startSession({ capabilities: { alwaysMatch: defaultCaps } });
352
+ const res = await getSession(session.sessionId);
353
+ should.not.exist(res.events);
354
+ await endSession(session.sessionId);
355
+ });
356
+ it('should add start session timings', async function () {
357
+ const caps = { ...defaultCaps, 'appium:eventTimings': true };
358
+ const session = await startSession({ capabilities: { alwaysMatch: caps } });
359
+ const res = await getSession(session.sessionId);
360
+ should.exist(res.events);
361
+ should.exist(res.events?.newSessionRequested);
362
+ should.exist(res.events?.newSessionStarted);
363
+ res.events?.newSessionRequested[0].should.be.a('number');
364
+ res.events?.newSessionStarted[0].should.be.a('number');
365
+ await endSession(session.sessionId);
366
+ });
377
367
  });
378
- const res = await getSession(session.sessionId);
379
- should.exist(res.events);
380
- should.exist((_res$events = res.events) === null || _res$events === void 0 ? void 0 : _res$events.newSessionRequested);
381
- should.exist((_res$events2 = res.events) === null || _res$events2 === void 0 ? void 0 : _res$events2.newSessionStarted);
382
- (_res$events3 = res.events) === null || _res$events3 === void 0 ? void 0 : _res$events3.newSessionRequested[0].should.be.a('number');
383
- (_res$events4 = res.events) === null || _res$events4 === void 0 ? void 0 : _res$events4.newSessionStarted[0].should.be.a('number');
384
- await endSession(session.sessionId);
385
- });
386
368
  });
387
- });
388
369
  }
389
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJzaG91bGQiLCJjaGFpIiwiY3JlYXRlU2Vzc2lvbkhlbHBlcnMiLCJwb3J0IiwiYWRkcmVzcyIsIlRFU1RfSE9TVCIsImNyZWF0ZUFwcGl1bVRlc3RVUkwiLCJjcmVhdGVBcHBpdW1VUkwiLCJjcmVhdGVTZXNzaW9uVVJMIiwiXyIsIm5ld1Nlc3Npb25VUkwiLCJwb3N0Q29tbWFuZCIsInNlc3Npb25JZCIsImNtZE5hbWUiLCJkYXRhIiwiY29uZmlnIiwidXJsIiwicmVzcG9uc2UiLCJheGlvcyIsInBvc3QiLCJ2YWx1ZSIsImdldENvbW1hbmQiLCJzZXNzaW9uSWRPckNtZE5hbWUiLCJjbWROYW1lT3JDb25maWciLCJpc1N0cmluZyIsInZhbGlkYXRlU3RhdHVzIiwic3RhcnRTZXNzaW9uIiwiZGVmYXVsdHNEZWVwIiwiY2FwYWJpbGl0aWVzIiwiYWx3YXlzTWF0Y2giLCJmaXJzdE1hdGNoIiwiZW5kU2Vzc2lvbiIsImRlbGV0ZSIsImdldFNlc3Npb24iLCJkcml2ZXJFMkVUZXN0U3VpdGUiLCJEcml2ZXJDbGFzcyIsImRlZmF1bHRDYXBzIiwiY2xhc3NOYW1lIiwibmFtZSIsImRlc2NyaWJlIiwiYmFzZVNlcnZlciIsImQiLCJiZWZvcmUiLCJnZXRUZXN0UG9ydCIsInNlcnZlciIsInJvdXRlQ29uZmlndXJpbmdGdW5jdGlvbiIsImhvc3RuYW1lIiwiY2xpQXJncyIsImFmdGVyIiwiY2xvc2UiLCJpdCIsInNlc3Npb25JZHMiLCJ0aW1lcyIsImhlYWRlcnMiLCJzaW1wbGUiLCJyZXNvbHZlV2l0aEZ1bGxSZXNwb25zZSIsInB1c2giLCJ1bmlxIiwibGVuZ3RoIiwiZXF1YWwiLCJzdGF0dXMiLCJyZXFzIiwibWFwIiwiQiIsImFsbCIsImV4aXN0IiwicGxhdGZvcm1OYW1lIiwiZGV2aWNlTmFtZSIsInNraXAiLCJvcmlnaW5hbEZpbmRFbGVtZW50Iiwib3JpZ2luYWxGaW5kRWxlbWVudHMiLCJzdGFydFRpbWVvdXRTZXNzaW9uIiwidGltZW91dCIsImNhcHMiLCJjbG9uZURlZXAiLCJmaW5kRWxlbWVudCIsImJpbmQiLCJmaW5kRWxlbWVudHMiLCJkZWxheSIsIm5ld1Nlc3Npb24iLCJuZXdDb21tYW5kVGltZW91dE1zIiwiYmUiLCJhYm92ZSIsInVzaW5nIiwiZXJyb3IiLCJyZXNwIiwic3RhcnQiLCJEYXRlIiwibm93IiwiZXFsIiwibm90Iiwibm9Db21tYW5kVGltZXIiLCJzZXR0aW5ncyIsIkRldmljZVNldHRpbmdzIiwiaWdub3JlVW5pbXBvcnRhbnRWaWV3cyIsImdldFNldHRpbmdzIiwiZmFsc2UiLCJ1cGRhdGUiLCJyZWplY3RlZCIsInJlamVjdGVkV2l0aCIsInNhbmRib3giLCJiZWZvcmVFYWNoIiwic2lub24iLCJjcmVhdGVTYW5kYm94IiwiYWZ0ZXJFYWNoIiwicmVzdG9yZSIsInN0dWIiLCJjYWxsc0Zha2UiLCJyZXFQcm9taXNlIiwic2h1dGRvd25FdmVudFByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0Iiwic2V0VGltZW91dCIsIkVycm9yIiwib25VbmV4cGVjdGVkU2h1dGRvd24iLCJzdGFydFVuZXhwZWN0ZWRTaHV0ZG93biIsIm1lc3NhZ2UiLCJjb250YWluIiwic2Vzc2lvbiIsInJlcyIsImV2ZW50cyIsIm5ld1Nlc3Npb25SZXF1ZXN0ZWQiLCJuZXdTZXNzaW9uU3RhcnRlZCIsImEiXSwic291cmNlcyI6WyIuLi8uLi9saWIvZTJlLXN1aXRlLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQge3NlcnZlciwgcm91dGVDb25maWd1cmluZ0Z1bmN0aW9uLCBEZXZpY2VTZXR0aW5nc30gZnJvbSAnYXBwaXVtL2RyaXZlcic7XG5pbXBvcnQgYXhpb3MgZnJvbSAnYXhpb3MnO1xuaW1wb3J0IEIgZnJvbSAnYmx1ZWJpcmQnO1xuaW1wb3J0IHtURVNUX0hPU1QsIGdldFRlc3RQb3J0LCBjcmVhdGVBcHBpdW1VUkx9IGZyb20gJy4vaGVscGVycyc7XG5pbXBvcnQgY2hhaSBmcm9tICdjaGFpJztcbmltcG9ydCBzaW5vbiBmcm9tICdzaW5vbic7XG5cbmNvbnN0IHNob3VsZCA9IGNoYWkuc2hvdWxkKCk7XG5cbi8qKlxuICogQ3JlYXRlcyBzb21lIGhlbHBlciBmdW5jdGlvbnMgZm9yIEUyRSB0ZXN0cyB0byBtYW5hZ2Ugc2Vzc2lvbnMuXG4gKiBAdGVtcGxhdGUgW0NvbW1hbmREYXRhPXVua25vd25dXG4gKiBAdGVtcGxhdGUgW1Jlc3BvbnNlRGF0YT1hbnldXG4gKiBAcGFyYW0ge251bWJlcn0gcG9ydCAtIFBvcnQgb24gd2hpY2ggdGhlIHNlcnZlciBpcyBydW5uaW5nLiBUeXBpY2FsbHkgdGhpcyB3aWxsIGJlIHJldHJpZXZlZCB2aWEgYGdldC1wb3J0YCBiZWZvcmVoYW5kXG4gKiBAcGFyYW0ge3N0cmluZ30gW2FkZHJlc3NdIC0gQWRkcmVzcy9ob3N0IG9uIHdoaWNoIHRoZSBzZXJ2ZXIgaXMgcnVubmluZy4gRGVmYXVsdHMgdG8ge0BsaW5rY29kZSBURVNUX0hPU1R9XG4gKiBAcmV0dXJucyB7U2Vzc2lvbkhlbHBlcnM8Q29tbWFuZERhdGEsIFJlc3BvbnNlRGF0YT59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVTZXNzaW9uSGVscGVycyhwb3J0LCBhZGRyZXNzID0gVEVTVF9IT1NUKSB7XG4gIGNvbnN0IGNyZWF0ZUFwcGl1bVRlc3RVUkwgPVxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KCdsb2Rhc2gnKS5DdXJyaWVkRnVuY3Rpb24yPHN0cmluZyxzdHJpbmcsc3RyaW5nPn0gKi8gKFxuICAgICAgY3JlYXRlQXBwaXVtVVJMKGFkZHJlc3MsIHBvcnQpXG4gICAgKTtcblxuICBjb25zdCBjcmVhdGVTZXNzaW9uVVJMID0gY3JlYXRlQXBwaXVtVGVzdFVSTChfLCAnJyk7XG4gIGNvbnN0IG5ld1Nlc3Npb25VUkwgPSBjcmVhdGVBcHBpdW1UZXN0VVJMKCcnLCAnc2Vzc2lvbicpO1xuICByZXR1cm4gLyoqIEB0eXBlIHtTZXNzaW9uSGVscGVyczxDb21tYW5kRGF0YSwgUmVzcG9uc2VEYXRhPn0gKi8gKHtcbiAgICBuZXdTZXNzaW9uVVJMLFxuICAgIGNyZWF0ZUFwcGl1bVRlc3RVUkwsXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc2Vzc2lvbklkXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGNtZE5hbWVcbiAgICAgKiBAcGFyYW0ge2FueX0gW2RhdGFdXG4gICAgICogQHBhcmFtIHtBeGlvc1JlcXVlc3RDb25maWd9IFtjb25maWddXG4gICAgICogQHJldHVybnMge1Byb21pc2U8YW55Pn1cbiAgICAgKi9cbiAgICBwb3N0Q29tbWFuZDogYXN5bmMgKHNlc3Npb25JZCwgY21kTmFtZSwgZGF0YSA9IHt9LCBjb25maWcgPSB7fSkgPT4ge1xuICAgICAgY29uc3QgdXJsID0gY3JlYXRlQXBwaXVtVGVzdFVSTChzZXNzaW9uSWQsIGNtZE5hbWUpO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBheGlvcy5wb3N0KHVybCwgZGF0YSwgY29uZmlnKTtcbiAgICAgIHJldHVybiByZXNwb25zZS5kYXRhPy52YWx1ZTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHNlc3Npb25JZE9yQ21kTmFtZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfEF4aW9zUmVxdWVzdENvbmZpZ30gY21kTmFtZU9yQ29uZmlnXG4gICAgICogQHBhcmFtIHtBeGlvc1JlcXVlc3RDb25maWd9IFtjb25maWddXG4gICAgICogQHJldHVybnMge1Byb21pc2U8YW55Pn1cbiAgICAgKi9cbiAgICBnZXRDb21tYW5kOiBhc3luYyAoc2Vzc2lvbklkT3JDbWROYW1lLCBjbWROYW1lT3JDb25maWcsIGNvbmZpZyA9IHt9KSA9PiB7XG4gICAgICBpZiAoIV8uaXNTdHJpbmcoY21kTmFtZU9yQ29uZmlnKSkge1xuICAgICAgICBjb25maWcgPSBjbWROYW1lT3JDb25maWc7XG4gICAgICAgIGNtZE5hbWVPckNvbmZpZyA9IHNlc3Npb25JZE9yQ21kTmFtZTtcbiAgICAgICAgc2Vzc2lvbklkT3JDbWROYW1lID0gJyc7XG4gICAgICB9XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGF4aW9zKHtcbiAgICAgICAgdXJsOiBjcmVhdGVBcHBpdW1UZXN0VVJMKHNlc3Npb25JZE9yQ21kTmFtZSwgY21kTmFtZU9yQ29uZmlnKSxcbiAgICAgICAgdmFsaWRhdGVTdGF0dXM6IG51bGwsXG4gICAgICAgIC4uLmNvbmZpZyxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlc3BvbnNlLmRhdGE/LnZhbHVlO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge05ld1Nlc3Npb25EYXRhfSBkYXRhXG4gICAgICogQHBhcmFtIHtBeGlvc1JlcXVlc3RDb25maWd9IFtjb25maWddXG4gICAgICovXG4gICAgc3RhcnRTZXNzaW9uOiBhc3luYyAoZGF0YSwgY29uZmlnID0ge30pID0+IHtcbiAgICAgIGRhdGEgPSBfLmRlZmF1bHRzRGVlcChkYXRhLCB7XG4gICAgICAgIGNhcGFiaWxpdGllczoge1xuICAgICAgICAgIGFsd2F5c01hdGNoOiB7fSxcbiAgICAgICAgICBmaXJzdE1hdGNoOiBbe31dLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGF4aW9zLnBvc3QobmV3U2Vzc2lvblVSTCwgZGF0YSwgY29uZmlnKTtcbiAgICAgIHJldHVybiByZXNwb25zZS5kYXRhPy52YWx1ZTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHNlc3Npb25JZFxuICAgICAqL1xuICAgIGVuZFNlc3Npb246IGFzeW5jIChzZXNzaW9uSWQpID0+XG4gICAgICBhd2FpdCBheGlvcy5kZWxldGUoY3JlYXRlU2Vzc2lvblVSTChzZXNzaW9uSWQpLCB7XG4gICAgICAgIHZhbGlkYXRlU3RhdHVzOiBudWxsLFxuICAgICAgfSksXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHNlc3Npb25JZFxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPGFueT59XG4gICAgICovXG4gICAgZ2V0U2Vzc2lvbjogYXN5bmMgKHNlc3Npb25JZCkgPT4ge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBheGlvcyh7XG4gICAgICAgIHVybDogY3JlYXRlU2Vzc2lvblVSTChzZXNzaW9uSWQpLFxuICAgICAgICB2YWxpZGF0ZVN0YXR1czogbnVsbCxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlc3BvbnNlLmRhdGE/LnZhbHVlO1xuICAgIH0sXG4gIH0pO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgRTJFIHRlc3Qgc3VpdGVzIGZvciBhIGRyaXZlci5cbiAqIEB0ZW1wbGF0ZSB7RHJpdmVyfSBQXG4gKiBAcGFyYW0ge0RyaXZlckNsYXNzPFA+fSBEcml2ZXJDbGFzc1xuICogQHBhcmFtIHtBcHBpdW1XM0NDYXBhYmlsaXRpZXN9IFtkZWZhdWx0Q2Fwc11cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRyaXZlckUyRVRlc3RTdWl0ZShEcml2ZXJDbGFzcywgZGVmYXVsdENhcHMgPSB7fSkge1xuICBsZXQgYWRkcmVzcyA9IGRlZmF1bHRDYXBzWydhcHBpdW06YWRkcmVzcyddID8/IFRFU1RfSE9TVDtcbiAgbGV0IHBvcnQgPSBkZWZhdWx0Q2Fwc1snYXBwaXVtOnBvcnQnXTtcbiAgY29uc3QgY2xhc3NOYW1lID0gRHJpdmVyQ2xhc3MubmFtZSB8fCAnKHVua25vd24gZHJpdmVyKSc7XG5cbiAgZGVzY3JpYmUoYEJhc2VEcml2ZXIgRTJFIChhcyAke2NsYXNzTmFtZX0pYCwgZnVuY3Rpb24gKCkge1xuICAgIGxldCBiYXNlU2VydmVyO1xuICAgIC8qKiBAdHlwZSB7UH0gKi9cbiAgICBsZXQgZDtcbiAgICAvKipcbiAgICAgKiBUaGlzIFVSTCBjcmVhdGVzIGEgbmV3IHNlc3Npb25cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqKi9cbiAgICBsZXQgbmV3U2Vzc2lvblVSTDtcblxuICAgIC8qKiBAdHlwZSB7U2Vzc2lvbkhlbHBlcnNbJ3N0YXJ0U2Vzc2lvbiddfSAqL1xuICAgIGxldCBzdGFydFNlc3Npb247XG4gICAgLyoqIEB0eXBlIHtTZXNzaW9uSGVscGVyc1snZ2V0U2Vzc2lvbiddfSAqL1xuICAgIGxldCBnZXRTZXNzaW9uO1xuICAgIC8qKiBAdHlwZSB7U2Vzc2lvbkhlbHBlcnNbJ2VuZFNlc3Npb24nXX0gKi9cbiAgICBsZXQgZW5kU2Vzc2lvbjtcbiAgICAvKiogQHR5cGUge1Nlc3Npb25IZWxwZXJzWydnZXRDb21tYW5kJ119ICovXG4gICAgbGV0IGdldENvbW1hbmQ7XG4gICAgLyoqIEB0eXBlIHtTZXNzaW9uSGVscGVyc1sncG9zdENvbW1hbmQnXX0gKi9cbiAgICBsZXQgcG9zdENvbW1hbmQ7XG4gICAgYmVmb3JlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHBvcnQgPSBwb3J0ID8/IChhd2FpdCBnZXRUZXN0UG9ydCgpKTtcbiAgICAgIGRlZmF1bHRDYXBzID0gey4uLmRlZmF1bHRDYXBzLCAnYXBwaXVtOnBvcnQnOiBwb3J0fTtcbiAgICAgIGQgPSBuZXcgRHJpdmVyQ2xhc3Moe3BvcnQsIGFkZHJlc3N9KTtcbiAgICAgIGJhc2VTZXJ2ZXIgPSBhd2FpdCBzZXJ2ZXIoe1xuICAgICAgICByb3V0ZUNvbmZpZ3VyaW5nRnVuY3Rpb246IHJvdXRlQ29uZmlndXJpbmdGdW5jdGlvbihkKSxcbiAgICAgICAgcG9ydCxcbiAgICAgICAgaG9zdG5hbWU6IGFkZHJlc3MsXG4gICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgY2xpQXJnczoge30sXG4gICAgICB9KTtcbiAgICAgICh7c3RhcnRTZXNzaW9uLCBnZXRTZXNzaW9uLCBlbmRTZXNzaW9uLCBuZXdTZXNzaW9uVVJMLCBnZXRDb21tYW5kLCBwb3N0Q29tbWFuZH0gPVxuICAgICAgICBjcmVhdGVTZXNzaW9uSGVscGVycyhwb3J0LCBhZGRyZXNzKSk7XG4gICAgfSk7XG5cbiAgICBhZnRlcihhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBiYXNlU2VydmVyLmNsb3NlKCk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnc2Vzc2lvbiBoYW5kbGluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIGlkZW1wb3RlbmN5IHdoaWxlIGNyZWF0aW5nIHNlc3Npb25zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzZXNzaW9uSWRzID0gW107XG4gICAgICAgIGxldCB0aW1lcyA9IDA7XG4gICAgICAgIGRvIHtcbiAgICAgICAgICBjb25zdCB7c2Vzc2lvbklkfSA9IGF3YWl0IHN0YXJ0U2Vzc2lvbihcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgY2FwYWJpbGl0aWVzOiB7YWx3YXlzTWF0Y2g6IGRlZmF1bHRDYXBzfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgICAnWC1JZGVtcG90ZW5jeS1LZXknOiAnMTIzNDU2JyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgLy8gWFhYOiBJJ20gbm90IHN1cmUgd2hhdCB0aGVzZSBhcmUsIGFzIHRoZXkgYXJlIG5vdCBkb2N1bWVudGVkIGF4aW9zIG9wdGlvbnMsXG4gICAgICAgICAgICAgIC8vIG5vciBhcmUgdGhleSBtZW50aW9uZWQgaW4gb3VyIHNvdXJjZVxuICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgICAgIHNpbXBsZTogZmFsc2UsXG4gICAgICAgICAgICAgIHJlc29sdmVXaXRoRnVsbFJlc3BvbnNlOiB0cnVlLFxuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBzZXNzaW9uSWRzLnB1c2goc2Vzc2lvbklkKTtcbiAgICAgICAgICB0aW1lcysrO1xuICAgICAgICB9IHdoaWxlICh0aW1lcyA8IDIpO1xuICAgICAgICBfLnVuaXEoc2Vzc2lvbklkcykubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcblxuICAgICAgICBjb25zdCB7c3RhdHVzLCBkYXRhfSA9IGF3YWl0IGVuZFNlc3Npb24oc2Vzc2lvbklkc1swXSk7XG4gICAgICAgIHN0YXR1cy5zaG91bGQuZXF1YWwoMjAwKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKGRhdGEudmFsdWUsIG51bGwpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIGlkZW1wb3RlbmN5IHdoaWxlIGNyZWF0aW5nIHBhcmFsbGVsIHNlc3Npb25zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCByZXFzID0gW107XG4gICAgICAgIGxldCB0aW1lcyA9IDA7XG4gICAgICAgIGRvIHtcbiAgICAgICAgICByZXFzLnB1c2goXG4gICAgICAgICAgICBzdGFydFNlc3Npb24oXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBjYXBhYmlsaXRpZXM6IHtcbiAgICAgICAgICAgICAgICAgIGFsd2F5c01hdGNoOiBkZWZhdWx0Q2FwcyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICAgICAgJ1gtSWRlbXBvdGVuY3ktS2V5JzogJzEyMzQ1JyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApXG4gICAgICAgICAgKTtcbiAgICAgICAgICB0aW1lcysrO1xuICAgICAgICB9IHdoaWxlICh0aW1lcyA8IDIpO1xuICAgICAgICBjb25zdCBzZXNzaW9uSWRzID0gXy5tYXAoYXdhaXQgQi5hbGwocmVxcyksICdzZXNzaW9uSWQnKTtcbiAgICAgICAgXy51bmlxKHNlc3Npb25JZHMpLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG5cbiAgICAgICAgY29uc3Qge3N0YXR1cywgZGF0YX0gPSBhd2FpdCBlbmRTZXNzaW9uKHNlc3Npb25JZHNbMF0pO1xuICAgICAgICBzdGF0dXMuc2hvdWxkLmVxdWFsKDIwMCk7XG4gICAgICAgIHNob3VsZC5lcXVhbChkYXRhLnZhbHVlLCBudWxsKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGNyZWF0ZSBzZXNzaW9uIGFuZCByZXRyaWV2ZSBhIHNlc3Npb24gaWQsIHRoZW4gZGVsZXRlIGl0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQge3N0YXR1cywgZGF0YX0gPSBhd2FpdCBheGlvcy5wb3N0KG5ld1Nlc3Npb25VUkwsIHtcbiAgICAgICAgICBjYXBhYmlsaXRpZXM6IHtcbiAgICAgICAgICAgIGFsd2F5c01hdGNoOiBkZWZhdWx0Q2FwcyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgICBzdGF0dXMuc2hvdWxkLmVxdWFsKDIwMCk7XG4gICAgICAgIHNob3VsZC5leGlzdChkYXRhLnZhbHVlLnNlc3Npb25JZCk7XG4gICAgICAgIGRhdGEudmFsdWUuY2FwYWJpbGl0aWVzLnBsYXRmb3JtTmFtZS5zaG91bGQuZXF1YWwoZGVmYXVsdENhcHMucGxhdGZvcm1OYW1lKTtcbiAgICAgICAgZGF0YS52YWx1ZS5jYXBhYmlsaXRpZXMuZGV2aWNlTmFtZS5zaG91bGQuZXF1YWwoZGVmYXVsdENhcHNbJ2FwcGl1bTpkZXZpY2VOYW1lJ10pO1xuXG4gICAgICAgICh7c3RhdHVzLCBkYXRhfSA9IGF3YWl0IGVuZFNlc3Npb24oLyoqIEB0eXBlIHtzdHJpbmd9ICovIChkLnNlc3Npb25JZCkpKTtcblxuICAgICAgICBzdGF0dXMuc2hvdWxkLmVxdWFsKDIwMCk7XG4gICAgICAgIHNob3VsZC5lcXVhbChkYXRhLnZhbHVlLCBudWxsKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKGQuc2Vzc2lvbklkLCBudWxsKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQuc2tpcCgnc2hvdWxkIHRocm93IE5ZSSBmb3IgY29tbWFuZHMgbm90IGltcGxlbWVudGVkJywgYXN5bmMgZnVuY3Rpb24gKCkge30pO1xuXG4gICAgZGVzY3JpYmUoJ2NvbW1hbmQgdGltZW91dHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgb3JpZ2luYWxGaW5kRWxlbWVudCwgb3JpZ2luYWxGaW5kRWxlbWVudHM7XG5cbiAgICAgIC8qKlxuICAgICAgICogQHBhcmFtIHtudW1iZXJ9IFt0aW1lb3V0XVxuICAgICAgICovXG4gICAgICBhc3luYyBmdW5jdGlvbiBzdGFydFRpbWVvdXRTZXNzaW9uKHRpbWVvdXQpIHtcbiAgICAgICAgY29uc3QgY2FwcyA9IF8uY2xvbmVEZWVwKGRlZmF1bHRDYXBzKTtcbiAgICAgICAgY2Fwc1snYXBwaXVtOm5ld0NvbW1hbmRUaW1lb3V0J10gPSB0aW1lb3V0O1xuICAgICAgICByZXR1cm4gYXdhaXQgc3RhcnRTZXNzaW9uKHtjYXBhYmlsaXRpZXM6IHthbHdheXNNYXRjaDogY2Fwc319KTtcbiAgICAgIH1cblxuICAgICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgb3JpZ2luYWxGaW5kRWxlbWVudCA9IGQuZmluZEVsZW1lbnQ7XG4gICAgICAgIGQuZmluZEVsZW1lbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcmV0dXJuICdmb28nO1xuICAgICAgICB9LmJpbmQoZCk7XG5cbiAgICAgICAgb3JpZ2luYWxGaW5kRWxlbWVudHMgPSBkLmZpbmRFbGVtZW50cztcbiAgICAgICAgZC5maW5kRWxlbWVudHMgPSBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgYXdhaXQgQi5kZWxheSgyMDApO1xuICAgICAgICAgIHJldHVybiBbJ2ZvbyddO1xuICAgICAgICB9LmJpbmQoZCk7XG4gICAgICB9KTtcblxuICAgICAgYWZ0ZXIoZnVuY3Rpb24gKCkge1xuICAgICAgICBkLmZpbmRFbGVtZW50ID0gb3JpZ2luYWxGaW5kRWxlbWVudDtcbiAgICAgICAgZC5maW5kRWxlbWVudHMgPSBvcmlnaW5hbEZpbmRFbGVtZW50cztcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHNldCBhIGRlZmF1bHQgY29tbWFuZFRpbWVvdXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBuZXdTZXNzaW9uID0gYXdhaXQgc3RhcnRUaW1lb3V0U2Vzc2lvbigpO1xuICAgICAgICBkLm5ld0NvbW1hbmRUaW1lb3V0TXMuc2hvdWxkLmJlLmFib3ZlKDApO1xuICAgICAgICBhd2FpdCBlbmRTZXNzaW9uKG5ld1Nlc3Npb24uc2Vzc2lvbklkKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRpbWVvdXQgb24gY29tbWFuZHMgdXNpbmcgY29tbWFuZFRpbWVvdXQgY2FwJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgbmV3U2Vzc2lvbiA9IGF3YWl0IHN0YXJ0VGltZW91dFNlc3Npb24oMC4yNSk7XG4gICAgICAgIGNvbnN0IHNlc3Npb25JZCA9IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZC5zZXNzaW9uSWQpO1xuICAgICAgICBhd2FpdCBwb3N0Q29tbWFuZChzZXNzaW9uSWQsICdlbGVtZW50Jywge1xuICAgICAgICAgIHVzaW5nOiAnbmFtZScsXG4gICAgICAgICAgdmFsdWU6ICdmb28nLFxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgQi5kZWxheSg0MDApO1xuICAgICAgICBjb25zdCB2YWx1ZSA9IGF3YWl0IGdldFNlc3Npb24oc2Vzc2lvbklkKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHZhbHVlLmVycm9yLCAnaW52YWxpZCBzZXNzaW9uIGlkJyk7XG4gICAgICAgIHNob3VsZC5lcXVhbChkLnNlc3Npb25JZCwgbnVsbCk7XG4gICAgICAgIGNvbnN0IHJlc3AgPSAoYXdhaXQgZW5kU2Vzc2lvbihuZXdTZXNzaW9uLnNlc3Npb25JZCkpLmRhdGEudmFsdWU7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXNwPy5lcnJvciwgJ2ludmFsaWQgc2Vzc2lvbiBpZCcpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgbm90IHRpbWVvdXQgd2l0aCBjb21tYW5kVGltZW91dCBvZiBmYWxzZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbGV0IG5ld1Nlc3Npb24gPSBhd2FpdCBzdGFydFRpbWVvdXRTZXNzaW9uKDAuMSk7XG4gICAgICAgIGxldCBzdGFydCA9IERhdGUubm93KCk7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gYXdhaXQgcG9zdENvbW1hbmQoLyoqIEB0eXBlIHtzdHJpbmd9ICovIChkLnNlc3Npb25JZCksICdlbGVtZW50cycsIHtcbiAgICAgICAgICB1c2luZzogJ25hbWUnLFxuICAgICAgICAgIHZhbHVlOiAnZm9vJyxcbiAgICAgICAgfSk7XG4gICAgICAgIChEYXRlLm5vdygpIC0gc3RhcnQpLnNob3VsZC5iZS5hYm92ZSgxNTApO1xuICAgICAgICB2YWx1ZS5zaG91bGQuZXFsKFsnZm9vJ10pO1xuICAgICAgICBhd2FpdCBlbmRTZXNzaW9uKG5ld1Nlc3Npb24uc2Vzc2lvbklkKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIG5vdCB0aW1lb3V0IHdpdGggY29tbWFuZFRpbWVvdXQgb2YgMCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZC5uZXdDb21tYW5kVGltZW91dE1zID0gMjtcbiAgICAgICAgbGV0IG5ld1Nlc3Npb24gPSBhd2FpdCBzdGFydFRpbWVvdXRTZXNzaW9uKDApO1xuXG4gICAgICAgIGF3YWl0IHBvc3RDb21tYW5kKC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZC5zZXNzaW9uSWQpLCAnZWxlbWVudCcsIHtcbiAgICAgICAgICB1c2luZzogJ25hbWUnLFxuICAgICAgICAgIHZhbHVlOiAnZm9vJyxcbiAgICAgICAgfSk7XG4gICAgICAgIGF3YWl0IEIuZGVsYXkoNDAwKTtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBhd2FpdCBnZXRTZXNzaW9uKC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZC5zZXNzaW9uSWQpKTtcbiAgICAgICAgdmFsdWUucGxhdGZvcm1OYW1lPy5zaG91bGQuZXF1YWwoZGVmYXVsdENhcHMucGxhdGZvcm1OYW1lKTtcbiAgICAgICAgY29uc3QgcmVzcCA9IChhd2FpdCBlbmRTZXNzaW9uKG5ld1Nlc3Npb24uc2Vzc2lvbklkKSkuZGF0YS52YWx1ZTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlc3AsIG51bGwpO1xuXG4gICAgICAgIGQubmV3Q29tbWFuZFRpbWVvdXRNcyA9IDYwICogMTAwMDtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIG5vdCB0aW1lb3V0IGlmIGl0cyBqdXN0IHRoZSBjb21tYW5kIHRha2luZyBhd2hpbGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBuZXdTZXNzaW9uID0gYXdhaXQgc3RhcnRUaW1lb3V0U2Vzc2lvbigwLjI1KTtcbiAgICAgICAgLy8gWFhYOiByYWNlIGNvbmRpdGlvbjogd2UgbXVzdCBidWlsZCB0aGlzIFVSTCBiZWZvcmUgLi4uc29tZXRoaW5nIGhhcHBlbnMuLi5cbiAgICAgICAgLy8gd2hpY2ggY2F1c2VzIGBkLnNlc3Npb25JZGAgdG8gYmUgbWlzc2luZ1xuICAgICAgICBjb25zdCB7c2Vzc2lvbklkfSA9IGQ7XG5cbiAgICAgICAgYXdhaXQgcG9zdENvbW1hbmQoLyoqIEB0eXBlIHtzdHJpbmd9ICovIChkLnNlc3Npb25JZCksICdlbGVtZW50Jywge1xuICAgICAgICAgIHVzaW5nOiAnbmFtZScsXG4gICAgICAgICAgdmFsdWU6ICdmb28nLFxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgQi5kZWxheSg0MDApO1xuICAgICAgICBjb25zdCB2YWx1ZSA9IGF3YWl0IGdldFNlc3Npb24oLyoqIEB0eXBlIHtzdHJpbmd9ICovIChzZXNzaW9uSWQpKTtcbiAgICAgICAgdmFsdWUuZXJyb3Iuc2hvdWxkLmVxdWFsKCdpbnZhbGlkIHNlc3Npb24gaWQnKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKGQuc2Vzc2lvbklkLCBudWxsKTtcbiAgICAgICAgY29uc3QgcmVzcCA9IChhd2FpdCBlbmRTZXNzaW9uKG5ld1Nlc3Npb24uc2Vzc2lvbklkKSkuZGF0YS52YWx1ZTtcbiAgICAgICAgLyoqIEB0eXBlIHtzdHJpbmd9ICovICgvKiogQHR5cGUgeyB7ZXJyb3I6IHN0cmluZ30gfSAqLyAocmVzcCkuZXJyb3IpLnNob3VsZC5lcXVhbChcbiAgICAgICAgICAnaW52YWxpZCBzZXNzaW9uIGlkJ1xuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgbm90IGhhdmUgYSB0aW1lciBydW5uaW5nIGJlZm9yZSBvciBhZnRlciBhIHNlc3Npb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgc2hvdWxkLm5vdC5leGlzdChkLm5vQ29tbWFuZFRpbWVyKTtcbiAgICAgICAgbGV0IG5ld1Nlc3Npb24gPSBhd2FpdCBzdGFydFRpbWVvdXRTZXNzaW9uKDAuMjUpO1xuICAgICAgICBuZXdTZXNzaW9uLnNlc3Npb25JZC5zaG91bGQuZXF1YWwoZC5zZXNzaW9uSWQpO1xuICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgIHNob3VsZC5leGlzdChkLm5vQ29tbWFuZFRpbWVyKTtcbiAgICAgICAgYXdhaXQgZW5kU2Vzc2lvbihuZXdTZXNzaW9uLnNlc3Npb25JZCk7XG4gICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgc2hvdWxkLm5vdC5leGlzdChkLm5vQ29tbWFuZFRpbWVyKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3NldHRpbmdzIGFwaScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIGQuc2V0dGluZ3MgPSBuZXcgRGV2aWNlU2V0dGluZ3Moe2lnbm9yZVVuaW1wb3J0YW50Vmlld3M6IGZhbHNlfSk7XG4gICAgICB9KTtcbiAgICAgIGl0KCdzaG91bGQgYmUgYWJsZSB0byBnZXQgc2V0dGluZ3Mgb2JqZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBkLnNldHRpbmdzLmdldFNldHRpbmdzKCkuaWdub3JlVW5pbXBvcnRhbnRWaWV3cy5zaG91bGQuYmUuZmFsc2U7XG4gICAgICB9KTtcbiAgICAgIGl0KCdzaG91bGQgbm90IHJlamVjdCB3aGVuIGB1cGRhdGVTZXR0aW5nc2AgbWV0aG9kIGlzIG5vdCBwcm92aWRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgZC5zZXR0aW5ncy51cGRhdGUoe2lnbm9yZVVuaW1wb3J0YW50Vmlld3M6IHRydWV9KS5zaG91bGQubm90LmJlLnJlamVjdGVkO1xuICAgICAgfSk7XG4gICAgICBpdCgnc2hvdWxkIHJlamVjdCBmb3IgaW52YWxpZCB1cGRhdGUgb2JqZWN0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBhd2FpdCBkLnNldHRpbmdzXG4gICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgIC51cGRhdGUoJ2ludmFsaWQganNvbicpXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0pTT04nKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3VuZXhwZWN0ZWQgZXhpdHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAvKiogQHR5cGUge2ltcG9ydCgnc2lub24nKS5TaW5vblNhbmRib3h9ICovXG4gICAgICBsZXQgc2FuZGJveDtcbiAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICBzYW5kYm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuICAgICAgfSk7XG5cbiAgICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNhbmRib3gucmVzdG9yZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgY3VycmVudCBjb21tYW5kIHdoZW4gdGhlIGRyaXZlciBjcmFzaGVzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBzYW5kYm94LnN0dWIoZCwgJ2dldFN0YXR1cycpLmNhbGxzRmFrZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgYXdhaXQgQi5kZWxheSg1MDAwKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHJlcVByb21pc2UgPSBnZXRDb21tYW5kKCdzdGF0dXMnLCB7dmFsaWRhdGVTdGF0dXM6IG51bGx9KTtcbiAgICAgICAgLy8gbWFrZSBzdXJlIHRoYXQgdGhlIHJlcXVlc3QgZ2V0cyB0byB0aGUgc2VydmVyIGJlZm9yZSBvdXIgc2h1dGRvd25cbiAgICAgICAgYXdhaXQgQi5kZWxheSgxMDApO1xuICAgICAgICBjb25zdCBzaHV0ZG93bkV2ZW50UHJvbWlzZSA9IG5ldyBCKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICBzZXRUaW1lb3V0KFxuICAgICAgICAgICAgKCkgPT5cbiAgICAgICAgICAgICAgcmVqZWN0KFxuICAgICAgICAgICAgICAgIG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICAgICdvblVuZXhwZWN0ZWRTaHV0ZG93biBldmVudCBpcyBleHBlY3RlZCB0byBiZSBmaXJlZCB3aXRoaW4gNSBzZWNvbmRzIHRpbWVvdXQnXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgNTAwMFxuICAgICAgICAgICk7XG4gICAgICAgICAgZC5vblVuZXhwZWN0ZWRTaHV0ZG93bihyZXNvbHZlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGQuc3RhcnRVbmV4cGVjdGVkU2h1dGRvd24obmV3IEVycm9yKCdDcmFzaHl0aW1lcycpKTtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBhd2FpdCByZXFQcm9taXNlO1xuICAgICAgICB2YWx1ZS5tZXNzYWdlLnNob3VsZC5jb250YWluKCdDcmFzaHl0aW1lcycpO1xuICAgICAgICBhd2FpdCBzaHV0ZG93bkV2ZW50UHJvbWlzZTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2V2ZW50IHRpbWluZ3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIG5vdCBhZGQgdGltaW5ncyBpZiBub3QgdXNpbmcgb3B0LWluIGNhcCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2Vzc2lvbiA9IGF3YWl0IHN0YXJ0U2Vzc2lvbih7Y2FwYWJpbGl0aWVzOiB7YWx3YXlzTWF0Y2g6IGRlZmF1bHRDYXBzfX0pO1xuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBnZXRTZXNzaW9uKHNlc3Npb24uc2Vzc2lvbklkKTtcbiAgICAgICAgc2hvdWxkLm5vdC5leGlzdChyZXMuZXZlbnRzKTtcbiAgICAgICAgYXdhaXQgZW5kU2Vzc2lvbihzZXNzaW9uLnNlc3Npb25JZCk7XG4gICAgICB9KTtcbiAgICAgIGl0KCdzaG91bGQgYWRkIHN0YXJ0IHNlc3Npb24gdGltaW5ncycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY2FwcyA9IHsuLi5kZWZhdWx0Q2FwcywgJ2FwcGl1bTpldmVudFRpbWluZ3MnOiB0cnVlfTtcbiAgICAgICAgY29uc3Qgc2Vzc2lvbiA9IGF3YWl0IHN0YXJ0U2Vzc2lvbih7Y2FwYWJpbGl0aWVzOiB7YWx3YXlzTWF0Y2g6IGNhcHN9fSk7XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGdldFNlc3Npb24oc2Vzc2lvbi5zZXNzaW9uSWQpO1xuICAgICAgICBzaG91bGQuZXhpc3QocmVzLmV2ZW50cyk7XG4gICAgICAgIHNob3VsZC5leGlzdChyZXMuZXZlbnRzPy5uZXdTZXNzaW9uUmVxdWVzdGVkKTtcbiAgICAgICAgc2hvdWxkLmV4aXN0KHJlcy5ldmVudHM/Lm5ld1Nlc3Npb25TdGFydGVkKTtcbiAgICAgICAgcmVzLmV2ZW50cz8ubmV3U2Vzc2lvblJlcXVlc3RlZFswXS5zaG91bGQuYmUuYSgnbnVtYmVyJyk7XG4gICAgICAgIHJlcy5ldmVudHM/Lm5ld1Nlc3Npb25TdGFydGVkWzBdLnNob3VsZC5iZS5hKCdudW1iZXInKTtcbiAgICAgICAgYXdhaXQgZW5kU2Vzc2lvbihzZXNzaW9uLnNlc3Npb25JZCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbi8qKlxuICogQSB7QGxpbmtjb2RlIERyaXZlckNsYXNzfSwgZXhjZXB0IHVzaW5nIHRoZSBiYXNlIHtAbGlua2NvZGUgRHJpdmVyfSB0eXBlIGluc3RlYWQgb2YgYEV4dGVybmFsRHJpdmVyYC5cbiAqIFRoaXMgYWxsb3dzIHRoZSBzdWl0ZSB0byB3b3JrIGZvciBgQmFzZURyaXZlcmAuXG4gKiBAdGVtcGxhdGUge0RyaXZlcn0gUFxuICogQHR5cGVkZWYge2ltcG9ydCgnQGFwcGl1bS90eXBlcycpLkRyaXZlckNsYXNzPFA+fSBEcml2ZXJDbGFzc1xuICovXG5cbi8qKlxuICogQHR5cGVkZWYge2ltcG9ydCgnQGFwcGl1bS90eXBlcycpLkNhcGFiaWxpdGllc30gQ2FwYWJpbGl0aWVzXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdAYXBwaXVtL3R5cGVzJykuRHJpdmVyfSBEcml2ZXJcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJ0BhcHBpdW0vdHlwZXMnKS5Ecml2ZXJTdGF0aWN9IERyaXZlclN0YXRpY1xuICogQHR5cGVkZWYge2ltcG9ydCgnQGFwcGl1bS90eXBlcycpLkFwcGl1bVczQ0NhcGFiaWxpdGllc30gQXBwaXVtVzNDQ2FwYWJpbGl0aWVzXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdheGlvcycpLkF4aW9zUmVxdWVzdENvbmZpZ30gQXhpb3NSZXF1ZXN0Q29uZmlnXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdAYXBwaXVtL3R5cGVzJykuU2luZ3VsYXJTZXNzaW9uRGF0YX0gU2luZ3VsYXJTZXNzaW9uRGF0YVxuICovXG5cbi8qKlxuICogQHRlbXBsYXRlIFQsRFxuICogQHR5cGVkZWYge2ltcG9ydCgnYXhpb3MnKS5BeGlvc1Jlc3BvbnNlPFQsIEQ+fSBBeGlvc1Jlc3BvbnNlXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiBOZXdTZXNzaW9uRGF0YVxuICogQHByb3BlcnR5IHtpbXBvcnQoJ3R5cGUtZmVzdCcpLlJlcXVpcmVBdExlYXN0T25lPGltcG9ydCgnQGFwcGl1bS90eXBlcycpLlczQ0NhcGFiaWxpdGllcywgJ2ZpcnN0TWF0Y2gnfCdhbHdheXNNYXRjaCc+fSBjYXBhYmlsaXRpZXNcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIE5ld1Nlc3Npb25SZXNwb25zZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IHNlc3Npb25JZCxcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KCdAYXBwaXVtL3R5cGVzJykuQ2FwYWJpbGl0aWVzfSBjYXBhYmlsaXRpZXNcbiAqL1xuXG4vKipcbiAqIFNvbWUgRTJFIGhlbHBlcnMgZm9yIG1ha2luZyByZXF1ZXN0cyBhbmQgbWFuYWdpbmcgc2Vzc2lvbnNcbiAqIFNlZSB7QGxpbmtjb2RlIGNyZWF0ZVNlc3Npb25IZWxwZXJzfVxuICogQHRlbXBsYXRlIFtDb21tYW5kRGF0YT11bmtub3duXVxuICogQHRlbXBsYXRlIFtSZXNwb25zZURhdGE9YW55XVxuICogQHR5cGVkZWYgU2Vzc2lvbkhlbHBlcnNcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBuZXdTZXNzaW9uVVJMIC0gVVJMIHRvIGNyZWF0ZSBhIG5ldyBzZXNzaW9uLiBDYW4gYmUgdXNlZCB3aXRoIHJhdyBgYXhpb3NgIHJlcXVlc3RzIHRvIGZ1bGx5IGluc3BlY3QgcmF3IHJlc3BvbnNlLiAgTW9zdGx5LCB0aGlzIHdpbGwgbm90IGJlIHVzZWQuXG4gKiBAcHJvcGVydHkgeyhkYXRhOiBOZXdTZXNzaW9uRGF0YSwgY29uZmlnPzogQXhpb3NSZXF1ZXN0Q29uZmlnKSA9PiBQcm9taXNlPE5ld1Nlc3Npb25SZXNwb25zZT59IHN0YXJ0U2Vzc2lvbiAtIEJlZ2luIGEgc2Vzc2lvblxuICogQHByb3BlcnR5IHsoc2Vzc2lvbklkOiBzdHJpbmcpID0+IFByb21pc2U8QXhpb3NSZXNwb25zZTx7dmFsdWU6IHtlcnJvcj86IHN0cmluZ30/fSwge3ZhbGlkYXRlU3RhdHVzOiBudWxsfT4+fSBlbmRTZXNzaW9uIC0gRW5kIGEgc2Vzc2lvbi4gX05vdGU6IHJlc29sdmVzIHdpdGggcmF3IHJlc3BvbnNlIG9iamVjdF9cbiAqIEBwcm9wZXJ0eSB7KHNlc3Npb25JZDogc3RyaW5nKSA9PiBQcm9taXNlPFNpbmd1bGFyU2Vzc2lvbkRhdGE+fSBnZXRTZXNzaW9uIC0gR2V0IGluZm8gYWJvdXQgYSBzZXNzaW9uXG4gKiBAcHJvcGVydHkgeyhzZXNzaW9uSWQ6IHN0cmluZywgY21kTmFtZTogc3RyaW5nLCBkYXRhPzogQ29tbWFuZERhdGEsIGNvbmZpZz86IEF4aW9zUmVxdWVzdENvbmZpZykgPT4gUHJvbWlzZTxSZXNwb25zZURhdGE+fSBwb3N0Q29tbWFuZCAtIFNlbmQgYW4gYXJiaXRyYXJ5IGNvbW1hbmQgdmlhIGBQT1NUYC5cbiAqIEBwcm9wZXJ0eSB7KHNlc3Npb25JZE9yQ21kTmFtZTogc3RyaW5nLCBjbWROYW1lT3JDb25maWc6IHN0cmluZ3xBeGlvc1JlcXVlc3RDb25maWcsIGNvbmZpZz86IEF4aW9zUmVxdWVzdENvbmZpZykgPT4gUHJvbWlzZTxSZXNwb25zZURhdGE+fSBnZXRDb21tYW5kIC0gU2VuZCBhbiBhcmJpdHJhcnkgY29tbWFuZCB2aWEgYEdFVGAuIE9wdGlvbmFsIGBzZXNzaW9uSWRgLlxuICovXG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUVBLE1BQU1BLE1BQU0sR0FBR0MsYUFBQSxDQUFLRCxNQUFMLEVBQWY7O0FBVU8sU0FBU0Usb0JBQVQsQ0FBOEJDLElBQTlCLEVBQW9DQyxPQUFPLEdBQUdDLGtCQUE5QyxFQUF5RDtFQUM5RCxNQUFNQyxtQkFBbUIsR0FFckIsSUFBQUMsd0JBQUEsRUFBZ0JILE9BQWhCLEVBQXlCRCxJQUF6QixDQUZKO0VBS0EsTUFBTUssZ0JBQWdCLEdBQUdGLG1CQUFtQixDQUFDRyxlQUFELEVBQUksRUFBSixDQUE1QztFQUNBLE1BQU1DLGFBQWEsR0FBR0osbUJBQW1CLENBQUMsRUFBRCxFQUFLLFNBQUwsQ0FBekM7RUFDQSxPQUFpRTtJQUMvREksYUFEK0Q7SUFFL0RKLG1CQUYrRDtJQVcvREssV0FBVyxFQUFFLE9BQU9DLFNBQVAsRUFBa0JDLE9BQWxCLEVBQTJCQyxJQUFJLEdBQUcsRUFBbEMsRUFBc0NDLE1BQU0sR0FBRyxFQUEvQyxLQUFzRDtNQUFBOztNQUNqRSxNQUFNQyxHQUFHLEdBQUdWLG1CQUFtQixDQUFDTSxTQUFELEVBQVlDLE9BQVosQ0FBL0I7TUFDQSxNQUFNSSxRQUFRLEdBQUcsTUFBTUMsY0FBQSxDQUFNQyxJQUFOLENBQVdILEdBQVgsRUFBZ0JGLElBQWhCLEVBQXNCQyxNQUF0QixDQUF2QjtNQUNBLHlCQUFPRSxRQUFRLENBQUNILElBQWhCLG1EQUFPLGVBQWVNLEtBQXRCO0lBQ0QsQ0FmOEQ7SUF1Qi9EQyxVQUFVLEVBQUUsT0FBT0Msa0JBQVAsRUFBMkJDLGVBQTNCLEVBQTRDUixNQUFNLEdBQUcsRUFBckQsS0FBNEQ7TUFBQTs7TUFDdEUsSUFBSSxDQUFDTixlQUFBLENBQUVlLFFBQUYsQ0FBV0QsZUFBWCxDQUFMLEVBQWtDO1FBQ2hDUixNQUFNLEdBQUdRLGVBQVQ7UUFDQUEsZUFBZSxHQUFHRCxrQkFBbEI7UUFDQUEsa0JBQWtCLEdBQUcsRUFBckI7TUFDRDs7TUFDRCxNQUFNTCxRQUFRLEdBQUcsTUFBTSxJQUFBQyxjQUFBLEVBQU07UUFDM0JGLEdBQUcsRUFBRVYsbUJBQW1CLENBQUNnQixrQkFBRCxFQUFxQkMsZUFBckIsQ0FERztRQUUzQkUsY0FBYyxFQUFFLElBRlc7UUFHM0IsR0FBR1Y7TUFId0IsQ0FBTixDQUF2QjtNQUtBLDBCQUFPRSxRQUFRLENBQUNILElBQWhCLG9EQUFPLGdCQUFlTSxLQUF0QjtJQUNELENBbkM4RDtJQXlDL0RNLFlBQVksRUFBRSxPQUFPWixJQUFQLEVBQWFDLE1BQU0sR0FBRyxFQUF0QixLQUE2QjtNQUFBOztNQUN6Q0QsSUFBSSxHQUFHTCxlQUFBLENBQUVrQixZQUFGLENBQWViLElBQWYsRUFBcUI7UUFDMUJjLFlBQVksRUFBRTtVQUNaQyxXQUFXLEVBQUUsRUFERDtVQUVaQyxVQUFVLEVBQUUsQ0FBQyxFQUFEO1FBRkE7TUFEWSxDQUFyQixDQUFQO01BTUEsTUFBTWIsUUFBUSxHQUFHLE1BQU1DLGNBQUEsQ0FBTUMsSUFBTixDQUFXVCxhQUFYLEVBQTBCSSxJQUExQixFQUFnQ0MsTUFBaEMsQ0FBdkI7TUFDQSwwQkFBT0UsUUFBUSxDQUFDSCxJQUFoQixvREFBTyxnQkFBZU0sS0FBdEI7SUFDRCxDQWxEOEQ7SUF1RC9EVyxVQUFVLEVBQUUsTUFBT25CLFNBQVAsSUFDVixNQUFNTSxjQUFBLENBQU1jLE1BQU4sQ0FBYXhCLGdCQUFnQixDQUFDSSxTQUFELENBQTdCLEVBQTBDO01BQzlDYSxjQUFjLEVBQUU7SUFEOEIsQ0FBMUMsQ0F4RHVEO0lBK0QvRFEsVUFBVSxFQUFFLE1BQU9yQixTQUFQLElBQXFCO01BQUE7O01BQy9CLE1BQU1LLFFBQVEsR0FBRyxNQUFNLElBQUFDLGNBQUEsRUFBTTtRQUMzQkYsR0FBRyxFQUFFUixnQkFBZ0IsQ0FBQ0ksU0FBRCxDQURNO1FBRTNCYSxjQUFjLEVBQUU7TUFGVyxDQUFOLENBQXZCO01BSUEsMEJBQU9SLFFBQVEsQ0FBQ0gsSUFBaEIsb0RBQU8sZ0JBQWVNLEtBQXRCO0lBQ0Q7RUFyRThELENBQWpFO0FBdUVEOztBQVFNLFNBQVNjLGtCQUFULENBQTRCQyxXQUE1QixFQUF5Q0MsV0FBVyxHQUFHLEVBQXZELEVBQTJEO0VBQ2hFLElBQUloQyxPQUFPLEdBQUdnQyxXQUFXLENBQUMsZ0JBQUQsQ0FBWCxJQUFpQy9CLGtCQUEvQztFQUNBLElBQUlGLElBQUksR0FBR2lDLFdBQVcsQ0FBQyxhQUFELENBQXRCO0VBQ0EsTUFBTUMsU0FBUyxHQUFHRixXQUFXLENBQUNHLElBQVosSUFBb0Isa0JBQXRDO0VBRUFDLFFBQVEsQ0FBRSxzQkFBcUJGLFNBQVUsR0FBakMsRUFBcUMsWUFBWTtJQUN2RCxJQUFJRyxVQUFKO0lBRUEsSUFBSUMsQ0FBSjtJQUtBLElBQUkvQixhQUFKO0lBR0EsSUFBSWdCLFlBQUo7SUFFQSxJQUFJTyxVQUFKO0lBRUEsSUFBSUYsVUFBSjtJQUVBLElBQUlWLFVBQUo7SUFFQSxJQUFJVixXQUFKO0lBQ0ErQixNQUFNLENBQUMsa0JBQWtCO01BQ3ZCdkMsSUFBSSxHQUFHQSxJQUFJLEtBQUssTUFBTSxJQUFBd0Msb0JBQUEsR0FBWCxDQUFYO01BQ0FQLFdBQVcsR0FBRyxFQUFDLEdBQUdBLFdBQUo7UUFBaUIsZUFBZWpDO01BQWhDLENBQWQ7TUFDQXNDLENBQUMsR0FBRyxJQUFJTixXQUFKLENBQWdCO1FBQUNoQyxJQUFEO1FBQU9DO01BQVAsQ0FBaEIsQ0FBSjtNQUNBb0MsVUFBVSxHQUFHLE1BQU0sSUFBQUksY0FBQSxFQUFPO1FBQ3hCQyx3QkFBd0IsRUFBRSxJQUFBQSxnQ0FBQSxFQUF5QkosQ0FBekIsQ0FERjtRQUV4QnRDLElBRndCO1FBR3hCMkMsUUFBUSxFQUFFMUMsT0FIYztRQUt4QjJDLE9BQU8sRUFBRTtNQUxlLENBQVAsQ0FBbkI7TUFPQSxDQUFDO1FBQUNyQixZQUFEO1FBQWVPLFVBQWY7UUFBMkJGLFVBQTNCO1FBQXVDckIsYUFBdkM7UUFBc0RXLFVBQXREO1FBQWtFVjtNQUFsRSxJQUNDVCxvQkFBb0IsQ0FBQ0MsSUFBRCxFQUFPQyxPQUFQLENBRHRCO0lBRUQsQ0FiSyxDQUFOO0lBZUE0QyxLQUFLLENBQUMsa0JBQWtCO01BQ3RCLE1BQU1SLFVBQVUsQ0FBQ1MsS0FBWCxFQUFOO0lBQ0QsQ0FGSSxDQUFMO0lBSUFWLFFBQVEsQ0FBQyxrQkFBRCxFQUFxQixZQUFZO01BQ3ZDVyxFQUFFLENBQUMsbURBQUQsRUFBc0Qsa0JBQWtCO1FBQ3hFLE1BQU1DLFVBQVUsR0FBRyxFQUFuQjtRQUNBLElBQUlDLEtBQUssR0FBRyxDQUFaOztRQUNBLEdBQUc7VUFDRCxNQUFNO1lBQUN4QztVQUFELElBQWMsTUFBTWMsWUFBWSxDQUNwQztZQUNFRSxZQUFZLEVBQUU7Y0FBQ0MsV0FBVyxFQUFFTztZQUFkO1VBRGhCLENBRG9DLEVBSXBDO1lBQ0VpQixPQUFPLEVBQUU7Y0FDUCxxQkFBcUI7WUFEZCxDQURYO1lBT0VDLE1BQU0sRUFBRSxLQVBWO1lBUUVDLHVCQUF1QixFQUFFO1VBUjNCLENBSm9DLENBQXRDO1VBZ0JBSixVQUFVLENBQUNLLElBQVgsQ0FBZ0I1QyxTQUFoQjtVQUNBd0MsS0FBSztRQUNOLENBbkJELFFBbUJTQSxLQUFLLEdBQUcsQ0FuQmpCOztRQW9CQTNDLGVBQUEsQ0FBRWdELElBQUYsQ0FBT04sVUFBUCxFQUFtQk8sTUFBbkIsQ0FBMEIxRCxNQUExQixDQUFpQzJELEtBQWpDLENBQXVDLENBQXZDOztRQUVBLE1BQU07VUFBQ0MsTUFBRDtVQUFTOUM7UUFBVCxJQUFpQixNQUFNaUIsVUFBVSxDQUFDb0IsVUFBVSxDQUFDLENBQUQsQ0FBWCxDQUF2QztRQUNBUyxNQUFNLENBQUM1RCxNQUFQLENBQWMyRCxLQUFkLENBQW9CLEdBQXBCO1FBQ0EzRCxNQUFNLENBQUMyRCxLQUFQLENBQWE3QyxJQUFJLENBQUNNLEtBQWxCLEVBQXlCLElBQXpCO01BQ0QsQ0E1QkMsQ0FBRjtNQThCQThCLEVBQUUsQ0FBQyw0REFBRCxFQUErRCxrQkFBa0I7UUFDakYsTUFBTVcsSUFBSSxHQUFHLEVBQWI7UUFDQSxJQUFJVCxLQUFLLEdBQUcsQ0FBWjs7UUFDQSxHQUFHO1VBQ0RTLElBQUksQ0FBQ0wsSUFBTCxDQUNFOUIsWUFBWSxDQUNWO1lBQ0VFLFlBQVksRUFBRTtjQUNaQyxXQUFXLEVBQUVPO1lBREQ7VUFEaEIsQ0FEVSxFQU1WO1lBQ0VpQixPQUFPLEVBQUU7Y0FDUCxxQkFBcUI7WUFEZDtVQURYLENBTlUsQ0FEZDtVQWNBRCxLQUFLO1FBQ04sQ0FoQkQsUUFnQlNBLEtBQUssR0FBRyxDQWhCakI7O1FBaUJBLE1BQU1ELFVBQVUsR0FBRzFDLGVBQUEsQ0FBRXFELEdBQUYsQ0FBTSxNQUFNQyxpQkFBQSxDQUFFQyxHQUFGLENBQU1ILElBQU4sQ0FBWixFQUF5QixXQUF6QixDQUFuQjs7UUFDQXBELGVBQUEsQ0FBRWdELElBQUYsQ0FBT04sVUFBUCxFQUFtQk8sTUFBbkIsQ0FBMEIxRCxNQUExQixDQUFpQzJELEtBQWpDLENBQXVDLENBQXZDOztRQUVBLE1BQU07VUFBQ0MsTUFBRDtVQUFTOUM7UUFBVCxJQUFpQixNQUFNaUIsVUFBVSxDQUFDb0IsVUFBVSxDQUFDLENBQUQsQ0FBWCxDQUF2QztRQUNBUyxNQUFNLENBQUM1RCxNQUFQLENBQWMyRCxLQUFkLENBQW9CLEdBQXBCO1FBQ0EzRCxNQUFNLENBQUMyRCxLQUFQLENBQWE3QyxJQUFJLENBQUNNLEtBQWxCLEVBQXlCLElBQXpCO01BQ0QsQ0ExQkMsQ0FBRjtNQTRCQThCLEVBQUUsQ0FBQyxpRUFBRCxFQUFvRSxrQkFBa0I7UUFDdEYsSUFBSTtVQUFDVSxNQUFEO1VBQVM5QztRQUFULElBQWlCLE1BQU1JLGNBQUEsQ0FBTUMsSUFBTixDQUFXVCxhQUFYLEVBQTBCO1VBQ25Ea0IsWUFBWSxFQUFFO1lBQ1pDLFdBQVcsRUFBRU87VUFERDtRQURxQyxDQUExQixDQUEzQjtRQU1Bd0IsTUFBTSxDQUFDNUQsTUFBUCxDQUFjMkQsS0FBZCxDQUFvQixHQUFwQjtRQUNBM0QsTUFBTSxDQUFDaUUsS0FBUCxDQUFhbkQsSUFBSSxDQUFDTSxLQUFMLENBQVdSLFNBQXhCO1FBQ0FFLElBQUksQ0FBQ00sS0FBTCxDQUFXUSxZQUFYLENBQXdCc0MsWUFBeEIsQ0FBcUNsRSxNQUFyQyxDQUE0QzJELEtBQTVDLENBQWtEdkIsV0FBVyxDQUFDOEIsWUFBOUQ7UUFDQXBELElBQUksQ0FBQ00sS0FBTCxDQUFXUSxZQUFYLENBQXdCdUMsVUFBeEIsQ0FBbUNuRSxNQUFuQyxDQUEwQzJELEtBQTFDLENBQWdEdkIsV0FBVyxDQUFDLG1CQUFELENBQTNEO1FBRUEsQ0FBQztVQUFDd0IsTUFBRDtVQUFTOUM7UUFBVCxJQUFpQixNQUFNaUIsVUFBVSxDQUF3QlUsQ0FBQyxDQUFDN0IsU0FBMUIsQ0FBbEM7UUFFQWdELE1BQU0sQ0FBQzVELE1BQVAsQ0FBYzJELEtBQWQsQ0FBb0IsR0FBcEI7UUFDQTNELE1BQU0sQ0FBQzJELEtBQVAsQ0FBYTdDLElBQUksQ0FBQ00sS0FBbEIsRUFBeUIsSUFBekI7UUFDQXBCLE1BQU0sQ0FBQzJELEtBQVAsQ0FBYWxCLENBQUMsQ0FBQzdCLFNBQWYsRUFBMEIsSUFBMUI7TUFDRCxDQWpCQyxDQUFGO0lBa0JELENBN0VPLENBQVI7SUErRUFzQyxFQUFFLENBQUNrQixJQUFILENBQVEsK0NBQVIsRUFBeUQsa0JBQWtCLENBQUUsQ0FBN0U7SUFFQTdCLFFBQVEsQ0FBQyxrQkFBRCxFQUFxQixZQUFZO01BQ3ZDLElBQUk4QixtQkFBSixFQUF5QkMsb0JBQXpCOztNQUtBLGVBQWVDLG1CQUFmLENBQW1DQyxPQUFuQyxFQUE0QztRQUMxQyxNQUFNQyxJQUFJLEdBQUdoRSxlQUFBLENBQUVpRSxTQUFGLENBQVl0QyxXQUFaLENBQWI7O1FBQ0FxQyxJQUFJLENBQUMsMEJBQUQsQ0FBSixHQUFtQ0QsT0FBbkM7UUFDQSxPQUFPLE1BQU05QyxZQUFZLENBQUM7VUFBQ0UsWUFBWSxFQUFFO1lBQUNDLFdBQVcsRUFBRTRDO1VBQWQ7UUFBZixDQUFELENBQXpCO01BQ0Q7O01BRUQvQixNQUFNLENBQUMsWUFBWTtRQUNqQjJCLG1CQUFtQixHQUFHNUIsQ0FBQyxDQUFDa0MsV0FBeEI7O1FBQ0FsQyxDQUFDLENBQUNrQyxXQUFGLEdBQWdCLFlBQVk7VUFDMUIsT0FBTyxLQUFQO1FBQ0QsQ0FGZSxDQUVkQyxJQUZjLENBRVRuQyxDQUZTLENBQWhCOztRQUlBNkIsb0JBQW9CLEdBQUc3QixDQUFDLENBQUNvQyxZQUF6Qjs7UUFDQXBDLENBQUMsQ0FBQ29DLFlBQUYsR0FBaUIsa0JBQWtCO1VBQ2pDLE1BQU1kLGlCQUFBLENBQUVlLEtBQUYsQ0FBUSxHQUFSLENBQU47VUFDQSxPQUFPLENBQUMsS0FBRCxDQUFQO1FBQ0QsQ0FIZ0IsQ0FHZkYsSUFIZSxDQUdWbkMsQ0FIVSxDQUFqQjtNQUlELENBWEssQ0FBTjtNQWFBTyxLQUFLLENBQUMsWUFBWTtRQUNoQlAsQ0FBQyxDQUFDa0MsV0FBRixHQUFnQk4sbUJBQWhCO1FBQ0E1QixDQUFDLENBQUNvQyxZQUFGLEdBQWlCUCxvQkFBakI7TUFDRCxDQUhJLENBQUw7TUFLQXBCLEVBQUUsQ0FBQyxxQ0FBRCxFQUF3QyxrQkFBa0I7UUFDMUQsSUFBSTZCLFVBQVUsR0FBRyxNQUFNUixtQkFBbUIsRUFBMUM7UUFDQTlCLENBQUMsQ0FBQ3VDLG1CQUFGLENBQXNCaEYsTUFBdEIsQ0FBNkJpRixFQUE3QixDQUFnQ0MsS0FBaEMsQ0FBc0MsQ0FBdEM7UUFDQSxNQUFNbkQsVUFBVSxDQUFDZ0QsVUFBVSxDQUFDbkUsU0FBWixDQUFoQjtNQUNELENBSkMsQ0FBRjtNQU1Bc0MsRUFBRSxDQUFDLHFEQUFELEVBQXdELGtCQUFrQjtRQUMxRSxJQUFJNkIsVUFBVSxHQUFHLE1BQU1SLG1CQUFtQixDQUFDLElBQUQsQ0FBMUM7UUFDQSxNQUFNM0QsU0FBUyxHQUEwQjZCLENBQUMsQ0FBQzdCLFNBQTNDO1FBQ0EsTUFBTUQsV0FBVyxDQUFDQyxTQUFELEVBQVksU0FBWixFQUF1QjtVQUN0Q3VFLEtBQUssRUFBRSxNQUQrQjtVQUV0Qy9ELEtBQUssRUFBRTtRQUYrQixDQUF2QixDQUFqQjtRQUlBLE1BQU0yQyxpQkFBQSxDQUFFZSxLQUFGLENBQVEsR0FBUixDQUFOO1FBQ0EsTUFBTTFELEtBQUssR0FBRyxNQUFNYSxVQUFVLENBQUNyQixTQUFELENBQTlCO1FBQ0FaLE1BQU0sQ0FBQzJELEtBQVAsQ0FBYXZDLEtBQUssQ0FBQ2dFLEtBQW5CLEVBQTBCLG9CQUExQjtRQUNBcEYsTUFBTSxDQUFDMkQsS0FBUCxDQUFhbEIsQ0FBQyxDQUFDN0IsU0FBZixFQUEwQixJQUExQjtRQUNBLE1BQU15RSxJQUFJLEdBQUcsQ0FBQyxNQUFNdEQsVUFBVSxDQUFDZ0QsVUFBVSxDQUFDbkUsU0FBWixDQUFqQixFQUF5Q0UsSUFBekMsQ0FBOENNLEtBQTNEO1FBQ0FwQixNQUFNLENBQUMyRCxLQUFQLENBQWEwQixJQUFiLGFBQWFBLElBQWIsdUJBQWFBLElBQUksQ0FBRUQsS0FBbkIsRUFBMEIsb0JBQTFCO01BQ0QsQ0FiQyxDQUFGO01BZUFsQyxFQUFFLENBQUMsaURBQUQsRUFBb0Qsa0JBQWtCO1FBQ3RFLElBQUk2QixVQUFVLEdBQUcsTUFBTVIsbUJBQW1CLENBQUMsR0FBRCxDQUExQztRQUNBLElBQUllLEtBQUssR0FBR0MsSUFBSSxDQUFDQyxHQUFMLEVBQVo7UUFDQSxNQUFNcEUsS0FBSyxHQUFHLE1BQU1ULFdBQVcsQ0FBd0I4QixDQUFDLENBQUM3QixTQUExQixFQUFzQyxVQUF0QyxFQUFrRDtVQUMvRXVFLEtBQUssRUFBRSxNQUR3RTtVQUUvRS9ELEtBQUssRUFBRTtRQUZ3RSxDQUFsRCxDQUEvQjtRQUlBLENBQUNtRSxJQUFJLENBQUNDLEdBQUwsS0FBYUYsS0FBZCxFQUFxQnRGLE1BQXJCLENBQTRCaUYsRUFBNUIsQ0FBK0JDLEtBQS9CLENBQXFDLEdBQXJDO1FBQ0E5RCxLQUFLLENBQUNwQixNQUFOLENBQWF5RixHQUFiLENBQWlCLENBQUMsS0FBRCxDQUFqQjtRQUNBLE1BQU0xRCxVQUFVLENBQUNnRCxVQUFVLENBQUNuRSxTQUFaLENBQWhCO01BQ0QsQ0FWQyxDQUFGO01BWUFzQyxFQUFFLENBQUMsNkNBQUQsRUFBZ0Qsa0JBQWtCO1FBQUE7O1FBQ2xFVCxDQUFDLENBQUN1QyxtQkFBRixHQUF3QixDQUF4QjtRQUNBLElBQUlELFVBQVUsR0FBRyxNQUFNUixtQkFBbUIsQ0FBQyxDQUFELENBQTFDO1FBRUEsTUFBTTVELFdBQVcsQ0FBd0I4QixDQUFDLENBQUM3QixTQUExQixFQUFzQyxTQUF0QyxFQUFpRDtVQUNoRXVFLEtBQUssRUFBRSxNQUR5RDtVQUVoRS9ELEtBQUssRUFBRTtRQUZ5RCxDQUFqRCxDQUFqQjtRQUlBLE1BQU0yQyxpQkFBQSxDQUFFZSxLQUFGLENBQVEsR0FBUixDQUFOO1FBQ0EsTUFBTTFELEtBQUssR0FBRyxNQUFNYSxVQUFVLENBQXdCUSxDQUFDLENBQUM3QixTQUExQixDQUE5QjtRQUNBLHVCQUFBUSxLQUFLLENBQUM4QyxZQUFOLDRFQUFvQmxFLE1BQXBCLENBQTJCMkQsS0FBM0IsQ0FBaUN2QixXQUFXLENBQUM4QixZQUE3QztRQUNBLE1BQU1tQixJQUFJLEdBQUcsQ0FBQyxNQUFNdEQsVUFBVSxDQUFDZ0QsVUFBVSxDQUFDbkUsU0FBWixDQUFqQixFQUF5Q0UsSUFBekMsQ0FBOENNLEtBQTNEO1FBQ0FwQixNQUFNLENBQUMyRCxLQUFQLENBQWEwQixJQUFiLEVBQW1CLElBQW5CO1FBRUE1QyxDQUFDLENBQUN1QyxtQkFBRixHQUF3QixLQUFLLElBQTdCO01BQ0QsQ0FmQyxDQUFGO01BaUJBOUIsRUFBRSxDQUFDLDBEQUFELEVBQTZELGtCQUFrQjtRQUMvRSxJQUFJNkIsVUFBVSxHQUFHLE1BQU1SLG1CQUFtQixDQUFDLElBQUQsQ0FBMUM7UUFHQSxNQUFNO1VBQUMzRDtRQUFELElBQWM2QixDQUFwQjtRQUVBLE1BQU05QixXQUFXLENBQXdCOEIsQ0FBQyxDQUFDN0IsU0FBMUIsRUFBc0MsU0FBdEMsRUFBaUQ7VUFDaEV1RSxLQUFLLEVBQUUsTUFEeUQ7VUFFaEUvRCxLQUFLLEVBQUU7UUFGeUQsQ0FBakQsQ0FBakI7UUFJQSxNQUFNMkMsaUJBQUEsQ0FBRWUsS0FBRixDQUFRLEdBQVIsQ0FBTjtRQUNBLE1BQU0xRCxLQUFLLEdBQUcsTUFBTWEsVUFBVSxDQUF3QnJCLFNBQXhCLENBQTlCO1FBQ0FRLEtBQUssQ0FBQ2dFLEtBQU4sQ0FBWXBGLE1BQVosQ0FBbUIyRCxLQUFuQixDQUF5QixvQkFBekI7UUFDQTNELE1BQU0sQ0FBQzJELEtBQVAsQ0FBYWxCLENBQUMsQ0FBQzdCLFNBQWYsRUFBMEIsSUFBMUI7UUFDQSxNQUFNeUUsSUFBSSxHQUFHLENBQUMsTUFBTXRELFVBQVUsQ0FBQ2dELFVBQVUsQ0FBQ25FLFNBQVosQ0FBakIsRUFBeUNFLElBQXpDLENBQThDTSxLQUEzRDtRQUN5RGlFLElBQUQsQ0FBT0QsS0FBekMsQ0FBZ0RwRixNQUFoRCxDQUF1RDJELEtBQXZELENBQ3BCLG9CQURvQjtNQUd2QixDQWxCQyxDQUFGO01Bb0JBVCxFQUFFLENBQUMsMkRBQUQsRUFBOEQsa0JBQWtCO1FBRWhGbEQsTUFBTSxDQUFDMEYsR0FBUCxDQUFXekIsS0FBWCxDQUFpQnhCLENBQUMsQ0FBQ2tELGNBQW5CO1FBQ0EsSUFBSVosVUFBVSxHQUFHLE1BQU1SLG1CQUFtQixDQUFDLElBQUQsQ0FBMUM7UUFDQVEsVUFBVSxDQUFDbkUsU0FBWCxDQUFxQlosTUFBckIsQ0FBNEIyRCxLQUE1QixDQUFrQ2xCLENBQUMsQ0FBQzdCLFNBQXBDO1FBRUFaLE1BQU0sQ0FBQ2lFLEtBQVAsQ0FBYXhCLENBQUMsQ0FBQ2tELGNBQWY7UUFDQSxNQUFNNUQsVUFBVSxDQUFDZ0QsVUFBVSxDQUFDbkUsU0FBWixDQUFoQjtRQUVBWixNQUFNLENBQUMwRixHQUFQLENBQVd6QixLQUFYLENBQWlCeEIsQ0FBQyxDQUFDa0QsY0FBbkI7TUFDRCxDQVZDLENBQUY7SUFXRCxDQS9HTyxDQUFSO0lBaUhBcEQsUUFBUSxDQUFDLGNBQUQsRUFBaUIsWUFBWTtNQUNuQ0csTUFBTSxDQUFDLFlBQVk7UUFDakJELENBQUMsQ0FBQ21ELFFBQUYsR0FBYSxJQUFJQyxzQkFBSixDQUFtQjtVQUFDQyxzQkFBc0IsRUFBRTtRQUF6QixDQUFuQixDQUFiO01BQ0QsQ0FGSyxDQUFOO01BR0E1QyxFQUFFLENBQUMsdUNBQUQsRUFBMEMsWUFBWTtRQUN0RFQsQ0FBQyxDQUFDbUQsUUFBRixDQUFXRyxXQUFYLEdBQXlCRCxzQkFBekIsQ0FBZ0Q5RixNQUFoRCxDQUF1RGlGLEVBQXZELENBQTBEZSxLQUExRDtNQUNELENBRkMsQ0FBRjtNQUdBOUMsRUFBRSxDQUFDLGdFQUFELEVBQW1FLGtCQUFrQjtRQUNyRixNQUFNVCxDQUFDLENBQUNtRCxRQUFGLENBQVdLLE1BQVgsQ0FBa0I7VUFBQ0gsc0JBQXNCLEVBQUU7UUFBekIsQ0FBbEIsRUFBa0Q5RixNQUFsRCxDQUF5RDBGLEdBQXpELENBQTZEVCxFQUE3RCxDQUFnRWlCLFFBQXRFO01BQ0QsQ0FGQyxDQUFGO01BR0FoRCxFQUFFLENBQUMseUNBQUQsRUFBNEMsa0JBQWtCO1FBQzlELE1BQU1ULENBQUMsQ0FBQ21ELFFBQUYsQ0FFSEssTUFGRyxDQUVJLGNBRkosRUFHSGpHLE1BSEcsQ0FHSWlGLEVBSEosQ0FHT2tCLFlBSFAsQ0FHb0IsTUFIcEIsQ0FBTjtNQUlELENBTEMsQ0FBRjtJQU1ELENBaEJPLENBQVI7SUFrQkE1RCxRQUFRLENBQUMsa0JBQUQsRUFBcUIsWUFBWTtNQUV2QyxJQUFJNkQsT0FBSjtNQUNBQyxVQUFVLENBQUMsWUFBWTtRQUNyQkQsT0FBTyxHQUFHRSxjQUFBLENBQU1DLGFBQU4sRUFBVjtNQUNELENBRlMsQ0FBVjtNQUlBQyxTQUFTLENBQUMsWUFBWTtRQUNwQkosT0FBTyxDQUFDSyxPQUFSO01BQ0QsQ0FGUSxDQUFUO01BSUF2RCxFQUFFLENBQUMseURBQUQsRUFBNEQsa0JBQWtCO1FBQzlFa0QsT0FBTyxDQUFDTSxJQUFSLENBQWFqRSxDQUFiLEVBQWdCLFdBQWhCLEVBQTZCa0UsU0FBN0IsQ0FBdUMsa0JBQWtCO1VBQ3ZELE1BQU01QyxpQkFBQSxDQUFFZSxLQUFGLENBQVEsSUFBUixDQUFOO1FBQ0QsQ0FGRDtRQUdBLE1BQU04QixVQUFVLEdBQUd2RixVQUFVLENBQUMsUUFBRCxFQUFXO1VBQUNJLGNBQWMsRUFBRTtRQUFqQixDQUFYLENBQTdCO1FBRUEsTUFBTXNDLGlCQUFBLENBQUVlLEtBQUYsQ0FBUSxHQUFSLENBQU47UUFDQSxNQUFNK0Isb0JBQW9CLEdBQUcsSUFBSTlDLGlCQUFKLENBQU0sQ0FBQytDLE9BQUQsRUFBVUMsTUFBVixLQUFxQjtVQUN0REMsVUFBVSxDQUNSLE1BQ0VELE1BQU0sQ0FDSixJQUFJRSxLQUFKLENBQ0UsNkVBREYsQ0FESSxDQUZBLEVBT1IsSUFQUSxDQUFWO1VBU0F4RSxDQUFDLENBQUN5RSxvQkFBRixDQUF1QkosT0FBdkI7UUFDRCxDQVg0QixDQUE3QjtRQVlBckUsQ0FBQyxDQUFDMEUsdUJBQUYsQ0FBMEIsSUFBSUYsS0FBSixDQUFVLGFBQVYsQ0FBMUI7UUFDQSxNQUFNN0YsS0FBSyxHQUFHLE1BQU13RixVQUFwQjtRQUNBeEYsS0FBSyxDQUFDZ0csT0FBTixDQUFjcEgsTUFBZCxDQUFxQnFILE9BQXJCLENBQTZCLGFBQTdCO1FBQ0EsTUFBTVIsb0JBQU47TUFDRCxDQXZCQyxDQUFGO0lBd0JELENBbkNPLENBQVI7SUFxQ0F0RSxRQUFRLENBQUMsZUFBRCxFQUFrQixZQUFZO01BQ3BDVyxFQUFFLENBQUMsZ0RBQUQsRUFBbUQsa0JBQWtCO1FBQ3JFLE1BQU1vRSxPQUFPLEdBQUcsTUFBTTVGLFlBQVksQ0FBQztVQUFDRSxZQUFZLEVBQUU7WUFBQ0MsV0FBVyxFQUFFTztVQUFkO1FBQWYsQ0FBRCxDQUFsQztRQUNBLE1BQU1tRixHQUFHLEdBQUcsTUFBTXRGLFVBQVUsQ0FBQ3FGLE9BQU8sQ0FBQzFHLFNBQVQsQ0FBNUI7UUFDQVosTUFBTSxDQUFDMEYsR0FBUCxDQUFXekIsS0FBWCxDQUFpQnNELEdBQUcsQ0FBQ0MsTUFBckI7UUFDQSxNQUFNekYsVUFBVSxDQUFDdUYsT0FBTyxDQUFDMUcsU0FBVCxDQUFoQjtNQUNELENBTEMsQ0FBRjtNQU1Bc0MsRUFBRSxDQUFDLGtDQUFELEVBQXFDLGtCQUFrQjtRQUFBOztRQUN2RCxNQUFNdUIsSUFBSSxHQUFHLEVBQUMsR0FBR3JDLFdBQUo7VUFBaUIsdUJBQXVCO1FBQXhDLENBQWI7UUFDQSxNQUFNa0YsT0FBTyxHQUFHLE1BQU01RixZQUFZLENBQUM7VUFBQ0UsWUFBWSxFQUFFO1lBQUNDLFdBQVcsRUFBRTRDO1VBQWQ7UUFBZixDQUFELENBQWxDO1FBQ0EsTUFBTThDLEdBQUcsR0FBRyxNQUFNdEYsVUFBVSxDQUFDcUYsT0FBTyxDQUFDMUcsU0FBVCxDQUE1QjtRQUNBWixNQUFNLENBQUNpRSxLQUFQLENBQWFzRCxHQUFHLENBQUNDLE1BQWpCO1FBQ0F4SCxNQUFNLENBQUNpRSxLQUFQLGdCQUFhc0QsR0FBRyxDQUFDQyxNQUFqQixnREFBYSxZQUFZQyxtQkFBekI7UUFDQXpILE1BQU0sQ0FBQ2lFLEtBQVAsaUJBQWFzRCxHQUFHLENBQUNDLE1BQWpCLGlEQUFhLGFBQVlFLGlCQUF6QjtRQUNBLGdCQUFBSCxHQUFHLENBQUNDLE1BQUosOERBQVlDLG1CQUFaLENBQWdDLENBQWhDLEVBQW1DekgsTUFBbkMsQ0FBMENpRixFQUExQyxDQUE2QzBDLENBQTdDLENBQStDLFFBQS9DO1FBQ0EsZ0JBQUFKLEdBQUcsQ0FBQ0MsTUFBSiw4REFBWUUsaUJBQVosQ0FBOEIsQ0FBOUIsRUFBaUMxSCxNQUFqQyxDQUF3Q2lGLEVBQXhDLENBQTJDMEMsQ0FBM0MsQ0FBNkMsUUFBN0M7UUFDQSxNQUFNNUYsVUFBVSxDQUFDdUYsT0FBTyxDQUFDMUcsU0FBVCxDQUFoQjtNQUNELENBVkMsQ0FBRjtJQVdELENBbEJPLENBQVI7RUFtQkQsQ0FuVE8sQ0FBUjtBQW9URCJ9
370
+ exports.driverE2ETestSuite = driverE2ETestSuite;
371
+ /**
372
+ * A {@linkcode DriverClass}, except using the base {@linkcode Driver} type instead of `ExternalDriver`.
373
+ * This allows the suite to work for `BaseDriver`.
374
+ * @template {Driver} P
375
+ * @typedef {import('@appium/types').DriverClass<P>} DriverClass
376
+ */
377
+ /**
378
+ * @typedef {import('@appium/types').Driver} Driver
379
+ * @typedef {import('@appium/types').Constraints} Constraints
380
+ * @typedef {import('@appium/types').DriverStatic} DriverStatic
381
+ * @typedef {import('@appium/types').StringRecord} StringRecord
382
+ * @typedef {import('@appium/types').BaseDriverCapConstraints} BaseDriverCapConstraints
383
+ * @typedef {import('@appium/types').BaseNSCapabilities} BaseNSCapabilities
384
+ * @typedef {import('axios').AxiosRequestConfig} AxiosRequestConfig
385
+ * @typedef {import('@appium/types').SingularSessionData} SingularSessionData
386
+ */
387
+ /**
388
+ * @template T,D
389
+ * @typedef {import('axios').AxiosResponse<T, D>} AxiosResponse
390
+ */
391
+ /**
392
+ * @template {Constraints} [C=BaseDriverCapConstraints]
393
+ * @template {StringRecord|void} [Extra=void]
394
+ * @typedef NewSessionData
395
+ * @property {import('type-fest').RequireAtLeastOne<import('@appium/types').W3CCapabilities<C, Extra>, 'firstMatch'|'alwaysMatch'>} capabilities
396
+ */
397
+ /**
398
+ * @template {Constraints} [C=BaseDriverCapConstraints]
399
+ * @template {StringRecord|void} [Extra=void]
400
+ * @typedef NewSessionResponse
401
+ * @property {string} sessionId,
402
+ * @property {import('@appium/types').Capabilities<C, Extra>} capabilities
403
+ */
404
+ /**
405
+ * Some E2E helpers for making requests and managing sessions
406
+ * See {@linkcode createSessionHelpers}
407
+ * @template [CommandData=unknown]
408
+ * @template [ResponseData=any]
409
+ * @typedef SessionHelpers
410
+ * @property {string} newSessionURL - URL to create a new session. Can be used with raw `axios` requests to fully inspect raw response. Mostly, this will not be used.
411
+ * @property {(data: NewSessionData, config?: AxiosRequestConfig) => Promise<NewSessionResponse>} startSession - Begin a session
412
+ * @property {(sessionId: string) => Promise<AxiosResponse<{value: {error?: string}?}, {validateStatus: null}>>} endSession - End a session. _Note: resolves with raw response object_
413
+ * @property {(sessionId: string) => Promise<SingularSessionData>} getSession - Get info about a session
414
+ * @property {(sessionId: string, cmdName: string, data?: CommandData, config?: AxiosRequestConfig) => Promise<ResponseData>} postCommand - Send an arbitrary command via `POST`.
415
+ * @property {(sessionIdOrCmdName: string, cmdNameOrConfig: string|AxiosRequestConfig, config?: AxiosRequestConfig) => Promise<ResponseData>} getCommand - Send an arbitrary command via `GET`. Optional `sessionId`.
416
+ */
417
+ //# sourceMappingURL=e2e-suite.js.map