@appium/test-support 1.3.21 → 1.4.1
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 +8 -8
- package/build/lib/driver-e2e-suite.d.ts +77 -0
- package/build/lib/driver-e2e-suite.d.ts.map +1 -0
- package/build/lib/driver-e2e-suite.js +388 -0
- package/build/lib/driver-unit-suite.d.ts +12 -0
- package/build/lib/driver-unit-suite.d.ts.map +1 -0
- package/build/lib/driver-unit-suite.js +564 -0
- package/build/lib/env-utils.d.ts +5 -0
- package/build/lib/env-utils.d.ts.map +1 -0
- package/build/lib/env-utils.js +3 -6
- package/build/lib/helpers.d.ts +19 -0
- package/build/lib/helpers.d.ts.map +1 -0
- package/build/lib/helpers.js +49 -0
- package/build/lib/index.d.ts +12 -0
- package/build/lib/index.d.ts.map +1 -0
- package/build/lib/index.js +59 -2
- package/build/lib/log-utils.d.ts +34 -0
- package/build/lib/log-utils.d.ts.map +1 -0
- package/build/lib/log-utils.js +4 -8
- package/build/lib/logger.d.ts +3 -0
- package/build/lib/logger.d.ts.map +1 -0
- package/build/lib/logger.js +2 -2
- package/build/lib/mock-utils.d.ts +47 -0
- package/build/lib/mock-utils.d.ts.map +1 -0
- package/build/lib/mock-utils.js +57 -29
- package/build/lib/plugin-e2e-harness.d.ts +67 -0
- package/build/lib/plugin-e2e-harness.d.ts.map +1 -0
- package/build/lib/plugin-e2e-harness.js +144 -0
- package/build/lib/sandbox-utils.d.ts +41 -0
- package/build/lib/sandbox-utils.d.ts.map +1 -0
- package/build/lib/sandbox-utils.js +46 -29
- package/build/lib/time-utils.d.ts +9 -0
- package/build/lib/time-utils.d.ts.map +1 -0
- package/build/lib/time-utils.js +1 -1
- package/build/lib/unhandled-rejection.d.ts +2 -0
- package/build/lib/unhandled-rejection.d.ts.map +1 -0
- package/build/tsconfig.tsbuildinfo +1 -0
- package/lib/driver-e2e-suite.js +463 -0
- package/lib/driver-unit-suite.js +642 -0
- package/lib/env-utils.js +5 -3
- package/lib/helpers.js +68 -0
- package/lib/index.js +17 -7
- package/lib/log-utils.js +25 -8
- package/lib/logger.js +1 -1
- package/lib/mock-utils.js +89 -25
- package/lib/plugin-e2e-harness.js +163 -0
- package/lib/sandbox-utils.js +70 -26
- package/lib/time-utils.js +1 -0
- package/package.json +15 -6
package/README.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
appium
|
|
1
|
+
@appium/test-support
|
|
2
2
|
===================
|
|
3
3
|
|
|
4
4
|
A collection of test utility lib used across Appium packages.
|
|
5
5
|
|
|
6
|
-
[](https://travis-ci.org/appium/@appium/test-support)
|
|
7
7
|
|
|
8
8
|
## Install
|
|
9
9
|
|
|
10
10
|
```
|
|
11
|
-
npm install appium
|
|
11
|
+
npm install @appium/test-support --save-dev
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
## Api
|
|
@@ -16,7 +16,7 @@ npm install appium-test-support --save-dev
|
|
|
16
16
|
### stubEnv
|
|
17
17
|
|
|
18
18
|
```js
|
|
19
|
-
import { stubEnv } from 'appium
|
|
19
|
+
import { stubEnv } from '@appium/test-support';
|
|
20
20
|
|
|
21
21
|
describe('myTest', () => {
|
|
22
22
|
stubEnv();
|
|
@@ -30,7 +30,7 @@ describe('myTest', () => {
|
|
|
30
30
|
### stubLog
|
|
31
31
|
|
|
32
32
|
```js
|
|
33
|
-
import { stubLog } from 'appium
|
|
33
|
+
import { stubLog } from '@appium/test-support';
|
|
34
34
|
|
|
35
35
|
describe('myTest', () => {
|
|
36
36
|
let sandbox;
|
|
@@ -62,7 +62,7 @@ describe('myTest', () => {
|
|
|
62
62
|
Use when mixing up sinon apis (mocks, spies stubs).
|
|
63
63
|
|
|
64
64
|
```js
|
|
65
|
-
import { withSandbox } from 'appium
|
|
65
|
+
import { withSandbox } from '@appium/test-support';
|
|
66
66
|
|
|
67
67
|
let api = {
|
|
68
68
|
abc: () => { return 'abc'; }
|
|
@@ -85,7 +85,7 @@ describe('MyTest', withSandbox({mocks: {api}}, (S) => {
|
|
|
85
85
|
When using mainly stubs.
|
|
86
86
|
|
|
87
87
|
```js
|
|
88
|
-
import { withMocks } from 'appium
|
|
88
|
+
import { withMocks } from '@appium/test-support';
|
|
89
89
|
|
|
90
90
|
let api = {
|
|
91
91
|
abc: () => { return 'abc'; }
|
|
@@ -103,7 +103,7 @@ describe('withMocks', withMocks({api}, (mocks) => {
|
|
|
103
103
|
### fakeTime
|
|
104
104
|
|
|
105
105
|
```js
|
|
106
|
-
import { fakeTime } from 'appium
|
|
106
|
+
import { fakeTime } from '@appium/test-support';
|
|
107
107
|
|
|
108
108
|
function doSomething() {
|
|
109
109
|
return new B.Promise((resolve) => {
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates some helper functions for E2E tests to manage sessions.
|
|
3
|
+
* @template [CommandData=unknown]
|
|
4
|
+
* @template [ResponseData=any]
|
|
5
|
+
* @param {number} port - Port on which the server is running. Typically this will be retrieved via `get-port` beforehand
|
|
6
|
+
* @param {string} [address] - Address/host on which the server is running. Defaults to {@linkcode TEST_HOST}
|
|
7
|
+
* @returns {SessionHelpers<CommandData, ResponseData>}
|
|
8
|
+
*/
|
|
9
|
+
export function createSessionHelpers<CommandData = unknown, ResponseData = any>(port: number, address?: string | undefined): SessionHelpers<CommandData, ResponseData>;
|
|
10
|
+
/**
|
|
11
|
+
* Creates E2E test suites for a driver.
|
|
12
|
+
* @template {Driver} P
|
|
13
|
+
* @param {DriverClass<P>} DriverClass
|
|
14
|
+
* @param {AppiumW3CCapabilities} [defaultCaps]
|
|
15
|
+
*/
|
|
16
|
+
export function driverE2ETestSuite<P extends import("@appium/types").Driver>(DriverClass: DriverClass<P>, defaultCaps?: Partial<import("@wdio/types/build/Capabilities").Capabilities & import("@wdio/types/build/Capabilities").AppiumW3CCapabilities & {
|
|
17
|
+
[x: `${string}:${string}`]: any;
|
|
18
|
+
}> | undefined): void;
|
|
19
|
+
/**
|
|
20
|
+
* A {@linkcode DriverClass }, except using the base {@linkcode Driver } type instead of `ExternalDriver`.
|
|
21
|
+
* This allows the suite to work for `BaseDriver`.
|
|
22
|
+
*/
|
|
23
|
+
export type DriverClass<P extends import("@appium/types").Driver> = import('@appium/types').DriverClass<P>;
|
|
24
|
+
export type Capabilities = import('@appium/types').Capabilities;
|
|
25
|
+
export type Driver = import('@appium/types').Driver;
|
|
26
|
+
export type DriverStatic = import('@appium/types').DriverStatic;
|
|
27
|
+
export type AppiumW3CCapabilities = import('@appium/types').AppiumW3CCapabilities;
|
|
28
|
+
export type AxiosRequestConfig = import('axios').AxiosRequestConfig;
|
|
29
|
+
export type SingularSessionData = import('@appium/types').SingularSessionData;
|
|
30
|
+
export type AxiosResponse<T, D> = import('axios').AxiosResponse<T, D>;
|
|
31
|
+
export type NewSessionData = {
|
|
32
|
+
capabilities: import('type-fest').RequireAtLeastOne<import('@appium/types').W3CCapabilities, 'firstMatch' | 'alwaysMatch'>;
|
|
33
|
+
};
|
|
34
|
+
export type NewSessionResponse = {
|
|
35
|
+
/**
|
|
36
|
+
* ,
|
|
37
|
+
*/
|
|
38
|
+
sessionId: string;
|
|
39
|
+
capabilities: import('@appium/types').Capabilities;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Some E2E helpers for making requests and managing sessions
|
|
43
|
+
* See {@linkcode createSessionHelpers }
|
|
44
|
+
*/
|
|
45
|
+
export type SessionHelpers<CommandData = unknown, ResponseData = any> = {
|
|
46
|
+
/**
|
|
47
|
+
* - URL to create a new session. Can be used with raw `axios` requests to fully inspect raw response. Mostly, this will not be used.
|
|
48
|
+
*/
|
|
49
|
+
newSessionURL: string;
|
|
50
|
+
/**
|
|
51
|
+
* - Begin a session
|
|
52
|
+
*/
|
|
53
|
+
startSession: (data: NewSessionData, config?: AxiosRequestConfig) => Promise<NewSessionResponse>;
|
|
54
|
+
/**
|
|
55
|
+
* - End a session. _Note: resolves with raw response object_
|
|
56
|
+
*/
|
|
57
|
+
endSession: (sessionId: string) => Promise<AxiosResponse<{
|
|
58
|
+
value: {
|
|
59
|
+
error?: string;
|
|
60
|
+
} | null;
|
|
61
|
+
}, {
|
|
62
|
+
validateStatus: null;
|
|
63
|
+
}>>;
|
|
64
|
+
/**
|
|
65
|
+
* - Get info about a session
|
|
66
|
+
*/
|
|
67
|
+
getSession: (sessionId: string) => Promise<SingularSessionData>;
|
|
68
|
+
/**
|
|
69
|
+
* - Send an arbitrary command via `POST`.
|
|
70
|
+
*/
|
|
71
|
+
postCommand: (sessionId: string, cmdName: string, data?: CommandData, config?: AxiosRequestConfig) => Promise<ResponseData>;
|
|
72
|
+
/**
|
|
73
|
+
* - Send an arbitrary command via `GET`. Optional `sessionId`.
|
|
74
|
+
*/
|
|
75
|
+
getCommand: (sessionIdOrCmdName: string, cmdNameOrConfig: string | AxiosRequestConfig, config?: AxiosRequestConfig) => Promise<ResponseData>;
|
|
76
|
+
};
|
|
77
|
+
//# sourceMappingURL=driver-e2e-suite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"driver-e2e-suite.d.ts","sourceRoot":"","sources":["../../lib/driver-e2e-suite.js"],"names":[],"mappings":"AAUA;;;;;;;GAOG;AACH,sFAJW,MAAM,2EAmFhB;AAED;;;;;GAKG;AACH;;sBAuTC;;;;;oEAMY,OAAO,eAAe,EAAE,WAAW,CAAC,CAAC,CAAC;2BAItC,OAAO,eAAe,EAAE,YAAY;qBACpC,OAAO,eAAe,EAAE,MAAM;2BAC9B,OAAO,eAAe,EAAE,YAAY;oCACpC,OAAO,eAAe,EAAE,qBAAqB;iCAC7C,OAAO,OAAO,EAAE,kBAAkB;kCAClC,OAAO,eAAe,EAAE,mBAAmB;kCAK3C,OAAO,OAAO,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC;;kBAKlC,OAAO,WAAW,EAAE,iBAAiB,CAAC,OAAO,eAAe,EAAE,eAAe,EAAE,YAAY,GAAC,aAAa,CAAC;;;;;;eAK1G,MAAM;kBACN,OAAO,eAAe,EAAE,YAAY;;;;;;;;;;mBASpC,MAAM;;;;yBACC,cAAc,WAAW,kBAAkB,KAAK,QAAQ,kBAAkB,CAAC;;;;4BACtE,MAAM,KAAK,QAAQ,cAAc;QAAC,KAAK,EAAE;YAAC,KAAK,CAAC,EAAE,MAAM,CAAA;SAAC,QAAC;KAAC,EAAE;QAAC,cAAc,EAAE,IAAI,CAAA;KAAC,CAAC,CAAC;;;;4BACrF,MAAM,KAAK,QAAQ,mBAAmB,CAAC;;;;6BACvC,MAAM,WAAW,MAAM,SAAS,WAAW,WAAW,kBAAkB,KAAK,QAAQ,YAAY,CAAC;;;;qCACzF,MAAM,mBAAmB,MAAM,GAAC,kBAAkB,WAAW,kBAAkB,KAAK,QAAQ,YAAY,CAAC"}
|
|
@@ -0,0 +1,388 @@
|
|
|
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
|
+
});
|
|
113
|
+
({
|
|
114
|
+
startSession,
|
|
115
|
+
getSession,
|
|
116
|
+
endSession,
|
|
117
|
+
newSessionURL,
|
|
118
|
+
getCommand,
|
|
119
|
+
postCommand
|
|
120
|
+
} = createSessionHelpers(port, address));
|
|
121
|
+
});
|
|
122
|
+
after(async function () {
|
|
123
|
+
await baseServer.close();
|
|
124
|
+
});
|
|
125
|
+
describe('session handling', function () {
|
|
126
|
+
it('should handle idempotency while creating sessions', async function () {
|
|
127
|
+
const sessionIds = [];
|
|
128
|
+
let times = 0;
|
|
129
|
+
|
|
130
|
+
do {
|
|
131
|
+
const {
|
|
132
|
+
sessionId
|
|
133
|
+
} = await startSession({
|
|
134
|
+
capabilities: {
|
|
135
|
+
alwaysMatch: defaultCaps
|
|
136
|
+
}
|
|
137
|
+
}, {
|
|
138
|
+
headers: {
|
|
139
|
+
'X-Idempotency-Key': '123456'
|
|
140
|
+
},
|
|
141
|
+
simple: false,
|
|
142
|
+
resolveWithFullResponse: true
|
|
143
|
+
});
|
|
144
|
+
sessionIds.push(sessionId);
|
|
145
|
+
times++;
|
|
146
|
+
} while (times < 2);
|
|
147
|
+
|
|
148
|
+
_lodash.default.uniq(sessionIds).length.should.equal(1);
|
|
149
|
+
|
|
150
|
+
const {
|
|
151
|
+
status,
|
|
152
|
+
data
|
|
153
|
+
} = await endSession(sessionIds[0]);
|
|
154
|
+
status.should.equal(200);
|
|
155
|
+
should.equal(data.value, null);
|
|
156
|
+
});
|
|
157
|
+
it('should handle idempotency while creating parallel sessions', async function () {
|
|
158
|
+
const reqs = [];
|
|
159
|
+
let times = 0;
|
|
160
|
+
|
|
161
|
+
do {
|
|
162
|
+
reqs.push(startSession({
|
|
163
|
+
capabilities: {
|
|
164
|
+
alwaysMatch: defaultCaps
|
|
165
|
+
}
|
|
166
|
+
}, {
|
|
167
|
+
headers: {
|
|
168
|
+
'X-Idempotency-Key': '12345'
|
|
169
|
+
}
|
|
170
|
+
}));
|
|
171
|
+
times++;
|
|
172
|
+
} while (times < 2);
|
|
173
|
+
|
|
174
|
+
const sessionIds = _lodash.default.map(await _bluebird.default.all(reqs), 'sessionId');
|
|
175
|
+
|
|
176
|
+
_lodash.default.uniq(sessionIds).length.should.equal(1);
|
|
177
|
+
|
|
178
|
+
const {
|
|
179
|
+
status,
|
|
180
|
+
data
|
|
181
|
+
} = await endSession(sessionIds[0]);
|
|
182
|
+
status.should.equal(200);
|
|
183
|
+
should.equal(data.value, null);
|
|
184
|
+
});
|
|
185
|
+
it('should create session and retrieve a session id, then delete it', async function () {
|
|
186
|
+
let {
|
|
187
|
+
status,
|
|
188
|
+
data
|
|
189
|
+
} = await _axios.default.post(newSessionURL, {
|
|
190
|
+
capabilities: {
|
|
191
|
+
alwaysMatch: defaultCaps
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
status.should.equal(200);
|
|
195
|
+
should.exist(data.value.sessionId);
|
|
196
|
+
data.value.capabilities.platformName.should.equal(defaultCaps.platformName);
|
|
197
|
+
data.value.capabilities.deviceName.should.equal(defaultCaps['appium:deviceName']);
|
|
198
|
+
({
|
|
199
|
+
status,
|
|
200
|
+
data
|
|
201
|
+
} = await endSession(d.sessionId));
|
|
202
|
+
status.should.equal(200);
|
|
203
|
+
should.equal(data.value, null);
|
|
204
|
+
should.equal(d.sessionId, null);
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
it.skip('should throw NYI for commands not implemented', async function () {});
|
|
208
|
+
describe('command timeouts', function () {
|
|
209
|
+
let originalFindElement, originalFindElements;
|
|
210
|
+
|
|
211
|
+
async function startTimeoutSession(timeout) {
|
|
212
|
+
const caps = _lodash.default.cloneDeep(defaultCaps);
|
|
213
|
+
|
|
214
|
+
caps['appium:newCommandTimeout'] = timeout;
|
|
215
|
+
return await startSession({
|
|
216
|
+
capabilities: {
|
|
217
|
+
alwaysMatch: caps
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
before(function () {
|
|
223
|
+
originalFindElement = d.findElement;
|
|
224
|
+
|
|
225
|
+
d.findElement = function () {
|
|
226
|
+
return 'foo';
|
|
227
|
+
}.bind(d);
|
|
228
|
+
|
|
229
|
+
originalFindElements = d.findElements;
|
|
230
|
+
|
|
231
|
+
d.findElements = async function () {
|
|
232
|
+
await _bluebird.default.delay(200);
|
|
233
|
+
return ['foo'];
|
|
234
|
+
}.bind(d);
|
|
235
|
+
});
|
|
236
|
+
after(function () {
|
|
237
|
+
d.findElement = originalFindElement;
|
|
238
|
+
d.findElements = originalFindElements;
|
|
239
|
+
});
|
|
240
|
+
it('should set a default commandTimeout', async function () {
|
|
241
|
+
let newSession = await startTimeoutSession();
|
|
242
|
+
d.newCommandTimeoutMs.should.be.above(0);
|
|
243
|
+
await endSession(newSession.sessionId);
|
|
244
|
+
});
|
|
245
|
+
it('should timeout on commands using commandTimeout cap', async function () {
|
|
246
|
+
let newSession = await startTimeoutSession(0.25);
|
|
247
|
+
const sessionId = d.sessionId;
|
|
248
|
+
await postCommand(sessionId, 'element', {
|
|
249
|
+
using: 'name',
|
|
250
|
+
value: 'foo'
|
|
251
|
+
});
|
|
252
|
+
await _bluebird.default.delay(400);
|
|
253
|
+
const value = await getSession(sessionId);
|
|
254
|
+
should.equal(value.error, 'invalid session id');
|
|
255
|
+
should.equal(d.sessionId, null);
|
|
256
|
+
const resp = (await endSession(newSession.sessionId)).data.value;
|
|
257
|
+
should.equal(resp === null || resp === void 0 ? void 0 : resp.error, 'invalid session id');
|
|
258
|
+
});
|
|
259
|
+
it('should not timeout with commandTimeout of false', async function () {
|
|
260
|
+
let newSession = await startTimeoutSession(0.1);
|
|
261
|
+
let start = Date.now();
|
|
262
|
+
const value = await postCommand(d.sessionId, 'elements', {
|
|
263
|
+
using: 'name',
|
|
264
|
+
value: 'foo'
|
|
265
|
+
});
|
|
266
|
+
(Date.now() - start).should.be.above(150);
|
|
267
|
+
value.should.eql(['foo']);
|
|
268
|
+
await endSession(newSession.sessionId);
|
|
269
|
+
});
|
|
270
|
+
it('should not timeout with commandTimeout of 0', async function () {
|
|
271
|
+
var _value$platformName;
|
|
272
|
+
|
|
273
|
+
d.newCommandTimeoutMs = 2;
|
|
274
|
+
let newSession = await startTimeoutSession(0);
|
|
275
|
+
await postCommand(d.sessionId, 'element', {
|
|
276
|
+
using: 'name',
|
|
277
|
+
value: 'foo'
|
|
278
|
+
});
|
|
279
|
+
await _bluebird.default.delay(400);
|
|
280
|
+
const value = await getSession(d.sessionId);
|
|
281
|
+
(_value$platformName = value.platformName) === null || _value$platformName === void 0 ? void 0 : _value$platformName.should.equal(defaultCaps.platformName);
|
|
282
|
+
const resp = (await endSession(newSession.sessionId)).data.value;
|
|
283
|
+
should.equal(resp, null);
|
|
284
|
+
d.newCommandTimeoutMs = 60 * 1000;
|
|
285
|
+
});
|
|
286
|
+
it('should not timeout if its just the command taking awhile', async function () {
|
|
287
|
+
let newSession = await startTimeoutSession(0.25);
|
|
288
|
+
const {
|
|
289
|
+
sessionId
|
|
290
|
+
} = d;
|
|
291
|
+
await postCommand(d.sessionId, 'element', {
|
|
292
|
+
using: 'name',
|
|
293
|
+
value: 'foo'
|
|
294
|
+
});
|
|
295
|
+
await _bluebird.default.delay(400);
|
|
296
|
+
const value = await getSession(sessionId);
|
|
297
|
+
value.error.should.equal('invalid session id');
|
|
298
|
+
should.equal(d.sessionId, null);
|
|
299
|
+
const resp = (await endSession(newSession.sessionId)).data.value;
|
|
300
|
+
resp.error.should.equal('invalid session id');
|
|
301
|
+
});
|
|
302
|
+
it('should not have a timer running before or after a session', async function () {
|
|
303
|
+
should.not.exist(d.noCommandTimer);
|
|
304
|
+
let newSession = await startTimeoutSession(0.25);
|
|
305
|
+
newSession.sessionId.should.equal(d.sessionId);
|
|
306
|
+
should.exist(d.noCommandTimer);
|
|
307
|
+
await endSession(newSession.sessionId);
|
|
308
|
+
should.not.exist(d.noCommandTimer);
|
|
309
|
+
});
|
|
310
|
+
});
|
|
311
|
+
describe('settings api', function () {
|
|
312
|
+
before(function () {
|
|
313
|
+
d.settings = new _driver.DeviceSettings({
|
|
314
|
+
ignoreUnimportantViews: false
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
it('should be able to get settings object', function () {
|
|
318
|
+
d.settings.getSettings().ignoreUnimportantViews.should.be.false;
|
|
319
|
+
});
|
|
320
|
+
it('should not reject when `updateSettings` method is not provided', async function () {
|
|
321
|
+
await d.settings.update({
|
|
322
|
+
ignoreUnimportantViews: true
|
|
323
|
+
}).should.not.be.rejected;
|
|
324
|
+
});
|
|
325
|
+
it('should reject for invalid update object', async function () {
|
|
326
|
+
await d.settings.update('invalid json').should.be.rejectedWith('JSON');
|
|
327
|
+
});
|
|
328
|
+
});
|
|
329
|
+
describe('unexpected exits', function () {
|
|
330
|
+
let sandbox;
|
|
331
|
+
beforeEach(function () {
|
|
332
|
+
sandbox = _sinon.default.createSandbox();
|
|
333
|
+
});
|
|
334
|
+
afterEach(function () {
|
|
335
|
+
sandbox.restore();
|
|
336
|
+
});
|
|
337
|
+
it('should reject a current command when the driver crashes', async function () {
|
|
338
|
+
sandbox.stub(d, 'getStatus').callsFake(async function () {
|
|
339
|
+
await _bluebird.default.delay(5000);
|
|
340
|
+
});
|
|
341
|
+
const reqPromise = getCommand('status', {
|
|
342
|
+
validateStatus: null
|
|
343
|
+
});
|
|
344
|
+
await _bluebird.default.delay(100);
|
|
345
|
+
const shutdownEventPromise = new _bluebird.default((resolve, reject) => {
|
|
346
|
+
setTimeout(() => reject(new Error('onUnexpectedShutdown event is expected to be fired within 5 seconds timeout')), 5000);
|
|
347
|
+
d.onUnexpectedShutdown(resolve);
|
|
348
|
+
});
|
|
349
|
+
d.startUnexpectedShutdown(new Error('Crashytimes'));
|
|
350
|
+
const value = await reqPromise;
|
|
351
|
+
value.message.should.contain('Crashytimes');
|
|
352
|
+
await shutdownEventPromise;
|
|
353
|
+
});
|
|
354
|
+
});
|
|
355
|
+
describe('event timings', function () {
|
|
356
|
+
it('should not add timings if not using opt-in cap', async function () {
|
|
357
|
+
const session = await startSession({
|
|
358
|
+
capabilities: {
|
|
359
|
+
alwaysMatch: defaultCaps
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
const res = await getSession(session.sessionId);
|
|
363
|
+
should.not.exist(res.events);
|
|
364
|
+
await endSession(session.sessionId);
|
|
365
|
+
});
|
|
366
|
+
it('should add start session timings', async function () {
|
|
367
|
+
var _res$events, _res$events2, _res$events3, _res$events4;
|
|
368
|
+
|
|
369
|
+
const caps = { ...defaultCaps,
|
|
370
|
+
'appium:eventTimings': true
|
|
371
|
+
};
|
|
372
|
+
const session = await startSession({
|
|
373
|
+
capabilities: {
|
|
374
|
+
alwaysMatch: caps
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
const res = await getSession(session.sessionId);
|
|
378
|
+
should.exist(res.events);
|
|
379
|
+
should.exist((_res$events = res.events) === null || _res$events === void 0 ? void 0 : _res$events.newSessionRequested);
|
|
380
|
+
should.exist((_res$events2 = res.events) === null || _res$events2 === void 0 ? void 0 : _res$events2.newSessionStarted);
|
|
381
|
+
(_res$events3 = res.events) === null || _res$events3 === void 0 ? void 0 : _res$events3.newSessionRequested[0].should.be.a('number');
|
|
382
|
+
(_res$events4 = res.events) === null || _res$events4 === void 0 ? void 0 : _res$events4.newSessionStarted[0].should.be.a('number');
|
|
383
|
+
await endSession(session.sessionId);
|
|
384
|
+
});
|
|
385
|
+
});
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJzaG91bGQiLCJjaGFpIiwiY3JlYXRlU2Vzc2lvbkhlbHBlcnMiLCJwb3J0IiwiYWRkcmVzcyIsIlRFU1RfSE9TVCIsImNyZWF0ZUFwcGl1bVRlc3RVUkwiLCJjcmVhdGVBcHBpdW1VUkwiLCJjcmVhdGVTZXNzaW9uVVJMIiwiXyIsIm5ld1Nlc3Npb25VUkwiLCJwb3N0Q29tbWFuZCIsInNlc3Npb25JZCIsImNtZE5hbWUiLCJkYXRhIiwiY29uZmlnIiwidXJsIiwicmVzcG9uc2UiLCJheGlvcyIsInBvc3QiLCJ2YWx1ZSIsImdldENvbW1hbmQiLCJzZXNzaW9uSWRPckNtZE5hbWUiLCJjbWROYW1lT3JDb25maWciLCJpc1N0cmluZyIsInZhbGlkYXRlU3RhdHVzIiwic3RhcnRTZXNzaW9uIiwiZGVmYXVsdHNEZWVwIiwiY2FwYWJpbGl0aWVzIiwiYWx3YXlzTWF0Y2giLCJmaXJzdE1hdGNoIiwiZW5kU2Vzc2lvbiIsImRlbGV0ZSIsImdldFNlc3Npb24iLCJkcml2ZXJFMkVUZXN0U3VpdGUiLCJEcml2ZXJDbGFzcyIsImRlZmF1bHRDYXBzIiwiY2xhc3NOYW1lIiwibmFtZSIsImRlc2NyaWJlIiwiYmFzZVNlcnZlciIsImQiLCJiZWZvcmUiLCJnZXRUZXN0UG9ydCIsInNlcnZlciIsInJvdXRlQ29uZmlndXJpbmdGdW5jdGlvbiIsImhvc3RuYW1lIiwiYWZ0ZXIiLCJjbG9zZSIsIml0Iiwic2Vzc2lvbklkcyIsInRpbWVzIiwiaGVhZGVycyIsInNpbXBsZSIsInJlc29sdmVXaXRoRnVsbFJlc3BvbnNlIiwicHVzaCIsInVuaXEiLCJsZW5ndGgiLCJlcXVhbCIsInN0YXR1cyIsInJlcXMiLCJtYXAiLCJCIiwiYWxsIiwiZXhpc3QiLCJwbGF0Zm9ybU5hbWUiLCJkZXZpY2VOYW1lIiwic2tpcCIsIm9yaWdpbmFsRmluZEVsZW1lbnQiLCJvcmlnaW5hbEZpbmRFbGVtZW50cyIsInN0YXJ0VGltZW91dFNlc3Npb24iLCJ0aW1lb3V0IiwiY2FwcyIsImNsb25lRGVlcCIsImZpbmRFbGVtZW50IiwiYmluZCIsImZpbmRFbGVtZW50cyIsImRlbGF5IiwibmV3U2Vzc2lvbiIsIm5ld0NvbW1hbmRUaW1lb3V0TXMiLCJiZSIsImFib3ZlIiwidXNpbmciLCJlcnJvciIsInJlc3AiLCJzdGFydCIsIkRhdGUiLCJub3ciLCJlcWwiLCJub3QiLCJub0NvbW1hbmRUaW1lciIsInNldHRpbmdzIiwiRGV2aWNlU2V0dGluZ3MiLCJpZ25vcmVVbmltcG9ydGFudFZpZXdzIiwiZ2V0U2V0dGluZ3MiLCJmYWxzZSIsInVwZGF0ZSIsInJlamVjdGVkIiwicmVqZWN0ZWRXaXRoIiwic2FuZGJveCIsImJlZm9yZUVhY2giLCJzaW5vbiIsImNyZWF0ZVNhbmRib3giLCJhZnRlckVhY2giLCJyZXN0b3JlIiwic3R1YiIsImNhbGxzRmFrZSIsInJlcVByb21pc2UiLCJzaHV0ZG93bkV2ZW50UHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJzZXRUaW1lb3V0IiwiRXJyb3IiLCJvblVuZXhwZWN0ZWRTaHV0ZG93biIsInN0YXJ0VW5leHBlY3RlZFNodXRkb3duIiwibWVzc2FnZSIsImNvbnRhaW4iLCJzZXNzaW9uIiwicmVzIiwiZXZlbnRzIiwibmV3U2Vzc2lvblJlcXVlc3RlZCIsIm5ld1Nlc3Npb25TdGFydGVkIiwiYSJdLCJzb3VyY2VzIjpbIi4uLy4uL2xpYi9kcml2ZXItZTJlLXN1aXRlLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQge3NlcnZlciwgcm91dGVDb25maWd1cmluZ0Z1bmN0aW9uLCBEZXZpY2VTZXR0aW5nc30gZnJvbSAnYXBwaXVtL2RyaXZlcic7XG5pbXBvcnQgYXhpb3MgZnJvbSAnYXhpb3MnO1xuaW1wb3J0IEIgZnJvbSAnYmx1ZWJpcmQnO1xuaW1wb3J0IHtURVNUX0hPU1QsIGdldFRlc3RQb3J0LCBjcmVhdGVBcHBpdW1VUkx9IGZyb20gJy4vaGVscGVycyc7XG5pbXBvcnQgY2hhaSBmcm9tICdjaGFpJztcbmltcG9ydCBzaW5vbiBmcm9tICdzaW5vbic7XG5cbmNvbnN0IHNob3VsZCA9IGNoYWkuc2hvdWxkKCk7XG5cbi8qKlxuICogQ3JlYXRlcyBzb21lIGhlbHBlciBmdW5jdGlvbnMgZm9yIEUyRSB0ZXN0cyB0byBtYW5hZ2Ugc2Vzc2lvbnMuXG4gKiBAdGVtcGxhdGUgW0NvbW1hbmREYXRhPXVua25vd25dXG4gKiBAdGVtcGxhdGUgW1Jlc3BvbnNlRGF0YT1hbnldXG4gKiBAcGFyYW0ge251bWJlcn0gcG9ydCAtIFBvcnQgb24gd2hpY2ggdGhlIHNlcnZlciBpcyBydW5uaW5nLiBUeXBpY2FsbHkgdGhpcyB3aWxsIGJlIHJldHJpZXZlZCB2aWEgYGdldC1wb3J0YCBiZWZvcmVoYW5kXG4gKiBAcGFyYW0ge3N0cmluZ30gW2FkZHJlc3NdIC0gQWRkcmVzcy9ob3N0IG9uIHdoaWNoIHRoZSBzZXJ2ZXIgaXMgcnVubmluZy4gRGVmYXVsdHMgdG8ge0BsaW5rY29kZSBURVNUX0hPU1R9XG4gKiBAcmV0dXJucyB7U2Vzc2lvbkhlbHBlcnM8Q29tbWFuZERhdGEsIFJlc3BvbnNlRGF0YT59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVTZXNzaW9uSGVscGVycyhwb3J0LCBhZGRyZXNzID0gVEVTVF9IT1NUKSB7XG4gIGNvbnN0IGNyZWF0ZUFwcGl1bVRlc3RVUkwgPVxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KCdsb2Rhc2gnKS5DdXJyaWVkRnVuY3Rpb24yPHN0cmluZyxzdHJpbmcsc3RyaW5nPn0gKi8gKFxuICAgICAgY3JlYXRlQXBwaXVtVVJMKGFkZHJlc3MsIHBvcnQpXG4gICAgKTtcblxuICBjb25zdCBjcmVhdGVTZXNzaW9uVVJMID0gY3JlYXRlQXBwaXVtVGVzdFVSTChfLCAnJyk7XG4gIGNvbnN0IG5ld1Nlc3Npb25VUkwgPSBjcmVhdGVBcHBpdW1UZXN0VVJMKCcnLCAnc2Vzc2lvbicpO1xuICByZXR1cm4gLyoqIEB0eXBlIHtTZXNzaW9uSGVscGVyczxDb21tYW5kRGF0YSwgUmVzcG9uc2VEYXRhPn0gKi8gKHtcbiAgICBuZXdTZXNzaW9uVVJMLFxuICAgIGNyZWF0ZUFwcGl1bVRlc3RVUkwsXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc2Vzc2lvbklkXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGNtZE5hbWVcbiAgICAgKiBAcGFyYW0ge2FueX0gW2RhdGFdXG4gICAgICogQHBhcmFtIHtBeGlvc1JlcXVlc3RDb25maWd9IFtjb25maWddXG4gICAgICogQHJldHVybnMge1Byb21pc2U8YW55Pn1cbiAgICAgKi9cbiAgICBwb3N0Q29tbWFuZDogYXN5bmMgKHNlc3Npb25JZCwgY21kTmFtZSwgZGF0YSA9IHt9LCBjb25maWcgPSB7fSkgPT4ge1xuICAgICAgY29uc3QgdXJsID0gY3JlYXRlQXBwaXVtVGVzdFVSTChzZXNzaW9uSWQsIGNtZE5hbWUpO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBheGlvcy5wb3N0KHVybCwgZGF0YSwgY29uZmlnKTtcbiAgICAgIHJldHVybiByZXNwb25zZS5kYXRhPy52YWx1ZTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHNlc3Npb25JZE9yQ21kTmFtZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfEF4aW9zUmVxdWVzdENvbmZpZ30gY21kTmFtZU9yQ29uZmlnXG4gICAgICogQHBhcmFtIHtBeGlvc1JlcXVlc3RDb25maWd9IFtjb25maWddXG4gICAgICogQHJldHVybnMge1Byb21pc2U8YW55Pn1cbiAgICAgKi9cbiAgICBnZXRDb21tYW5kOiBhc3luYyAoc2Vzc2lvbklkT3JDbWROYW1lLCBjbWROYW1lT3JDb25maWcsIGNvbmZpZyA9IHt9KSA9PiB7XG4gICAgICBpZiAoIV8uaXNTdHJpbmcoY21kTmFtZU9yQ29uZmlnKSkge1xuICAgICAgICBjb25maWcgPSBjbWROYW1lT3JDb25maWc7XG4gICAgICAgIGNtZE5hbWVPckNvbmZpZyA9IHNlc3Npb25JZE9yQ21kTmFtZTtcbiAgICAgICAgc2Vzc2lvbklkT3JDbWROYW1lID0gJyc7XG4gICAgICB9XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGF4aW9zKHtcbiAgICAgICAgdXJsOiBjcmVhdGVBcHBpdW1UZXN0VVJMKHNlc3Npb25JZE9yQ21kTmFtZSwgY21kTmFtZU9yQ29uZmlnKSxcbiAgICAgICAgdmFsaWRhdGVTdGF0dXM6IG51bGwsXG4gICAgICAgIC4uLmNvbmZpZyxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlc3BvbnNlLmRhdGE/LnZhbHVlO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge05ld1Nlc3Npb25EYXRhfSBkYXRhXG4gICAgICogQHBhcmFtIHtBeGlvc1JlcXVlc3RDb25maWd9IFtjb25maWddXG4gICAgICovXG4gICAgc3RhcnRTZXNzaW9uOiBhc3luYyAoZGF0YSwgY29uZmlnID0ge30pID0+IHtcbiAgICAgIGRhdGEgPSBfLmRlZmF1bHRzRGVlcChkYXRhLCB7XG4gICAgICAgIGNhcGFiaWxpdGllczoge1xuICAgICAgICAgIGFsd2F5c01hdGNoOiB7fSxcbiAgICAgICAgICBmaXJzdE1hdGNoOiBbe31dLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGF4aW9zLnBvc3QobmV3U2Vzc2lvblVSTCwgZGF0YSwgY29uZmlnKTtcbiAgICAgIHJldHVybiByZXNwb25zZS5kYXRhPy52YWx1ZTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHNlc3Npb25JZFxuICAgICAqL1xuICAgIGVuZFNlc3Npb246IGFzeW5jIChzZXNzaW9uSWQpID0+XG4gICAgICBhd2FpdCBheGlvcy5kZWxldGUoY3JlYXRlU2Vzc2lvblVSTChzZXNzaW9uSWQpLCB7XG4gICAgICAgIHZhbGlkYXRlU3RhdHVzOiBudWxsLFxuICAgICAgfSksXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHNlc3Npb25JZFxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPGFueT59XG4gICAgICovXG4gICAgZ2V0U2Vzc2lvbjogYXN5bmMgKHNlc3Npb25JZCkgPT4ge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBheGlvcyh7XG4gICAgICAgIHVybDogY3JlYXRlU2Vzc2lvblVSTChzZXNzaW9uSWQpLFxuICAgICAgICB2YWxpZGF0ZVN0YXR1czogbnVsbCxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlc3BvbnNlLmRhdGE/LnZhbHVlO1xuICAgIH0sXG4gIH0pO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgRTJFIHRlc3Qgc3VpdGVzIGZvciBhIGRyaXZlci5cbiAqIEB0ZW1wbGF0ZSB7RHJpdmVyfSBQXG4gKiBAcGFyYW0ge0RyaXZlckNsYXNzPFA+fSBEcml2ZXJDbGFzc1xuICogQHBhcmFtIHtBcHBpdW1XM0NDYXBhYmlsaXRpZXN9IFtkZWZhdWx0Q2Fwc11cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRyaXZlckUyRVRlc3RTdWl0ZShEcml2ZXJDbGFzcywgZGVmYXVsdENhcHMgPSB7fSkge1xuICBsZXQgYWRkcmVzcyA9IGRlZmF1bHRDYXBzWydhcHBpdW06YWRkcmVzcyddID8/IFRFU1RfSE9TVDtcbiAgbGV0IHBvcnQgPSBkZWZhdWx0Q2Fwc1snYXBwaXVtOnBvcnQnXTtcbiAgY29uc3QgY2xhc3NOYW1lID0gRHJpdmVyQ2xhc3MubmFtZSB8fCAnKHVua25vd24gZHJpdmVyKSc7XG5cbiAgZGVzY3JpYmUoYEJhc2VEcml2ZXIgRTJFIChhcyAke2NsYXNzTmFtZX0pYCwgZnVuY3Rpb24gKCkge1xuICAgIGxldCBiYXNlU2VydmVyO1xuICAgIC8qKiBAdHlwZSB7UH0gKi9cbiAgICBsZXQgZDtcbiAgICAvKipcbiAgICAgKiBUaGlzIFVSTCBjcmVhdGVzIGEgbmV3IHNlc3Npb25cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqKi9cbiAgICBsZXQgbmV3U2Vzc2lvblVSTDtcblxuICAgIC8qKiBAdHlwZSB7U2Vzc2lvbkhlbHBlcnNbJ3N0YXJ0U2Vzc2lvbiddfSAqL1xuICAgIGxldCBzdGFydFNlc3Npb247XG4gICAgLyoqIEB0eXBlIHtTZXNzaW9uSGVscGVyc1snZ2V0U2Vzc2lvbiddfSAqL1xuICAgIGxldCBnZXRTZXNzaW9uO1xuICAgIC8qKiBAdHlwZSB7U2Vzc2lvbkhlbHBlcnNbJ2VuZFNlc3Npb24nXX0gKi9cbiAgICBsZXQgZW5kU2Vzc2lvbjtcbiAgICAvKiogQHR5cGUge1Nlc3Npb25IZWxwZXJzWydnZXRDb21tYW5kJ119ICovXG4gICAgbGV0IGdldENvbW1hbmQ7XG4gICAgLyoqIEB0eXBlIHtTZXNzaW9uSGVscGVyc1sncG9zdENvbW1hbmQnXX0gKi9cbiAgICBsZXQgcG9zdENvbW1hbmQ7XG4gICAgYmVmb3JlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHBvcnQgPSBwb3J0ID8/IChhd2FpdCBnZXRUZXN0UG9ydCgpKTtcbiAgICAgIGRlZmF1bHRDYXBzID0gey4uLmRlZmF1bHRDYXBzLCAnYXBwaXVtOnBvcnQnOiBwb3J0fTtcbiAgICAgIGQgPSBuZXcgRHJpdmVyQ2xhc3Moe3BvcnQsIGFkZHJlc3N9KTtcbiAgICAgIGJhc2VTZXJ2ZXIgPSBhd2FpdCBzZXJ2ZXIoe1xuICAgICAgICByb3V0ZUNvbmZpZ3VyaW5nRnVuY3Rpb246IHJvdXRlQ29uZmlndXJpbmdGdW5jdGlvbihkKSxcbiAgICAgICAgcG9ydCxcbiAgICAgICAgaG9zdG5hbWU6IGFkZHJlc3MsXG4gICAgICB9KTtcbiAgICAgICh7c3RhcnRTZXNzaW9uLCBnZXRTZXNzaW9uLCBlbmRTZXNzaW9uLCBuZXdTZXNzaW9uVVJMLCBnZXRDb21tYW5kLCBwb3N0Q29tbWFuZH0gPVxuICAgICAgICBjcmVhdGVTZXNzaW9uSGVscGVycyhwb3J0LCBhZGRyZXNzKSk7XG4gICAgfSk7XG5cbiAgICBhZnRlcihhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBiYXNlU2VydmVyLmNsb3NlKCk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnc2Vzc2lvbiBoYW5kbGluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIGlkZW1wb3RlbmN5IHdoaWxlIGNyZWF0aW5nIHNlc3Npb25zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzZXNzaW9uSWRzID0gW107XG4gICAgICAgIGxldCB0aW1lcyA9IDA7XG4gICAgICAgIGRvIHtcbiAgICAgICAgICBjb25zdCB7c2Vzc2lvbklkfSA9IGF3YWl0IHN0YXJ0U2Vzc2lvbihcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgY2FwYWJpbGl0aWVzOiB7YWx3YXlzTWF0Y2g6IGRlZmF1bHRDYXBzfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgICAnWC1JZGVtcG90ZW5jeS1LZXknOiAnMTIzNDU2JyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgLy8gWFhYOiBJJ20gbm90IHN1cmUgd2hhdCB0aGVzZSBhcmUsIGFzIHRoZXkgYXJlIG5vdCBkb2N1bWVudGVkIGF4aW9zIG9wdGlvbnMsXG4gICAgICAgICAgICAgIC8vIG5vciBhcmUgdGhleSBtZW50aW9uZWQgaW4gb3VyIHNvdXJjZVxuICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgICAgIHNpbXBsZTogZmFsc2UsXG4gICAgICAgICAgICAgIHJlc29sdmVXaXRoRnVsbFJlc3BvbnNlOiB0cnVlLFxuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBzZXNzaW9uSWRzLnB1c2goc2Vzc2lvbklkKTtcbiAgICAgICAgICB0aW1lcysrO1xuICAgICAgICB9IHdoaWxlICh0aW1lcyA8IDIpO1xuICAgICAgICBfLnVuaXEoc2Vzc2lvbklkcykubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcblxuICAgICAgICBjb25zdCB7c3RhdHVzLCBkYXRhfSA9IGF3YWl0IGVuZFNlc3Npb24oc2Vzc2lvbklkc1swXSk7XG4gICAgICAgIHN0YXR1cy5zaG91bGQuZXF1YWwoMjAwKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKGRhdGEudmFsdWUsIG51bGwpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIGlkZW1wb3RlbmN5IHdoaWxlIGNyZWF0aW5nIHBhcmFsbGVsIHNlc3Npb25zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCByZXFzID0gW107XG4gICAgICAgIGxldCB0aW1lcyA9IDA7XG4gICAgICAgIGRvIHtcbiAgICAgICAgICByZXFzLnB1c2goXG4gICAgICAgICAgICBzdGFydFNlc3Npb24oXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBjYXBhYmlsaXRpZXM6IHtcbiAgICAgICAgICAgICAgICAgIGFsd2F5c01hdGNoOiBkZWZhdWx0Q2FwcyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICAgICAgJ1gtSWRlbXBvdGVuY3ktS2V5JzogJzEyMzQ1JyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApXG4gICAgICAgICAgKTtcbiAgICAgICAgICB0aW1lcysrO1xuICAgICAgICB9IHdoaWxlICh0aW1lcyA8IDIpO1xuICAgICAgICBjb25zdCBzZXNzaW9uSWRzID0gXy5tYXAoYXdhaXQgQi5hbGwocmVxcyksICdzZXNzaW9uSWQnKTtcbiAgICAgICAgXy51bmlxKHNlc3Npb25JZHMpLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG5cbiAgICAgICAgY29uc3Qge3N0YXR1cywgZGF0YX0gPSBhd2FpdCBlbmRTZXNzaW9uKHNlc3Npb25JZHNbMF0pO1xuICAgICAgICBzdGF0dXMuc2hvdWxkLmVxdWFsKDIwMCk7XG4gICAgICAgIHNob3VsZC5lcXVhbChkYXRhLnZhbHVlLCBudWxsKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGNyZWF0ZSBzZXNzaW9uIGFuZCByZXRyaWV2ZSBhIHNlc3Npb24gaWQsIHRoZW4gZGVsZXRlIGl0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQge3N0YXR1cywgZGF0YX0gPSBhd2FpdCBheGlvcy5wb3N0KG5ld1Nlc3Npb25VUkwsIHtcbiAgICAgICAgICBjYXBhYmlsaXRpZXM6IHtcbiAgICAgICAgICAgIGFsd2F5c01hdGNoOiBkZWZhdWx0Q2FwcyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgICBzdGF0dXMuc2hvdWxkLmVxdWFsKDIwMCk7XG4gICAgICAgIHNob3VsZC5leGlzdChkYXRhLnZhbHVlLnNlc3Npb25JZCk7XG4gICAgICAgIGRhdGEudmFsdWUuY2FwYWJpbGl0aWVzLnBsYXRmb3JtTmFtZS5zaG91bGQuZXF1YWwoZGVmYXVsdENhcHMucGxhdGZvcm1OYW1lKTtcbiAgICAgICAgZGF0YS52YWx1ZS5jYXBhYmlsaXRpZXMuZGV2aWNlTmFtZS5zaG91bGQuZXF1YWwoZGVmYXVsdENhcHNbJ2FwcGl1bTpkZXZpY2VOYW1lJ10pO1xuXG4gICAgICAgICh7c3RhdHVzLCBkYXRhfSA9IGF3YWl0IGVuZFNlc3Npb24oLyoqIEB0eXBlIHtzdHJpbmd9ICovIChkLnNlc3Npb25JZCkpKTtcblxuICAgICAgICBzdGF0dXMuc2hvdWxkLmVxdWFsKDIwMCk7XG4gICAgICAgIHNob3VsZC5lcXVhbChkYXRhLnZhbHVlLCBudWxsKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKGQuc2Vzc2lvbklkLCBudWxsKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQuc2tpcCgnc2hvdWxkIHRocm93IE5ZSSBmb3IgY29tbWFuZHMgbm90IGltcGxlbWVudGVkJywgYXN5bmMgZnVuY3Rpb24gKCkge30pO1xuXG4gICAgZGVzY3JpYmUoJ2NvbW1hbmQgdGltZW91dHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgb3JpZ2luYWxGaW5kRWxlbWVudCwgb3JpZ2luYWxGaW5kRWxlbWVudHM7XG5cbiAgICAgIC8qKlxuICAgICAgICogQHBhcmFtIHtudW1iZXJ9IFt0aW1lb3V0XVxuICAgICAgICovXG4gICAgICBhc3luYyBmdW5jdGlvbiBzdGFydFRpbWVvdXRTZXNzaW9uKHRpbWVvdXQpIHtcbiAgICAgICAgY29uc3QgY2FwcyA9IF8uY2xvbmVEZWVwKGRlZmF1bHRDYXBzKTtcbiAgICAgICAgY2Fwc1snYXBwaXVtOm5ld0NvbW1hbmRUaW1lb3V0J10gPSB0aW1lb3V0O1xuICAgICAgICByZXR1cm4gYXdhaXQgc3RhcnRTZXNzaW9uKHtjYXBhYmlsaXRpZXM6IHthbHdheXNNYXRjaDogY2Fwc319KTtcbiAgICAgIH1cblxuICAgICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgb3JpZ2luYWxGaW5kRWxlbWVudCA9IGQuZmluZEVsZW1lbnQ7XG4gICAgICAgIGQuZmluZEVsZW1lbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcmV0dXJuICdmb28nO1xuICAgICAgICB9LmJpbmQoZCk7XG5cbiAgICAgICAgb3JpZ2luYWxGaW5kRWxlbWVudHMgPSBkLmZpbmRFbGVtZW50cztcbiAgICAgICAgZC5maW5kRWxlbWVudHMgPSBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgYXdhaXQgQi5kZWxheSgyMDApO1xuICAgICAgICAgIHJldHVybiBbJ2ZvbyddO1xuICAgICAgICB9LmJpbmQoZCk7XG4gICAgICB9KTtcblxuICAgICAgYWZ0ZXIoZnVuY3Rpb24gKCkge1xuICAgICAgICBkLmZpbmRFbGVtZW50ID0gb3JpZ2luYWxGaW5kRWxlbWVudDtcbiAgICAgICAgZC5maW5kRWxlbWVudHMgPSBvcmlnaW5hbEZpbmRFbGVtZW50cztcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHNldCBhIGRlZmF1bHQgY29tbWFuZFRpbWVvdXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBuZXdTZXNzaW9uID0gYXdhaXQgc3RhcnRUaW1lb3V0U2Vzc2lvbigpO1xuICAgICAgICBkLm5ld0NvbW1hbmRUaW1lb3V0TXMuc2hvdWxkLmJlLmFib3ZlKDApO1xuICAgICAgICBhd2FpdCBlbmRTZXNzaW9uKG5ld1Nlc3Npb24uc2Vzc2lvbklkKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRpbWVvdXQgb24gY29tbWFuZHMgdXNpbmcgY29tbWFuZFRpbWVvdXQgY2FwJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgbmV3U2Vzc2lvbiA9IGF3YWl0IHN0YXJ0VGltZW91dFNlc3Npb24oMC4yNSk7XG4gICAgICAgIGNvbnN0IHNlc3Npb25JZCA9IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZC5zZXNzaW9uSWQpO1xuICAgICAgICBhd2FpdCBwb3N0Q29tbWFuZChzZXNzaW9uSWQsICdlbGVtZW50Jywge1xuICAgICAgICAgIHVzaW5nOiAnbmFtZScsXG4gICAgICAgICAgdmFsdWU6ICdmb28nLFxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgQi5kZWxheSg0MDApO1xuICAgICAgICBjb25zdCB2YWx1ZSA9IGF3YWl0IGdldFNlc3Npb24oc2Vzc2lvbklkKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHZhbHVlLmVycm9yLCAnaW52YWxpZCBzZXNzaW9uIGlkJyk7XG4gICAgICAgIHNob3VsZC5lcXVhbChkLnNlc3Npb25JZCwgbnVsbCk7XG4gICAgICAgIGNvbnN0IHJlc3AgPSAoYXdhaXQgZW5kU2Vzc2lvbihuZXdTZXNzaW9uLnNlc3Npb25JZCkpLmRhdGEudmFsdWU7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXNwPy5lcnJvciwgJ2ludmFsaWQgc2Vzc2lvbiBpZCcpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgbm90IHRpbWVvdXQgd2l0aCBjb21tYW5kVGltZW91dCBvZiBmYWxzZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbGV0IG5ld1Nlc3Npb24gPSBhd2FpdCBzdGFydFRpbWVvdXRTZXNzaW9uKDAuMSk7XG4gICAgICAgIGxldCBzdGFydCA9IERhdGUubm93KCk7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gYXdhaXQgcG9zdENvbW1hbmQoLyoqIEB0eXBlIHtzdHJpbmd9ICovIChkLnNlc3Npb25JZCksICdlbGVtZW50cycsIHtcbiAgICAgICAgICB1c2luZzogJ25hbWUnLFxuICAgICAgICAgIHZhbHVlOiAnZm9vJyxcbiAgICAgICAgfSk7XG4gICAgICAgIChEYXRlLm5vdygpIC0gc3RhcnQpLnNob3VsZC5iZS5hYm92ZSgxNTApO1xuICAgICAgICB2YWx1ZS5zaG91bGQuZXFsKFsnZm9vJ10pO1xuICAgICAgICBhd2FpdCBlbmRTZXNzaW9uKG5ld1Nlc3Npb24uc2Vzc2lvbklkKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIG5vdCB0aW1lb3V0IHdpdGggY29tbWFuZFRpbWVvdXQgb2YgMCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZC5uZXdDb21tYW5kVGltZW91dE1zID0gMjtcbiAgICAgICAgbGV0IG5ld1Nlc3Npb24gPSBhd2FpdCBzdGFydFRpbWVvdXRTZXNzaW9uKDApO1xuXG4gICAgICAgIGF3YWl0IHBvc3RDb21tYW5kKC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZC5zZXNzaW9uSWQpLCAnZWxlbWVudCcsIHtcbiAgICAgICAgICB1c2luZzogJ25hbWUnLFxuICAgICAgICAgIHZhbHVlOiAnZm9vJyxcbiAgICAgICAgfSk7XG4gICAgICAgIGF3YWl0IEIuZGVsYXkoNDAwKTtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBhd2FpdCBnZXRTZXNzaW9uKC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZC5zZXNzaW9uSWQpKTtcbiAgICAgICAgdmFsdWUucGxhdGZvcm1OYW1lPy5zaG91bGQuZXF1YWwoZGVmYXVsdENhcHMucGxhdGZvcm1OYW1lKTtcbiAgICAgICAgY29uc3QgcmVzcCA9IChhd2FpdCBlbmRTZXNzaW9uKG5ld1Nlc3Npb24uc2Vzc2lvbklkKSkuZGF0YS52YWx1ZTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlc3AsIG51bGwpO1xuXG4gICAgICAgIGQubmV3Q29tbWFuZFRpbWVvdXRNcyA9IDYwICogMTAwMDtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIG5vdCB0aW1lb3V0IGlmIGl0cyBqdXN0IHRoZSBjb21tYW5kIHRha2luZyBhd2hpbGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBuZXdTZXNzaW9uID0gYXdhaXQgc3RhcnRUaW1lb3V0U2Vzc2lvbigwLjI1KTtcbiAgICAgICAgLy8gWFhYOiByYWNlIGNvbmRpdGlvbjogd2UgbXVzdCBidWlsZCB0aGlzIFVSTCBiZWZvcmUgLi4uc29tZXRoaW5nIGhhcHBlbnMuLi5cbiAgICAgICAgLy8gd2hpY2ggY2F1c2VzIGBkLnNlc3Npb25JZGAgdG8gYmUgbWlzc2luZ1xuICAgICAgICBjb25zdCB7c2Vzc2lvbklkfSA9IGQ7XG5cbiAgICAgICAgYXdhaXQgcG9zdENvbW1hbmQoLyoqIEB0eXBlIHtzdHJpbmd9ICovIChkLnNlc3Npb25JZCksICdlbGVtZW50Jywge1xuICAgICAgICAgIHVzaW5nOiAnbmFtZScsXG4gICAgICAgICAgdmFsdWU6ICdmb28nLFxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgQi5kZWxheSg0MDApO1xuICAgICAgICBjb25zdCB2YWx1ZSA9IGF3YWl0IGdldFNlc3Npb24oLyoqIEB0eXBlIHtzdHJpbmd9ICovIChzZXNzaW9uSWQpKTtcbiAgICAgICAgdmFsdWUuZXJyb3Iuc2hvdWxkLmVxdWFsKCdpbnZhbGlkIHNlc3Npb24gaWQnKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKGQuc2Vzc2lvbklkLCBudWxsKTtcbiAgICAgICAgY29uc3QgcmVzcCA9IChhd2FpdCBlbmRTZXNzaW9uKG5ld1Nlc3Npb24uc2Vzc2lvbklkKSkuZGF0YS52YWx1ZTtcbiAgICAgICAgLyoqIEB0eXBlIHtzdHJpbmd9ICovICgvKiogQHR5cGUgeyB7ZXJyb3I6IHN0cmluZ30gfSAqLyAocmVzcCkuZXJyb3IpLnNob3VsZC5lcXVhbChcbiAgICAgICAgICAnaW52YWxpZCBzZXNzaW9uIGlkJ1xuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgbm90IGhhdmUgYSB0aW1lciBydW5uaW5nIGJlZm9yZSBvciBhZnRlciBhIHNlc3Npb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgc2hvdWxkLm5vdC5leGlzdChkLm5vQ29tbWFuZFRpbWVyKTtcbiAgICAgICAgbGV0IG5ld1Nlc3Npb24gPSBhd2FpdCBzdGFydFRpbWVvdXRTZXNzaW9uKDAuMjUpO1xuICAgICAgICBuZXdTZXNzaW9uLnNlc3Npb25JZC5zaG91bGQuZXF1YWwoZC5zZXNzaW9uSWQpO1xuICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgIHNob3VsZC5leGlzdChkLm5vQ29tbWFuZFRpbWVyKTtcbiAgICAgICAgYXdhaXQgZW5kU2Vzc2lvbihuZXdTZXNzaW9uLnNlc3Npb25JZCk7XG4gICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgc2hvdWxkLm5vdC5leGlzdChkLm5vQ29tbWFuZFRpbWVyKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3NldHRpbmdzIGFwaScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIGQuc2V0dGluZ3MgPSBuZXcgRGV2aWNlU2V0dGluZ3Moe2lnbm9yZVVuaW1wb3J0YW50Vmlld3M6IGZhbHNlfSk7XG4gICAgICB9KTtcbiAgICAgIGl0KCdzaG91bGQgYmUgYWJsZSB0byBnZXQgc2V0dGluZ3Mgb2JqZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBkLnNldHRpbmdzLmdldFNldHRpbmdzKCkuaWdub3JlVW5pbXBvcnRhbnRWaWV3cy5zaG91bGQuYmUuZmFsc2U7XG4gICAgICB9KTtcbiAgICAgIGl0KCdzaG91bGQgbm90IHJlamVjdCB3aGVuIGB1cGRhdGVTZXR0aW5nc2AgbWV0aG9kIGlzIG5vdCBwcm92aWRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgZC5zZXR0aW5ncy51cGRhdGUoe2lnbm9yZVVuaW1wb3J0YW50Vmlld3M6IHRydWV9KS5zaG91bGQubm90LmJlLnJlamVjdGVkO1xuICAgICAgfSk7XG4gICAgICBpdCgnc2hvdWxkIHJlamVjdCBmb3IgaW52YWxpZCB1cGRhdGUgb2JqZWN0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBhd2FpdCBkLnNldHRpbmdzXG4gICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgIC51cGRhdGUoJ2ludmFsaWQganNvbicpXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0pTT04nKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3VuZXhwZWN0ZWQgZXhpdHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAvKiogQHR5cGUge2ltcG9ydCgnc2lub24nKS5TaW5vblNhbmRib3h9ICovXG4gICAgICBsZXQgc2FuZGJveDtcbiAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICBzYW5kYm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuICAgICAgfSk7XG5cbiAgICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNhbmRib3gucmVzdG9yZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgY3VycmVudCBjb21tYW5kIHdoZW4gdGhlIGRyaXZlciBjcmFzaGVzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBzYW5kYm94LnN0dWIoZCwgJ2dldFN0YXR1cycpLmNhbGxzRmFrZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgYXdhaXQgQi5kZWxheSg1MDAwKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHJlcVByb21pc2UgPSBnZXRDb21tYW5kKCdzdGF0dXMnLCB7dmFsaWRhdGVTdGF0dXM6IG51bGx9KTtcbiAgICAgICAgLy8gbWFrZSBzdXJlIHRoYXQgdGhlIHJlcXVlc3QgZ2V0cyB0byB0aGUgc2VydmVyIGJlZm9yZSBvdXIgc2h1dGRvd25cbiAgICAgICAgYXdhaXQgQi5kZWxheSgxMDApO1xuICAgICAgICBjb25zdCBzaHV0ZG93bkV2ZW50UHJvbWlzZSA9IG5ldyBCKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICBzZXRUaW1lb3V0KFxuICAgICAgICAgICAgKCkgPT5cbiAgICAgICAgICAgICAgcmVqZWN0KFxuICAgICAgICAgICAgICAgIG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICAgICdvblVuZXhwZWN0ZWRTaHV0ZG93biBldmVudCBpcyBleHBlY3RlZCB0byBiZSBmaXJlZCB3aXRoaW4gNSBzZWNvbmRzIHRpbWVvdXQnXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgNTAwMFxuICAgICAgICAgICk7XG4gICAgICAgICAgZC5vblVuZXhwZWN0ZWRTaHV0ZG93bihyZXNvbHZlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGQuc3RhcnRVbmV4cGVjdGVkU2h1dGRvd24obmV3IEVycm9yKCdDcmFzaHl0aW1lcycpKTtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBhd2FpdCByZXFQcm9taXNlO1xuICAgICAgICB2YWx1ZS5tZXNzYWdlLnNob3VsZC5jb250YWluKCdDcmFzaHl0aW1lcycpO1xuICAgICAgICBhd2FpdCBzaHV0ZG93bkV2ZW50UHJvbWlzZTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2V2ZW50IHRpbWluZ3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIG5vdCBhZGQgdGltaW5ncyBpZiBub3QgdXNpbmcgb3B0LWluIGNhcCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2Vzc2lvbiA9IGF3YWl0IHN0YXJ0U2Vzc2lvbih7Y2FwYWJpbGl0aWVzOiB7YWx3YXlzTWF0Y2g6IGRlZmF1bHRDYXBzfX0pO1xuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBnZXRTZXNzaW9uKHNlc3Npb24uc2Vzc2lvbklkKTtcbiAgICAgICAgc2hvdWxkLm5vdC5leGlzdChyZXMuZXZlbnRzKTtcbiAgICAgICAgYXdhaXQgZW5kU2Vzc2lvbihzZXNzaW9uLnNlc3Npb25JZCk7XG4gICAgICB9KTtcbiAgICAgIGl0KCdzaG91bGQgYWRkIHN0YXJ0IHNlc3Npb24gdGltaW5ncycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY2FwcyA9IHsuLi5kZWZhdWx0Q2FwcywgJ2FwcGl1bTpldmVudFRpbWluZ3MnOiB0cnVlfTtcbiAgICAgICAgY29uc3Qgc2Vzc2lvbiA9IGF3YWl0IHN0YXJ0U2Vzc2lvbih7Y2FwYWJpbGl0aWVzOiB7YWx3YXlzTWF0Y2g6IGNhcHN9fSk7XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGdldFNlc3Npb24oc2Vzc2lvbi5zZXNzaW9uSWQpO1xuICAgICAgICBzaG91bGQuZXhpc3QocmVzLmV2ZW50cyk7XG4gICAgICAgIHNob3VsZC5leGlzdChyZXMuZXZlbnRzPy5uZXdTZXNzaW9uUmVxdWVzdGVkKTtcbiAgICAgICAgc2hvdWxkLmV4aXN0KHJlcy5ldmVudHM/Lm5ld1Nlc3Npb25TdGFydGVkKTtcbiAgICAgICAgcmVzLmV2ZW50cz8ubmV3U2Vzc2lvblJlcXVlc3RlZFswXS5zaG91bGQuYmUuYSgnbnVtYmVyJyk7XG4gICAgICAgIHJlcy5ldmVudHM/Lm5ld1Nlc3Npb25TdGFydGVkWzBdLnNob3VsZC5iZS5hKCdudW1iZXInKTtcbiAgICAgICAgYXdhaXQgZW5kU2Vzc2lvbihzZXNzaW9uLnNlc3Npb25JZCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbi8qKlxuICogQSB7QGxpbmtjb2RlIERyaXZlckNsYXNzfSwgZXhjZXB0IHVzaW5nIHRoZSBiYXNlIHtAbGlua2NvZGUgRHJpdmVyfSB0eXBlIGluc3RlYWQgb2YgYEV4dGVybmFsRHJpdmVyYC5cbiAqIFRoaXMgYWxsb3dzIHRoZSBzdWl0ZSB0byB3b3JrIGZvciBgQmFzZURyaXZlcmAuXG4gKiBAdGVtcGxhdGUge0RyaXZlcn0gUFxuICogQHR5cGVkZWYge2ltcG9ydCgnQGFwcGl1bS90eXBlcycpLkRyaXZlckNsYXNzPFA+fSBEcml2ZXJDbGFzc1xuICovXG5cbi8qKlxuICogQHR5cGVkZWYge2ltcG9ydCgnQGFwcGl1bS90eXBlcycpLkNhcGFiaWxpdGllc30gQ2FwYWJpbGl0aWVzXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdAYXBwaXVtL3R5cGVzJykuRHJpdmVyfSBEcml2ZXJcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJ0BhcHBpdW0vdHlwZXMnKS5Ecml2ZXJTdGF0aWN9IERyaXZlclN0YXRpY1xuICogQHR5cGVkZWYge2ltcG9ydCgnQGFwcGl1bS90eXBlcycpLkFwcGl1bVczQ0NhcGFiaWxpdGllc30gQXBwaXVtVzNDQ2FwYWJpbGl0aWVzXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdheGlvcycpLkF4aW9zUmVxdWVzdENvbmZpZ30gQXhpb3NSZXF1ZXN0Q29uZmlnXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdAYXBwaXVtL3R5cGVzJykuU2luZ3VsYXJTZXNzaW9uRGF0YX0gU2luZ3VsYXJTZXNzaW9uRGF0YVxuICovXG5cbi8qKlxuICogQHRlbXBsYXRlIFQsRFxuICogQHR5cGVkZWYge2ltcG9ydCgnYXhpb3MnKS5BeGlvc1Jlc3BvbnNlPFQsIEQ+fSBBeGlvc1Jlc3BvbnNlXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiBOZXdTZXNzaW9uRGF0YVxuICogQHByb3BlcnR5IHtpbXBvcnQoJ3R5cGUtZmVzdCcpLlJlcXVpcmVBdExlYXN0T25lPGltcG9ydCgnQGFwcGl1bS90eXBlcycpLlczQ0NhcGFiaWxpdGllcywgJ2ZpcnN0TWF0Y2gnfCdhbHdheXNNYXRjaCc+fSBjYXBhYmlsaXRpZXNcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIE5ld1Nlc3Npb25SZXNwb25zZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IHNlc3Npb25JZCxcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KCdAYXBwaXVtL3R5cGVzJykuQ2FwYWJpbGl0aWVzfSBjYXBhYmlsaXRpZXNcbiAqL1xuXG4vKipcbiAqIFNvbWUgRTJFIGhlbHBlcnMgZm9yIG1ha2luZyByZXF1ZXN0cyBhbmQgbWFuYWdpbmcgc2Vzc2lvbnNcbiAqIFNlZSB7QGxpbmtjb2RlIGNyZWF0ZVNlc3Npb25IZWxwZXJzfVxuICogQHRlbXBsYXRlIFtDb21tYW5kRGF0YT11bmtub3duXVxuICogQHRlbXBsYXRlIFtSZXNwb25zZURhdGE9YW55XVxuICogQHR5cGVkZWYgU2Vzc2lvbkhlbHBlcnNcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBuZXdTZXNzaW9uVVJMIC0gVVJMIHRvIGNyZWF0ZSBhIG5ldyBzZXNzaW9uLiBDYW4gYmUgdXNlZCB3aXRoIHJhdyBgYXhpb3NgIHJlcXVlc3RzIHRvIGZ1bGx5IGluc3BlY3QgcmF3IHJlc3BvbnNlLiAgTW9zdGx5LCB0aGlzIHdpbGwgbm90IGJlIHVzZWQuXG4gKiBAcHJvcGVydHkgeyhkYXRhOiBOZXdTZXNzaW9uRGF0YSwgY29uZmlnPzogQXhpb3NSZXF1ZXN0Q29uZmlnKSA9PiBQcm9taXNlPE5ld1Nlc3Npb25SZXNwb25zZT59IHN0YXJ0U2Vzc2lvbiAtIEJlZ2luIGEgc2Vzc2lvblxuICogQHByb3BlcnR5IHsoc2Vzc2lvbklkOiBzdHJpbmcpID0+IFByb21pc2U8QXhpb3NSZXNwb25zZTx7dmFsdWU6IHtlcnJvcj86IHN0cmluZ30/fSwge3ZhbGlkYXRlU3RhdHVzOiBudWxsfT4+fSBlbmRTZXNzaW9uIC0gRW5kIGEgc2Vzc2lvbi4gX05vdGU6IHJlc29sdmVzIHdpdGggcmF3IHJlc3BvbnNlIG9iamVjdF9cbiAqIEBwcm9wZXJ0eSB7KHNlc3Npb25JZDogc3RyaW5nKSA9PiBQcm9taXNlPFNpbmd1bGFyU2Vzc2lvbkRhdGE+fSBnZXRTZXNzaW9uIC0gR2V0IGluZm8gYWJvdXQgYSBzZXNzaW9uXG4gKiBAcHJvcGVydHkgeyhzZXNzaW9uSWQ6IHN0cmluZywgY21kTmFtZTogc3RyaW5nLCBkYXRhPzogQ29tbWFuZERhdGEsIGNvbmZpZz86IEF4aW9zUmVxdWVzdENvbmZpZykgPT4gUHJvbWlzZTxSZXNwb25zZURhdGE+fSBwb3N0Q29tbWFuZCAtIFNlbmQgYW4gYXJiaXRyYXJ5IGNvbW1hbmQgdmlhIGBQT1NUYC5cbiAqIEBwcm9wZXJ0eSB7KHNlc3Npb25JZE9yQ21kTmFtZTogc3RyaW5nLCBjbWROYW1lT3JDb25maWc6IHN0cmluZ3xBeGlvc1JlcXVlc3RDb25maWcsIGNvbmZpZz86IEF4aW9zUmVxdWVzdENvbmZpZykgPT4gUHJvbWlzZTxSZXNwb25zZURhdGE+fSBnZXRDb21tYW5kIC0gU2VuZCBhbiBhcmJpdHJhcnkgY29tbWFuZCB2aWEgYEdFVGAuIE9wdGlvbmFsIGBzZXNzaW9uSWRgLlxuICovXG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUVBLE1BQU1BLE1BQU0sR0FBR0MsYUFBQSxDQUFLRCxNQUFMLEVBQWY7O0FBVU8sU0FBU0Usb0JBQVQsQ0FBOEJDLElBQTlCLEVBQW9DQyxPQUFPLEdBQUdDLGtCQUE5QyxFQUF5RDtFQUM5RCxNQUFNQyxtQkFBbUIsR0FFckIsSUFBQUMsd0JBQUEsRUFBZ0JILE9BQWhCLEVBQXlCRCxJQUF6QixDQUZKO0VBS0EsTUFBTUssZ0JBQWdCLEdBQUdGLG1CQUFtQixDQUFDRyxlQUFELEVBQUksRUFBSixDQUE1QztFQUNBLE1BQU1DLGFBQWEsR0FB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
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates unit test suites for a driver.
|
|
3
|
+
* @param {DriverClass} DriverClass
|
|
4
|
+
* @param {AppiumW3CCapabilities} [defaultCaps]
|
|
5
|
+
*/
|
|
6
|
+
export function driverUnitTestSuite(DriverClass: DriverClass, defaultCaps?: Partial<import("@wdio/types/build/Capabilities").Capabilities & import("@wdio/types/build/Capabilities").AppiumW3CCapabilities & {
|
|
7
|
+
[x: `${string}:${string}`]: any;
|
|
8
|
+
}> | undefined): void;
|
|
9
|
+
export type DriverClass = import('@appium/types').DriverClass;
|
|
10
|
+
export type W3CCapabilities = import('@appium/types').W3CCapabilities;
|
|
11
|
+
export type AppiumW3CCapabilities = import('@appium/types').AppiumW3CCapabilities;
|
|
12
|
+
//# sourceMappingURL=driver-unit-suite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"driver-unit-suite.d.ts","sourceRoot":"","sources":["../../lib/driver-unit-suite.js"],"names":[],"mappings":"AAaA;;;;GAIG;AAEH,iDAJW,WAAW;;sBA4mBrB;0BAGY,OAAO,eAAe,EAAE,WAAW;8BACnC,OAAO,eAAe,EAAE,eAAe;oCACvC,OAAO,eAAe,EAAE,qBAAqB"}
|