@appium/base-driver 8.2.3 → 8.3.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/build/lib/basedriver/capabilities.js +2 -4
- package/build/lib/basedriver/commands/event.js +2 -4
- package/build/lib/basedriver/commands/find.js +5 -14
- package/build/lib/basedriver/commands/index.js +2 -4
- package/build/lib/basedriver/commands/log.js +4 -9
- package/build/lib/basedriver/commands/session.js +19 -30
- package/build/lib/basedriver/commands/settings.js +5 -11
- package/build/lib/basedriver/commands/timeout.js +11 -18
- package/build/lib/basedriver/desired-caps.js +2 -4
- package/build/lib/basedriver/device-settings.js +15 -5
- package/build/lib/basedriver/driver.js +36 -23
- package/build/lib/basedriver/helpers.js +10 -12
- package/build/lib/basedriver/logger.js +2 -4
- package/build/lib/constants.js +2 -4
- package/build/lib/express/crash.js +2 -4
- package/build/lib/express/express-logging.js +3 -5
- package/build/lib/express/idempotency.js +3 -5
- package/build/lib/express/logger.js +2 -4
- package/build/lib/express/middleware.js +2 -4
- package/build/lib/express/server.js +2 -4
- package/build/lib/express/static.js +2 -4
- package/build/lib/express/websocket.js +2 -4
- package/build/lib/helpers/capabilities.js +37 -0
- package/build/lib/index.js +4 -8
- package/build/lib/jsonwp-proxy/protocol-converter.js +19 -15
- package/build/lib/jsonwp-proxy/proxy.js +20 -15
- package/build/lib/jsonwp-status/status.js +2 -4
- package/build/lib/protocol/errors.js +2 -4
- package/build/lib/protocol/helpers.js +2 -4
- package/build/lib/protocol/index.js +2 -4
- package/build/lib/protocol/protocol.js +37 -30
- package/build/lib/protocol/routes.js +68 -4
- package/build/lib/protocol/validators.js +2 -4
- package/build/test/basedriver/README.md +5 -0
- package/build/test/basedriver/driver-e2e-tests.js +2 -4
- package/build/test/basedriver/driver-tests.js +12 -17
- package/build/test/basedriver/index.js +2 -4
- package/build/test/e2e/basedriver/driver.e2e.spec.js +15 -0
- package/build/test/e2e/basedriver/helpers.e2e.spec.js +192 -0
- package/build/test/e2e/basedriver/websockets.e2e.spec.js +82 -0
- package/build/test/e2e/express/server.e2e.spec.js +159 -0
- package/build/test/e2e/jsonwp-proxy/proxy.e2e.spec.js +59 -0
- package/build/test/e2e/protocol/fake-driver.js +163 -0
- package/build/test/e2e/protocol/helpers.js +25 -0
- package/build/test/e2e/protocol/protocol.e2e.spec.js +1186 -0
- package/build/test/helpers.js +2 -4
- package/build/test/unit/basedriver/capabilities.spec.js +672 -0
- package/build/test/unit/basedriver/capability.spec.js +353 -0
- package/build/test/unit/basedriver/commands/event.spec.js +110 -0
- package/build/test/unit/basedriver/commands/log.spec.js +85 -0
- package/build/test/unit/basedriver/driver.spec.js +15 -0
- package/build/test/unit/basedriver/helpers.spec.js +151 -0
- package/build/test/unit/basedriver/timeout.spec.js +135 -0
- package/build/test/unit/express/server.spec.js +155 -0
- package/build/test/unit/express/static.spec.js +26 -0
- package/build/test/unit/jsonwp-proxy/mock-request.js +91 -0
- package/build/test/unit/jsonwp-proxy/protocol-converter.spec.js +171 -0
- package/build/test/unit/jsonwp-proxy/proxy.spec.js +292 -0
- package/build/test/unit/jsonwp-proxy/url.spec.js +165 -0
- package/build/test/unit/jsonwp-status/status.spec.js +34 -0
- package/build/test/unit/protocol/errors.spec.js +390 -0
- package/build/test/unit/protocol/routes.spec.js +80 -0
- package/build/test/unit/protocol/validator.spec.js +149 -0
- package/lib/basedriver/commands/find.js +3 -6
- package/lib/basedriver/commands/log.js +2 -4
- package/lib/basedriver/commands/session.js +21 -22
- package/lib/basedriver/commands/settings.js +3 -5
- package/lib/basedriver/commands/timeout.js +9 -10
- package/lib/basedriver/device-settings.js +10 -1
- package/lib/basedriver/driver.js +36 -12
- package/lib/basedriver/helpers.js +13 -11
- package/lib/express/express-logging.js +1 -1
- package/lib/express/idempotency.js +1 -1
- package/lib/helpers/capabilities.js +25 -0
- package/lib/index.js +2 -2
- package/lib/jsonwp-proxy/protocol-converter.js +14 -13
- package/lib/jsonwp-proxy/proxy.js +16 -12
- package/lib/protocol/protocol.js +34 -29
- package/lib/protocol/routes.js +60 -1
- package/package.json +36 -24
- package/test/basedriver/README.md +5 -0
- package/test/basedriver/driver-e2e-tests.js +1 -1
- package/test/basedriver/driver-tests.js +12 -7
- package/build/lib/protocol/sessions-cache.js +0 -88
- package/build/test/basedriver/capabilities-specs.js +0 -632
- package/build/test/basedriver/capability-specs.js +0 -396
- package/build/test/basedriver/commands/event-specs.js +0 -112
- package/build/test/basedriver/commands/log-specs.js +0 -80
- package/build/test/basedriver/driver-e2e-specs.js +0 -17
- package/build/test/basedriver/driver-specs.js +0 -17
- package/build/test/basedriver/helpers-e2e-specs.js +0 -194
- package/build/test/basedriver/helpers-specs.js +0 -153
- package/build/test/basedriver/timeout-specs.js +0 -139
- package/build/test/basedriver/websockets-e2e-specs.js +0 -84
- package/build/test/express/server-e2e-specs.js +0 -156
- package/build/test/express/server-specs.js +0 -151
- package/build/test/express/static-specs.js +0 -23
- package/build/test/jsonwp-proxy/mock-request.js +0 -93
- package/build/test/jsonwp-proxy/protocol-converter-specs.js +0 -173
- package/build/test/jsonwp-proxy/proxy-e2e-specs.js +0 -61
- package/build/test/jsonwp-proxy/proxy-specs.js +0 -294
- package/build/test/jsonwp-proxy/url-specs.js +0 -167
- package/build/test/jsonwp-status/status-specs.js +0 -36
- package/build/test/protocol/errors-specs.js +0 -388
- package/build/test/protocol/fake-driver.js +0 -168
- package/build/test/protocol/helpers.js +0 -27
- package/build/test/protocol/protocol-e2e-specs.js +0 -1182
- package/build/test/protocol/routes-specs.js +0 -82
- package/build/test/protocol/validator-specs.js +0 -151
- package/lib/protocol/sessions-cache.js +0 -74
- package/test/basedriver/capabilities-specs.js +0 -505
- package/test/basedriver/capability-specs.js +0 -409
- package/test/basedriver/commands/event-specs.js +0 -74
- package/test/basedriver/commands/log-specs.js +0 -70
- package/test/basedriver/driver-e2e-specs.js +0 -8
- package/test/basedriver/driver-specs.js +0 -8
- package/test/basedriver/fixtures/BadZippedApp.zip +0 -1
- package/test/basedriver/fixtures/FakeAndroidApp.apk +0 -1
- package/test/basedriver/fixtures/FakeAndroidApp.asd +0 -0
- package/test/basedriver/fixtures/FakeIOSApp.app +0 -1
- package/test/basedriver/fixtures/FakeIOSApp.app.zip +0 -0
- package/test/basedriver/fixtures/FakeIOSApp.ipa +0 -0
- package/test/basedriver/fixtures/custom-element-finder-bad.js +0 -5
- package/test/basedriver/fixtures/custom-element-finder.js +0 -29
- package/test/basedriver/helpers-e2e-specs.js +0 -187
- package/test/basedriver/helpers-specs.js +0 -137
- package/test/basedriver/timeout-specs.js +0 -133
- package/test/basedriver/websockets-e2e-specs.js +0 -75
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
require("source-map-support/register");
|
|
6
|
+
|
|
7
|
+
var _lib = require("../../../lib");
|
|
8
|
+
|
|
9
|
+
var _errors = require("../../../lib/protocol/errors");
|
|
10
|
+
|
|
11
|
+
var _lodash = _interopRequireDefault(require("lodash"));
|
|
12
|
+
|
|
13
|
+
var _httpStatusCodes = require("http-status-codes");
|
|
14
|
+
|
|
15
|
+
var _path = _interopRequireDefault(require("path"));
|
|
16
|
+
|
|
17
|
+
const basename = _path.default.basename(__filename);
|
|
18
|
+
|
|
19
|
+
let errorsList = [{
|
|
20
|
+
errorName: 'NoSuchDriverError',
|
|
21
|
+
errorMsg: 'A session is either terminated or not started',
|
|
22
|
+
error: 'invalid session id',
|
|
23
|
+
errorCode: 6
|
|
24
|
+
}, {
|
|
25
|
+
errorName: 'ElementClickInterceptedError',
|
|
26
|
+
errorMsg: 'The Element Click command could not be completed because the element receiving the events is obscuring the element that was requested clicked',
|
|
27
|
+
error: 'element click intercepted'
|
|
28
|
+
}, {
|
|
29
|
+
errorName: 'ElementNotInteractableError',
|
|
30
|
+
errorMsg: 'A command could not be completed because the element is not pointer- or keyboard interactable',
|
|
31
|
+
error: 'element not interactable'
|
|
32
|
+
}, {
|
|
33
|
+
errorName: 'InsecureCertificateError',
|
|
34
|
+
errorMsg: 'Navigation caused the user agent to hit a certificate warning, which is usually the result of an expired or invalid TLS certificate',
|
|
35
|
+
error: 'insecure certificate'
|
|
36
|
+
}, {
|
|
37
|
+
errorName: 'InvalidArgumentError',
|
|
38
|
+
errorMsg: 'The arguments passed to the command are either invalid or malformed',
|
|
39
|
+
error: 'invalid argument'
|
|
40
|
+
}, {
|
|
41
|
+
errorName: 'NoSuchElementError',
|
|
42
|
+
errorMsg: 'An element could not be located on the page using the ' + 'given search parameters.',
|
|
43
|
+
error: 'no such element',
|
|
44
|
+
errorCode: 7
|
|
45
|
+
}, {
|
|
46
|
+
errorName: 'NoSuchFrameError',
|
|
47
|
+
errorMsg: 'A request to switch to a frame could not be satisfied ' + 'because the frame could not be found.',
|
|
48
|
+
error: 'no such frame',
|
|
49
|
+
errorCode: 8
|
|
50
|
+
}, {
|
|
51
|
+
errorName: 'UnknownCommandError',
|
|
52
|
+
errorMsg: 'The requested resource could not be found, or a request ' + 'was received using an HTTP method that is not supported by ' + 'the mapped resource.',
|
|
53
|
+
error: 'unknown command',
|
|
54
|
+
errorCode: 9
|
|
55
|
+
}, {
|
|
56
|
+
errorName: 'StaleElementReferenceError',
|
|
57
|
+
errorMsg: 'An element command failed because the referenced element is ' + 'no longer attached to the DOM.',
|
|
58
|
+
error: 'stale element reference',
|
|
59
|
+
errorCode: 10
|
|
60
|
+
}, {
|
|
61
|
+
errorName: 'ElementNotVisibleError',
|
|
62
|
+
errorMsg: 'An element command could not be completed because the ' + 'element is not visible on the page.',
|
|
63
|
+
errorCode: 11
|
|
64
|
+
}, {
|
|
65
|
+
errorName: 'InvalidElementStateError',
|
|
66
|
+
errorMsg: 'An element command could not be completed because the element ' + 'is in an invalid state (e.g. attempting to click a disabled ' + 'element).',
|
|
67
|
+
error: 'invalid element state',
|
|
68
|
+
errorCode: 12
|
|
69
|
+
}, {
|
|
70
|
+
errorName: 'UnknownError',
|
|
71
|
+
errorMsg: 'An unknown server-side error occurred while processing the ' + 'command.',
|
|
72
|
+
error: 'unknown error',
|
|
73
|
+
errorCode: 13
|
|
74
|
+
}, {
|
|
75
|
+
errorName: 'ElementIsNotSelectableError',
|
|
76
|
+
errorMsg: 'An attempt was made to select an element that cannot ' + 'be selected.',
|
|
77
|
+
error: 'element not selectable',
|
|
78
|
+
errorCode: 15
|
|
79
|
+
}, {
|
|
80
|
+
errorName: 'JavaScriptError',
|
|
81
|
+
errorMsg: 'An error occurred while executing user supplied JavaScript.',
|
|
82
|
+
error: 'javascript error',
|
|
83
|
+
errorCode: 17
|
|
84
|
+
}, {
|
|
85
|
+
errorName: 'XPathLookupError',
|
|
86
|
+
errorMsg: 'An error occurred while searching for an element by XPath.',
|
|
87
|
+
errorCode: 19
|
|
88
|
+
}, {
|
|
89
|
+
errorName: 'TimeoutError',
|
|
90
|
+
errorMsg: 'An operation did not complete before its timeout expired.',
|
|
91
|
+
error: 'timeout',
|
|
92
|
+
errorCode: 21
|
|
93
|
+
}, {
|
|
94
|
+
errorName: 'NoSuchWindowError',
|
|
95
|
+
errorMsg: 'A request to switch to a different window could not be ' + 'satisfied because the window could not be found.',
|
|
96
|
+
error: 'no such window',
|
|
97
|
+
errorCode: 23
|
|
98
|
+
}, {
|
|
99
|
+
errorName: 'InvalidCookieDomainError',
|
|
100
|
+
errorMsg: 'An illegal attempt was made to set a cookie under a different ' + 'domain than the current page.',
|
|
101
|
+
error: 'invalid cookie domain',
|
|
102
|
+
errorCode: 24
|
|
103
|
+
}, {
|
|
104
|
+
errorName: 'InvalidCoordinatesError',
|
|
105
|
+
errorMsg: 'The coordinates provided to an interactions operation are invalid.',
|
|
106
|
+
error: 'invalid coordinates'
|
|
107
|
+
}, {
|
|
108
|
+
errorName: 'UnableToSetCookieError',
|
|
109
|
+
errorMsg: `A request to set a cookie's value could not be satisfied.`,
|
|
110
|
+
error: 'unable to set cookie',
|
|
111
|
+
errorCode: 25
|
|
112
|
+
}, {
|
|
113
|
+
errorName: 'UnexpectedAlertOpenError',
|
|
114
|
+
errorMsg: 'A modal dialog was open, blocking this operation',
|
|
115
|
+
error: 'unexpected alert open',
|
|
116
|
+
errorCode: 26
|
|
117
|
+
}, {
|
|
118
|
+
errorName: 'NoAlertOpenError',
|
|
119
|
+
errorMsg: 'An attempt was made to operate on a modal dialog when one was ' + 'not open.',
|
|
120
|
+
errorCode: 27
|
|
121
|
+
}, {
|
|
122
|
+
errorName: 'ScriptTimeoutError',
|
|
123
|
+
errorMsg: 'A script did not complete before its timeout expired.',
|
|
124
|
+
error: 'script timeout',
|
|
125
|
+
errorCode: 28
|
|
126
|
+
}, {
|
|
127
|
+
errorName: 'InvalidElementCoordinatesError',
|
|
128
|
+
errorMsg: 'The coordinates provided to an interactions operation are ' + 'invalid.',
|
|
129
|
+
errorCode: 29
|
|
130
|
+
}, {
|
|
131
|
+
errorName: 'IMENotAvailableError',
|
|
132
|
+
errorMsg: 'IME was not available.',
|
|
133
|
+
errorCode: 30
|
|
134
|
+
}, {
|
|
135
|
+
errorName: 'IMEEngineActivationFailedError',
|
|
136
|
+
errorMsg: 'An IME engine could not be started.',
|
|
137
|
+
errorCode: 31
|
|
138
|
+
}, {
|
|
139
|
+
errorName: 'InvalidSelectorError',
|
|
140
|
+
errorMsg: 'Argument was an invalid selector (e.g. XPath/CSS).',
|
|
141
|
+
error: 'invalid selector',
|
|
142
|
+
errorCode: 32
|
|
143
|
+
}, {
|
|
144
|
+
errorName: 'SessionNotCreatedError',
|
|
145
|
+
errorMsg: 'A new session could not be created.',
|
|
146
|
+
error: 'session not created',
|
|
147
|
+
errorCode: 33
|
|
148
|
+
}, {
|
|
149
|
+
errorName: 'MoveTargetOutOfBoundsError',
|
|
150
|
+
errorMsg: 'Target provided for a move action is out of bounds.',
|
|
151
|
+
error: 'move target out of bounds',
|
|
152
|
+
errorCode: 34
|
|
153
|
+
}, {
|
|
154
|
+
errorName: 'NoSuchAlertError',
|
|
155
|
+
errorMsg: 'An attempt was made to operate on a modal dialog when one was not open.',
|
|
156
|
+
error: 'no such alert'
|
|
157
|
+
}, {
|
|
158
|
+
errorName: 'NoSuchCookieError',
|
|
159
|
+
errorMsg: 'No cookie matching the given path name was found amongst the associated cookies of the current browsing context’s active document',
|
|
160
|
+
error: 'no such cookie'
|
|
161
|
+
}, {
|
|
162
|
+
errorName: 'NotYetImplementedError',
|
|
163
|
+
errorMsg: 'Method has not yet been implemented',
|
|
164
|
+
error: 'unknown method',
|
|
165
|
+
errorCode: 405
|
|
166
|
+
}, {
|
|
167
|
+
errorName: 'UnknownCommandError',
|
|
168
|
+
errorMsg: 'The requested resource could not be found, or a request was received using an HTTP method that is not supported by the mapped resource.',
|
|
169
|
+
error: 'unknown command'
|
|
170
|
+
}, {
|
|
171
|
+
errorName: 'UnknownMethodError',
|
|
172
|
+
errorMsg: 'The requested command matched a known URL but did not match an method for that URL',
|
|
173
|
+
error: 'unknown method'
|
|
174
|
+
}, {
|
|
175
|
+
errorName: 'UnsupportedOperationError',
|
|
176
|
+
errorMsg: 'A server-side error occurred. Command cannot be supported.',
|
|
177
|
+
error: 'unsupported operation'
|
|
178
|
+
}];
|
|
179
|
+
describe('errors', function () {
|
|
180
|
+
for (let error of errorsList) {
|
|
181
|
+
it(error.errorName + ' should have a JSONWP code or W3C code and message', function () {
|
|
182
|
+
if (error.errorCode) {
|
|
183
|
+
new _lib.errors[error.errorName]().should.have.property('jsonwpCode', error.errorCode);
|
|
184
|
+
} else {
|
|
185
|
+
new _lib.errors[error.errorName]().should.have.property('error', error.error);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
new _lib.errors[error.errorName]().should.have.property('message', error.errorMsg);
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
it('BadParametersError should not have code and should have messg', function () {
|
|
193
|
+
new _lib.errors.BadParametersError().should.not.have.property('jsonwpCode');
|
|
194
|
+
new _lib.errors.BadParametersError().should.have.property('message');
|
|
195
|
+
});
|
|
196
|
+
it('ProxyRequestError should have message and jsonwp', function () {
|
|
197
|
+
new _lib.errors.ProxyRequestError().should.have.property('jsonwp');
|
|
198
|
+
new _lib.errors.ProxyRequestError().should.have.property('message');
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
describe('errorFromMJSONWPStatusCode', function () {
|
|
202
|
+
for (let error of errorsList) {
|
|
203
|
+
if (error.errorName !== 'NotYetImplementedError') {
|
|
204
|
+
it(error.errorCode + ' should return correct error', function () {
|
|
205
|
+
if (error.errorCode) {
|
|
206
|
+
(0, _lib.errorFromMJSONWPStatusCode)(error.errorCode).should.have.property('jsonwpCode', error.errorCode);
|
|
207
|
+
(0, _lib.errorFromMJSONWPStatusCode)(error.errorCode).should.have.property('message', error.errorMsg);
|
|
208
|
+
|
|
209
|
+
if (!_lodash.default.includes([13, 33], error.errorCode)) {
|
|
210
|
+
(0, _lib.errorFromMJSONWPStatusCode)(error.errorCode, 'abcd').should.have.property('jsonwpCode', error.errorCode);
|
|
211
|
+
(0, _lib.errorFromMJSONWPStatusCode)(error.errorCode, 'abcd').should.have.property('message', 'abcd');
|
|
212
|
+
}
|
|
213
|
+
} else {
|
|
214
|
+
(0, _lib.isErrorType)((0, _lib.errorFromMJSONWPStatusCode)(error.errorCode), _lib.errors.UnknownError).should.be.true;
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
it('should throw unknown error for unknown code', function () {
|
|
221
|
+
(0, _lib.errorFromMJSONWPStatusCode)(99).should.have.property('jsonwpCode', 13);
|
|
222
|
+
(0, _lib.errorFromMJSONWPStatusCode)(99).should.have.property('message', 'An unknown server-side error occurred ' + 'while processing the command.');
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
describe('errorFromW3CJsonCode', function () {
|
|
226
|
+
for (let error of errorsList) {
|
|
227
|
+
if (error.errorName !== 'NotYetImplementedError') {
|
|
228
|
+
it(error.errorName + ' should return correct error', function () {
|
|
229
|
+
const {
|
|
230
|
+
error: w3cError
|
|
231
|
+
} = error;
|
|
232
|
+
|
|
233
|
+
if (w3cError) {
|
|
234
|
+
(0, _lib.errorFromW3CJsonCode)(w3cError).error.should.equal(error.error);
|
|
235
|
+
(0, _lib.errorFromW3CJsonCode)(w3cError).should.have.property('message', error.errorMsg);
|
|
236
|
+
} else {
|
|
237
|
+
(0, _lib.isErrorType)((0, _lib.errorFromW3CJsonCode)(w3cError), _lib.errors.UnknownError).should.be.true;
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
it('should parse unknown errors', function () {
|
|
244
|
+
(0, _lib.isErrorType)((0, _lib.errorFromW3CJsonCode)('not a real error code'), _lib.errors.UnknownError).should.be.true;
|
|
245
|
+
(0, _lib.errorFromW3CJsonCode)('not a real error code').message.should.match(/An unknown server-side error occurred/);
|
|
246
|
+
(0, _lib.errorFromW3CJsonCode)('not a real error code').error.should.equal('unknown error');
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
describe('w3c Status Codes', function () {
|
|
250
|
+
it('should match the correct error codes', function () {
|
|
251
|
+
let non400Errors = [['NoSuchDriverError', 404], ['NoSuchFrameError', 404], ['NoAlertOpenError', 404], ['NoSuchWindowError', 404], ['StaleElementReferenceError', 404], ['JavaScriptError', 500], ['MoveTargetOutOfBoundsError', 500], ['NoSuchCookieError', 404], ['NoSuchElementError', 404], ['ScriptTimeoutError', 408], ['SessionNotCreatedError', 500], ['TimeoutError', 408], ['UnableToSetCookieError', 500], ['UnableToCaptureScreen', 500], ['UnexpectedAlertOpenError', 500], ['UnknownCommandError', 404], ['UnknownError', 500], ['UnknownMethodError', 405], ['UnsupportedOperationError', 500]];
|
|
252
|
+
|
|
253
|
+
for (let [errorName, expectedErrorCode] of non400Errors) {
|
|
254
|
+
_lib.errors[errorName].should.exist;
|
|
255
|
+
new _lib.errors[errorName]().should.have.property('w3cStatus', expectedErrorCode);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
new _lib.errors.ElementClickInterceptedError().should.have.property('w3cStatus', 400);
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
describe('.getResponseForW3CError', function () {
|
|
262
|
+
it('should return an error, message and stacktrace for just a generic exception', function () {
|
|
263
|
+
try {
|
|
264
|
+
throw new Error('Some random error');
|
|
265
|
+
} catch (e) {
|
|
266
|
+
const [httpStatus, httpResponseBody] = (0, _errors.getResponseForW3CError)(e);
|
|
267
|
+
httpStatus.should.equal(500);
|
|
268
|
+
const {
|
|
269
|
+
error,
|
|
270
|
+
message,
|
|
271
|
+
stacktrace
|
|
272
|
+
} = httpResponseBody.value;
|
|
273
|
+
message.should.match(/Some random error/);
|
|
274
|
+
error.should.equal('unknown error');
|
|
275
|
+
stacktrace.should.match(/at getResponseForW3CError/);
|
|
276
|
+
stacktrace.should.match(/Some random error/);
|
|
277
|
+
stacktrace.should.contain(basename);
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
it('should return an error, message and stacktrace for a NoSuchElementError', function () {
|
|
281
|
+
const noSuchElementError = new _lib.errors.NoSuchElementError('specific error message');
|
|
282
|
+
const [httpStatus, httpResponseBody] = (0, _errors.getResponseForW3CError)(noSuchElementError);
|
|
283
|
+
httpStatus.should.equal(404);
|
|
284
|
+
const {
|
|
285
|
+
error,
|
|
286
|
+
message,
|
|
287
|
+
stacktrace
|
|
288
|
+
} = httpResponseBody.value;
|
|
289
|
+
error.should.equal('no such element');
|
|
290
|
+
message.should.match(/specific error message/);
|
|
291
|
+
stacktrace.should.contain(basename);
|
|
292
|
+
});
|
|
293
|
+
it('should handle BadParametersError', function () {
|
|
294
|
+
const badParamsError = new _lib.errors.BadParametersError('__FOO__', '__BAR__', '__HELLO_WORLD__');
|
|
295
|
+
const [httpStatus, httpResponseBody] = (0, _errors.getResponseForW3CError)(badParamsError);
|
|
296
|
+
httpStatus.should.equal(400);
|
|
297
|
+
const {
|
|
298
|
+
error,
|
|
299
|
+
message,
|
|
300
|
+
stacktrace
|
|
301
|
+
} = httpResponseBody.value;
|
|
302
|
+
error.should.equal('invalid argument');
|
|
303
|
+
message.should.match(/__BAR__/);
|
|
304
|
+
message.should.match(/__HELLO_WORLD__/);
|
|
305
|
+
stacktrace.should.contain(basename);
|
|
306
|
+
});
|
|
307
|
+
it('should translate JSONWP errors', function () {
|
|
308
|
+
const [httpStatus, httpResponseBody] = (0, _errors.getResponseForW3CError)({
|
|
309
|
+
status: 7,
|
|
310
|
+
value: 'My custom message',
|
|
311
|
+
sessionId: 'Fake Session Id'
|
|
312
|
+
});
|
|
313
|
+
httpStatus.should.equal(404);
|
|
314
|
+
const {
|
|
315
|
+
error,
|
|
316
|
+
message,
|
|
317
|
+
stacktrace
|
|
318
|
+
} = httpResponseBody.value;
|
|
319
|
+
message.should.equal('My custom message');
|
|
320
|
+
error.should.equal('no such element');
|
|
321
|
+
stacktrace.should.exist;
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
describe('.getActualError', function () {
|
|
325
|
+
describe('MJSONWP', function () {
|
|
326
|
+
it('should map a status code 7 no such element error as a NoSuchElementError', function () {
|
|
327
|
+
const actualError = new _lib.errors.ProxyRequestError('Error message does not matter', {
|
|
328
|
+
value: 'does not matter',
|
|
329
|
+
status: 7
|
|
330
|
+
}).getActualError();
|
|
331
|
+
(0, _lib.isErrorType)(actualError, _lib.errors.NoSuchElementError).should.be.true;
|
|
332
|
+
});
|
|
333
|
+
it('should map a status code 10, StaleElementReferenceError', function () {
|
|
334
|
+
const actualError = new _lib.errors.ProxyRequestError('Error message does not matter', {
|
|
335
|
+
value: 'Does not matter',
|
|
336
|
+
status: 10
|
|
337
|
+
}).getActualError();
|
|
338
|
+
(0, _lib.isErrorType)(actualError, _lib.errors.StaleElementReferenceError).should.be.true;
|
|
339
|
+
});
|
|
340
|
+
it('should map an unknown error to UnknownError', function () {
|
|
341
|
+
const actualError = new _lib.errors.ProxyRequestError('Error message does not matter', {
|
|
342
|
+
value: 'Does not matter',
|
|
343
|
+
status: -100
|
|
344
|
+
}).getActualError();
|
|
345
|
+
(0, _lib.isErrorType)(actualError, _lib.errors.UnknownError).should.be.true;
|
|
346
|
+
});
|
|
347
|
+
it('should parse a JSON string', function () {
|
|
348
|
+
const actualError = new _lib.errors.ProxyRequestError('Error message does not matter', JSON.stringify({
|
|
349
|
+
value: 'Does not matter',
|
|
350
|
+
status: -100
|
|
351
|
+
})).getActualError();
|
|
352
|
+
(0, _lib.isErrorType)(actualError, _lib.errors.UnknownError).should.be.true;
|
|
353
|
+
});
|
|
354
|
+
});
|
|
355
|
+
describe('W3C', function () {
|
|
356
|
+
it('should map a 404 no such element error as a NoSuchElementError', function () {
|
|
357
|
+
const actualError = new _lib.errors.ProxyRequestError('Error message does not matter', {
|
|
358
|
+
value: {
|
|
359
|
+
error: _lib.errors.NoSuchElementError.error()
|
|
360
|
+
}
|
|
361
|
+
}, _httpStatusCodes.StatusCodes.NOT_FOUND).getActualError();
|
|
362
|
+
(0, _lib.isErrorType)(actualError, _lib.errors.NoSuchElementError).should.be.true;
|
|
363
|
+
});
|
|
364
|
+
it('should map a 400 StaleElementReferenceError', function () {
|
|
365
|
+
const actualError = new _lib.errors.ProxyRequestError('Error message does not matter', {
|
|
366
|
+
value: {
|
|
367
|
+
error: _lib.errors.StaleElementReferenceError.error()
|
|
368
|
+
}
|
|
369
|
+
}, _httpStatusCodes.StatusCodes.BAD_REQUEST).getActualError();
|
|
370
|
+
(0, _lib.isErrorType)(actualError, _lib.errors.StaleElementReferenceError).should.be.true;
|
|
371
|
+
});
|
|
372
|
+
it('should map an unknown error to UnknownError', function () {
|
|
373
|
+
const actualError = new _lib.errors.ProxyRequestError('Error message does not matter', null, {
|
|
374
|
+
value: {
|
|
375
|
+
error: 'Not a valid w3c JSON code'
|
|
376
|
+
}
|
|
377
|
+
}, 456).getActualError();
|
|
378
|
+
(0, _lib.isErrorType)(actualError, _lib.errors.UnknownError).should.be.true;
|
|
379
|
+
});
|
|
380
|
+
it('should parse a JSON string', function () {
|
|
381
|
+
const actualError = new _lib.errors.ProxyRequestError('Error message does not matter', JSON.stringify({
|
|
382
|
+
value: {
|
|
383
|
+
error: _lib.errors.StaleElementReferenceError.error()
|
|
384
|
+
}
|
|
385
|
+
}), _httpStatusCodes.StatusCodes.BAD_REQUEST).getActualError();
|
|
386
|
+
(0, _lib.isErrorType)(actualError, _lib.errors.StaleElementReferenceError).should.be.true;
|
|
387
|
+
});
|
|
388
|
+
});
|
|
389
|
+
});
|
|
390
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvdW5pdC9wcm90b2NvbC9lcnJvcnMuc3BlYy5qcyJdLCJuYW1lcyI6WyJiYXNlbmFtZSIsInBhdGgiLCJfX2ZpbGVuYW1lIiwiZXJyb3JzTGlzdCIsImVycm9yTmFtZSIsImVycm9yTXNnIiwiZXJyb3IiLCJlcnJvckNvZGUiLCJkZXNjcmliZSIsIml0IiwiZXJyb3JzIiwic2hvdWxkIiwiaGF2ZSIsInByb3BlcnR5IiwiQmFkUGFyYW1ldGVyc0Vycm9yIiwibm90IiwiUHJveHlSZXF1ZXN0RXJyb3IiLCJfIiwiaW5jbHVkZXMiLCJVbmtub3duRXJyb3IiLCJiZSIsInRydWUiLCJ3M2NFcnJvciIsImVxdWFsIiwibWVzc2FnZSIsIm1hdGNoIiwibm9uNDAwRXJyb3JzIiwiZXhwZWN0ZWRFcnJvckNvZGUiLCJleGlzdCIsIkVsZW1lbnRDbGlja0ludGVyY2VwdGVkRXJyb3IiLCJFcnJvciIsImUiLCJodHRwU3RhdHVzIiwiaHR0cFJlc3BvbnNlQm9keSIsInN0YWNrdHJhY2UiLCJ2YWx1ZSIsImNvbnRhaW4iLCJub1N1Y2hFbGVtZW50RXJyb3IiLCJOb1N1Y2hFbGVtZW50RXJyb3IiLCJiYWRQYXJhbXNFcnJvciIsInN0YXR1cyIsInNlc3Npb25JZCIsImFjdHVhbEVycm9yIiwiZ2V0QWN0dWFsRXJyb3IiLCJTdGFsZUVsZW1lbnRSZWZlcmVuY2VFcnJvciIsIkpTT04iLCJzdHJpbmdpZnkiLCJIVFRQU3RhdHVzQ29kZXMiLCJOT1RfRk9VTkQiLCJCQURfUkVRVUVTVCJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUE7O0FBR0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUEsTUFBTUEsUUFBUSxHQUFHQyxjQUFLRCxRQUFMLENBQWNFLFVBQWQsQ0FBakI7O0FBS0EsSUFBSUMsVUFBVSxHQUFHLENBQ2Y7QUFDRUMsRUFBQUEsU0FBUyxFQUFFLG1CQURiO0FBRUVDLEVBQUFBLFFBQVEsRUFBRSwrQ0FGWjtBQUdFQyxFQUFBQSxLQUFLLEVB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RCxXQUFaLEVBQXlCaEMsWUFBT2tDLDBCQUFoQyxFQUE0RGpDLE1BQTVELENBQW1FUyxFQUFuRSxDQUFzRUMsSUFBdEU7QUFDRCxLQVJDLENBQUY7QUFTRCxHQXBDTyxDQUFSO0FBcUNELENBckVPLENBQVIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBlcnJvcnMsIGVycm9yRnJvbU1KU09OV1BTdGF0dXNDb2RlLCBlcnJvckZyb21XM0NKc29uQ29kZSwgaXNFcnJvclR5cGVcbn0gZnJvbSAnLi4vLi4vLi4vbGliJztcbmltcG9ydCB7IGdldFJlc3BvbnNlRm9yVzNDRXJyb3IgfSBmcm9tICcuLi8uLi8uLi9saWIvcHJvdG9jb2wvZXJyb3JzJztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBTdGF0dXNDb2RlcyBhcyBIVFRQU3RhdHVzQ29kZXMgfSBmcm9tICdodHRwLXN0YXR1cy1jb2Rlcyc7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcblxuY29uc3QgYmFzZW5hbWUgPSBwYXRoLmJhc2VuYW1lKF9fZmlsZW5hbWUpO1xuXG5cbi8vIEVycm9yIGNvZGVzIGFuZCBtZXNzYWdlcyBoYXZlIGJlZW4gYWRkZWQgYWNjb3JkaW5nIHRvIEpzb25XaXJlUHJvdG9jb2wgc2VlXG4vLyBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL3NlbGVuaXVtL3dpa2kvSnNvbldpcmVQcm90b2NvbCNSZXNwb25zZV9TdGF0dXNfQ29kZXNcbmxldCBlcnJvcnNMaXN0ID0gW1xuICB7XG4gICAgZXJyb3JOYW1lOiAnTm9TdWNoRHJpdmVyRXJyb3InLFxuICAgIGVycm9yTXNnOiAnQSBzZXNzaW9uIGlzIGVpdGhlciB0ZXJtaW5hdGVkIG9yIG5vdCBzdGFydGVkJyxcbiAgICBlcnJvcjogJ2ludmFsaWQgc2Vzc2lvbiBpZCcsXG4gICAgZXJyb3JDb2RlOiA2XG4gIH0sXG4gIHtcbiAgICBlcnJvck5hbWU6ICdFbGVtZW50Q2xpY2tJbnRlcmNlcHRlZEVycm9yJyxcbiAgICBlcnJvck1zZzogJ1RoZSBFbGVtZW50IENsaWNrIGNvbW1hbmQgY291bGQgbm90IGJlIGNvbXBsZXRlZCBiZWNhdXNlIHRoZSBlbGVtZW50IHJlY2VpdmluZyB0aGUgZXZlbnRzIGlzIG9ic2N1cmluZyB0aGUgZWxlbWVudCB0aGF0IHdhcyByZXF1ZXN0ZWQgY2xpY2tlZCcsXG4gICAgZXJyb3I6ICdlbGVtZW50IGNsaWNrIGludGVyY2VwdGVkJyxcbiAgfSxcbiAge1xuICAgIGVycm9yTmFtZTogJ0VsZW1lbnROb3RJbnRlcmFjdGFibGVFcnJvcicsXG4gICAgZXJyb3JNc2c6ICdBIGNvbW1hbmQgY291bGQgbm90IGJlIGNvbXBsZXRlZCBiZWNhdXNlIHRoZSBlbGVtZW50IGlzIG5vdCBwb2ludGVyLSBvciBrZXlib2FyZCBpbnRlcmFjdGFibGUnLFxuICAgIGVycm9yOiAnZWxlbWVudCBub3QgaW50ZXJhY3RhYmxlJyxcbiAgfSxcbiAge1xuICAgIGVycm9yTmFtZTogJ0luc2VjdXJlQ2VydGlmaWNhdGVFcnJvcicsXG4gICAgZXJyb3JNc2c6ICdOYXZpZ2F0aW9uIGNhdXNlZCB0aGUgdXNlciBhZ2VudCB0byBoaXQgYSBjZXJ0aWZpY2F0ZSB3YXJuaW5nLCB3aGljaCBpcyB1c3VhbGx5IHRoZSByZXN1bHQgb2YgYW4gZXhwaXJlZCBvciBpbnZhbGlkIFRMUyBjZXJ0aWZpY2F0ZScsXG4gICAgZXJyb3I6ICdpbnNlY3VyZSBjZXJ0aWZpY2F0ZScsXG4gIH0sXG4gIHtcbiAgICBlcnJvck5hbWU6ICdJbnZhbGlkQXJndW1lbnRFcnJvcicsXG4gICAgZXJyb3JNc2c6ICdUaGUgYXJndW1lbnRzIHBhc3NlZCB0byB0aGUgY29tbWFuZCBhcmUgZWl0aGVyIGludmFsaWQgb3IgbWFsZm9ybWVkJyxcbiAgICBlcnJvcjogJ2ludmFsaWQgYXJndW1lbnQnLFxuICB9LFxuICB7XG4gICAgZXJyb3JOYW1lOiAnTm9TdWNoRWxlbWVudEVycm9yJyxcbiAgICBlcnJvck1zZzogJ0FuIGVsZW1lbnQgY291bGQgbm90IGJlIGxvY2F0ZWQgb24gdGhlIHBhZ2UgdXNpbmcgdGhlICcgK1xuICAgICAgICAnZ2l2ZW4gc2VhcmNoIHBhcmFtZXRlcnMuJyxcbiAgICBlcnJvcjogJ25vIHN1Y2ggZWxlbWVudCcsXG4gICAgZXJyb3JDb2RlOiA3XG4gIH0sXG4gIHtcbiAgICBlcnJvck5hbWU6ICdOb1N1Y2hGcmFtZUVycm9yJyxcbiAgICBlcnJvck1zZzogJ0EgcmVxdWVzdCB0byBzd2l0Y2ggdG8gYSBmcmFtZSBjb3VsZCBub3QgYmUgc2F0aXNmaWVkICcgK1xuICAgICAgICAnYmVjYXVzZSB0aGUgZnJhbWUgY291bGQgbm90IGJlIGZvdW5kLicsXG4gICAgZXJyb3I6ICdubyBzdWNoIGZyYW1lJyxcbiAgICBlcnJvckNvZGU6IDhcbiAgfSxcbiAge1xuICAgIGVycm9yTmFtZTogJ1Vua25vd25Db21tYW5kRXJyb3InLFxuICAgIGVycm9yTXNnOiAnVGhlIHJlcXVlc3RlZCByZXNvdXJjZSBjb3VsZCBub3QgYmUgZm91bmQsIG9yIGEgcmVxdWVzdCAnICtcbiAgICAgICAgJ3dhcyByZWNlaXZlZCB1c2luZyBhbiBIVFRQIG1ldGhvZCB0aGF0IGlzIG5vdCBzdXBwb3J0ZWQgYnkgJyArXG4gICAgICAgICd0aGUgbWFwcGVkIHJlc291cmNlLicsXG4gICAgZXJyb3I6ICd1bmtub3duIGNvbW1hbmQnLFxuICAgIGVycm9yQ29kZTogOVxuICB9LFxuICB7XG4gICAgZXJyb3JOYW1lOiAnU3RhbGVFbGVtZW50UmVmZXJlbmNlRXJyb3InLFxuICAgIGVycm9yTXNnOiAnQW4gZWxlbWVudCBjb21tYW5kIGZhaWxlZCBiZWNhdXNlIHRoZSByZWZlcmVuY2VkIGVsZW1lbnQgaXMgJyArXG4gICAgICAgICdubyBsb25nZXIgYXR0YWNoZWQgdG8gdGhlIERPTS4nLFxuICAgIGVycm9yOiAnc3RhbGUgZWxlbWVudCByZWZlcmVuY2UnLFxuICAgIGVycm9yQ29kZTogMTBcbiAgfSxcbiAge1xuICAgIGVycm9yTmFtZTogJ0VsZW1lbnROb3RWaXNpYmxlRXJyb3InLFxuICAgIGVycm9yTXNnOiAnQW4gZWxlbWVudCBjb21tYW5kIGNvdWxkIG5vdCBiZSBjb21wbGV0ZWQgYmVjYXVzZSB0aGUgJyArXG4gICAgICAgICdlbGVtZW50IGlzIG5vdCB2aXNpYmxlIG9uIHRoZSBwYWdlLicsXG4gICAgZXJyb3JDb2RlOiAxMVxuICB9LFxuICB7XG4gICAgZXJyb3JOYW1lOiAnSW52YWxpZEVsZW1lbnRTdGF0ZUVycm9yJyxcbiAgICBlcnJvck1zZzogJ0FuIGVsZW1lbnQgY29tbWFuZCBjb3VsZCBub3QgYmUgY29tcGxldGVkIGJlY2F1c2UgdGhlIGVsZW1lbnQgJyArXG4gICAgICAgICdpcyBpbiBhbiBpbnZhbGlkIHN0YXRlIChlLmcuIGF0dGVtcHRpbmcgdG8gY2xpY2sgYSBkaXNhYmxlZCAnICtcbiAgICAgICAgJ2VsZW1lbnQpLicsXG4gICAgZXJyb3I6ICdpbnZhbGlkIGVsZW1lbnQgc3RhdGUnLFxuICAgIGVycm9yQ29kZTogMTJcbiAgfSxcbiAge1xuICAgIGVycm9yTmFtZTogJ1Vua25vd25FcnJvcicsXG4gICAgZXJyb3JNc2c6ICdBbiB1bmtub3duIHNlcnZlci1zaWRlIGVycm9yIG9jY3VycmVkIHdoaWxlIHByb2Nlc3NpbmcgdGhlICcgK1xuICAgICAgICAnY29tbWFuZC4nLFxuICAgIGVycm9yOiAndW5rbm93biBlcnJvcicsXG4gICAgZXJyb3JDb2RlOiAxM1xuICB9LFxuICB7XG4gICAgZXJyb3JOYW1lOiAnRWxlbWVudElzTm90U2VsZWN0YWJsZUVycm9yJyxcbiAgICBlcnJvck1zZzogJ0FuIGF0dGVtcHQgd2FzIG1hZGUgdG8gc2VsZWN0IGFuIGVsZW1lbnQgdGhhdCBjYW5ub3QgJyArXG4gICAgICAgICdiZSBzZWxlY3RlZC4nLFxuICAgIGVycm9yOiAnZWxlbWVudCBub3Qgc2VsZWN0YWJsZScsXG4gICAgZXJyb3JDb2RlOiAxNVxuICB9LFxuICB7XG4gICAgZXJyb3JOYW1lOiAnSmF2YVNjcmlwdEVycm9yJyxcbiAgICBlcnJvck1zZzogJ0FuIGVycm9yIG9jY3VycmVkIHdoaWxlIGV4ZWN1dGluZyB1c2VyIHN1cHBsaWVkIEphdmFTY3JpcHQuJyxcbiAgICBlcnJvcjogJ2phdmFzY3JpcHQgZXJyb3InLFxuICAgIGVycm9yQ29kZTogMTdcbiAgfSxcbiAge1xuICAgIGVycm9yTmFtZTogJ1hQYXRoTG9va3VwRXJyb3InLFxuICAgIGVycm9yTXNnOiAnQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgc2VhcmNoaW5nIGZvciBhbiBlbGVtZW50IGJ5IFhQYXRoLicsXG4gICAgZXJyb3JDb2RlOiAxOVxuICB9LFxuICB7XG4gICAgZXJyb3JOYW1lOiAnVGltZW91dEVycm9yJyxcbiAgICBlcnJvck1zZzogJ0FuIG9wZXJhdGlvbiBkaWQgbm90IGNvbXBsZXRlIGJlZm9yZSBpdHMgdGltZW91dCBleHBpcmVkLicsXG4gICAgZXJyb3I6ICd0aW1lb3V0JyxcbiAgICBlcnJvckNvZGU6IDIxXG4gIH0sXG4gIHtcbiAgICBlcnJvck5hbWU6ICdOb1N1Y2hXaW5kb3dFcnJvcicsXG4gICAgZXJyb3JNc2c6ICdBIHJlcXVlc3QgdG8gc3dpdGNoIHRvIGEgZGlmZmVyZW50IHdpbmRvdyBjb3VsZCBub3QgYmUgJyArXG4gICAgICAgICdzYXRpc2ZpZWQgYmVjYXVzZSB0aGUgd2luZG93IGNvdWxkIG5vdCBiZSBmb3VuZC4nLFxuICAgIGVycm9yOiAnbm8gc3VjaCB3aW5kb3cnLFxuICAgIGVycm9yQ29kZTogMjNcbiAgfSxcbiAge1xuICAgIGVycm9yTmFtZTogJ0ludmFsaWRDb29raWVEb21haW5FcnJvcicsXG4gICAgZXJyb3JNc2c6ICdBbiBpbGxlZ2FsIGF0dGVtcHQgd2FzIG1hZGUgdG8gc2V0IGEgY29va2llIHVuZGVyIGEgZGlmZmVyZW50ICcgK1xuICAgICAgICAnZG9tYWluIHRoYW4gdGhlIGN1cnJlbnQgcGFnZS4nLFxuICAgIGVycm9yOiAnaW52YWxpZCBjb29raWUgZG9tYWluJyxcbiAgICBlcnJvckNvZGU6IDI0XG4gIH0sXG4gIHtcbiAgICBlcnJvck5hbWU6ICdJbnZhbGlkQ29vcmRpbmF0ZXNFcnJvcicsXG4gICAgZXJyb3JNc2c6ICdUaGUgY29vcmRpbmF0ZXMgcHJvdmlkZWQgdG8gYW4gaW50ZXJhY3Rpb25zIG9wZXJhdGlvbiBhcmUgaW52YWxpZC4nLFxuICAgIGVycm9yOiAnaW52YWxpZCBjb29yZGluYXRlcycsXG4gIH0sXG4gIHtcbiAgICBlcnJvck5hbWU6ICdVbmFibGVUb1NldENvb2tpZUVycm9yJyxcbiAgICBlcnJvck1zZzogYEEgcmVxdWVzdCB0byBzZXQgYSBjb29raWUncyB2YWx1ZSBjb3VsZCBub3QgYmUgc2F0aXNmaWVkLmAsXG4gICAgZXJyb3I6ICd1bmFibGUgdG8gc2V0IGNvb2tpZScsXG4gICAgZXJyb3JDb2RlOiAyNVxuICB9LFxuICB7XG4gICAgZXJyb3JOYW1lOiAnVW5leHBlY3RlZEFsZXJ0T3BlbkVycm9yJyxcbiAgICBlcnJvck1zZzogJ0EgbW9kYWwgZGlhbG9nIHdhcyBvcGVuLCBibG9ja2luZyB0aGlzIG9wZXJhdGlvbicsXG4gICAgZXJyb3I6ICd1bmV4cGVjdGVkIGFsZXJ0IG9wZW4nLFxuICAgIGVycm9yQ29kZTogMjZcbiAgfSxcbiAge1xuICAgIGVycm9yTmFtZTogJ05vQWxlcnRPcGVuRXJyb3InLFxuICAgIGVycm9yTXNnOiAnQW4gYXR0ZW1wdCB3YXMgbWFkZSB0byBvcGVyYXRlIG9uIGEgbW9kYWwgZGlhbG9nIHdoZW4gb25lIHdhcyAnICtcbiAgICAgICAgJ25vdCBvcGVuLicsXG4gICAgZXJyb3JDb2RlOiAyN1xuICB9LFxuICB7XG4gICAgZXJyb3JOYW1lOiAnU2NyaXB0VGltZW91dEVycm9yJyxcbiAgICBlcnJvck1zZzogJ0Egc2NyaXB0IGRpZCBub3QgY29tcGxldGUgYmVmb3JlIGl0cyB0aW1lb3V0IGV4cGlyZWQuJyxcbiAgICBlcnJvcjogJ3NjcmlwdCB0aW1lb3V0JyxcbiAgICBlcnJvckNvZGU6IDI4XG4gIH0sXG4gIHtcbiAgICBlcnJvck5hbWU6ICdJbnZhbGlkRWxlbWVudENvb3JkaW5hdGVzRXJyb3InLFxuICAgIGVycm9yTXNnOiAnVGhlIGNvb3JkaW5hdGVzIHByb3ZpZGVkIHRvIGFuIGludGVyYWN0aW9ucyBvcGVyYXRpb24gYXJlICcgK1xuICAgICAgICAnaW52YWxpZC4nLFxuICAgIGVycm9yQ29kZTogMjlcbiAgfSxcbiAge1xuICAgIGVycm9yTmFtZTogJ0lNRU5vdEF2YWlsYWJsZUVycm9yJyxcbiAgICBlcnJvck1zZzogJ0lNRSB3YXMgbm90IGF2YWlsYWJsZS4nLFxuICAgIGVycm9yQ29kZTogMzBcbiAgfSxcbiAge1xuICAgIGVycm9yTmFtZTogJ0lNRUVuZ2luZUFjdGl2YXRpb25GYWlsZWRFcnJvcicsXG4gICAgZXJyb3JNc2c6ICdBbiBJTUUgZW5naW5lIGNvdWxkIG5vdCBiZSBzdGFydGVkLicsXG4gICAgZXJyb3JDb2RlOiAzMVxuICB9LFxuICB7XG4gICAgZXJyb3JOYW1lOiAnSW52YWxpZFNlbGVjdG9yRXJyb3InLFxuICAgIGVycm9yTXNnOiAnQXJndW1lbnQgd2FzIGFuIGludmFsaWQgc2VsZWN0b3IgKGUuZy4gWFBhdGgvQ1NTKS4nLFxuICAgIGVycm9yOiAnaW52YWxpZCBzZWxlY3RvcicsXG4gICAgZXJyb3JDb2RlOiAzMlxuICB9LFxuICB7XG4gICAgZXJyb3JOYW1lOiAnU2Vzc2lvbk5vdENyZWF0ZWRFcnJvcicsXG4gICAgZXJyb3JNc2c6ICdBIG5ldyBzZXNzaW9uIGNvdWxkIG5vdCBiZSBjcmVhdGVkLicsXG4gICAgZXJyb3I6ICdzZXNzaW9uIG5vdCBjcmVhdGVkJyxcbiAgICBlcnJvckNvZGU6IDMzXG4gIH0sXG4gIHtcbiAgICBlcnJvck5hbWU6ICdNb3ZlVGFyZ2V0T3V0T2ZCb3VuZHNFcnJvcicsXG4gICAgZXJyb3JNc2c6ICdUYXJnZXQgcHJvdmlkZWQgZm9yIGEgbW92ZSBhY3Rpb24gaXMgb3V0IG9mIGJvdW5kcy4nLFxuICAgIGVycm9yOiAnbW92ZSB0YXJnZXQgb3V0IG9mIGJvdW5kcycsXG4gICAgZXJyb3JDb2RlOiAzNFxuICB9LFxuICB7XG4gICAgZXJyb3JOYW1lOiAnTm9TdWNoQWxlcnRFcnJvcicsXG4gICAgZXJyb3JNc2c6ICdBbiBhdHRlbXB0IHdhcyBtYWRlIHRvIG9wZXJhdGUgb24gYSBtb2RhbCBkaWFsb2cgd2hlbiBvbmUgd2FzIG5vdCBvcGVuLicsXG4gICAgZXJyb3I6ICdubyBzdWNoIGFsZXJ0JyxcbiAgfSxcbiAge1xuICAgIGVycm9yTmFtZTogJ05vU3VjaENvb2tpZUVycm9yJyxcbiAgICBlcnJvck1zZzogJ05vIGNvb2tpZSBtYXRjaGluZyB0aGUgZ2l2ZW4gcGF0aCBuYW1lIHdhcyBmb3VuZCBhbW9uZ3N0IHRoZSBhc3NvY2lhdGVkIGNvb2tpZXMgb2YgdGhlIGN1cnJlbnQgYnJvd3NpbmcgY29udGV4dOKAmXMgYWN0aXZlIGRvY3VtZW50JyxcbiAgICBlcnJvcjogJ25vIHN1Y2ggY29va2llJyxcbiAgfSxcbiAge1xuICAgIGVycm9yTmFtZTogJ05vdFlldEltcGxlbWVudGVkRXJyb3InLFxuICAgIGVycm9yTXNnOiAnTWV0aG9kIGhhcyBub3QgeWV0IGJlZW4gaW1wbGVtZW50ZWQnLFxuICAgIGVycm9yOiAndW5rbm93biBtZXRob2QnLFxuICAgIGVycm9yQ29kZTogNDA1XG4gIH0sXG4gIHtcbiAgICBlcnJvck5hbWU6ICdVbmtub3duQ29tbWFuZEVycm9yJyxcbiAgICBlcnJvck1zZzogJ1RoZSByZXF1ZXN0ZWQgcmVzb3VyY2UgY291bGQgbm90IGJlIGZvdW5kLCBvciBhIHJlcXVlc3Qgd2FzIHJlY2VpdmVkIHVzaW5nIGFuIEhUVFAgbWV0aG9kIHRoYXQgaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgbWFwcGVkIHJlc291cmNlLicsXG4gICAgZXJyb3I6ICd1bmtub3duIGNvbW1hbmQnLFxuICB9LFxuICB7XG4gICAgZXJyb3JOYW1lOiAnVW5rbm93bk1ldGhvZEVycm9yJyxcbiAgICBlcnJvck1zZzogJ1RoZSByZXF1ZXN0ZWQgY29tbWFuZCBtYXRjaGVkIGEga25vd24gVVJMIGJ1dCBkaWQgbm90IG1hdGNoIGFuIG1ldGhvZCBmb3IgdGhhdCBVUkwnLFxuICAgIGVycm9yOiAndW5rbm93biBtZXRob2QnLFxuICB9LFxuICB7XG4gICAgZXJyb3JOYW1lOiAnVW5zdXBwb3J0ZWRPcGVyYXRpb25FcnJvcicsXG4gICAgZXJyb3JNc2c6ICdBIHNlcnZlci1zaWRlIGVycm9yIG9jY3VycmVkLiBDb21tYW5kIGNhbm5vdCBiZSBzdXBwb3J0ZWQuJyxcbiAgICBlcnJvcjogJ3Vuc3VwcG9ydGVkIG9wZXJhdGlvbicsXG4gIH0sXG5dO1xuXG5kZXNjcmliZSgnZXJyb3JzJywgZnVuY3Rpb24gKCkge1xuICBmb3IgKGxldCBlcnJvciBvZiBlcnJvcnNMaXN0KSB7XG4gICAgaXQoZXJyb3IuZXJyb3JOYW1lICsgJyBzaG91bGQgaGF2ZSBhIEpTT05XUCBjb2RlIG9yIFczQyBjb2RlIGFuZCBtZXNzYWdlJywgZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKGVycm9yLmVycm9yQ29kZSkge1xuICAgICAgICBuZXcgZXJyb3JzW2Vycm9yLmVycm9yTmFtZV0oKVxuICAgICAgICAgIC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnanNvbndwQ29kZScsIGVycm9yLmVycm9yQ29kZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuZXcgZXJyb3JzW2Vycm9yLmVycm9yTmFtZV0oKVxuICAgICAgICAgIC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZXJyb3InLCBlcnJvci5lcnJvcik7XG4gICAgICB9XG4gICAgICBuZXcgZXJyb3JzW2Vycm9yLmVycm9yTmFtZV0oKVxuICAgICAgICAuc2hvdWxkLmhhdmUucHJvcGVydHkoJ21lc3NhZ2UnLCBlcnJvci5lcnJvck1zZyk7XG4gICAgfSk7XG4gIH1cbiAgaXQoJ0JhZFBhcmFtZXRlcnNFcnJvciBzaG91bGQgbm90IGhhdmUgY29kZSBhbmQgc2hvdWxkIGhhdmUgbWVzc2cnLCBmdW5jdGlvbiAoKSB7XG4gICAgbmV3IGVycm9ycy5CYWRQYXJhbWV0ZXJzRXJyb3IoKVxuICAgICAgLnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgnanNvbndwQ29kZScpO1xuICAgIG5ldyBlcnJvcnMuQmFkUGFyYW1ldGVyc0Vycm9yKClcbiAgICAgIC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnbWVzc2FnZScpO1xuICB9KTtcbiAgaXQoJ1Byb3h5UmVxdWVzdEVycm9yIHNob3VsZCBoYXZlIG1lc3NhZ2UgYW5kIGpzb253cCcsIGZ1bmN0aW9uICgpIHtcbiAgICBuZXcgZXJyb3JzLlByb3h5UmVxdWVzdEVycm9yKClcbiAgICAgICAgLnNob3VsZC5oYXZlLnByb3BlcnR5KCdqc29ud3AnKTtcbiAgICBuZXcgZXJyb3JzLlByb3h5UmVxdWVzdEVycm9yKClcbiAgICAgICAgLnNob3VsZC5oYXZlLnByb3BlcnR5KCdtZXNzYWdlJyk7XG4gIH0pO1xufSk7XG5kZXNjcmliZSgnZXJyb3JGcm9tTUpTT05XUFN0YXR1c0NvZGUnLCBmdW5jdGlvbiAoKSB7XG4gIGZvciAobGV0IGVycm9yIG9mIGVycm9yc0xpc3QpIHtcbiAgICBpZiAoZXJyb3IuZXJyb3JOYW1lICE9PSAnTm90WWV0SW1wbGVtZW50ZWRFcnJvcicpIHtcbiAgICAgIGl0KGVycm9yLmVycm9yQ29kZSArICcgc2hvdWxkIHJldHVybiBjb3JyZWN0IGVycm9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoZXJyb3IuZXJyb3JDb2RlKSB7XG4gICAgICAgICAgZXJyb3JGcm9tTUpTT05XUFN0YXR1c0NvZGUoZXJyb3IuZXJyb3JDb2RlKVxuICAgICAgICAgICAgLnNob3VsZC5oYXZlLnByb3BlcnR5KCdqc29ud3BDb2RlJywgZXJyb3IuZXJyb3JDb2RlKTtcbiAgICAgICAgICBlcnJvckZyb21NSlNPTldQU3RhdHVzQ29kZShlcnJvci5lcnJvckNvZGUpXG4gICAgICAgICAgICAuc2hvdWxkLmhhdmUucHJvcGVydHkoJ21lc3NhZ2UnLCBlcnJvci5lcnJvck1zZyk7XG4gICAgICAgICAgaWYgKCFfLmluY2x1ZGVzKFsxMywgMzNdLCBlcnJvci5lcnJvckNvZGUpKSB7XG4gICAgICAgICAgICBlcnJvckZyb21NSlNPTldQU3RhdHVzQ29kZShlcnJvci5lcnJvckNvZGUsICdhYmNkJylcbiAgICAgICAgICAgICAgLnNob3VsZC5oYXZlLnByb3BlcnR5KCdqc29ud3BDb2RlJywgZXJyb3IuZXJyb3JDb2RlKTtcbiAgICAgICAgICAgIGVycm9yRnJvbU1KU09OV1BTdGF0dXNDb2RlKGVycm9yLmVycm9yQ29kZSwgJ2FiY2QnKVxuICAgICAgICAgICAgICAuc2hvdWxkLmhhdmUucHJvcGVydHkoJ21lc3NhZ2UnLCAnYWJjZCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpc0Vycm9yVHlwZShlcnJvckZyb21NSlNPTldQU3RhdHVzQ29kZShlcnJvci5lcnJvckNvZGUpLCBlcnJvcnMuVW5rbm93bkVycm9yKS5zaG91bGQuYmUudHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIGl0KCdzaG91bGQgdGhyb3cgdW5rbm93biBlcnJvciBmb3IgdW5rbm93biBjb2RlJywgZnVuY3Rpb24gKCkge1xuICAgIGVycm9yRnJvbU1KU09OV1BTdGF0dXNDb2RlKDk5KVxuICAgICAgLnNob3VsZC5oYXZlLnByb3BlcnR5KCdqc29ud3BDb2RlJywgMTMpO1xuICAgIGVycm9yRnJvbU1KU09OV1BTdGF0dXNDb2RlKDk5KVxuICAgICAgLnNob3VsZC5oYXZlLnByb3BlcnR5KCdtZXNzYWdlJywgJ0FuIHVua25vd24gc2VydmVyLXNpZGUgZXJyb3Igb2NjdXJyZWQgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnd2hpbGUgcHJvY2Vzc2luZyB0aGUgY29tbWFuZC4nKTtcbiAgfSk7XG59KTtcbmRlc2NyaWJlKCdlcnJvckZyb21XM0NKc29uQ29kZScsIGZ1bmN0aW9uICgpIHtcbiAgZm9yIChsZXQgZXJyb3Igb2YgZXJyb3JzTGlzdCkge1xuICAgIGlmIChlcnJvci5lcnJvck5hbWUgIT09ICdOb3RZZXRJbXBsZW1lbnRlZEVycm9yJykge1xuICAgICAgaXQoZXJyb3IuZXJyb3JOYW1lICsgJyBzaG91bGQgcmV0dXJuIGNvcnJlY3QgZXJyb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHtlcnJvcjogdzNjRXJyb3J9ID0gZXJyb3I7XG4gICAgICAgIGlmICh3M2NFcnJvcikge1xuICAgICAgICAgIGVycm9yRnJvbVczQ0pzb25Db2RlKHczY0Vycm9yKS5lcnJvci5zaG91bGQuZXF1YWwoZXJyb3IuZXJyb3IpO1xuICAgICAgICAgIGVycm9yRnJvbVczQ0pzb25Db2RlKHczY0Vycm9yKS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnbWVzc2FnZScsIGVycm9yLmVycm9yTXNnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpc0Vycm9yVHlwZShlcnJvckZyb21XM0NKc29uQ29kZSh3M2NFcnJvciksIGVycm9ycy5Vbmtub3duRXJyb3IpLnNob3VsZC5iZS50cnVlO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbiAgaXQoJ3Nob3VsZCBwYXJzZSB1bmtub3duIGVycm9ycycsIGZ1bmN0aW9uICgpIHtcbiAgICBpc0Vycm9yVHlwZShlcnJvckZyb21XM0NKc29uQ29kZSgnbm90IGEgcmVhbCBlcnJvciBjb2RlJyksIGVycm9ycy5Vbmtub3duRXJyb3IpLnNob3VsZC5iZS50cnVlO1xuICAgIGVycm9yRnJvbVczQ0pzb25Db2RlKCdub3QgYSByZWFsIGVycm9yIGNvZGUnKS5tZXNzYWdlLnNob3VsZC5tYXRjaCgvQW4gdW5rbm93biBzZXJ2ZXItc2lkZSBlcnJvciBvY2N1cnJlZC8pO1xuICAgIGVycm9yRnJvbVczQ0pzb25Db2RlKCdub3QgYSByZWFsIGVycm9yIGNvZGUnKS5lcnJvci5zaG91bGQuZXF1YWwoJ3Vua25vd24gZXJyb3InKTtcbiAgfSk7XG59KTtcbmRlc2NyaWJlKCd3M2MgU3RhdHVzIENvZGVzJywgZnVuY3Rpb24gKCkge1xuICBpdCgnc2hvdWxkIG1hdGNoIHRoZSBjb3JyZWN0IGVycm9yIGNvZGVzJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBub240MDBFcnJvcnMgPSBbXG4gICAgICBbJ05vU3VjaERyaXZlckVycm9yJywgNDA0XSxcbiAgICAgIFsnTm9TdWNoRnJhbWVFcnJvcicsIDQwNF0sXG4gICAgICBbJ05vQWxlcnRPcGVuRXJyb3InLCA0MDRdLFxuICAgICAgWydOb1N1Y2hXaW5kb3dFcnJvcicsIDQwNF0sXG4gICAgICBbJ1N0YWxlRWxlbWVudFJlZmVyZW5jZUVycm9yJywgNDA0XSxcbiAgICAgIFsnSmF2YVNjcmlwdEVycm9yJywgNTAwXSxcbiAgICAgIFsnTW92ZVRhcmdldE91dE9mQm91bmRzRXJyb3InLCA1MDBdLFxuICAgICAgWydOb1N1Y2hDb29raWVFcnJvcicsIDQwNF0sXG4gICAgICBbJ05vU3VjaEVsZW1lbnRFcnJvcicsIDQwNF0sXG4gICAgICBbJ1NjcmlwdFRpbWVvdXRFcnJvcicsIDQwOF0sXG4gICAgICBbJ1Nlc3Npb25Ob3RDcmVhdGVkRXJyb3InLCA1MDBdLFxuICAgICAgWydUaW1lb3V0RXJyb3InLCA0MDhdLFxuICAgICAgWydVbmFibGVUb1NldENvb2tpZUVycm9yJywgNTAwXSxcbiAgICAgIFsnVW5hYmxlVG9DYXB0dXJlU2NyZWVuJywgNTAwXSxcbiAgICAgIFsnVW5leHBlY3RlZEFsZXJ0T3BlbkVycm9yJywgNTAwXSxcbiAgICAgIFsnVW5rbm93bkNvbW1hbmRFcnJvcicsIDQwNF0sXG4gICAgICBbJ1Vua25vd25FcnJvcicsIDUwMF0sXG4gICAgICBbJ1Vua25vd25NZXRob2RFcnJvcicsIDQwNV0sXG4gICAgICBbJ1Vuc3VwcG9ydGVkT3BlcmF0aW9uRXJyb3InLCA1MDBdLFxuICAgIF07XG5cbiAgICAvLyBUZXN0IHRoZSBlcnJvcnMgdGhhdCB3ZSBkb24ndCBleHBlY3QgdG8gcmV0dXJuIDQwMCBjb2RlXG4gICAgZm9yIChsZXQgW2Vycm9yTmFtZSwgZXhwZWN0ZWRFcnJvckNvZGVdIG9mIG5vbjQwMEVycm9ycykge1xuICAgICAgZXJyb3JzW2Vycm9yTmFtZV0uc2hvdWxkLmV4aXN0O1xuICAgICAgKG5ldyBlcnJvcnNbZXJyb3JOYW1lXSgpKS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndzNjU3RhdHVzJywgZXhwZWN0ZWRFcnJvckNvZGUpO1xuICAgIH1cblxuICAgIC8vIFRlc3QgYW4gZXJyb3IgdGhhdCB3ZSBleHBlY3QgdG8gcmV0dXJuIDQwMCBjb2RlXG4gICAgKG5ldyBlcnJvcnMuRWxlbWVudENsaWNrSW50ZXJjZXB0ZWRFcnJvcigpKS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndzNjU3RhdHVzJywgNDAwKTtcbiAgfSk7XG59KTtcbmRlc2NyaWJlKCcuZ2V0UmVzcG9uc2VGb3JXM0NFcnJvcicsIGZ1bmN0aW9uICgpIHtcbiAgaXQoJ3Nob3VsZCByZXR1cm4gYW4gZXJyb3IsIG1lc3NhZ2UgYW5kIHN0YWNrdHJhY2UgZm9yIGp1c3QgYSBnZW5lcmljIGV4Y2VwdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICB0cnkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdTb21lIHJhbmRvbSBlcnJvcicpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnN0IFtodHRwU3RhdHVzLCBodHRwUmVzcG9uc2VCb2R5XSA9IGdldFJlc3BvbnNlRm9yVzNDRXJyb3IoZSk7XG4gICAgICBodHRwU3RhdHVzLnNob3VsZC5lcXVhbCg1MDApO1xuICAgICAgY29uc3Qge2Vycm9yLCBtZXNzYWdlLCBzdGFja3RyYWNlfSA9IGh0dHBSZXNwb25zZUJvZHkudmFsdWU7XG4gICAgICBtZXNzYWdlLnNob3VsZC5tYXRjaCgvU29tZSByYW5kb20gZXJyb3IvKTtcbiAgICAgIGVycm9yLnNob3VsZC5lcXVhbCgndW5rbm93biBlcnJvcicpO1xuICAgICAgc3RhY2t0cmFjZS5zaG91bGQubWF0Y2goL2F0IGdldFJlc3BvbnNlRm9yVzNDRXJyb3IvKTtcbiAgICAgIHN0YWNrdHJhY2Uuc2hvdWxkLm1hdGNoKC9Tb21lIHJhbmRvbSBlcnJvci8pO1xuICAgICAgc3RhY2t0cmFjZS5zaG91bGQuY29udGFpbihiYXNlbmFtZSk7XG4gICAgfVxuICB9KTtcbiAgaXQoJ3Nob3VsZCByZXR1cm4gYW4gZXJyb3IsIG1lc3NhZ2UgYW5kIHN0YWNrdHJhY2UgZm9yIGEgTm9TdWNoRWxlbWVudEVycm9yJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IG5vU3VjaEVsZW1lbnRFcnJvciA9IG5ldyBlcnJvcnMuTm9TdWNoRWxlbWVudEVycm9yKCdzcGVjaWZpYyBlcnJvciBtZXNzYWdlJyk7XG4gICAgY29uc3QgW2h0dHBTdGF0dXMsIGh0dHBSZXNwb25zZUJvZHldID0gZ2V0UmVzcG9uc2VGb3JXM0NFcnJvcihub1N1Y2hFbGVtZW50RXJyb3IpO1xuICAgIGh0dHBTdGF0dXMuc2hvdWxkLmVxdWFsKDQwNCk7XG4gICAgY29uc3Qge2Vycm9yLCBtZXNzYWdlLCBzdGFja3RyYWNlfSA9IGh0dHBSZXNwb25zZUJvZHkudmFsdWU7XG4gICAgZXJyb3Iuc2hvdWxkLmVxdWFsKCdubyBzdWNoIGVsZW1lbnQnKTtcbiAgICBtZXNzYWdlLnNob3VsZC5tYXRjaCgvc3BlY2lmaWMgZXJyb3IgbWVzc2FnZS8pO1xuICAgIHN0YWNrdHJhY2Uuc2hvdWxkLmNvbnRhaW4oYmFzZW5hbWUpO1xuICB9KTtcbiAgaXQoJ3Nob3VsZCBoYW5kbGUgQmFkUGFyYW1ldGVyc0Vycm9yJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGJhZFBhcmFtc0Vycm9yID0gbmV3IGVycm9ycy5CYWRQYXJhbWV0ZXJzRXJyb3IoJ19fRk9PX18nLCAnX19CQVJfXycsICdfX0hFTExPX1dPUkxEX18nKTtcbiAgICBjb25zdCBbaHR0cFN0YXR1cywgaHR0cFJlc3BvbnNlQm9keV0gPSBnZXRSZXNwb25zZUZvclczQ0Vycm9yKGJhZFBhcmFtc0Vycm9yKTtcbiAgICBodHRwU3RhdHVzLnNob3VsZC5lcXVhbCg0MDApO1xuICAgIGNvbnN0IHtlcnJvciwgbWVzc2FnZSwgc3RhY2t0cmFjZX0gPSBodHRwUmVzcG9uc2VCb2R5LnZhbHVlO1xuICAgIGVycm9yLnNob3VsZC5lcXVhbCgnaW52YWxpZCBhcmd1bWVudCcpO1xuICAgIG1lc3NhZ2Uuc2hvdWxkLm1hdGNoKC9fX0JBUl9fLyk7XG4gICAgbWVzc2FnZS5zaG91bGQubWF0Y2goL19fSEVMTE9fV09STERfXy8pO1xuICAgIHN0YWNrdHJhY2Uuc2hvdWxkLmNvbnRhaW4oYmFzZW5hbWUpO1xuICB9KTtcbiAgaXQoJ3Nob3VsZCB0cmFuc2xhdGUgSlNPTldQIGVycm9ycycsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBbaHR0cFN0YXR1cywgaHR0cFJlc3BvbnNlQm9keV0gPSBnZXRSZXNwb25zZUZvclczQ0Vycm9yKHtcbiAgICAgIHN0YXR1czogNyxcbiAgICAgIHZhbHVlOiAnTXkgY3VzdG9tIG1lc3NhZ2UnLFxuICAgICAgc2Vzc2lvbklkOiAnRmFrZSBTZXNzaW9uIElkJyxcbiAgICB9KTtcbiAgICBodHRwU3RhdHVzLnNob3VsZC5lcXVhbCg0MDQpO1xuICAgIGNvbnN0IHtlcnJvciwgbWVzc2FnZSwgc3RhY2t0cmFjZX0gPSBodHRwUmVzcG9uc2VCb2R5LnZhbHVlO1xuICAgIG1lc3NhZ2Uuc2hvdWxkLmVxdWFsKCdNeSBjdXN0b20gbWVzc2FnZScpO1xuICAgIGVycm9yLnNob3VsZC5lcXVhbCgnbm8gc3VjaCBlbGVtZW50Jyk7XG4gICAgc3RhY2t0cmFjZS5zaG91bGQuZXhpc3Q7XG4gIH0pO1xufSk7XG5kZXNjcmliZSgnLmdldEFjdHVhbEVycm9yJywgZnVuY3Rpb24gKCkge1xuICBkZXNjcmliZSgnTUpTT05XUCcsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIG1hcCBhIHN0YXR1cyBjb2RlIDcgbm8gc3VjaCBlbGVtZW50IGVycm9yIGFzIGEgTm9TdWNoRWxlbWVudEVycm9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWN0dWFsRXJyb3IgPSBuZXcgZXJyb3JzLlByb3h5UmVxdWVzdEVycm9yKCdFcnJvciBtZXNzYWdlIGRvZXMgbm90IG1hdHRlcicsIHtcbiAgICAgICAgdmFsdWU6ICdkb2VzIG5vdCBtYXR0ZXInLFxuICAgICAgICBzdGF0dXM6IDcsXG4gICAgICB9KS5nZXRBY3R1YWxFcnJvcigpO1xuICAgICAgaXNFcnJvclR5cGUoYWN0dWFsRXJyb3IsIGVycm9ycy5Ob1N1Y2hFbGVtZW50RXJyb3IpLnNob3VsZC5iZS50cnVlO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgbWFwIGEgc3RhdHVzIGNvZGUgMTAsIFN0YWxlRWxlbWVudFJlZmVyZW5jZUVycm9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWN0dWFsRXJyb3IgPSBuZXcgZXJyb3JzLlByb3h5UmVxdWVzdEVycm9yKCdFcnJvciBtZXNzYWdlIGRvZXMgbm90IG1hdHRlcicsIHtcbiAgICAgICAgdmFsdWU6ICdEb2VzIG5vdCBtYXR0ZXInLFxuICAgICAgICBzdGF0dXM6IDEwLFxuICAgICAgfSkuZ2V0QWN0dWFsRXJyb3IoKTtcbiAgICAgIGlzRXJyb3JUeXBlKGFjdHVhbEVycm9yLCBlcnJvcnMuU3RhbGVFbGVtZW50UmVmZXJlbmNlRXJyb3IpLnNob3VsZC5iZS50cnVlO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgbWFwIGFuIHVua25vd24gZXJyb3IgdG8gVW5rbm93bkVycm9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWN0dWFsRXJyb3IgPSBuZXcgZXJyb3JzLlByb3h5UmVxdWVzdEVycm9yKCdFcnJvciBtZXNzYWdlIGRvZXMgbm90IG1hdHRlcicsIHtcbiAgICAgICAgdmFsdWU6ICdEb2VzIG5vdCBtYXR0ZXInLFxuICAgICAgICBzdGF0dXM6IC0xMDBcbiAgICAgIH0pLmdldEFjdHVhbEVycm9yKCk7XG4gICAgICBpc0Vycm9yVHlwZShhY3R1YWxFcnJvciwgZXJyb3JzLlVua25vd25FcnJvcikuc2hvdWxkLmJlLnRydWU7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBwYXJzZSBhIEpTT04gc3RyaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWN0dWFsRXJyb3IgPSBuZXcgZXJyb3JzLlByb3h5UmVxdWVzdEVycm9yKCdFcnJvciBtZXNzYWdlIGRvZXMgbm90IG1hdHRlcicsIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgdmFsdWU6ICdEb2VzIG5vdCBtYXR0ZXInLFxuICAgICAgICBzdGF0dXM6IC0xMDBcbiAgICAgIH0pKS5nZXRBY3R1YWxFcnJvcigpO1xuICAgICAgaXNFcnJvclR5cGUoYWN0dWFsRXJyb3IsIGVycm9ycy5Vbmtub3duRXJyb3IpLnNob3VsZC5iZS50cnVlO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnVzNDJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgbWFwIGEgNDA0IG5vIHN1Y2ggZWxlbWVudCBlcnJvciBhcyBhIE5vU3VjaEVsZW1lbnRFcnJvcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFjdHVhbEVycm9yID0gbmV3IGVycm9ycy5Qcm94eVJlcXVlc3RFcnJvcignRXJyb3IgbWVzc2FnZSBkb2VzIG5vdCBtYXR0ZXInLCB7XG4gICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgZXJyb3I6IGVycm9ycy5Ob1N1Y2hFbGVtZW50RXJyb3IuZXJyb3IoKSxcbiAgICAgICAgfSxcbiAgICAgIH0sIEhUVFBTdGF0dXNDb2Rlcy5OT1RfRk9VTkQpLmdldEFjdHVhbEVycm9yKCk7XG4gICAgICBpc0Vycm9yVHlwZShhY3R1YWxFcnJvciwgZXJyb3JzLk5vU3VjaEVsZW1lbnRFcnJvcikuc2hvdWxkLmJlLnRydWU7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBtYXAgYSA0MDAgU3RhbGVFbGVtZW50UmVmZXJlbmNlRXJyb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhY3R1YWxFcnJvciA9IG5ldyBlcnJvcnMuUHJveHlSZXF1ZXN0RXJyb3IoJ0Vycm9yIG1lc3NhZ2UgZG9lcyBub3QgbWF0dGVyJywge1xuICAgICAgICB2YWx1ZToge1xuICAgICAgICAgIGVycm9yOiBlcnJvcnMuU3RhbGVFbGVtZW50UmVmZXJlbmNlRXJyb3IuZXJyb3IoKSxcblxuICAgICAgICB9LFxuICAgICAgfSwgSFRUUFN0YXR1c0NvZGVzLkJBRF9SRVFVRVNUKS5nZXRBY3R1YWxFcnJvcigpO1xuICAgICAgaXNFcnJvclR5cGUoYWN0dWFsRXJyb3IsIGVycm9ycy5TdGFsZUVsZW1lbnRSZWZlcmVuY2VFcnJvcikuc2hvdWxkLmJlLnRydWU7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBtYXAgYW4gdW5rbm93biBlcnJvciB0byBVbmtub3duRXJyb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhY3R1YWxFcnJvciA9IG5ldyBlcnJvcnMuUHJveHlSZXF1ZXN0RXJyb3IoJ0Vycm9yIG1lc3NhZ2UgZG9lcyBub3QgbWF0dGVyJywgbnVsbCwge1xuICAgICAgICB2YWx1ZToge1xuICAgICAgICAgIGVycm9yOiAnTm90IGEgdmFsaWQgdzNjIEpTT04gY29kZSdcblxuICAgICAgICB9LFxuICAgICAgfSwgNDU2KS5nZXRBY3R1YWxFcnJvcigpO1xuICAgICAgaXNFcnJvclR5cGUoYWN0dWFsRXJyb3IsIGVycm9ycy5Vbmtub3duRXJyb3IpLnNob3VsZC5iZS50cnVlO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgcGFyc2UgYSBKU09OIHN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFjdHVhbEVycm9yID0gbmV3IGVycm9ycy5Qcm94eVJlcXVlc3RFcnJvcignRXJyb3IgbWVzc2FnZSBkb2VzIG5vdCBtYXR0ZXInLCBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgZXJyb3I6IGVycm9ycy5TdGFsZUVsZW1lbnRSZWZlcmVuY2VFcnJvci5lcnJvcigpLFxuXG4gICAgICAgIH0sXG4gICAgICB9KSwgSFRUUFN0YXR1c0NvZGVzLkJBRF9SRVFVRVNUKS5nZXRBY3R1YWxFcnJvcigpO1xuICAgICAgaXNFcnJvclR5cGUoYWN0dWFsRXJyb3IsIGVycm9ycy5TdGFsZUVsZW1lbnRSZWZlcmVuY2VFcnJvcikuc2hvdWxkLmJlLnRydWU7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
require("source-map-support/register");
|
|
6
|
+
|
|
7
|
+
var _lodash = require("lodash");
|
|
8
|
+
|
|
9
|
+
var _protocol = require("../../../lib/protocol");
|
|
10
|
+
|
|
11
|
+
var _crypto = _interopRequireDefault(require("crypto"));
|
|
12
|
+
|
|
13
|
+
describe('Protocol', function () {
|
|
14
|
+
describe('ensure protocol consistency', function () {
|
|
15
|
+
it('should not change protocol between patch versions', function () {
|
|
16
|
+
let shasum = _crypto.default.createHash('sha1');
|
|
17
|
+
|
|
18
|
+
for (let [url, urlMapping] of _lodash._.toPairs(_protocol.METHOD_MAP)) {
|
|
19
|
+
shasum.update(url);
|
|
20
|
+
|
|
21
|
+
for (let [method, methodMapping] of _lodash._.toPairs(urlMapping)) {
|
|
22
|
+
shasum.update(method);
|
|
23
|
+
|
|
24
|
+
if (methodMapping.command) {
|
|
25
|
+
shasum.update(methodMapping.command);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (methodMapping.payloadParams) {
|
|
29
|
+
let allParams = _lodash._.flatten(methodMapping.payloadParams.required);
|
|
30
|
+
|
|
31
|
+
if (methodMapping.payloadParams.optional) {
|
|
32
|
+
allParams = allParams.concat(_lodash._.flatten(methodMapping.payloadParams.optional));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
for (let param of allParams) {
|
|
36
|
+
shasum.update(param);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (methodMapping.payloadParams.wrap) {
|
|
40
|
+
shasum.update('skip');
|
|
41
|
+
shasum.update(methodMapping.payloadParams.wrap);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
let hash = shasum.digest('hex').substring(0, 8);
|
|
48
|
+
hash.should.equal('262ca3c4');
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
describe('check route to command name conversion', function () {
|
|
52
|
+
it('should properly lookup correct command name for endpoint with session', function () {
|
|
53
|
+
const cmdName = (0, _protocol.routeToCommandName)('/timeouts', 'POST');
|
|
54
|
+
cmdName.should.equal('timeouts');
|
|
55
|
+
});
|
|
56
|
+
it('should properly lookup correct command name for endpoint with session', function () {
|
|
57
|
+
const cmdName = (0, _protocol.routeToCommandName)('/timeouts/implicit_wait', 'POST');
|
|
58
|
+
cmdName.should.equal('implicitWait');
|
|
59
|
+
});
|
|
60
|
+
it('should properly lookup correct command name for endpoint without session', function () {
|
|
61
|
+
const cmdName = (0, _protocol.routeToCommandName)('/status', 'GET');
|
|
62
|
+
cmdName.should.equal('getStatus');
|
|
63
|
+
});
|
|
64
|
+
it('should properly lookup correct command name for endpoint without leading slash', function () {
|
|
65
|
+
const cmdName = (0, _protocol.routeToCommandName)('status', 'GET');
|
|
66
|
+
cmdName.should.equal('getStatus');
|
|
67
|
+
});
|
|
68
|
+
it('should properly lookup correct command name for fully specified endpoint', function () {
|
|
69
|
+
const cmdName = (0, _protocol.routeToCommandName)('/status', 'GET');
|
|
70
|
+
cmdName.should.equal('getStatus');
|
|
71
|
+
});
|
|
72
|
+
it('should not find command name if incorrect input data has been specified', function () {
|
|
73
|
+
for (let [route, method] of [['/status', 'POST'], ['/xstatus', 'GET'], ['status', 'POST']]) {
|
|
74
|
+
const cmdName = (0, _protocol.routeToCommandName)(route, method);
|
|
75
|
+
chai.should().equal(cmdName, undefined);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvdW5pdC9wcm90b2NvbC9yb3V0ZXMuc3BlYy5qcyJdLCJuYW1lcyI6WyJkZXNjcmliZSIsIml0Iiwic2hhc3VtIiwiY3J5cHRvIiwiY3JlYXRlSGFzaCIsInVybCIsInVybE1hcHBpbmciLCJfIiwidG9QYWlycyIsIk1FVEhPRF9NQVAiLCJ1cGRhdGUiLCJtZXRob2QiLCJtZXRob2RNYXBwaW5nIiwiY29tbWFuZCIsInBheWxvYWRQYXJhbXMiLCJhbGxQYXJhbXMiLCJmbGF0dGVuIiwicmVxdWlyZWQiLCJvcHRpb25hbCIsImNvbmNhdCIsInBhcmFtIiwid3JhcCIsImhhc2giLCJkaWdlc3QiLCJzdWJzdHJpbmciLCJzaG91bGQiLCJlcXVhbCIsImNtZE5hbWUiLCJyb3V0ZSIsImNoYWkiLCJ1bmRlZmluZWQiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUVBOztBQUNBOztBQUNBOztBQUlBQSxRQUFRLENBQUMsVUFBRCxFQUFhLFlBQVk7QUFLL0JBLEVBQUFBLFFBQVEsQ0FBQyw2QkFBRCxFQUFnQyxZQUFZO0FBQ2xEQyxJQUFBQSxFQUFFLENBQUMsbURBQUQsRUFBc0QsWUFBWTtBQUNsRSxVQUFJQyxNQUFNLEdBQUdDLGdCQUFPQyxVQUFQLENBQWtCLE1BQWxCLENBQWI7O0FBQ0EsV0FBSyxJQUFJLENBQUNDLEdBQUQsRUFBTUMsVUFBTixDQUFULElBQThCQyxVQUFFQyxPQUFGLENBQVVDLG9CQUFWLENBQTlCLEVBQXFEO0FBQ25EUCxRQUFBQSxNQUFNLENBQUNRLE1BQVAsQ0FBY0wsR0FBZDs7QUFDQSxhQUFLLElBQUksQ0FBQ00sTUFBRCxFQUFTQyxhQUFULENBQVQsSUFBb0NMLFVBQUVDLE9BQUYsQ0FBVUYsVUFBVixDQUFwQyxFQUEyRDtBQUN6REosVUFBQUEsTUFBTSxDQUFDUSxNQUFQLENBQWNDLE1BQWQ7O0FBQ0EsY0FBSUMsYUFBYSxDQUFDQyxPQUFsQixFQUEyQjtBQUN6QlgsWUFBQUEsTUFBTSxDQUFDUSxNQUFQLENB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QUFuQixFQUEwQmpCLE1BQTFCLENBQWhCO0FBQ0FrQixRQUFBQSxJQUFJLENBQUNKLE1BQUwsR0FBY0MsS0FBZCxDQUFvQkMsT0FBcEIsRUFBNkJHLFNBQTdCO0FBQ0Q7QUFDRixLQUxDLENBQUY7QUFNRCxHQWhDTyxDQUFSO0FBa0NELENBdEVPLENBQVIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyB0cmFuc3BpbGU6bW9jaGFcblxuaW1wb3J0IHsgXyB9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBNRVRIT0RfTUFQLCByb3V0ZVRvQ29tbWFuZE5hbWUgfSBmcm9tICcuLi8uLi8uLi9saWIvcHJvdG9jb2wnO1xuaW1wb3J0IGNyeXB0byBmcm9tICdjcnlwdG8nO1xuXG5cblxuZGVzY3JpYmUoJ1Byb3RvY29sJywgZnVuY3Rpb24gKCkge1xuXG4gIC8vIFRPRE8gdGVzdCBhZ2FpbnN0IGFuIGV4cGxpY2l0IHByb3RvY29sIHJhdGhlciB0aGFuIGEgaGFzaCBvZiBhIHByZXZpb3VzXG4gIC8vIHByb3RvY29sXG5cbiAgZGVzY3JpYmUoJ2Vuc3VyZSBwcm90b2NvbCBjb25zaXN0ZW5jeScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIG5vdCBjaGFuZ2UgcHJvdG9jb2wgYmV0d2VlbiBwYXRjaCB2ZXJzaW9ucycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCBzaGFzdW0gPSBjcnlwdG8uY3JlYXRlSGFzaCgnc2hhMScpO1xuICAgICAgZm9yIChsZXQgW3VybCwgdXJsTWFwcGluZ10gb2YgXy50b1BhaXJzKE1FVEhPRF9NQVApKSB7XG4gICAgICAgIHNoYXN1bS51cGRhdGUodXJsKTtcbiAgICAgICAgZm9yIChsZXQgW21ldGhvZCwgbWV0aG9kTWFwcGluZ10gb2YgXy50b1BhaXJzKHVybE1hcHBpbmcpKSB7XG4gICAgICAgICAgc2hhc3VtLnVwZGF0ZShtZXRob2QpO1xuICAgICAgICAgIGlmIChtZXRob2RNYXBwaW5nLmNvbW1hbmQpIHtcbiAgICAgICAgICAgIHNoYXN1bS51cGRhdGUobWV0aG9kTWFwcGluZy5jb21tYW5kKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKG1ldGhvZE1hcHBpbmcucGF5bG9hZFBhcmFtcykge1xuICAgICAgICAgICAgbGV0IGFsbFBhcmFtcyA9IF8uZmxhdHRlbihtZXRob2RNYXBwaW5nLnBheWxvYWRQYXJhbXMucmVxdWlyZWQpO1xuICAgICAgICAgICAgaWYgKG1ldGhvZE1hcHBpbmcucGF5bG9hZFBhcmFtcy5vcHRpb25hbCkge1xuICAgICAgICAgICAgICBhbGxQYXJhbXMgPSBhbGxQYXJhbXMuY29uY2F0KF8uZmxhdHRlbihtZXRob2RNYXBwaW5nLnBheWxvYWRQYXJhbXMub3B0aW9uYWwpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAobGV0IHBhcmFtIG9mIGFsbFBhcmFtcykge1xuICAgICAgICAgICAgICBzaGFzdW0udXBkYXRlKHBhcmFtKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXRob2RNYXBwaW5nLnBheWxvYWRQYXJhbXMud3JhcCkge1xuICAgICAgICAgICAgICBzaGFzdW0udXBkYXRlKCdza2lwJyk7XG4gICAgICAgICAgICAgIHNoYXN1bS51cGRhdGUobWV0aG9kTWFwcGluZy5wYXlsb2FkUGFyYW1zLndyYXApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGV0IGhhc2ggPSBzaGFzdW0uZGlnZXN0KCdoZXgnKS5zdWJzdHJpbmcoMCwgOCk7XG4gICAgICAvLyBNb2RpZnkgdGhlIGhhc2ggd2hlbmV2ZXIgdGhlIHByb3RvY29sIGhhcyBpbnRlbnRpb25hbGx5IGJlZW4gbW9kaWZpZWQuXG4gICAgICBoYXNoLnNob3VsZC5lcXVhbCgnMjYyY2EzYzQnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2NoZWNrIHJvdXRlIHRvIGNvbW1hbmQgbmFtZSBjb252ZXJzaW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgcHJvcGVybHkgbG9va3VwIGNvcnJlY3QgY29tbWFuZCBuYW1lIGZvciBlbmRwb2ludCB3aXRoIHNlc3Npb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjbWROYW1lID0gcm91dGVUb0NvbW1hbmROYW1lKCcvdGltZW91dHMnLCAnUE9TVCcpO1xuICAgICAgY21kTmFtZS5zaG91bGQuZXF1YWwoJ3RpbWVvdXRzJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHByb3Blcmx5IGxvb2t1cCBjb3JyZWN0IGNvbW1hbmQgbmFtZSBmb3IgZW5kcG9pbnQgd2l0aCBzZXNzaW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY21kTmFtZSA9IHJvdXRlVG9Db21tYW5kTmFtZSgnL3RpbWVvdXRzL2ltcGxpY2l0X3dhaXQnLCAnUE9TVCcpO1xuICAgICAgY21kTmFtZS5zaG91bGQuZXF1YWwoJ2ltcGxpY2l0V2FpdCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwcm9wZXJseSBsb29rdXAgY29ycmVjdCBjb21tYW5kIG5hbWUgZm9yIGVuZHBvaW50IHdpdGhvdXQgc2Vzc2lvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNtZE5hbWUgPSByb3V0ZVRvQ29tbWFuZE5hbWUoJy9zdGF0dXMnLCAnR0VUJyk7XG4gICAgICBjbWROYW1lLnNob3VsZC5lcXVhbCgnZ2V0U3RhdHVzJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHByb3Blcmx5IGxvb2t1cCBjb3JyZWN0IGNvbW1hbmQgbmFtZSBmb3IgZW5kcG9pbnQgd2l0aG91dCBsZWFkaW5nIHNsYXNoJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY21kTmFtZSA9IHJvdXRlVG9Db21tYW5kTmFtZSgnc3RhdHVzJywgJ0dFVCcpO1xuICAgICAgY21kTmFtZS5zaG91bGQuZXF1YWwoJ2dldFN0YXR1cycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwcm9wZXJseSBsb29rdXAgY29ycmVjdCBjb21tYW5kIG5hbWUgZm9yIGZ1bGx5IHNwZWNpZmllZCBlbmRwb2ludCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNtZE5hbWUgPSByb3V0ZVRvQ29tbWFuZE5hbWUoJy9zdGF0dXMnLCAnR0VUJyk7XG4gICAgICBjbWROYW1lLnNob3VsZC5lcXVhbCgnZ2V0U3RhdHVzJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG5vdCBmaW5kIGNvbW1hbmQgbmFtZSBpZiBpbmNvcnJlY3QgaW5wdXQgZGF0YSBoYXMgYmVlbiBzcGVjaWZpZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBmb3IgKGxldCBbcm91dGUsIG1ldGhvZF0gb2YgW1snL3N0YXR1cycsICdQT1NUJ10sIFsnL3hzdGF0dXMnLCAnR0VUJ10sIFsnc3RhdHVzJywgJ1BPU1QnXV0pIHtcbiAgICAgICAgY29uc3QgY21kTmFtZSA9IHJvdXRlVG9Db21tYW5kTmFtZShyb3V0ZSwgbWV0aG9kKTtcbiAgICAgICAgY2hhaS5zaG91bGQoKS5lcXVhbChjbWROYW1lLCB1bmRlZmluZWQpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxufSk7XG4iXX0=
|