@appium/base-driver 8.3.0 → 8.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. package/build/lib/basedriver/capabilities.d.ts +80 -0
  2. package/build/lib/basedriver/capabilities.d.ts.map +1 -0
  3. package/build/lib/basedriver/capabilities.js +12 -13
  4. package/build/lib/basedriver/commands/event.d.ts +9 -0
  5. package/build/lib/basedriver/commands/event.d.ts.map +1 -0
  6. package/build/lib/basedriver/commands/event.js +21 -23
  7. package/build/lib/basedriver/commands/find.d.ts +11 -0
  8. package/build/lib/basedriver/commands/find.d.ts.map +1 -0
  9. package/build/lib/basedriver/commands/find.js +42 -37
  10. package/build/lib/basedriver/commands/index.d.ts +8 -0
  11. package/build/lib/basedriver/commands/index.d.ts.map +1 -0
  12. package/build/lib/basedriver/commands/index.js +17 -16
  13. package/build/lib/basedriver/commands/log.d.ts +12 -0
  14. package/build/lib/basedriver/commands/log.d.ts.map +1 -0
  15. package/build/lib/basedriver/commands/log.js +23 -27
  16. package/build/lib/basedriver/commands/session.d.ts +11 -0
  17. package/build/lib/basedriver/commands/session.d.ts.map +1 -0
  18. package/build/lib/basedriver/commands/session.js +21 -149
  19. package/build/lib/basedriver/commands/settings.d.ts +10 -0
  20. package/build/lib/basedriver/commands/settings.d.ts.map +1 -0
  21. package/build/lib/basedriver/commands/settings.js +19 -19
  22. package/build/lib/basedriver/commands/timeout.d.ts +8 -0
  23. package/build/lib/basedriver/commands/timeout.d.ts.map +1 -0
  24. package/build/lib/basedriver/commands/timeout.js +118 -139
  25. package/build/lib/basedriver/core.d.ts +235 -0
  26. package/build/lib/basedriver/core.d.ts.map +1 -0
  27. package/build/lib/basedriver/core.js +283 -0
  28. package/build/lib/basedriver/desired-caps.d.ts +5 -0
  29. package/build/lib/basedriver/desired-caps.d.ts.map +1 -0
  30. package/build/lib/basedriver/desired-caps.js +2 -4
  31. package/build/lib/basedriver/device-settings.d.ts +32 -0
  32. package/build/lib/basedriver/device-settings.d.ts.map +1 -0
  33. package/build/lib/basedriver/device-settings.js +20 -14
  34. package/build/lib/basedriver/driver.d.ts +83 -0
  35. package/build/lib/basedriver/driver.d.ts.map +1 -0
  36. package/build/lib/basedriver/driver.js +101 -256
  37. package/build/lib/basedriver/helpers.d.ts +132 -0
  38. package/build/lib/basedriver/helpers.d.ts.map +1 -0
  39. package/build/lib/basedriver/helpers.js +16 -2
  40. package/build/lib/basedriver/logger.d.ts +3 -0
  41. package/build/lib/basedriver/logger.d.ts.map +1 -0
  42. package/build/lib/basedriver/logger.js +2 -4
  43. package/build/lib/constants.d.ts +9 -0
  44. package/build/lib/constants.d.ts.map +1 -0
  45. package/build/lib/constants.js +2 -4
  46. package/build/lib/express/crash.d.ts +3 -0
  47. package/build/lib/express/crash.d.ts.map +1 -0
  48. package/build/lib/express/crash.js +2 -4
  49. package/build/lib/express/express-logging.d.ts +3 -0
  50. package/build/lib/express/express-logging.d.ts.map +1 -0
  51. package/build/lib/express/express-logging.js +2 -4
  52. package/build/lib/express/idempotency.d.ts +2 -0
  53. package/build/lib/express/idempotency.d.ts.map +1 -0
  54. package/build/lib/express/idempotency.js +2 -4
  55. package/build/lib/express/logger.d.ts +3 -0
  56. package/build/lib/express/logger.d.ts.map +1 -0
  57. package/build/lib/express/logger.js +2 -4
  58. package/build/lib/express/middleware.d.ts +9 -0
  59. package/build/lib/express/middleware.d.ts.map +1 -0
  60. package/build/lib/express/middleware.js +2 -4
  61. package/build/lib/express/server.d.ts +10 -0
  62. package/build/lib/express/server.d.ts.map +1 -0
  63. package/build/lib/express/server.js +2 -4
  64. package/build/lib/express/static.d.ts +6 -0
  65. package/build/lib/express/static.d.ts.map +1 -0
  66. package/build/lib/express/static.js +2 -4
  67. package/build/lib/express/websocket.d.ts +64 -0
  68. package/build/lib/express/websocket.d.ts.map +1 -0
  69. package/build/lib/express/websocket.js +40 -41
  70. package/build/lib/helpers/capabilities.d.ts +13 -0
  71. package/build/lib/helpers/capabilities.d.ts.map +1 -0
  72. package/build/lib/helpers/capabilities.js +40 -2
  73. package/build/lib/index.d.ts +183 -0
  74. package/build/lib/index.d.ts.map +1 -0
  75. package/build/lib/index.js +41 -23
  76. package/build/lib/jsonwp-proxy/protocol-converter.d.ts +48 -0
  77. package/build/lib/jsonwp-proxy/protocol-converter.d.ts.map +1 -0
  78. package/build/lib/jsonwp-proxy/protocol-converter.js +2 -4
  79. package/build/lib/jsonwp-proxy/proxy.d.ts +41 -0
  80. package/build/lib/jsonwp-proxy/proxy.d.ts.map +1 -0
  81. package/build/lib/jsonwp-proxy/proxy.js +25 -9
  82. package/build/lib/jsonwp-status/status.d.ts +159 -0
  83. package/build/lib/jsonwp-status/status.d.ts.map +1 -0
  84. package/build/lib/jsonwp-status/status.js +2 -4
  85. package/build/lib/protocol/errors.d.ts +310 -0
  86. package/build/lib/protocol/errors.d.ts.map +1 -0
  87. package/build/lib/protocol/errors.js +82 -5
  88. package/build/lib/protocol/helpers.d.ts +22 -0
  89. package/build/lib/protocol/helpers.d.ts.map +1 -0
  90. package/build/lib/protocol/helpers.js +2 -4
  91. package/build/lib/protocol/index.d.ts +16 -0
  92. package/build/lib/protocol/index.d.ts.map +1 -0
  93. package/build/lib/protocol/index.js +8 -10
  94. package/build/lib/protocol/protocol.d.ts +11 -0
  95. package/build/lib/protocol/protocol.d.ts.map +1 -0
  96. package/build/lib/protocol/protocol.js +3 -9
  97. package/build/lib/protocol/routes.d.ts +6 -0
  98. package/build/lib/protocol/routes.d.ts.map +1 -0
  99. package/build/lib/protocol/routes.js +18 -4
  100. package/build/lib/protocol/validators.d.ts +8 -0
  101. package/build/lib/protocol/validators.d.ts.map +1 -0
  102. package/build/lib/protocol/validators.js +2 -4
  103. package/build/test/basedriver/README.md +5 -0
  104. package/build/test/basedriver/driver-e2e-tests.js +2 -4
  105. package/build/test/basedriver/driver-tests.js +31 -6
  106. package/build/test/basedriver/index.js +2 -4
  107. package/build/test/e2e/basedriver/driver.e2e.spec.js +15 -0
  108. package/build/test/e2e/basedriver/helpers.e2e.spec.js +192 -0
  109. package/build/test/e2e/basedriver/websockets.e2e.spec.js +87 -0
  110. package/build/test/e2e/express/server.e2e.spec.js +159 -0
  111. package/build/test/e2e/jsonwp-proxy/proxy.e2e.spec.js +59 -0
  112. package/build/test/e2e/protocol/fake-driver.js +163 -0
  113. package/build/test/e2e/protocol/helpers.js +25 -0
  114. package/build/test/e2e/protocol/protocol.e2e.spec.js +1186 -0
  115. package/build/test/helpers.js +2 -4
  116. package/build/test/unit/basedriver/capabilities.spec.js +672 -0
  117. package/build/test/unit/basedriver/capability.spec.js +353 -0
  118. package/build/test/unit/basedriver/commands/event.spec.js +110 -0
  119. package/build/test/unit/basedriver/commands/log.spec.js +92 -0
  120. package/build/test/unit/basedriver/driver.spec.js +15 -0
  121. package/build/test/unit/basedriver/helpers.spec.js +151 -0
  122. package/build/test/unit/basedriver/timeout.spec.js +135 -0
  123. package/build/test/unit/express/server.spec.js +155 -0
  124. package/build/test/unit/express/static.spec.js +26 -0
  125. package/build/test/unit/jsonwp-proxy/mock-request.js +91 -0
  126. package/build/test/unit/jsonwp-proxy/protocol-converter.spec.js +171 -0
  127. package/build/test/unit/jsonwp-proxy/proxy.spec.js +292 -0
  128. package/build/test/unit/jsonwp-proxy/url.spec.js +165 -0
  129. package/build/test/unit/jsonwp-status/status.spec.js +34 -0
  130. package/build/test/unit/protocol/errors.spec.js +390 -0
  131. package/build/test/unit/protocol/routes.spec.js +80 -0
  132. package/build/test/unit/protocol/validator.spec.js +149 -0
  133. package/build/tsconfig.tsbuildinfo +1 -0
  134. package/lib/basedriver/capabilities.js +49 -10
  135. package/lib/basedriver/commands/event.js +49 -31
  136. package/lib/basedriver/commands/find.js +108 -43
  137. package/lib/basedriver/commands/index.js +25 -19
  138. package/lib/basedriver/commands/log.js +60 -33
  139. package/lib/basedriver/commands/session.js +39 -141
  140. package/lib/basedriver/commands/settings.js +33 -13
  141. package/lib/basedriver/commands/timeout.js +153 -153
  142. package/lib/basedriver/core.js +497 -0
  143. package/lib/basedriver/desired-caps.js +1 -1
  144. package/lib/basedriver/device-settings.js +47 -12
  145. package/lib/basedriver/driver.js +272 -383
  146. package/lib/basedriver/helpers.js +18 -2
  147. package/lib/express/websocket.js +35 -32
  148. package/lib/helpers/capabilities.js +60 -1
  149. package/lib/index.js +16 -12
  150. package/lib/jsonwp-proxy/proxy.js +26 -6
  151. package/lib/protocol/errors.js +42 -42
  152. package/lib/protocol/index.js +4 -4
  153. package/lib/protocol/protocol.js +1 -3
  154. package/lib/protocol/routes.js +9 -0
  155. package/package.json +22 -14
  156. package/test/basedriver/README.md +5 -0
  157. package/test/basedriver/driver-e2e-tests.js +1 -1
  158. package/test/basedriver/driver-tests.js +31 -2
  159. package/build/test/basedriver/capabilities-specs.js +0 -674
  160. package/build/test/basedriver/capability-specs.js +0 -355
  161. package/build/test/basedriver/commands/event-specs.js +0 -112
  162. package/build/test/basedriver/commands/log-specs.js +0 -87
  163. package/build/test/basedriver/driver-e2e-specs.js +0 -17
  164. package/build/test/basedriver/driver-specs.js +0 -17
  165. package/build/test/basedriver/helpers-e2e-specs.js +0 -194
  166. package/build/test/basedriver/helpers-specs.js +0 -153
  167. package/build/test/basedriver/timeout-specs.js +0 -137
  168. package/build/test/basedriver/websockets-e2e-specs.js +0 -84
  169. package/build/test/express/server-e2e-specs.js +0 -161
  170. package/build/test/express/server-specs.js +0 -157
  171. package/build/test/express/static-specs.js +0 -28
  172. package/build/test/jsonwp-proxy/mock-request.js +0 -93
  173. package/build/test/jsonwp-proxy/protocol-converter-specs.js +0 -173
  174. package/build/test/jsonwp-proxy/proxy-e2e-specs.js +0 -61
  175. package/build/test/jsonwp-proxy/proxy-specs.js +0 -294
  176. package/build/test/jsonwp-proxy/url-specs.js +0 -167
  177. package/build/test/jsonwp-status/status-specs.js +0 -36
  178. package/build/test/protocol/errors-specs.js +0 -388
  179. package/build/test/protocol/fake-driver.js +0 -165
  180. package/build/test/protocol/helpers.js +0 -27
  181. package/build/test/protocol/protocol-e2e-specs.js +0 -1188
  182. package/build/test/protocol/routes-specs.js +0 -82
  183. package/build/test/protocol/validator-specs.js +0 -151
  184. package/index.d.ts +0 -386
  185. package/test/basedriver/capabilities-specs.js +0 -537
  186. package/test/basedriver/capability-specs.js +0 -383
  187. package/test/basedriver/commands/event-specs.js +0 -74
  188. package/test/basedriver/commands/log-specs.js +0 -79
  189. package/test/basedriver/driver-e2e-specs.js +0 -8
  190. package/test/basedriver/driver-specs.js +0 -8
  191. package/test/basedriver/fixtures/BadZippedApp.zip +0 -1
  192. package/test/basedriver/fixtures/FakeAndroidApp.apk +0 -1
  193. package/test/basedriver/fixtures/FakeAndroidApp.asd +0 -0
  194. package/test/basedriver/fixtures/FakeIOSApp.app +0 -1
  195. package/test/basedriver/fixtures/FakeIOSApp.app.zip +0 -0
  196. package/test/basedriver/fixtures/FakeIOSApp.ipa +0 -0
  197. package/test/basedriver/fixtures/custom-element-finder-bad.js +0 -5
  198. package/test/basedriver/fixtures/custom-element-finder.js +0 -29
  199. package/test/basedriver/helpers-e2e-specs.js +0 -187
  200. package/test/basedriver/helpers-specs.js +0 -137
  201. package/test/basedriver/timeout-specs.js +0 -128
  202. package/test/basedriver/websockets-e2e-specs.js +0 -75
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ require("source-map-support/register");
6
+
7
+ var _lodash = _interopRequireDefault(require("lodash"));
8
+
9
+ var _constants = require("../../../lib/constants");
10
+
11
+ var _protocolConverter = _interopRequireWildcard(require("../../../lib/jsonwp-proxy/protocol-converter"));
12
+
13
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
14
+
15
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
16
+
17
+ const {
18
+ MJSONWP,
19
+ W3C
20
+ } = _constants.PROTOCOLS;
21
+ describe('Protocol Converter', function () {
22
+ describe('getTimeoutRequestObjects', function () {
23
+ let converter;
24
+ before(function () {
25
+ converter = new _protocolConverter.default(_lodash.default.noop);
26
+ });
27
+ it('should take W3C inputs and produce MJSONWP compatible objects', function () {
28
+ converter.downstreamProtocol = MJSONWP;
29
+ let timeoutObjects = converter.getTimeoutRequestObjects({
30
+ script: 100
31
+ });
32
+ timeoutObjects.length.should.equal(1);
33
+ timeoutObjects[0].should.eql({
34
+ type: 'script',
35
+ ms: 100
36
+ });
37
+ });
38
+ it('should ignore invalid entries while converting from W3C', function () {
39
+ converter.downstreamProtocol = MJSONWP;
40
+ let timeoutObjects = converter.getTimeoutRequestObjects({
41
+ script: 100,
42
+ sessionId: '5432a4f3-cd89-4781-8905-ea9d3150840c',
43
+ bar: -1,
44
+ baz: undefined
45
+ });
46
+ timeoutObjects.length.should.equal(1);
47
+ timeoutObjects[0].should.eql({
48
+ type: 'script',
49
+ ms: 100
50
+ });
51
+ });
52
+ it('should take multiple W3C timeouts and produce multiple MJSONWP compatible objects', function () {
53
+ converter.downstreamProtocol = MJSONWP;
54
+ let [scriptTimeout, pageLoadTimeout, implicitTimeout] = converter.getTimeoutRequestObjects({
55
+ script: 100,
56
+ pageLoad: 200,
57
+ implicit: 300
58
+ });
59
+ scriptTimeout.should.eql({
60
+ type: 'script',
61
+ ms: 100
62
+ });
63
+ pageLoadTimeout.should.eql({
64
+ type: 'page load',
65
+ ms: 200
66
+ });
67
+ implicitTimeout.should.eql({
68
+ type: 'implicit',
69
+ ms: 300
70
+ });
71
+ });
72
+ it('should take MJSONWP input and produce W3C compatible object', function () {
73
+ converter.downstreamProtocol = W3C;
74
+ let timeoutObjects = converter.getTimeoutRequestObjects({
75
+ type: 'implicit',
76
+ ms: 300
77
+ });
78
+ timeoutObjects.length.should.equal(1);
79
+ timeoutObjects[0].should.eql({
80
+ implicit: 300
81
+ });
82
+ });
83
+ it('should not change the input if protocol name is unknown', function () {
84
+ converter.downstreamProtocol = null;
85
+ let timeoutObjects = converter.getTimeoutRequestObjects({
86
+ type: 'implicit',
87
+ ms: 300
88
+ });
89
+ timeoutObjects.length.should.equal(1);
90
+ timeoutObjects[0].should.eql({
91
+ type: 'implicit',
92
+ ms: 300
93
+ });
94
+ });
95
+ it('should not change the input if protocol name is unchanged', function () {
96
+ converter.downstreamProtocol = MJSONWP;
97
+ let timeoutObjects = converter.getTimeoutRequestObjects({
98
+ type: 'implicit',
99
+ ms: 300
100
+ });
101
+ timeoutObjects.length.should.equal(1);
102
+ timeoutObjects[0].should.eql({
103
+ type: 'implicit',
104
+ ms: 300
105
+ });
106
+ });
107
+ });
108
+ describe('setValue', function () {
109
+ let converter;
110
+ let responseBody;
111
+ before(function () {
112
+ responseBody = null;
113
+ converter = new _protocolConverter.default((url, method, body) => {
114
+ responseBody = body;
115
+ });
116
+ });
117
+ beforeEach(function () {
118
+ responseBody = {};
119
+ });
120
+ it('should calculate value if not present', async function () {
121
+ await converter.proxySetValue('', '', {
122
+ text: 'bla'
123
+ });
124
+ responseBody.should.eql({
125
+ text: 'bla',
126
+ value: ['b', 'l', 'a']
127
+ });
128
+ });
129
+ it('should calculate text if not present', async function () {
130
+ await converter.proxySetValue('', '', {
131
+ value: ['b', 'l', 'a']
132
+ });
133
+ responseBody.should.eql({
134
+ text: 'bla',
135
+ value: ['b', 'l', 'a']
136
+ });
137
+ });
138
+ it('should keep the response body unchanged if both value and text are present', async function () {
139
+ await converter.proxySetValue('', '', {
140
+ text: 'bla',
141
+ value: ['b', 'l', 'a']
142
+ });
143
+ responseBody.should.eql({
144
+ text: 'bla',
145
+ value: ['b', 'l', 'a']
146
+ });
147
+ });
148
+ });
149
+ describe('getProperty', function () {
150
+ let jsonwpConverter, w3cConverter;
151
+ before(function () {
152
+ for (let command of _protocolConverter.COMMAND_URLS_CONFLICTS) {
153
+ if (command.commandNames.includes('getProperty')) {
154
+ jsonwpConverter = command.jsonwpConverter;
155
+ w3cConverter = command.w3cConverter;
156
+ }
157
+ }
158
+ });
159
+ it('should convert "property/value" to "attribute/value"', function () {
160
+ jsonwpConverter('/session/123/element/456/property/value').should.equal('/session/123/element/456/attribute/value');
161
+ });
162
+ it('should convert "property/:somePropName" to "attribute/:somePropName"', function () {
163
+ jsonwpConverter('/session/123/element/456/property/somePropName').should.equal('/session/123/element/456/attribute/somePropName');
164
+ });
165
+ it('should not convert from JSONWP to W3C', function () {
166
+ w3cConverter('/session/123/element/456/attribute/someAttr').should.equal('/session/123/element/456/attribute/someAttr');
167
+ w3cConverter('/session/123/element/456/property/someProp').should.equal('/session/123/element/456/property/someProp');
168
+ });
169
+ });
170
+ });
171
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvdW5pdC9qc29ud3AtcHJveHkvcHJvdG9jb2wtY29udmVydGVyLnNwZWMuanMiXSwibmFtZXMiOlsiTUpTT05XUCIsIlczQyIsIlBST1RPQ09MUyIsImRlc2NyaWJlIiwiY29udmVydGVyIiwiYmVmb3JlIiwiUHJvdG9jb2xDb252ZXJ0ZXIiLCJfIiwibm9vcCIsIml0IiwiZG93bnN0cmVhbVByb3RvY29sIiwidGltZW91dE9iamVjdHMiLCJnZXRUaW1lb3V0UmVxdWVzdE9iamVjdHMiLCJzY3JpcHQiLCJsZW5ndGgiLCJzaG91bGQiLCJlcXVhbCIsImVxbCIsInR5cGUiLCJtcyIsInNlc3Npb25JZCIsImJhciIsImJheiIsInVuZGVmaW5lZCIsInNjcmlwdFRpbWVvdXQiLCJwYWdlTG9hZFRpbWVvdXQiLCJpbXBsaWNpdFRpbWVvdXQiLCJwYWdlTG9hZCIsImltcGxpY2l0IiwicmVzcG9uc2VCb2R5IiwidXJsIiwibWV0aG9kIiwiYm9keSIsImJlZm9yZUVhY2giLCJwcm94eVNldFZhbHVlIiwidGV4dCIsInZhbHVlIiwianNvbndwQ29udmVydGVyIiwidzNjQ29udmVydGVyIiwiY29tbWFuZCIsIkNPTU1BTkRfVVJMU19DT05GTElDVFMiLCJjb21tYW5kTmFtZXMiLCJpbmNsdWRlcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7Ozs7OztBQUVBLE1BQU07QUFBQ0EsRUFBQUEsT0FBRDtBQUFVQyxFQUFBQTtBQUFWLElBQWlCQyxvQkFBdkI7QUFHQUMsUUFBUSxDQUFDLG9CQUFELEVBQXVCLFlBQVk7QUFDekNBLEVBQUFBLFFBQVEsQ0FBQywwQkFBRCxFQUE2QixZQUFZO0FBQy9DLFFBQUlDLFNBQUo7QUFDQUMsSUFBQUEsTUFBTSxDQUFDLFlBQVk7QUFDakJELE1BQUFBLFNBQVMsR0FBRyxJQUFJRSwwQkFBSixDQUFzQkMsZ0JBQUVDLElBQXhCLENBQVo7QUFDRCxLQUZLLENBQU47QUFHQUMsSUFBQUEs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eUVDLEtBQXpFLENBQStFLGlEQUEvRTtBQUNELEtBRkMsQ0FBRjtBQUdBUCxJQUFBQSxFQUFFLENBQUMsdUNBQUQsRUFBMEMsWUFBWTtBQUN0RDZCLE1BQUFBLFlBQVksQ0FBQyw2Q0FBRCxDQUFaLENBQTREdkIsTUFBNUQsQ0FBbUVDLEtBQW5FLENBQXlFLDZDQUF6RTtBQUNBc0IsTUFBQUEsWUFBWSxDQUFDLDRDQUFELENBQVosQ0FBMkR2QixNQUEzRCxDQUFrRUMsS0FBbEUsQ0FBd0UsNENBQXhFO0FBQ0QsS0FIQyxDQUFGO0FBSUQsR0FwQk8sQ0FBUjtBQXFCRCxDQTFITyxDQUFSIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IFBST1RPQ09MUyB9IGZyb20gJy4uLy4uLy4uL2xpYi9jb25zdGFudHMnO1xuaW1wb3J0IFByb3RvY29sQ29udmVydGVyLCB7Q09NTUFORF9VUkxTX0NPTkZMSUNUU30gZnJvbSAnLi4vLi4vLi4vbGliL2pzb253cC1wcm94eS9wcm90b2NvbC1jb252ZXJ0ZXInO1xuXG5jb25zdCB7TUpTT05XUCwgVzNDfSA9IFBST1RPQ09MUztcblxuXG5kZXNjcmliZSgnUHJvdG9jb2wgQ29udmVydGVyJywgZnVuY3Rpb24gKCkge1xuICBkZXNjcmliZSgnZ2V0VGltZW91dFJlcXVlc3RPYmplY3RzJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBjb252ZXJ0ZXI7XG4gICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnZlcnRlciA9IG5ldyBQcm90b2NvbENvbnZlcnRlcihfLm5vb3ApO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgdGFrZSBXM0MgaW5wdXRzIGFuZCBwcm9kdWNlIE1KU09OV1AgY29tcGF0aWJsZSBvYmplY3RzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29udmVydGVyLmRvd25zdHJlYW1Qcm90b2NvbCA9IE1KU09OV1A7XG4gICAgICBsZXQgdGltZW91dE9iamVjdHMgPSBjb252ZXJ0ZXIuZ2V0VGltZW91dFJlcXVlc3RPYmplY3RzKHtzY3JpcHQ6IDEwMH0pO1xuICAgICAgdGltZW91dE9iamVjdHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIHRpbWVvdXRPYmplY3RzWzBdLnNob3VsZC5lcWwoe3R5cGU6ICdzY3JpcHQnLCBtczogMTAwfSk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBpZ25vcmUgaW52YWxpZCBlbnRyaWVzIHdoaWxlIGNvbnZlcnRpbmcgZnJvbSBXM0MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb252ZXJ0ZXIuZG93bnN0cmVhbVByb3RvY29sID0gTUpTT05XUDtcbiAgICAgIGxldCB0aW1lb3V0T2JqZWN0cyA9IGNvbnZlcnRlci5nZXRUaW1lb3V0UmVxdWVzdE9iamVjdHMoe1xuICAgICAgICBzY3JpcHQ6IDEwMCxcbiAgICAgICAgc2Vzc2lvbklkOiAnNTQzMmE0ZjMtY2Q4OS00NzgxLTg5MDUtZWE5ZDMxNTA4NDBjJyxcbiAgICAgICAgYmFyOiAtMSxcbiAgICAgICAgYmF6OiB1bmRlZmluZWQsXG4gICAgICB9KTtcbiAgICAgIHRpbWVvdXRPYmplY3RzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICB0aW1lb3V0T2JqZWN0c1swXS5zaG91bGQuZXFsKHt0eXBlOiAnc2NyaXB0JywgbXM6IDEwMH0pO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgdGFrZSBtdWx0aXBsZSBXM0MgdGltZW91dHMgYW5kIHByb2R1Y2UgbXVsdGlwbGUgTUpTT05XUCBjb21wYXRpYmxlIG9iamVjdHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb252ZXJ0ZXIuZG93bnN0cmVhbVByb3RvY29sID0gTUpTT05XUDtcbiAgICAgIGxldCBbc2NyaXB0VGltZW91dCwgcGFnZUxvYWRUaW1lb3V0LCBpbXBsaWNpdFRpbWVvdXRdID0gY29udmVydGVyLmdldFRpbWVvdXRSZXF1ZXN0T2JqZWN0cyh7c2NyaXB0OiAxMDAsIHBhZ2VMb2FkOiAyMDAsIGltcGxpY2l0OiAzMDB9KTtcbiAgICAgIHNjcmlwdFRpbWVvdXQuc2hvdWxkLmVxbCh7XG4gICAgICAgIHR5cGU6ICdzY3JpcHQnLFxuICAgICAgICBtczogMTAwLFxuICAgICAgfSk7XG4gICAgICBwYWdlTG9hZFRpbWVvdXQuc2hvdWxkLmVxbCh7XG4gICAgICAgIHR5cGU6ICdwYWdlIGxvYWQnLFxuICAgICAgICBtczogMjAwLFxuICAgICAgfSk7XG4gICAgICBpbXBsaWNpdFRpbWVvdXQuc2hvdWxkLmVxbCh7XG4gICAgICAgIHR5cGU6ICdpbXBsaWNpdCcsXG4gICAgICAgIG1zOiAzMDAsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIHRha2UgTUpTT05XUCBpbnB1dCBhbmQgcHJvZHVjZSBXM0MgY29tcGF0aWJsZSBvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb252ZXJ0ZXIuZG93bnN0cmVhbVByb3RvY29sID0gVzNDO1xuICAgICAgbGV0IHRpbWVvdXRPYmplY3RzID0gY29udmVydGVyLmdldFRpbWVvdXRSZXF1ZXN0T2JqZWN0cyh7dHlwZTogJ2ltcGxpY2l0JywgbXM6IDMwMH0pO1xuICAgICAgdGltZW91dE9iamVjdHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIHRpbWVvdXRPYmplY3RzWzBdLnNob3VsZC5lcWwoe2ltcGxpY2l0OiAzMDB9KTtcbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIG5vdCBjaGFuZ2UgdGhlIGlucHV0IGlmIHByb3RvY29sIG5hbWUgaXMgdW5rbm93bicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnZlcnRlci5kb3duc3RyZWFtUHJvdG9jb2wgPSBudWxsO1xuICAgICAgbGV0IHRpbWVvdXRPYmplY3RzID0gY29udmVydGVyLmdldFRpbWVvdXRSZXF1ZXN0T2JqZWN0cyh7dHlwZTogJ2ltcGxpY2l0JywgbXM6IDMwMH0pO1xuICAgICAgdGltZW91dE9iamVjdHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIHRpbWVvdXRPYmplY3RzWzBdLnNob3VsZC5lcWwoe3R5cGU6ICdpbXBsaWNpdCcsIG1zOiAzMDB9KTtcbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIG5vdCBjaGFuZ2UgdGhlIGlucHV0IGlmIHByb3RvY29sIG5hbWUgaXMgdW5jaGFuZ2VkJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29udmVydGVyLmRvd25zdHJlYW1Qcm90b2NvbCA9IE1KU09OV1A7XG4gICAgICBsZXQgdGltZW91dE9iamVjdHMgPSBjb252ZXJ0ZXIuZ2V0VGltZW91dFJlcXVlc3RPYmplY3RzKHt0eXBlOiAnaW1wbGljaXQnLCBtczogMzAwfSk7XG4gICAgICB0aW1lb3V0T2JqZWN0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgdGltZW91dE9iamVjdHNbMF0uc2hvdWxkLmVxbCh7dHlwZTogJ2ltcGxpY2l0JywgbXM6IDMwMH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnc2V0VmFsdWUnLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IGNvbnZlcnRlcjtcbiAgICBsZXQgcmVzcG9uc2VCb2R5O1xuICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICByZXNwb25zZUJvZHkgPSBudWxsO1xuICAgICAgY29udmVydGVyID0gbmV3IFByb3RvY29sQ29udmVydGVyKCh1cmwsIG1ldGhvZCwgYm9keSkgPT4ge1xuICAgICAgICByZXNwb25zZUJvZHkgPSBib2R5O1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICByZXNwb25zZUJvZHkgPSB7fTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY2FsY3VsYXRlIHZhbHVlIGlmIG5vdCBwcmVzZW50JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgY29udmVydGVyLnByb3h5U2V0VmFsdWUoJycsICcnLCB7XG4gICAgICAgIHRleHQ6ICdibGEnLFxuICAgICAgfSk7XG4gICAgICByZXNwb25zZUJvZHkuc2hvdWxkLmVxbCh7XG4gICAgICAgIHRleHQ6ICdibGEnLFxuICAgICAgICB2YWx1ZTogWydiJywgJ2wnLCAnYSddLFxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBjYWxjdWxhdGUgdGV4dCBpZiBub3QgcHJlc2VudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGNvbnZlcnRlci5wcm94eVNldFZhbHVlKCcnLCAnJywge1xuICAgICAgICB2YWx1ZTogWydiJywgJ2wnLCAnYSddLFxuICAgICAgfSk7XG4gICAgICByZXNwb25zZUJvZHkuc2hvdWxkLmVxbCh7XG4gICAgICAgIHRleHQ6ICdibGEnLFxuICAgICAgICB2YWx1ZTogWydiJywgJ2wnLCAnYSddLFxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBrZWVwIHRoZSByZXNwb25zZSBib2R5IHVuY2hhbmdlZCBpZiBib3RoIHZhbHVlIGFuZCB0ZXh0IGFyZSBwcmVzZW50JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgY29udmVydGVyLnByb3h5U2V0VmFsdWUoJycsICcnLCB7XG4gICAgICAgIHRleHQ6ICdibGEnLFxuICAgICAgICB2YWx1ZTogWydiJywgJ2wnLCAnYSddLFxuICAgICAgfSk7XG4gICAgICByZXNwb25zZUJvZHkuc2hvdWxkLmVxbCh7XG4gICAgICAgIHRleHQ6ICdibGEnLFxuICAgICAgICB2YWx1ZTogWydiJywgJ2wnLCAnYSddLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuICBkZXNjcmliZSgnZ2V0UHJvcGVydHknLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IGpzb253cENvbnZlcnRlciwgdzNjQ29udmVydGVyO1xuICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICBmb3IgKGxldCBjb21tYW5kIG9mIENPTU1BTkRfVVJMU19DT05GTElDVFMpIHtcbiAgICAgICAgaWYgKGNvbW1hbmQuY29tbWFuZE5hbWVzLmluY2x1ZGVzKCdnZXRQcm9wZXJ0eScpKSB7XG4gICAgICAgICAganNvbndwQ29udmVydGVyID0gY29tbWFuZC5qc29ud3BDb252ZXJ0ZXI7XG4gICAgICAgICAgdzNjQ29udmVydGVyID0gY29tbWFuZC53M2NDb252ZXJ0ZXI7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIGNvbnZlcnQgXCJwcm9wZXJ0eS92YWx1ZVwiIHRvIFwiYXR0cmlidXRlL3ZhbHVlXCInLCBmdW5jdGlvbiAoKSB7XG4gICAgICBqc29ud3BDb252ZXJ0ZXIoJy9zZXNzaW9uLzEyMy9lbGVtZW50LzQ1Ni9wcm9wZXJ0eS92YWx1ZScpLnNob3VsZC5lcXVhbCgnL3Nlc3Npb24vMTIzL2VsZW1lbnQvNDU2L2F0dHJpYnV0ZS92YWx1ZScpO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgY29udmVydCBcInByb3BlcnR5Lzpzb21lUHJvcE5hbWVcIiB0byBcImF0dHJpYnV0ZS86c29tZVByb3BOYW1lXCInLCBmdW5jdGlvbiAoKSB7XG4gICAgICBqc29ud3BDb252ZXJ0ZXIoJy9zZXNzaW9uLzEyMy9lbGVtZW50LzQ1Ni9wcm9wZXJ0eS9zb21lUHJvcE5hbWUnKS5zaG91bGQuZXF1YWwoJy9zZXNzaW9uLzEyMy9lbGVtZW50LzQ1Ni9hdHRyaWJ1dGUvc29tZVByb3BOYW1lJyk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBub3QgY29udmVydCBmcm9tIEpTT05XUCB0byBXM0MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICB3M2NDb252ZXJ0ZXIoJy9zZXNzaW9uLzEyMy9lbGVtZW50LzQ1Ni9hdHRyaWJ1dGUvc29tZUF0dHInKS5zaG91bGQuZXF1YWwoJy9zZXNzaW9uLzEyMy9lbGVtZW50LzQ1Ni9hdHRyaWJ1dGUvc29tZUF0dHInKTtcbiAgICAgIHczY0NvbnZlcnRlcignL3Nlc3Npb24vMTIzL2VsZW1lbnQvNDU2L3Byb3BlcnR5L3NvbWVQcm9wJykuc2hvdWxkLmVxdWFsKCcvc2Vzc2lvbi8xMjMvZWxlbWVudC80NTYvcHJvcGVydHkvc29tZVByb3AnKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==
@@ -0,0 +1,292 @@
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 _mockRequest = _interopRequireDefault(require("./mock-request"));
10
+
11
+ var _errors = require("../../../lib/protocol/errors");
12
+
13
+ var _helpers = require("../../helpers");
14
+
15
+ function buildReqRes(url, method, body) {
16
+ let req = {
17
+ originalUrl: url,
18
+ method,
19
+ body
20
+ };
21
+ let res = {};
22
+ res.headers = {};
23
+
24
+ res.set = (k, v) => {
25
+ res[k] = v;
26
+ };
27
+
28
+ res.status = code => {
29
+ res.sentCode = code;
30
+ return res;
31
+ };
32
+
33
+ res.send = body => {
34
+ try {
35
+ body = JSON.parse(body);
36
+ } catch (e) {}
37
+
38
+ res.sentBody = body;
39
+ };
40
+
41
+ return [req, res];
42
+ }
43
+
44
+ describe('proxy', function () {
45
+ let port;
46
+
47
+ function mockProxy(opts = {}) {
48
+ opts = {
49
+ server: _helpers.TEST_HOST,
50
+ port,
51
+ ...opts
52
+ };
53
+ let proxy = new _lib.JWProxy(opts);
54
+
55
+ proxy.request = async function (...args) {
56
+ return await (0, _mockRequest.default)(...args);
57
+ };
58
+
59
+ return proxy;
60
+ }
61
+
62
+ before(async function () {
63
+ port = await (0, _helpers.getTestPort)();
64
+ });
65
+ it('should override default params', function () {
66
+ let j = mockProxy({
67
+ server: '127.0.0.2',
68
+ port
69
+ });
70
+ j.server.should.equal('127.0.0.2');
71
+ j.port.should.equal(port);
72
+ });
73
+ it('should save session id on session creation', async function () {
74
+ let j = mockProxy();
75
+ let [res, body] = await j.proxy('/session', 'POST', {
76
+ desiredCapabilities: {}
77
+ });
78
+ res.statusCode.should.equal(200);
79
+ body.should.eql({
80
+ status: 0,
81
+ sessionId: '123',
82
+ value: {
83
+ browserName: 'boo'
84
+ }
85
+ });
86
+ j.sessionId.should.equal('123');
87
+ });
88
+ describe('getUrlForProxy', function () {
89
+ it('should modify session id, host, and port', function () {
90
+ let j = mockProxy({
91
+ sessionId: '123'
92
+ });
93
+ j.getUrlForProxy('http://host.com:1234/session/456/element/200/value').should.eql(`http://${_helpers.TEST_HOST}:${port}/session/123/element/200/value`);
94
+ });
95
+ it('should prepend scheme, host and port if not provided', function () {
96
+ let j = mockProxy({
97
+ sessionId: '123'
98
+ });
99
+ j.getUrlForProxy('/session/456/element/200/value').should.eql(`http://${_helpers.TEST_HOST}:${port}/session/123/element/200/value`);
100
+ });
101
+ it('should respect nonstandard incoming request base path', function () {
102
+ let j = mockProxy({
103
+ sessionId: '123',
104
+ reqBasePath: ''
105
+ });
106
+ j.getUrlForProxy('/session/456/element/200/value').should.eql(`http://${_helpers.TEST_HOST}:${port}/session/123/element/200/value`);
107
+ j = mockProxy({
108
+ sessionId: '123',
109
+ reqBasePath: '/my/base/path'
110
+ });
111
+ j.getUrlForProxy('/my/base/path/session/456/element/200/value').should.eql(`http://${_helpers.TEST_HOST}:${port}/session/123/element/200/value`);
112
+ });
113
+ it('should work with urls which do not have session ids', function () {
114
+ let j = mockProxy({
115
+ sessionId: '123'
116
+ });
117
+ j.getUrlForProxy('http://host.com:1234/session').should.eql(`http://${_helpers.TEST_HOST}:${port}/session`);
118
+ let newUrl = j.getUrlForProxy('/session');
119
+ newUrl.should.eql(`http://${_helpers.TEST_HOST}:${port}/session`);
120
+ });
121
+ it('should throw an error if url requires a sessionId but its null', function () {
122
+ let j = mockProxy();
123
+ let e;
124
+
125
+ try {
126
+ j.getUrlForProxy('/session/456/element/200/value');
127
+ } catch (err) {
128
+ e = err;
129
+ }
130
+
131
+ should.exist(e);
132
+ e.message.should.contain('without session id');
133
+ });
134
+ it('should not throw an error if url does not require a session id and its null', function () {
135
+ let j = mockProxy();
136
+ let newUrl = j.getUrlForProxy('/status');
137
+ should.exist(newUrl);
138
+ });
139
+ });
140
+ describe('straight proxy', function () {
141
+ it('should successfully proxy straight', async function () {
142
+ let j = mockProxy();
143
+ let [res, body] = await j.proxy('/status', 'GET');
144
+ res.statusCode.should.equal(200);
145
+ body.should.eql({
146
+ status: 0,
147
+ value: {
148
+ foo: 'bar'
149
+ }
150
+ });
151
+ });
152
+ it('should pass along request errors', function () {
153
+ let j = mockProxy({
154
+ sessionId: '123'
155
+ });
156
+ j.proxy('/badurl', 'GET').should.eventually.be.rejectedWith('Could not proxy');
157
+ });
158
+ it('should proxy error responses and codes', async function () {
159
+ let j = mockProxy({
160
+ sessionId: '123'
161
+ });
162
+
163
+ try {
164
+ await j.proxy('/element/bad/text', 'GET');
165
+ } catch (e) {
166
+ (0, _errors.isErrorType)(e.getActualError(), _errors.errors.ElementNotVisibleError).should.be.true;
167
+ }
168
+ });
169
+ });
170
+ describe('command proxy', function () {
171
+ it('should successfully proxy command', async function () {
172
+ let j = mockProxy();
173
+ let res = await j.command('/status', 'GET');
174
+ res.should.eql({
175
+ foo: 'bar'
176
+ });
177
+ });
178
+ it('should pass along request errors', function () {
179
+ let j = mockProxy({
180
+ sessionId: '123'
181
+ });
182
+ j.command('/badurl', 'GET').should.eventually.be.rejectedWith('Could not proxy');
183
+ });
184
+ it('should throw when a command fails', async function () {
185
+ let j = mockProxy({
186
+ sessionId: '123'
187
+ });
188
+ let e = null;
189
+
190
+ try {
191
+ await j.command('/element/bad/text', 'GET');
192
+ } catch (err) {
193
+ e = err;
194
+ }
195
+
196
+ should.exist(e);
197
+ e.message.should.contain('Invisible element');
198
+ });
199
+ it('should throw when a command fails with a 200 because the status is not 0', async function () {
200
+ let j = mockProxy({
201
+ sessionId: '123'
202
+ });
203
+ let e = null;
204
+
205
+ try {
206
+ await j.command('/element/200/text', 'GET');
207
+ } catch (err) {
208
+ e = err;
209
+ }
210
+
211
+ should.exist(e);
212
+ e.error.should.eql('element not visible');
213
+ });
214
+ it('should throw when a command fails with a 100', async function () {
215
+ let j = mockProxy({
216
+ sessionId: '123'
217
+ });
218
+ let e = null;
219
+
220
+ try {
221
+ await j.command('/session/badchrome/nochrome', 'GET');
222
+ } catch (err) {
223
+ e = err;
224
+ }
225
+
226
+ should.exist(e);
227
+ e.message.should.contain('chrome not reachable');
228
+ });
229
+ });
230
+ describe('req/res proxy', function () {
231
+ it('should successfully proxy via req and send to res', async function () {
232
+ let j = mockProxy();
233
+ let [req, res] = buildReqRes('/status', 'GET');
234
+ await j.proxyReqRes(req, res);
235
+ res.headers['content-type'].should.equal('application/json; charset=utf-8');
236
+ res.sentCode.should.equal(200);
237
+ res.sentBody.should.eql({
238
+ value: {
239
+ foo: 'bar'
240
+ }
241
+ });
242
+ });
243
+ it('should rewrite the inner session id so it doesnt change', async function () {
244
+ let j = mockProxy({
245
+ sessionId: '123'
246
+ });
247
+ let [req, res] = buildReqRes('/element/200/value', 'GET');
248
+ await j.proxyReqRes(req, res);
249
+ res.sentBody.should.eql({
250
+ value: 'foobar',
251
+ sessionId: '123'
252
+ });
253
+ });
254
+ it('should rewrite the inner session id with sessionId in url', async function () {
255
+ let j = mockProxy({
256
+ sessionId: '123'
257
+ });
258
+ let [req, res] = buildReqRes('/session/456/element/200/value', 'POST');
259
+ await j.proxyReqRes(req, res);
260
+ res.sentBody.should.eql({
261
+ value: 'foobar',
262
+ sessionId: '456'
263
+ });
264
+ });
265
+ it('should pass through urls that do not require session IDs', async function () {
266
+ let j = mockProxy({
267
+ sessionId: '123'
268
+ });
269
+ let [req, res] = buildReqRes('/status', 'GET');
270
+ await j.proxyReqRes(req, res);
271
+ res.sentBody.should.eql({
272
+ value: {
273
+ 'foo': 'bar'
274
+ }
275
+ });
276
+ });
277
+ it('should proxy strange responses', async function () {
278
+ let j = mockProxy({
279
+ sessionId: '123'
280
+ });
281
+ let [req, res] = buildReqRes('/nochrome', 'GET');
282
+ await j.proxyReqRes(req, res);
283
+ res.sentCode.should.equal(100);
284
+ res.sentBody.should.eql({
285
+ value: {
286
+ message: 'chrome not reachable'
287
+ }
288
+ });
289
+ });
290
+ });
291
+ });
292
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvdW5pdC9qc29ud3AtcHJveHkvcHJveHkuc3BlYy5qcyJdLCJuYW1lcyI6WyJidWlsZFJlcVJlcyIsInVybCIsIm1ldGhvZCIsImJvZHkiLCJyZXEiLCJvcmlnaW5hbFVybCIsInJlcyIsImhlYWRlcnMiLCJzZXQiLCJrIiwidiIsInN0YXR1cyIsImNvZGUiLCJzZW50Q29kZSIsInNlbmQiLCJKU09OIiwicGFyc2UiLCJlIiwic2VudEJvZHkiLCJkZXNjcmliZSIsInBvcnQiLCJtb2NrUHJveHkiLCJvcHRzIiwic2VydmVyIiwiVEVTVF9IT1NUIiwicHJveHkiLCJKV1Byb3h5IiwicmVxdWVzdCIsImFyZ3MiLCJiZWZvcmUiLCJpdCIsImoiLCJzaG91bGQiLCJlcXVhbCIsImRlc2lyZWRDYXBhYmlsaXRpZXMiLCJzdGF0dXNDb2RlIiwiZXFsIiwic2Vzc2lvbklkIiwidmFsdWUiLCJicm93c2VyTmFtZSIsImdldFVybEZvclByb3h5IiwicmVxQmFzZVBhdGgiLCJuZXdVcmwiLCJlcnIiLCJleGlzdCIsIm1lc3NhZ2UiLCJjb250YWluIiwiZm9vIiwiZXZlbnR1YWxseSIsImJlIiwicmVqZWN0ZWRXaXRoIiwiZ2V0QWN0dWFsRXJyb3IiLCJlcnJvcnMiLCJFbGVtZW50Tm90VmlzaWJsZUVycm9yIiwidHJ1ZSIsImNvbW1hbmQiLCJlcnJvciIsInByb3h5UmVxUmVzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFFQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFFQSxTQUFTQSxXQUFULENBQXNCQyxHQUF0QixFQUEyQkMsTUFBM0IsRUFBbUNDLElBQW5DLEVBQXlDO0FBQ3ZDLE1BQUlDLEdBQUcsR0FBRztBQUFDQyxJQUFBQSxXQUFXLEVBQUVKLEdBQWQ7QUFBbUJDLElBQUFBLE1BQW5CO0FBQTJCQyxJQUFBQTtBQUEzQixHQUFWO0FBQ0EsTUFBSUcsR0FBRyxHQUFHLEVBQVY7QUFDQUEsRUFBQUEsR0FBRyxDQUFDQyxPQUFKLEdBQWMsRUFB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K0IsQ0FBQyxDQUFDMEIsV0FBRixDQUFjckQsR0FBZCxFQUFtQkUsR0FBbkIsQ0FBTjtBQUNBQSxNQUFBQSxHQUFHLENBQUNPLFFBQUosQ0FBYW1CLE1BQWIsQ0FBb0JDLEtBQXBCLENBQTBCLEdBQTFCO0FBQ0EzQixNQUFBQSxHQUFHLENBQUNZLFFBQUosQ0FBYWMsTUFBYixDQUFvQkksR0FBcEIsQ0FBd0I7QUFBQ0UsUUFBQUEsS0FBSyxFQUFFO0FBQUNPLFVBQUFBLE9BQU8sRUFBRTtBQUFWO0FBQVIsT0FBeEI7QUFDRCxLQU5DLENBQUY7QUFPRCxHQWxDTyxDQUFSO0FBbUNELENBOUtPLENBQVIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyB0cmFuc3BpbGU6bW9jaGFcblxuaW1wb3J0IHsgSldQcm94eSB9IGZyb20gJy4uLy4uLy4uL2xpYic7XG5pbXBvcnQgcmVxdWVzdCBmcm9tICcuL21vY2stcmVxdWVzdCc7XG5pbXBvcnQgeyBpc0Vycm9yVHlwZSwgZXJyb3JzIH0gZnJvbSAnLi4vLi4vLi4vbGliL3Byb3RvY29sL2Vycm9ycyc7XG5pbXBvcnQgeyBnZXRUZXN0UG9ydCwgVEVTVF9IT1NUIH0gZnJvbSAnLi4vLi4vaGVscGVycyc7XG5cbmZ1bmN0aW9uIGJ1aWxkUmVxUmVzICh1cmwsIG1ldGhvZCwgYm9keSkge1xuICBsZXQgcmVxID0ge29yaWdpbmFsVXJsOiB1cmwsIG1ldGhvZCwgYm9keX07XG4gIGxldCByZXMgPSB7fTtcbiAgcmVzLmhlYWRlcnMgPSB7fTtcbiAgcmVzLnNldCA9IChrLCB2KSA9PiB7IHJlc1trXSA9IHY7IH07XG4gIHJlcy5zdGF0dXMgPSAoY29kZSkgPT4ge1xuICAgIHJlcy5zZW50Q29kZSA9IGNvZGU7XG4gICAgcmV0dXJuIHJlcztcbiAgfTtcbiAgcmVzLnNlbmQgPSAoYm9keSkgPT4ge1xuICAgIHRyeSB7XG4gICAgICBib2R5ID0gSlNPTi5wYXJzZShib2R5KTtcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJlcy5zZW50Qm9keSA9IGJvZHk7XG4gIH07XG4gIHJldHVybiBbcmVxLCByZXNdO1xufVxuXG5kZXNjcmliZSgncHJveHknLCBmdW5jdGlvbiAoKSB7XG4gIGxldCBwb3J0O1xuXG4gIGZ1bmN0aW9uIG1vY2tQcm94eSAob3B0cyA9IHt9KSB7XG4gICAgLy8gc2V0cyBkZWZhdWx0IHNlcnZlci9wb3J0XG4gICAgb3B0cyA9IHtzZXJ2ZXI6IFRFU1RfSE9TVCwgcG9ydCwgLi4ub3B0c307XG4gICAgbGV0IHByb3h5ID0gbmV3IEpXUHJveHkob3B0cyk7XG4gICAgcHJveHkucmVxdWVzdCA9IGFzeW5jIGZ1bmN0aW9uICguLi5hcmdzKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVxdWVzdCguLi5hcmdzKTtcbiAgICB9O1xuICAgIHJldHVybiBwcm94eTtcbiAgfVxuXG4gIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgcG9ydCA9IGF3YWl0IGdldFRlc3RQb3J0KCk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgb3ZlcnJpZGUgZGVmYXVsdCBwYXJhbXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IGogPSBtb2NrUHJveHkoe3NlcnZlcjogJzEyNy4wLjAuMicsIHBvcnR9KTtcbiAgICBqLnNlcnZlci5zaG91bGQuZXF1YWwoJzEyNy4wLjAuMicpO1xuICAgIGoucG9ydC5zaG91bGQuZXF1YWwocG9ydCk7XG4gIH0pO1xuICBpdCgnc2hvdWxkIHNhdmUgc2Vzc2lvbiBpZCBvbiBzZXNzaW9uIGNyZWF0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGxldCBqID0gbW9ja1Byb3h5KCk7XG4gICAgbGV0IFtyZXMsIGJvZHldID0gYXdhaXQgai5wcm94eSgnL3Nlc3Npb24nLCAnUE9TVCcsIHtkZXNpcmVkQ2FwYWJpbGl0aWVzOiB7fX0pO1xuICAgIHJlcy5zdGF0dXNDb2RlLnNob3VsZC5lcXVhbCgyMDApO1xuICAgIGJvZHkuc2hvdWxkLmVxbCh7c3RhdHVzOiAwLCBzZXNzaW9uSWQ6ICcxMjMnLCB2YWx1ZToge2Jyb3dzZXJOYW1lOiAnYm9vJ319KTtcbiAgICBqLnNlc3Npb25JZC5zaG91bGQuZXF1YWwoJzEyMycpO1xuICB9KTtcbiAgZGVzY3JpYmUoJ2dldFVybEZvclByb3h5JywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgbW9kaWZ5IHNlc3Npb24gaWQsIGhvc3QsIGFuZCBwb3J0JywgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IGogPSBtb2NrUHJveHkoe3Nlc3Npb25JZDogJzEyMyd9KTtcbiAgICAgIGouZ2V0VXJsRm9yUHJveHkoJ2h0dHA6Ly9ob3N0LmNvbToxMjM0L3Nlc3Npb24vNDU2L2VsZW1lbnQvMjAwL3ZhbHVlJylcbiAgICAgICAuc2hvdWxkLmVxbChgaHR0cDovLyR7VEVTVF9IT1NUfToke3BvcnR9L3Nlc3Npb24vMTIzL2VsZW1lbnQvMjAwL3ZhbHVlYCk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBwcmVwZW5kIHNjaGVtZSwgaG9zdCBhbmQgcG9ydCBpZiBub3QgcHJvdmlkZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgaiA9IG1vY2tQcm94eSh7c2Vzc2lvbklkOiAnMTIzJ30pO1xuICAgICAgai5nZXRVcmxGb3JQcm94eSgnL3Nlc3Npb24vNDU2L2VsZW1lbnQvMjAwL3ZhbHVlJylcbiAgICAgICAuc2hvdWxkLmVxbChgaHR0cDovLyR7VEVTVF9IT1NUfToke3BvcnR9L3Nlc3Npb24vMTIzL2VsZW1lbnQvMjAwL3ZhbHVlYCk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCByZXNwZWN0IG5vbnN0YW5kYXJkIGluY29taW5nIHJlcXVlc3QgYmFzZSBwYXRoJywgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IGogPSBtb2NrUHJveHkoe3Nlc3Npb25JZDogJzEyMycsIHJlcUJhc2VQYXRoOiAnJ30pO1xuICAgICAgai5nZXRVcmxGb3JQcm94eSgnL3Nlc3Npb24vNDU2L2VsZW1lbnQvMjAwL3ZhbHVlJylcbiAgICAgICAuc2hvdWxkLmVxbChgaHR0cDovLyR7VEVTVF9IT1NUfToke3BvcnR9L3Nlc3Npb24vMTIzL2VsZW1lbnQvMjAwL3ZhbHVlYCk7XG5cbiAgICAgIGogPSBtb2NrUHJveHkoe3Nlc3Npb25JZDogJzEyMycsIHJlcUJhc2VQYXRoOiAnL215L2Jhc2UvcGF0aCd9KTtcbiAgICAgIGouZ2V0VXJsRm9yUHJveHkoJy9teS9iYXNlL3BhdGgvc2Vzc2lvbi80NTYvZWxlbWVudC8yMDAvdmFsdWUnKVxuICAgICAgIC5zaG91bGQuZXFsKGBodHRwOi8vJHtURVNUX0hPU1R9OiR7cG9ydH0vc2Vzc2lvbi8xMjMvZWxlbWVudC8yMDAvdmFsdWVgKTtcbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIHdvcmsgd2l0aCB1cmxzIHdoaWNoIGRvIG5vdCBoYXZlIHNlc3Npb24gaWRzJywgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IGogPSBtb2NrUHJveHkoe3Nlc3Npb25JZDogJzEyMyd9KTtcbiAgICAgIGouZ2V0VXJsRm9yUHJveHkoJ2h0dHA6Ly9ob3N0LmNvbToxMjM0L3Nlc3Npb24nKVxuICAgICAgIC5zaG91bGQuZXFsKGBodHRwOi8vJHtURVNUX0hPU1R9OiR7cG9ydH0vc2Vzc2lvbmApO1xuXG4gICAgICBsZXQgbmV3VXJsID0gai5nZXRVcmxGb3JQcm94eSgnL3Nlc3Npb24nKTtcbiAgICAgIG5ld1VybC5zaG91bGQuZXFsKGBodHRwOi8vJHtURVNUX0hPU1R9OiR7cG9ydH0vc2Vzc2lvbmApO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgdGhyb3cgYW4gZXJyb3IgaWYgdXJsIHJlcXVpcmVzIGEgc2Vzc2lvbklkIGJ1dCBpdHMgbnVsbCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCBqID0gbW9ja1Byb3h5KCk7XG4gICAgICBsZXQgZTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGouZ2V0VXJsRm9yUHJveHkoJy9zZXNzaW9uLzQ1Ni9lbGVtZW50LzIwMC92YWx1ZScpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGUgPSBlcnI7XG4gICAgICB9XG4gICAgICBzaG91bGQuZXhpc3QoZSk7XG4gICAgICBlLm1lc3NhZ2Uuc2hvdWxkLmNvbnRhaW4oJ3dpdGhvdXQgc2Vzc2lvbiBpZCcpO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgbm90IHRocm93IGFuIGVycm9yIGlmIHVybCBkb2VzIG5vdCByZXF1aXJlIGEgc2Vzc2lvbiBpZCBhbmQgaXRzIG51bGwnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgaiA9IG1vY2tQcm94eSgpO1xuICAgICAgbGV0IG5ld1VybCA9IGouZ2V0VXJsRm9yUHJveHkoJy9zdGF0dXMnKTtcblxuICAgICAgc2hvdWxkLmV4aXN0KG5ld1VybCk7XG4gICAgfSk7XG4gIH0pO1xuICBkZXNjcmliZSgnc3RyYWlnaHQgcHJveHknLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBzdWNjZXNzZnVsbHkgcHJveHkgc3RyYWlnaHQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgaiA9IG1vY2tQcm94eSgpO1xuICAgICAgbGV0IFtyZXMsIGJvZHldID0gYXdhaXQgai5wcm94eSgnL3N0YXR1cycsICdHRVQnKTtcbiAgICAgIHJlcy5zdGF0dXNDb2RlLnNob3VsZC5lcXVhbCgyMDApO1xuICAgICAgYm9keS5zaG91bGQuZXFsKHtzdGF0dXM6IDAsIHZhbHVlOiB7Zm9vOiAnYmFyJ319KTtcbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIHBhc3MgYWxvbmcgcmVxdWVzdCBlcnJvcnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgaiA9IG1vY2tQcm94eSh7c2Vzc2lvbklkOiAnMTIzJ30pO1xuICAgICAgai5wcm94eSgnL2JhZHVybCcsICdHRVQnKS5zaG91bGQuZXZlbnR1YWxseS5iZS5yZWplY3RlZFdpdGgoJ0NvdWxkIG5vdCBwcm94eScpO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgcHJveHkgZXJyb3IgcmVzcG9uc2VzIGFuZCBjb2RlcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCBqID0gbW9ja1Byb3h5KHtzZXNzaW9uSWQ6ICcxMjMnfSk7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBqLnByb3h5KCcvZWxlbWVudC9iYWQvdGV4dCcsICdHRVQnKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaXNFcnJvclR5cGUoZS5nZXRBY3R1YWxFcnJvcigpLCBlcnJvcnMuRWxlbWVudE5vdFZpc2libGVFcnJvcikuc2hvdWxkLmJlLnRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuICBkZXNjcmliZSgnY29tbWFuZCBwcm94eScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHN1Y2Nlc3NmdWxseSBwcm94eSBjb21tYW5kJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IGogPSBtb2NrUHJveHkoKTtcbiAgICAgIGxldCByZXMgPSBhd2FpdCBqLmNvbW1hbmQoJy9zdGF0dXMnLCAnR0VUJyk7XG4gICAgICByZXMuc2hvdWxkLmVxbCh7Zm9vOiAnYmFyJ30pO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgcGFzcyBhbG9uZyByZXF1ZXN0IGVycm9ycycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCBqID0gbW9ja1Byb3h5KHtzZXNzaW9uSWQ6ICcxMjMnfSk7XG4gICAgICBqLmNvbW1hbmQoJy9iYWR1cmwnLCAnR0VUJykuc2hvdWxkLmV2ZW50dWFsbHkuYmUucmVqZWN0ZWRXaXRoKCdDb3VsZCBub3QgcHJveHknKTtcbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIHRocm93IHdoZW4gYSBjb21tYW5kIGZhaWxzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IGogPSBtb2NrUHJveHkoe3Nlc3Npb25JZDogJzEyMyd9KTtcbiAgICAgIGxldCBlID0gbnVsbDtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGouY29tbWFuZCgnL2VsZW1lbnQvYmFkL3RleHQnLCAnR0VUJyk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgZSA9IGVycjtcbiAgICAgIH1cbiAgICAgIHNob3VsZC5leGlzdChlKTtcbiAgICAgIGUubWVzc2FnZS5zaG91bGQuY29udGFpbignSW52aXNpYmxlIGVsZW1lbnQnKTtcbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIHRocm93IHdoZW4gYSBjb21tYW5kIGZhaWxzIHdpdGggYSAyMDAgYmVjYXVzZSB0aGUgc3RhdHVzIGlzIG5vdCAwJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IGogPSBtb2NrUHJveHkoe3Nlc3Npb25JZDogJzEyMyd9KTtcbiAgICAgIGxldCBlID0gbnVsbDtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGouY29tbWFuZCgnL2VsZW1lbnQvMjAwL3RleHQnLCAnR0VUJyk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgZSA9IGVycjtcbiAgICAgIH1cbiAgICAgIHNob3VsZC5leGlzdChlKTtcbiAgICAgIGUuZXJyb3Iuc2hvdWxkLmVxbCgnZWxlbWVudCBub3QgdmlzaWJsZScpO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgdGhyb3cgd2hlbiBhIGNvbW1hbmQgZmFpbHMgd2l0aCBhIDEwMCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCBqID0gbW9ja1Byb3h5KHtzZXNzaW9uSWQ6ICcxMjMnfSk7XG4gICAgICBsZXQgZSA9IG51bGw7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBqLmNvbW1hbmQoJy9zZXNzaW9uL2JhZGNocm9tZS9ub2Nocm9tZScsICdHRVQnKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBlID0gZXJyO1xuICAgICAgfVxuICAgICAgc2hvdWxkLmV4aXN0KGUpO1xuICAgICAgZS5tZXNzYWdlLnNob3VsZC5jb250YWluKCdjaHJvbWUgbm90IHJlYWNoYWJsZScpO1xuICAgIH0pO1xuICB9KTtcbiAgZGVzY3JpYmUoJ3JlcS9yZXMgcHJveHknLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBzdWNjZXNzZnVsbHkgcHJveHkgdmlhIHJlcSBhbmQgc2VuZCB0byByZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgaiA9IG1vY2tQcm94eSgpO1xuICAgICAgbGV0IFtyZXEsIHJlc10gPSBidWlsZFJlcVJlcygnL3N0YXR1cycsICdHRVQnKTtcbiAgICAgIGF3YWl0IGoucHJveHlSZXFSZXMocmVxLCByZXMpO1xuICAgICAgcmVzLmhlYWRlcnNbJ2NvbnRlbnQtdHlwZSddLnNob3VsZC5lcXVhbCgnYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD11dGYtOCcpO1xuICAgICAgcmVzLnNlbnRDb2RlLnNob3VsZC5lcXVhbCgyMDApO1xuICAgICAgcmVzLnNlbnRCb2R5LnNob3VsZC5lcWwoe3ZhbHVlOiB7Zm9vOiAnYmFyJ319KTtcbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIHJld3JpdGUgdGhlIGlubmVyIHNlc3Npb24gaWQgc28gaXQgZG9lc250IGNoYW5nZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCBqID0gbW9ja1Byb3h5KHtzZXNzaW9uSWQ6ICcxMjMnfSk7XG4gICAgICBsZXQgW3JlcSwgcmVzXSA9IGJ1aWxkUmVxUmVzKCcvZWxlbWVudC8yMDAvdmFsdWUnLCAnR0VUJyk7XG4gICAgICBhd2FpdCBqLnByb3h5UmVxUmVzKHJlcSwgcmVzKTtcbiAgICAgIHJlcy5zZW50Qm9keS5zaG91bGQuZXFsKHt2YWx1ZTogJ2Zvb2JhcicsIHNlc3Npb25JZDogJzEyMyd9KTtcbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIHJld3JpdGUgdGhlIGlubmVyIHNlc3Npb24gaWQgd2l0aCBzZXNzaW9uSWQgaW4gdXJsJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IGogPSBtb2NrUHJveHkoe3Nlc3Npb25JZDogJzEyMyd9KTtcbiAgICAgIGxldCBbcmVxLCByZXNdID0gYnVpbGRSZXFSZXMoJy9zZXNzaW9uLzQ1Ni9lbGVtZW50LzIwMC92YWx1ZScsICdQT1NUJyk7XG4gICAgICBhd2FpdCBqLnByb3h5UmVxUmVzKHJlcSwgcmVzKTtcbiAgICAgIHJlcy5zZW50Qm9keS5zaG91bGQuZXFsKHt2YWx1ZTogJ2Zvb2JhcicsIHNlc3Npb25JZDogJzQ1Nid9KTtcbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIHBhc3MgdGhyb3VnaCB1cmxzIHRoYXQgZG8gbm90IHJlcXVpcmUgc2Vzc2lvbiBJRHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgaiA9IG1vY2tQcm94eSh7c2Vzc2lvbklkOiAnMTIzJ30pO1xuICAgICAgbGV0IFtyZXEsIHJlc10gPSBidWlsZFJlcVJlcygnL3N0YXR1cycsICdHRVQnKTtcbiAgICAgIGF3YWl0IGoucHJveHlSZXFSZXMocmVxLCByZXMpO1xuICAgICAgcmVzLnNlbnRCb2R5LnNob3VsZC5lcWwoe3ZhbHVlOiB7J2Zvbyc6ICdiYXInfX0pO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgcHJveHkgc3RyYW5nZSByZXNwb25zZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgaiA9IG1vY2tQcm94eSh7c2Vzc2lvbklkOiAnMTIzJ30pO1xuICAgICAgbGV0IFtyZXEsIHJlc10gPSBidWlsZFJlcVJlcygnL25vY2hyb21lJywgJ0dFVCcpO1xuICAgICAgYXdhaXQgai5wcm94eVJlcVJlcyhyZXEsIHJlcyk7XG4gICAgICByZXMuc2VudENvZGUuc2hvdWxkLmVxdWFsKDEwMCk7XG4gICAgICByZXMuc2VudEJvZHkuc2hvdWxkLmVxbCh7dmFsdWU6IHttZXNzYWdlOiAnY2hyb21lIG5vdCByZWFjaGFibGUnfX0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19