@appium/test-support 1.3.22 → 1.5.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.
- 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 +389 -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 +465 -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;;sBAyTC;;;;;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,389 @@
|
|
|
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,
|
|
118
|
+
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
|
|
137
|
+
}
|
|
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
|
+
});
|
|
207
|
+
});
|
|
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'
|
|
295
|
+
});
|
|
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
|
|
316
|
+
});
|
|
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);
|
|
341
|
+
});
|
|
342
|
+
const reqPromise = getCommand('status', {
|
|
343
|
+
validateStatus: null
|
|
344
|
+
});
|
|
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);
|
|
349
|
+
});
|
|
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
|
+
}
|
|
362
|
+
});
|
|
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
|
+
}
|
|
377
|
+
});
|
|
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
|
+
});
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJzaG91bGQiLCJjaGFpIiwiY3JlYXRlU2Vzc2lvbkhlbHBlcnMiLCJwb3J0IiwiYWRkcmVzcyIsIlRFU1RfSE9TVCIsImNyZWF0ZUFwcGl1bVRlc3RVUkwiLCJjcmVhdGVBcHBpdW1VUkwiLCJjcmVhdGVTZXNzaW9uVVJMIiwiXyIsIm5ld1Nlc3Npb25VUkwiLCJwb3N0Q29tbWFuZCIsInNlc3Npb25JZCIsImNtZE5hbWUiLCJkYXRhIiwiY29uZmlnIiwidXJsIiwicmVzcG9uc2UiLCJheGlvcyIsInBvc3QiLCJ2YWx1ZSIsImdldENvbW1hbmQiLCJzZXNzaW9uSWRPckNtZE5hbWUiLCJjbWROYW1lT3JDb25maWciLCJpc1N0cmluZyIsInZhbGlkYXRlU3RhdHVzIiwic3RhcnRTZXNzaW9uIiwiZGVmYXVsdHNEZWVwIiwiY2FwYWJpbGl0aWVzIiwiYWx3YXlzTWF0Y2giLCJmaXJzdE1hdGNoIiwiZW5kU2Vzc2lvbiIsImRlbGV0ZSIsImdldFNlc3Npb24iLCJkcml2ZXJFMkVUZXN0U3VpdGUiLCJEcml2ZXJDbGFzcyIsImRlZmF1bHRDYXBzIiwiY2xhc3NOYW1lIiwibmFtZSIsImRlc2NyaWJlIiwiYmFzZVNlcnZlciIsImQiLCJiZWZvcmUiLCJnZXRUZXN0UG9ydCIsInNlcnZlciIsInJvdXRlQ29uZmlndXJpbmdGdW5jdGlvbiIsImhvc3RuYW1lIiwiY2xpQXJncyIsImFmdGVyIiwiY2xvc2UiLCJpdCIsInNlc3Npb25JZHMiLCJ0aW1lcyIsImhlYWRlcnMiLCJzaW1wbGUiLCJyZXNvbHZlV2l0aEZ1bGxSZXNwb25zZSIsInB1c2giLCJ1bmlxIiwibGVuZ3RoIiwiZXF1YWwiLCJzdGF0dXMiLCJyZXFzIiwibWFwIiwiQiIsImFsbCIsImV4aXN0IiwicGxhdGZvcm1OYW1lIiwiZGV2aWNlTmFtZSIsInNraXAiLCJvcmlnaW5hbEZpbmRFbGVtZW50Iiwib3JpZ2luYWxGaW5kRWxlbWVudHMiLCJzdGFydFRpbWVvdXRTZXNzaW9uIiwidGltZW91dCIsImNhcHMiLCJjbG9uZURlZXAiLCJmaW5kRWxlbWVudCIsImJpbmQiLCJmaW5kRWxlbWVudHMiLCJkZWxheSIsIm5ld1Nlc3Npb24iLCJuZXdDb21tYW5kVGltZW91dE1zIiwiYmUiLCJhYm92ZSIsInVzaW5nIiwiZXJyb3IiLCJyZXNwIiwic3RhcnQiLCJEYXRlIiwibm93IiwiZXFsIiwibm90Iiwibm9Db21tYW5kVGltZXIiLCJzZXR0aW5ncyIsIkRldmljZVNldHRpbmdzIiwiaWdub3JlVW5pbXBvcnRhbnRWaWV3cyIsImdldFNldHRpbmdzIiwiZmFsc2UiLCJ1cGRhdGUiLCJyZWplY3RlZCIsInJlamVjdGVkV2l0aCIsInNhbmRib3giLCJiZWZvcmVFYWNoIiwic2lub24iLCJjcmVhdGVTYW5kYm94IiwiYWZ0ZXJFYWNoIiwicmVzdG9yZSIsInN0dWIiLCJjYWxsc0Zha2UiLCJyZXFQcm9taXNlIiwic2h1dGRvd25FdmVudFByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0Iiwic2V0VGltZW91dCIsIkVycm9yIiwib25VbmV4cGVjdGVkU2h1dGRvd24iLCJzdGFydFVuZXhwZWN0ZWRTaHV0ZG93biIsIm1lc3NhZ2UiLCJjb250YWluIiwic2Vzc2lvbiIsInJlcyIsImV2ZW50cyIsIm5ld1Nlc3Npb25SZXF1ZXN0ZWQiLCJuZXdTZXNzaW9uU3RhcnRlZCIsImEiXSwic291cmNlcyI6WyIuLi8uLi9saWIvZHJpdmVyLWUyZS1zdWl0ZS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHtzZXJ2ZXIsIHJvdXRlQ29uZmlndXJpbmdGdW5jdGlvbiwgRGV2aWNlU2V0dGluZ3N9IGZyb20gJ2FwcGl1bS9kcml2ZXInO1xuaW1wb3J0IGF4aW9zIGZyb20gJ2F4aW9zJztcbmltcG9ydCBCIGZyb20gJ2JsdWViaXJkJztcbmltcG9ydCB7VEVTVF9IT1NULCBnZXRUZXN0UG9ydCwgY3JlYXRlQXBwaXVtVVJMfSBmcm9tICcuL2hlbHBlcnMnO1xuaW1wb3J0IGNoYWkgZnJvbSAnY2hhaSc7XG5pbXBvcnQgc2lub24gZnJvbSAnc2lub24nO1xuXG5jb25zdCBzaG91bGQgPSBjaGFpLnNob3VsZCgpO1xuXG4vKipcbiAqIENyZWF0ZXMgc29tZSBoZWxwZXIgZnVuY3Rpb25zIGZvciBFMkUgdGVzdHMgdG8gbWFuYWdlIHNlc3Npb25zLlxuICogQHRlbXBsYXRlIFtDb21tYW5kRGF0YT11bmtub3duXVxuICogQHRlbXBsYXRlIFtSZXNwb25zZURhdGE9YW55XVxuICogQHBhcmFtIHtudW1iZXJ9IHBvcnQgLSBQb3J0IG9uIHdoaWNoIHRoZSBzZXJ2ZXIgaXMgcnVubmluZy4gVHlwaWNhbGx5IHRoaXMgd2lsbCBiZSByZXRyaWV2ZWQgdmlhIGBnZXQtcG9ydGAgYmVmb3JlaGFuZFxuICogQHBhcmFtIHtzdHJpbmd9IFthZGRyZXNzXSAtIEFkZHJlc3MvaG9zdCBvbiB3aGljaCB0aGUgc2VydmVyIGlzIHJ1bm5pbmcuIERlZmF1bHRzIHRvIHtAbGlua2NvZGUgVEVTVF9IT1NUfVxuICogQHJldHVybnMge1Nlc3Npb25IZWxwZXJzPENvbW1hbmREYXRhLCBSZXNwb25zZURhdGE+fVxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlU2Vzc2lvbkhlbHBlcnMocG9ydCwgYWRkcmVzcyA9IFRFU1RfSE9TVCkge1xuICBjb25zdCBjcmVhdGVBcHBpdW1UZXN0VVJMID1cbiAgICAvKiogQHR5cGUge2ltcG9ydCgnbG9kYXNoJykuQ3VycmllZEZ1bmN0aW9uMjxzdHJpbmcsc3RyaW5nLHN0cmluZz59ICovIChcbiAgICAgIGNyZWF0ZUFwcGl1bVVSTChhZGRyZXNzLCBwb3J0KVxuICAgICk7XG5cbiAgY29uc3QgY3JlYXRlU2Vzc2lvblVSTCA9IGNyZWF0ZUFwcGl1bVRlc3RVUkwoXywgJycpO1xuICBjb25zdCBuZXdTZXNzaW9uVVJMID0gY3JlYXRlQXBwaXVtVGVzdFVSTCgnJywgJ3Nlc3Npb24nKTtcbiAgcmV0dXJuIC8qKiBAdHlwZSB7U2Vzc2lvbkhlbHBlcnM8Q29tbWFuZERhdGEsIFJlc3BvbnNlRGF0YT59ICovICh7XG4gICAgbmV3U2Vzc2lvblVSTCxcbiAgICBjcmVhdGVBcHBpdW1UZXN0VVJMLFxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHNlc3Npb25JZFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBjbWROYW1lXG4gICAgICogQHBhcmFtIHthbnl9IFtkYXRhXVxuICAgICAqIEBwYXJhbSB7QXhpb3NSZXF1ZXN0Q29uZmlnfSBbY29uZmlnXVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPGFueT59XG4gICAgICovXG4gICAgcG9zdENvbW1hbmQ6IGFzeW5jIChzZXNzaW9uSWQsIGNtZE5hbWUsIGRhdGEgPSB7fSwgY29uZmlnID0ge30pID0+IHtcbiAgICAgIGNvbnN0IHVybCA9IGNyZWF0ZUFwcGl1bVRlc3RVUkwoc2Vzc2lvbklkLCBjbWROYW1lKTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgYXhpb3MucG9zdCh1cmwsIGRhdGEsIGNvbmZpZyk7XG4gICAgICByZXR1cm4gcmVzcG9uc2UuZGF0YT8udmFsdWU7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzZXNzaW9uSWRPckNtZE5hbWVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xBeGlvc1JlcXVlc3RDb25maWd9IGNtZE5hbWVPckNvbmZpZ1xuICAgICAqIEBwYXJhbSB7QXhpb3NSZXF1ZXN0Q29uZmlnfSBbY29uZmlnXVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPGFueT59XG4gICAgICovXG4gICAgZ2V0Q29tbWFuZDogYXN5bmMgKHNlc3Npb25JZE9yQ21kTmFtZSwgY21kTmFtZU9yQ29uZmlnLCBjb25maWcgPSB7fSkgPT4ge1xuICAgICAgaWYgKCFfLmlzU3RyaW5nKGNtZE5hbWVPckNvbmZpZykpIHtcbiAgICAgICAgY29uZmlnID0gY21kTmFtZU9yQ29uZmlnO1xuICAgICAgICBjbWROYW1lT3JDb25maWcgPSBzZXNzaW9uSWRPckNtZE5hbWU7XG4gICAgICAgIHNlc3Npb25JZE9yQ21kTmFtZSA9ICcnO1xuICAgICAgfVxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBheGlvcyh7XG4gICAgICAgIHVybDogY3JlYXRlQXBwaXVtVGVzdFVSTChzZXNzaW9uSWRPckNtZE5hbWUsIGNtZE5hbWVPckNvbmZpZyksXG4gICAgICAgIHZhbGlkYXRlU3RhdHVzOiBudWxsLFxuICAgICAgICAuLi5jb25maWcsXG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXNwb25zZS5kYXRhPy52YWx1ZTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtOZXdTZXNzaW9uRGF0YX0gZGF0YVxuICAgICAqIEBwYXJhbSB7QXhpb3NSZXF1ZXN0Q29uZmlnfSBbY29uZmlnXVxuICAgICAqL1xuICAgIHN0YXJ0U2Vzc2lvbjogYXN5bmMgKGRhdGEsIGNvbmZpZyA9IHt9KSA9PiB7XG4gICAgICBkYXRhID0gXy5kZWZhdWx0c0RlZXAoZGF0YSwge1xuICAgICAgICBjYXBhYmlsaXRpZXM6IHtcbiAgICAgICAgICBhbHdheXNNYXRjaDoge30sXG4gICAgICAgICAgZmlyc3RNYXRjaDogW3t9XSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBheGlvcy5wb3N0KG5ld1Nlc3Npb25VUkwsIGRhdGEsIGNvbmZpZyk7XG4gICAgICByZXR1cm4gcmVzcG9uc2UuZGF0YT8udmFsdWU7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzZXNzaW9uSWRcbiAgICAgKi9cbiAgICBlbmRTZXNzaW9uOiBhc3luYyAoc2Vzc2lvbklkKSA9PlxuICAgICAgYXdhaXQgYXhpb3MuZGVsZXRlKGNyZWF0ZVNlc3Npb25VUkwoc2Vzc2lvbklkKSwge1xuICAgICAgICB2YWxpZGF0ZVN0YXR1czogbnVsbCxcbiAgICAgIH0pLFxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzZXNzaW9uSWRcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxhbnk+fVxuICAgICAqL1xuICAgIGdldFNlc3Npb246IGFzeW5jIChzZXNzaW9uSWQpID0+IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgYXhpb3Moe1xuICAgICAgICB1cmw6IGNyZWF0ZVNlc3Npb25VUkwoc2Vzc2lvbklkKSxcbiAgICAgICAgdmFsaWRhdGVTdGF0dXM6IG51bGwsXG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXNwb25zZS5kYXRhPy52YWx1ZTtcbiAgICB9LFxuICB9KTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIEUyRSB0ZXN0IHN1aXRlcyBmb3IgYSBkcml2ZXIuXG4gKiBAdGVtcGxhdGUge0RyaXZlcn0gUFxuICogQHBhcmFtIHtEcml2ZXJDbGFzczxQPn0gRHJpdmVyQ2xhc3NcbiAqIEBwYXJhbSB7QXBwaXVtVzNDQ2FwYWJpbGl0aWVzfSBbZGVmYXVsdENhcHNdXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkcml2ZXJFMkVUZXN0U3VpdGUoRHJpdmVyQ2xhc3MsIGRlZmF1bHRDYXBzID0ge30pIHtcbiAgbGV0IGFkZHJlc3MgPSBkZWZhdWx0Q2Fwc1snYXBwaXVtOmFkZHJlc3MnXSA/PyBURVNUX0hPU1Q7XG4gIGxldCBwb3J0ID0gZGVmYXVsdENhcHNbJ2FwcGl1bTpwb3J0J107XG4gIGNvbnN0IGNsYXNzTmFtZSA9IERyaXZlckNsYXNzLm5hbWUgfHwgJyh1bmtub3duIGRyaXZlciknO1xuXG4gIGRlc2NyaWJlKGBCYXNlRHJpdmVyIEUyRSAoYXMgJHtjbGFzc05hbWV9KWAsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgYmFzZVNlcnZlcjtcbiAgICAvKiogQHR5cGUge1B9ICovXG4gICAgbGV0IGQ7XG4gICAgLyoqXG4gICAgICogVGhpcyBVUkwgY3JlYXRlcyBhIG5ldyBzZXNzaW9uXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKiovXG4gICAgbGV0IG5ld1Nlc3Npb25VUkw7XG5cbiAgICAvKiogQHR5cGUge1Nlc3Npb25IZWxwZXJzWydzdGFydFNlc3Npb24nXX0gKi9cbiAgICBsZXQgc3RhcnRTZXNzaW9uO1xuICAgIC8qKiBAdHlwZSB7U2Vzc2lvbkhlbHBlcnNbJ2dldFNlc3Npb24nXX0gKi9cbiAgICBsZXQgZ2V0U2Vzc2lvbjtcbiAgICAvKiogQHR5cGUge1Nlc3Npb25IZWxwZXJzWydlbmRTZXNzaW9uJ119ICovXG4gICAgbGV0IGVuZFNlc3Npb247XG4gICAgLyoqIEB0eXBlIHtTZXNzaW9uSGVscGVyc1snZ2V0Q29tbWFuZCddfSAqL1xuICAgIGxldCBnZXRDb21tYW5kO1xuICAgIC8qKiBAdHlwZSB7U2Vzc2lvbkhlbHBlcnNbJ3Bvc3RDb21tYW5kJ119ICovXG4gICAgbGV0IHBvc3RDb21tYW5kO1xuICAgIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBwb3J0ID0gcG9ydCA/PyAoYXdhaXQgZ2V0VGVzdFBvcnQoKSk7XG4gICAgICBkZWZhdWx0Q2FwcyA9IHsuLi5kZWZhdWx0Q2FwcywgJ2FwcGl1bTpwb3J0JzogcG9ydH07XG4gICAgICBkID0gbmV3IERyaXZlckNsYXNzKHtwb3J0LCBhZGRyZXNzfSk7XG4gICAgICBiYXNlU2VydmVyID0gYXdhaXQgc2VydmVyKHtcbiAgICAgICAgcm91dGVDb25maWd1cmluZ0Z1bmN0aW9uOiByb3V0ZUNvbmZpZ3VyaW5nRnVuY3Rpb24oZCksXG4gICAgICAgIHBvcnQsXG4gICAgICAgIGhvc3RuYW1lOiBhZGRyZXNzLFxuICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgIGNsaUFyZ3M6IHt9LFxuICAgICAgfSk7XG4gICAgICAoe3N0YXJ0U2Vzc2lvbiwgZ2V0U2Vzc2lvbiwgZW5kU2Vzc2lvbiwgbmV3U2Vzc2lvblVSTCwgZ2V0Q29tbWFuZCwgcG9zdENvbW1hbmR9ID1cbiAgICAgICAgY3JlYXRlU2Vzc2lvbkhlbHBlcnMocG9ydCwgYWRkcmVzcykpO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXIoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgYmFzZVNlcnZlci5jbG9zZSgpO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3Nlc3Npb24gaGFuZGxpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBpZGVtcG90ZW5jeSB3aGlsZSBjcmVhdGluZyBzZXNzaW9ucycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2Vzc2lvbklkcyA9IFtdO1xuICAgICAgICBsZXQgdGltZXMgPSAwO1xuICAgICAgICBkbyB7XG4gICAgICAgICAgY29uc3Qge3Nlc3Npb25JZH0gPSBhd2FpdCBzdGFydFNlc3Npb24oXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGNhcGFiaWxpdGllczoge2Fsd2F5c01hdGNoOiBkZWZhdWx0Q2Fwc30sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAgICAgJ1gtSWRlbXBvdGVuY3ktS2V5JzogJzEyMzQ1NicsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIC8vIFhYWDogSSdtIG5vdCBzdXJlIHdoYXQgdGhlc2UgYXJlLCBhcyB0aGV5IGFyZSBub3QgZG9jdW1lbnRlZCBheGlvcyBvcHRpb25zLFxuICAgICAgICAgICAgICAvLyBub3IgYXJlIHRoZXkgbWVudGlvbmVkIGluIG91ciBzb3VyY2VcbiAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgICBzaW1wbGU6IGZhbHNlLFxuICAgICAgICAgICAgICByZXNvbHZlV2l0aEZ1bGxSZXNwb25zZTogdHJ1ZSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuXG4gICAgICAgICAgc2Vzc2lvbklkcy5wdXNoKHNlc3Npb25JZCk7XG4gICAgICAgICAgdGltZXMrKztcbiAgICAgICAgfSB3aGlsZSAodGltZXMgPCAyKTtcbiAgICAgICAgXy51bmlxKHNlc3Npb25JZHMpLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG5cbiAgICAgICAgY29uc3Qge3N0YXR1cywgZGF0YX0gPSBhd2FpdCBlbmRTZXNzaW9uKHNlc3Npb25JZHNbMF0pO1xuICAgICAgICBzdGF0dXMuc2hvdWxkLmVxdWFsKDIwMCk7XG4gICAgICAgIHNob3VsZC5lcXVhbChkYXRhLnZhbHVlLCBudWxsKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBpZGVtcG90ZW5jeSB3aGlsZSBjcmVhdGluZyBwYXJhbGxlbCBzZXNzaW9ucycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcmVxcyA9IFtdO1xuICAgICAgICBsZXQgdGltZXMgPSAwO1xuICAgICAgICBkbyB7XG4gICAgICAgICAgcmVxcy5wdXNoKFxuICAgICAgICAgICAgc3RhcnRTZXNzaW9uKFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgY2FwYWJpbGl0aWVzOiB7XG4gICAgICAgICAgICAgICAgICBhbHdheXNNYXRjaDogZGVmYXVsdENhcHMsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgICAgICdYLUlkZW1wb3RlbmN5LUtleSc6ICcxMjM0NScsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKVxuICAgICAgICAgICk7XG4gICAgICAgICAgdGltZXMrKztcbiAgICAgICAgfSB3aGlsZSAodGltZXMgPCAyKTtcbiAgICAgICAgY29uc3Qgc2Vzc2lvbklkcyA9IF8ubWFwKGF3YWl0IEIuYWxsKHJlcXMpLCAnc2Vzc2lvbklkJyk7XG4gICAgICAgIF8udW5pcShzZXNzaW9uSWRzKS5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuXG4gICAgICAgIGNvbnN0IHtzdGF0dXMsIGRhdGF9ID0gYXdhaXQgZW5kU2Vzc2lvbihzZXNzaW9uSWRzWzBdKTtcbiAgICAgICAgc3RhdHVzLnNob3VsZC5lcXVhbCgyMDApO1xuICAgICAgICBzaG91bGQuZXF1YWwoZGF0YS52YWx1ZSwgbnVsbCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBjcmVhdGUgc2Vzc2lvbiBhbmQgcmV0cmlldmUgYSBzZXNzaW9uIGlkLCB0aGVuIGRlbGV0ZSBpdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbGV0IHtzdGF0dXMsIGRhdGF9ID0gYXdhaXQgYXhpb3MucG9zdChuZXdTZXNzaW9uVVJMLCB7XG4gICAgICAgICAgY2FwYWJpbGl0aWVzOiB7XG4gICAgICAgICAgICBhbHdheXNNYXRjaDogZGVmYXVsdENhcHMsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgc3RhdHVzLnNob3VsZC5lcXVhbCgyMDApO1xuICAgICAgICBzaG91bGQuZXhpc3QoZGF0YS52YWx1ZS5zZXNzaW9uSWQpO1xuICAgICAgICBkYXRhLnZhbHVlLmNhcGFiaWxpdGllcy5wbGF0Zm9ybU5hbWUuc2hvdWxkLmVxdWFsKGRlZmF1bHRDYXBzLnBsYXRmb3JtTmFtZSk7XG4gICAgICAgIGRhdGEudmFsdWUuY2FwYWJpbGl0aWVzLmRldmljZU5hbWUuc2hvdWxkLmVxdWFsKGRlZmF1bHRDYXBzWydhcHBpdW06ZGV2aWNlTmFtZSddKTtcblxuICAgICAgICAoe3N0YXR1cywgZGF0YX0gPSBhd2FpdCBlbmRTZXNzaW9uKC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZC5zZXNzaW9uSWQpKSk7XG5cbiAgICAgICAgc3RhdHVzLnNob3VsZC5lcXVhbCgyMDApO1xuICAgICAgICBzaG91bGQuZXF1YWwoZGF0YS52YWx1ZSwgbnVsbCk7XG4gICAgICAgIHNob3VsZC5lcXVhbChkLnNlc3Npb25JZCwgbnVsbCk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0LnNraXAoJ3Nob3VsZCB0aHJvdyBOWUkgZm9yIGNvbW1hbmRzIG5vdCBpbXBsZW1lbnRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHt9KTtcblxuICAgIGRlc2NyaWJlKCdjb21tYW5kIHRpbWVvdXRzJywgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IG9yaWdpbmFsRmluZEVsZW1lbnQsIG9yaWdpbmFsRmluZEVsZW1lbnRzO1xuXG4gICAgICAvKipcbiAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbdGltZW91dF1cbiAgICAgICAqL1xuICAgICAgYXN5bmMgZnVuY3Rpb24gc3RhcnRUaW1lb3V0U2Vzc2lvbih0aW1lb3V0KSB7XG4gICAgICAgIGNvbnN0IGNhcHMgPSBfLmNsb25lRGVlcChkZWZhdWx0Q2Fwcyk7XG4gICAgICAgIGNhcHNbJ2FwcGl1bTpuZXdDb21tYW5kVGltZW91dCddID0gdGltZW91dDtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHN0YXJ0U2Vzc2lvbih7Y2FwYWJpbGl0aWVzOiB7YWx3YXlzTWF0Y2g6IGNhcHN9fSk7XG4gICAgICB9XG5cbiAgICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIG9yaWdpbmFsRmluZEVsZW1lbnQgPSBkLmZpbmRFbGVtZW50O1xuICAgICAgICBkLmZpbmRFbGVtZW50ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHJldHVybiAnZm9vJztcbiAgICAgICAgfS5iaW5kKGQpO1xuXG4gICAgICAgIG9yaWdpbmFsRmluZEVsZW1lbnRzID0gZC5maW5kRWxlbWVudHM7XG4gICAgICAgIGQuZmluZEVsZW1lbnRzID0gYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGF3YWl0IEIuZGVsYXkoMjAwKTtcbiAgICAgICAgICByZXR1cm4gWydmb28nXTtcbiAgICAgICAgfS5iaW5kKGQpO1xuICAgICAgfSk7XG5cbiAgICAgIGFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZC5maW5kRWxlbWVudCA9IG9yaWdpbmFsRmluZEVsZW1lbnQ7XG4gICAgICAgIGQuZmluZEVsZW1lbnRzID0gb3JpZ2luYWxGaW5kRWxlbWVudHM7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBzZXQgYSBkZWZhdWx0IGNvbW1hbmRUaW1lb3V0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgbmV3U2Vzc2lvbiA9IGF3YWl0IHN0YXJ0VGltZW91dFNlc3Npb24oKTtcbiAgICAgICAgZC5uZXdDb21tYW5kVGltZW91dE1zLnNob3VsZC5iZS5hYm92ZSgwKTtcbiAgICAgICAgYXdhaXQgZW5kU2Vzc2lvbihuZXdTZXNzaW9uLnNlc3Npb25JZCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aW1lb3V0IG9uIGNvbW1hbmRzIHVzaW5nIGNvbW1hbmRUaW1lb3V0IGNhcCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbGV0IG5ld1Nlc3Npb24gPSBhd2FpdCBzdGFydFRpbWVvdXRTZXNzaW9uKDAuMjUpO1xuICAgICAgICBjb25zdCBzZXNzaW9uSWQgPSAvKiogQHR5cGUge3N0cmluZ30gKi8gKGQuc2Vzc2lvbklkKTtcbiAgICAgICAgYXdhaXQgcG9zdENvbW1hbmQoc2Vzc2lvbklkLCAnZWxlbWVudCcsIHtcbiAgICAgICAgICB1c2luZzogJ25hbWUnLFxuICAgICAgICAgIHZhbHVlOiAnZm9vJyxcbiAgICAgICAgfSk7XG4gICAgICAgIGF3YWl0IEIuZGVsYXkoNDAwKTtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBhd2FpdCBnZXRTZXNzaW9uKHNlc3Npb25JZCk7XG4gICAgICAgIHNob3VsZC5lcXVhbCh2YWx1ZS5lcnJvciwgJ2ludmFsaWQgc2Vzc2lvbiBpZCcpO1xuICAgICAgICBzaG91bGQuZXF1YWwoZC5zZXNzaW9uSWQsIG51bGwpO1xuICAgICAgICBjb25zdCByZXNwID0gKGF3YWl0IGVuZFNlc3Npb24obmV3U2Vzc2lvbi5zZXNzaW9uSWQpKS5kYXRhLnZhbHVlO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzcD8uZXJyb3IsICdpbnZhbGlkIHNlc3Npb24gaWQnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIG5vdCB0aW1lb3V0IHdpdGggY29tbWFuZFRpbWVvdXQgb2YgZmFsc2UnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBuZXdTZXNzaW9uID0gYXdhaXQgc3RhcnRUaW1lb3V0U2Vzc2lvbigwLjEpO1xuICAgICAgICBsZXQgc3RhcnQgPSBEYXRlLm5vdygpO1xuICAgICAgICBjb25zdCB2YWx1ZSA9IGF3YWl0IHBvc3RDb21tYW5kKC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZC5zZXNzaW9uSWQpLCAnZWxlbWVudHMnLCB7XG4gICAgICAgICAgdXNpbmc6ICduYW1lJyxcbiAgICAgICAgICB2YWx1ZTogJ2ZvbycsXG4gICAgICAgIH0pO1xuICAgICAgICAoRGF0ZS5ub3coKSAtIHN0YXJ0KS5zaG91bGQuYmUuYWJvdmUoMTUwKTtcbiAgICAgICAgdmFsdWUuc2hvdWxkLmVxbChbJ2ZvbyddKTtcbiAgICAgICAgYXdhaXQgZW5kU2Vzc2lvbihuZXdTZXNzaW9uLnNlc3Npb25JZCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBub3QgdGltZW91dCB3aXRoIGNvbW1hbmRUaW1lb3V0IG9mIDAnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGQubmV3Q29tbWFuZFRpbWVvdXRNcyA9IDI7XG4gICAgICAgIGxldCBuZXdTZXNzaW9uID0gYXdhaXQgc3RhcnRUaW1lb3V0U2Vzc2lvbigwKTtcblxuICAgICAgICBhd2FpdCBwb3N0Q29tbWFuZCgvKiogQHR5cGUge3N0cmluZ30gKi8gKGQuc2Vzc2lvbklkKSwgJ2VsZW1lbnQnLCB7XG4gICAgICAgICAgdXNpbmc6ICduYW1lJyxcbiAgICAgICAgICB2YWx1ZTogJ2ZvbycsXG4gICAgICAgIH0pO1xuICAgICAgICBhd2FpdCBCLmRlbGF5KDQwMCk7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gYXdhaXQgZ2V0U2Vzc2lvbigvKiogQHR5cGUge3N0cmluZ30gKi8gKGQuc2Vzc2lvbklkKSk7XG4gICAgICAgIHZhbHVlLnBsYXRmb3JtTmFtZT8uc2hvdWxkLmVxdWFsKGRlZmF1bHRDYXBzLnBsYXRmb3JtTmFtZSk7XG4gICAgICAgIGNvbnN0IHJlc3AgPSAoYXdhaXQgZW5kU2Vzc2lvbihuZXdTZXNzaW9uLnNlc3Npb25JZCkpLmRhdGEudmFsdWU7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXNwLCBudWxsKTtcblxuICAgICAgICBkLm5ld0NvbW1hbmRUaW1lb3V0TXMgPSA2MCAqIDEwMDA7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBub3QgdGltZW91dCBpZiBpdHMganVzdCB0aGUgY29tbWFuZCB0YWtpbmcgYXdoaWxlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgbmV3U2Vzc2lvbiA9IGF3YWl0IHN0YXJ0VGltZW91dFNlc3Npb24oMC4yNSk7XG4gICAgICAgIC8vIFhYWDogcmFjZSBjb25kaXRpb246IHdlIG11c3QgYnVpbGQgdGhpcyBVUkwgYmVmb3JlIC4uLnNvbWV0aGluZyBoYXBwZW5zLi4uXG4gICAgICAgIC8vIHdoaWNoIGNhdXNlcyBgZC5zZXNzaW9uSWRgIHRvIGJlIG1pc3NpbmdcbiAgICAgICAgY29uc3Qge3Nlc3Npb25JZH0gPSBkO1xuXG4gICAgICAgIGF3YWl0IHBvc3RDb21tYW5kKC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZC5zZXNzaW9uSWQpLCAnZWxlbWVudCcsIHtcbiAgICAgICAgICB1c2luZzogJ25hbWUnLFxuICAgICAgICAgIHZhbHVlOiAnZm9vJyxcbiAgICAgICAgfSk7XG4gICAgICAgIGF3YWl0IEIuZGVsYXkoNDAwKTtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBhd2FpdCBnZXRTZXNzaW9uKC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoc2Vzc2lvbklkKSk7XG4gICAgICAgIHZhbHVlLmVycm9yLnNob3VsZC5lcXVhbCgnaW52YWxpZCBzZXNzaW9uIGlkJyk7XG4gICAgICAgIHNob3VsZC5lcXVhbChkLnNlc3Npb25JZCwgbnVsbCk7XG4gICAgICAgIGNvbnN0IHJlc3AgPSAoYXdhaXQgZW5kU2Vzc2lvbihuZXdTZXNzaW9uLnNlc3Npb25JZCkpLmRhdGEudmFsdWU7XG4gICAgICAgIC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoLyoqIEB0eXBlIHsge2Vycm9yOiBzdHJpbmd9IH0gKi8gKHJlc3ApLmVycm9yKS5zaG91bGQuZXF1YWwoXG4gICAgICAgICAgJ2ludmFsaWQgc2Vzc2lvbiBpZCdcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIG5vdCBoYXZlIGEgdGltZXIgcnVubmluZyBiZWZvcmUgb3IgYWZ0ZXIgYSBzZXNzaW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgIHNob3VsZC5ub3QuZXhpc3QoZC5ub0NvbW1hbmRUaW1lcik7XG4gICAgICAgIGxldCBuZXdTZXNzaW9uID0gYXdhaXQgc3RhcnRUaW1lb3V0U2Vzc2lvbigwLjI1KTtcbiAgICAgICAgbmV3U2Vzc2lvbi5zZXNzaW9uSWQuc2hvdWxkLmVxdWFsKGQuc2Vzc2lvbklkKTtcbiAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICBzaG91bGQuZXhpc3QoZC5ub0NvbW1hbmRUaW1lcik7XG4gICAgICAgIGF3YWl0IGVuZFNlc3Npb24obmV3U2Vzc2lvbi5zZXNzaW9uSWQpO1xuICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgIHNob3VsZC5ub3QuZXhpc3QoZC5ub0NvbW1hbmRUaW1lcik7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdzZXR0aW5ncyBhcGknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgICAgICBkLnNldHRpbmdzID0gbmV3IERldmljZVNldHRpbmdzKHtpZ25vcmVVbmltcG9ydGFudFZpZXdzOiBmYWxzZX0pO1xuICAgICAgfSk7XG4gICAgICBpdCgnc2hvdWxkIGJlIGFibGUgdG8gZ2V0IHNldHRpbmdzIG9iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZC5zZXR0aW5ncy5nZXRTZXR0aW5ncygpLmlnbm9yZVVuaW1wb3J0YW50Vmlld3Muc2hvdWxkLmJlLmZhbHNlO1xuICAgICAgfSk7XG4gICAgICBpdCgnc2hvdWxkIG5vdCByZWplY3Qgd2hlbiBgdXBkYXRlU2V0dGluZ3NgIG1ldGhvZCBpcyBub3QgcHJvdmlkZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGF3YWl0IGQuc2V0dGluZ3MudXBkYXRlKHtpZ25vcmVVbmltcG9ydGFudFZpZXdzOiB0cnVlfSkuc2hvdWxkLm5vdC5iZS5yZWplY3RlZDtcbiAgICAgIH0pO1xuICAgICAgaXQoJ3Nob3VsZCByZWplY3QgZm9yIGludmFsaWQgdXBkYXRlIG9iamVjdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgZC5zZXR0aW5nc1xuICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgICAudXBkYXRlKCdpbnZhbGlkIGpzb24nKVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdKU09OJyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCd1bmV4cGVjdGVkIGV4aXRzJywgZnVuY3Rpb24gKCkge1xuICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoJ3Npbm9uJykuU2lub25TYW5kYm94fSAqL1xuICAgICAgbGV0IHNhbmRib3g7XG4gICAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgICAgIH0pO1xuXG4gICAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICBzYW5kYm94LnJlc3RvcmUoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlamVjdCBhIGN1cnJlbnQgY29tbWFuZCB3aGVuIHRoZSBkcml2ZXIgY3Jhc2hlcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2FuZGJveC5zdHViKGQsICdnZXRTdGF0dXMnKS5jYWxsc0Zha2UoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGF3YWl0IEIuZGVsYXkoNTAwMCk7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCByZXFQcm9taXNlID0gZ2V0Q29tbWFuZCgnc3RhdHVzJywge3ZhbGlkYXRlU3RhdHVzOiBudWxsfSk7XG4gICAgICAgIC8vIG1ha2Ugc3VyZSB0aGF0IHRoZSByZXF1ZXN0IGdldHMgdG8gdGhlIHNlcnZlciBiZWZvcmUgb3VyIHNodXRkb3duXG4gICAgICAgIGF3YWl0IEIuZGVsYXkoMTAwKTtcbiAgICAgICAgY29uc3Qgc2h1dGRvd25FdmVudFByb21pc2UgPSBuZXcgQigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgc2V0VGltZW91dChcbiAgICAgICAgICAgICgpID0+XG4gICAgICAgICAgICAgIHJlamVjdChcbiAgICAgICAgICAgICAgICBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAnb25VbmV4cGVjdGVkU2h1dGRvd24gZXZlbnQgaXMgZXhwZWN0ZWQgdG8gYmUgZmlyZWQgd2l0aGluIDUgc2Vjb25kcyB0aW1lb3V0J1xuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIDUwMDBcbiAgICAgICAgICApO1xuICAgICAgICAgIGQub25VbmV4cGVjdGVkU2h1dGRvd24ocmVzb2x2ZSk7XG4gICAgICAgIH0pO1xuICAgICAgICBkLnN0YXJ0VW5leHBlY3RlZFNodXRkb3duKG5ldyBFcnJvcignQ3Jhc2h5dGltZXMnKSk7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gYXdhaXQgcmVxUHJvbWlzZTtcbiAgICAgICAgdmFsdWUubWVzc2FnZS5zaG91bGQuY29udGFpbignQ3Jhc2h5dGltZXMnKTtcbiAgICAgICAgYXdhaXQgc2h1dGRvd25FdmVudFByb21pc2U7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdldmVudCB0aW1pbmdzJywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCBub3QgYWRkIHRpbWluZ3MgaWYgbm90IHVzaW5nIG9wdC1pbiBjYXAnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNlc3Npb24gPSBhd2FpdCBzdGFydFNlc3Npb24oe2NhcGFiaWxpdGllczoge2Fsd2F5c01hdGNoOiBkZWZhdWx0Q2Fwc319KTtcbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgZ2V0U2Vzc2lvbihzZXNzaW9uLnNlc3Npb25JZCk7XG4gICAgICAgIHNob3VsZC5ub3QuZXhpc3QocmVzLmV2ZW50cyk7XG4gICAgICAgIGF3YWl0IGVuZFNlc3Npb24oc2Vzc2lvbi5zZXNzaW9uSWQpO1xuICAgICAgfSk7XG4gICAgICBpdCgnc2hvdWxkIGFkZCBzdGFydCBzZXNzaW9uIHRpbWluZ3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGNhcHMgPSB7Li4uZGVmYXVsdENhcHMsICdhcHBpdW06ZXZlbnRUaW1pbmdzJzogdHJ1ZX07XG4gICAgICAgIGNvbnN0IHNlc3Npb24gPSBhd2FpdCBzdGFydFNlc3Npb24oe2NhcGFiaWxpdGllczoge2Fsd2F5c01hdGNoOiBjYXBzfX0pO1xuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBnZXRTZXNzaW9uKHNlc3Npb24uc2Vzc2lvbklkKTtcbiAgICAgICAgc2hvdWxkLmV4aXN0KHJlcy5ldmVudHMpO1xuICAgICAgICBzaG91bGQuZXhpc3QocmVzLmV2ZW50cz8ubmV3U2Vzc2lvblJlcXVlc3RlZCk7XG4gICAgICAgIHNob3VsZC5leGlzdChyZXMuZXZlbnRzPy5uZXdTZXNzaW9uU3RhcnRlZCk7XG4gICAgICAgIHJlcy5ldmVudHM/Lm5ld1Nlc3Npb25SZXF1ZXN0ZWRbMF0uc2hvdWxkLmJlLmEoJ251bWJlcicpO1xuICAgICAgICByZXMuZXZlbnRzPy5uZXdTZXNzaW9uU3RhcnRlZFswXS5zaG91bGQuYmUuYSgnbnVtYmVyJyk7XG4gICAgICAgIGF3YWl0IGVuZFNlc3Npb24oc2Vzc2lvbi5zZXNzaW9uSWQpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufVxuXG4vKipcbiAqIEEge0BsaW5rY29kZSBEcml2ZXJDbGFzc30sIGV4Y2VwdCB1c2luZyB0aGUgYmFzZSB7QGxpbmtjb2RlIERyaXZlcn0gdHlwZSBpbnN0ZWFkIG9mIGBFeHRlcm5hbERyaXZlcmAuXG4gKiBUaGlzIGFsbG93cyB0aGUgc3VpdGUgdG8gd29yayBmb3IgYEJhc2VEcml2ZXJgLlxuICogQHRlbXBsYXRlIHtEcml2ZXJ9IFBcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJ0BhcHBpdW0vdHlwZXMnKS5Ecml2ZXJDbGFzczxQPn0gRHJpdmVyQ2xhc3NcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJ0BhcHBpdW0vdHlwZXMnKS5DYXBhYmlsaXRpZXN9IENhcGFiaWxpdGllc1xuICogQHR5cGVkZWYge2ltcG9ydCgnQGFwcGl1bS90eXBlcycpLkRyaXZlcn0gRHJpdmVyXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdAYXBwaXVtL3R5cGVzJykuRHJpdmVyU3RhdGljfSBEcml2ZXJTdGF0aWNcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJ0BhcHBpdW0vdHlwZXMnKS5BcHBpdW1XM0NDYXBhYmlsaXRpZXN9IEFwcGl1bVczQ0NhcGFiaWxpdGllc1xuICogQHR5cGVkZWYge2ltcG9ydCgnYXhpb3MnKS5BeGlvc1JlcXVlc3RDb25maWd9IEF4aW9zUmVxdWVzdENvbmZpZ1xuICogQHR5cGVkZWYge2ltcG9ydCgnQGFwcGl1bS90eXBlcycpLlNpbmd1bGFyU2Vzc2lvbkRhdGF9IFNpbmd1bGFyU2Vzc2lvbkRhdGFcbiAqL1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSBULERcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJ2F4aW9zJykuQXhpb3NSZXNwb25zZTxULCBEPn0gQXhpb3NSZXNwb25zZVxuICovXG5cbi8qKlxuICogQHR5cGVkZWYgTmV3U2Vzc2lvbkRhdGFcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KCd0eXBlLWZlc3QnKS5SZXF1aXJlQXRMZWFzdE9uZTxpbXBvcnQoJ0BhcHBpdW0vdHlwZXMnKS5XM0NDYXBhYmlsaXRpZXMsICdmaXJzdE1hdGNoJ3wnYWx3YXlzTWF0Y2gnPn0gY2FwYWJpbGl0aWVzXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiBOZXdTZXNzaW9uUmVzcG9uc2VcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzZXNzaW9uSWQsXG4gKiBAcHJvcGVydHkge2ltcG9ydCgnQGFwcGl1bS90eXBlcycpLkNhcGFiaWxpdGllc30gY2FwYWJpbGl0aWVzXG4gKi9cblxuLyoqXG4gKiBTb21lIEUyRSBoZWxwZXJzIGZvciBtYWtpbmcgcmVxdWVzdHMgYW5kIG1hbmFnaW5nIHNlc3Npb25zXG4gKiBTZWUge0BsaW5rY29kZSBjcmVhdGVTZXNzaW9uSGVscGVyc31cbiAqIEB0ZW1wbGF0ZSBbQ29tbWFuZERhdGE9dW5rbm93bl1cbiAqIEB0ZW1wbGF0ZSBbUmVzcG9uc2VEYXRhPWFueV1cbiAqIEB0eXBlZGVmIFNlc3Npb25IZWxwZXJzXG4gKiBAcHJvcGVydHkge3N0cmluZ30gbmV3U2Vzc2lvblVSTCAtIFVSTCB0byBjcmVhdGUgYSBuZXcgc2Vzc2lvbi4gQ2FuIGJlIHVzZWQgd2l0aCByYXcgYGF4aW9zYCByZXF1ZXN0cyB0byBmdWxseSBpbnNwZWN0IHJhdyByZXNwb25zZS4gIE1vc3RseSwgdGhpcyB3aWxsIG5vdCBiZSB1c2VkLlxuICogQHByb3BlcnR5IHsoZGF0YTogTmV3U2Vzc2lvbkRhdGEsIGNvbmZpZz86IEF4aW9zUmVxdWVzdENvbmZpZykgPT4gUHJvbWlzZTxOZXdTZXNzaW9uUmVzcG9uc2U+fSBzdGFydFNlc3Npb24gLSBCZWdpbiBhIHNlc3Npb25cbiAqIEBwcm9wZXJ0eSB7KHNlc3Npb25JZDogc3RyaW5nKSA9PiBQcm9taXNlPEF4aW9zUmVzcG9uc2U8e3ZhbHVlOiB7ZXJyb3I/OiBzdHJpbmd9P30sIHt2YWxpZGF0ZVN0YXR1czogbnVsbH0+Pn0gZW5kU2Vzc2lvbiAtIEVuZCBhIHNlc3Npb24uIF9Ob3RlOiByZXNvbHZlcyB3aXRoIHJhdyByZXNwb25zZSBvYmplY3RfXG4gKiBAcHJvcGVydHkgeyhzZXNzaW9uSWQ6IHN0cmluZykgPT4gUHJvbWlzZTxTaW5ndWxhclNlc3Npb25EYXRhPn0gZ2V0U2Vzc2lvbiAtIEdldCBpbmZvIGFib3V0IGEgc2Vzc2lvblxuICogQHByb3BlcnR5IHsoc2Vzc2lvbklkOiBzdHJpbmcsIGNtZE5hbWU6IHN0cmluZywgZGF0YT86IENvbW1hbmREYXRhLCBjb25maWc/OiBBeGlvc1JlcXVlc3RDb25maWcpID0+IFByb21pc2U8UmVzcG9uc2VEYXRhPn0gcG9zdENvbW1hbmQgLSBTZW5kIGFuIGFyYml0cmFyeSBjb21tYW5kIHZpYSBgUE9TVGAuXG4gKiBAcHJvcGVydHkgeyhzZXNzaW9uSWRPckNtZE5hbWU6IHN0cmluZywgY21kTmFtZU9yQ29uZmlnOiBzdHJpbmd8QXhpb3NSZXF1ZXN0Q29uZmlnLCBjb25maWc/OiBBeGlvc1JlcXVlc3RDb25maWcpID0+IFByb21pc2U8UmVzcG9uc2VEYXRhPn0gZ2V0Q29tbWFuZCAtIFNlbmQgYW4gYXJiaXRyYXJ5IGNvbW1hbmQgdmlhIGBHRVRgLiBPcHRpb25hbCBgc2Vzc2lvbklkYC5cbiAqL1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFFQSxNQUFNQSxNQUFNLEdBQUdDLGFBQUEsQ0FBS0QsTUFBTCxFQUFmOztBQVVPLFNBQVNFLG9CQUFULENBQThCQyxJQUE5QixFQUFvQ0MsT0FBTyxHQUFHQyxrQkFBOUMsRUFBeUQ7RUFDOUQsTUFBTUMsbUJBQW1CLEdBRXJCLElBQUFDLHdCQUFBLEVBQWdCSCxPQUFoQixFQUF5QkQsSUFBekIsQ0FGSjtFQUtBLE1BQU1LLGdCQUFn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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"}
|