@appium/base-driver 8.2.4 → 8.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) 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 +41 -43
  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 -30
  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 -158
  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 +18 -22
  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 -144
  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 +33 -15
  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 +104 -257
  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 +24 -10
  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 +3 -5
  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 +3 -5
  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 +2 -4
  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 +77 -0
  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 -25
  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 +19 -15
  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 +20 -15
  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 +38 -35
  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 +84 -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 +41 -19
  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 +82 -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 +107 -45
  137. package/lib/basedriver/commands/index.js +25 -19
  138. package/lib/basedriver/commands/log.js +59 -34
  139. package/lib/basedriver/commands/session.js +39 -142
  140. package/lib/basedriver/commands/settings.js +32 -14
  141. package/lib/basedriver/commands/timeout.js +153 -154
  142. package/lib/basedriver/core.js +497 -0
  143. package/lib/basedriver/desired-caps.js +1 -1
  144. package/lib/basedriver/device-settings.js +57 -13
  145. package/lib/basedriver/driver.js +277 -375
  146. package/lib/basedriver/helpers.js +31 -13
  147. package/lib/express/express-logging.js +1 -1
  148. package/lib/express/idempotency.js +1 -1
  149. package/lib/helpers/capabilities.js +84 -0
  150. package/lib/index.js +17 -13
  151. package/lib/jsonwp-proxy/protocol-converter.js +14 -13
  152. package/lib/jsonwp-proxy/proxy.js +16 -12
  153. package/lib/protocol/errors.js +42 -42
  154. package/lib/protocol/index.js +4 -4
  155. package/lib/protocol/protocol.js +35 -32
  156. package/lib/protocol/routes.js +69 -1
  157. package/package.json +37 -24
  158. package/test/basedriver/README.md +5 -0
  159. package/test/basedriver/driver-e2e-tests.js +1 -1
  160. package/test/basedriver/driver-tests.js +43 -9
  161. package/build/lib/protocol/sessions-cache.js +0 -88
  162. package/build/test/basedriver/capabilities-specs.js +0 -632
  163. package/build/test/basedriver/capability-specs.js +0 -396
  164. package/build/test/basedriver/commands/event-specs.js +0 -112
  165. package/build/test/basedriver/commands/log-specs.js +0 -80
  166. package/build/test/basedriver/driver-e2e-specs.js +0 -17
  167. package/build/test/basedriver/driver-specs.js +0 -17
  168. package/build/test/basedriver/helpers-e2e-specs.js +0 -194
  169. package/build/test/basedriver/helpers-specs.js +0 -153
  170. package/build/test/basedriver/timeout-specs.js +0 -139
  171. package/build/test/basedriver/websockets-e2e-specs.js +0 -84
  172. package/build/test/express/server-e2e-specs.js +0 -156
  173. package/build/test/express/server-specs.js +0 -151
  174. package/build/test/express/static-specs.js +0 -23
  175. package/build/test/jsonwp-proxy/mock-request.js +0 -93
  176. package/build/test/jsonwp-proxy/protocol-converter-specs.js +0 -173
  177. package/build/test/jsonwp-proxy/proxy-e2e-specs.js +0 -61
  178. package/build/test/jsonwp-proxy/proxy-specs.js +0 -294
  179. package/build/test/jsonwp-proxy/url-specs.js +0 -167
  180. package/build/test/jsonwp-status/status-specs.js +0 -36
  181. package/build/test/protocol/errors-specs.js +0 -388
  182. package/build/test/protocol/fake-driver.js +0 -168
  183. package/build/test/protocol/helpers.js +0 -27
  184. package/build/test/protocol/protocol-e2e-specs.js +0 -1182
  185. package/build/test/protocol/routes-specs.js +0 -82
  186. package/build/test/protocol/validator-specs.js +0 -151
  187. package/index.d.ts +0 -386
  188. package/lib/protocol/sessions-cache.js +0 -74
  189. package/test/basedriver/capabilities-specs.js +0 -505
  190. package/test/basedriver/capability-specs.js +0 -409
  191. package/test/basedriver/commands/event-specs.js +0 -74
  192. package/test/basedriver/commands/log-specs.js +0 -70
  193. package/test/basedriver/driver-e2e-specs.js +0 -8
  194. package/test/basedriver/driver-specs.js +0 -8
  195. package/test/basedriver/fixtures/BadZippedApp.zip +0 -1
  196. package/test/basedriver/fixtures/FakeAndroidApp.apk +0 -1
  197. package/test/basedriver/fixtures/FakeAndroidApp.asd +0 -0
  198. package/test/basedriver/fixtures/FakeIOSApp.app +0 -1
  199. package/test/basedriver/fixtures/FakeIOSApp.app.zip +0 -0
  200. package/test/basedriver/fixtures/FakeIOSApp.ipa +0 -0
  201. package/test/basedriver/fixtures/custom-element-finder-bad.js +0 -5
  202. package/test/basedriver/fixtures/custom-element-finder.js +0 -29
  203. package/test/basedriver/helpers-e2e-specs.js +0 -187
  204. package/test/basedriver/helpers-specs.js +0 -137
  205. package/test/basedriver/timeout-specs.js +0 -133
  206. package/test/basedriver/websockets-e2e-specs.js +0 -75
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ require("source-map-support/register");
6
+
7
+ var _path = _interopRequireDefault(require("path"));
8
+
9
+ var _url = _interopRequireDefault(require("url"));
10
+
11
+ var _support = require("@appium/support");
12
+
13
+ var _helpers = require("../../../lib/basedriver/helpers");
14
+
15
+ var _http = _interopRequireDefault(require("http"));
16
+
17
+ var _finalhandler = _interopRequireDefault(require("finalhandler"));
18
+
19
+ var _serveStatic = _interopRequireDefault(require("serve-static"));
20
+
21
+ var _contentDisposition = _interopRequireDefault(require("content-disposition"));
22
+
23
+ var _bluebird = _interopRequireDefault(require("bluebird"));
24
+
25
+ var _helpers2 = require("../../helpers");
26
+
27
+ function getFixture(file) {
28
+ return _path.default.resolve(__dirname, '..', 'fixtures', file);
29
+ }
30
+
31
+ describe('app download and configuration', function () {
32
+ describe('configureApp', function () {
33
+ it('should get the path for a local .app', async function () {
34
+ let newAppPath = await (0, _helpers.configureApp)(getFixture('FakeIOSApp.app'), '.app');
35
+ newAppPath.should.contain('FakeIOSApp.app');
36
+ let contents = await _support.fs.readFile(newAppPath, 'utf8');
37
+ contents.should.eql('this is not really an app\n');
38
+ });
39
+ it('should get the path for a local .apk', async function () {
40
+ let newAppPath = await (0, _helpers.configureApp)(getFixture('FakeAndroidApp.apk'), '.apk');
41
+ newAppPath.should.contain('FakeAndroidApp.apk');
42
+ let contents = await _support.fs.readFile(newAppPath, 'utf8');
43
+ contents.should.eql('this is not really an apk\n');
44
+ });
45
+ it('should unzip and get the path for a local .app.zip', async function () {
46
+ let newAppPath = await (0, _helpers.configureApp)(getFixture('FakeIOSApp.app.zip'), '.app');
47
+ newAppPath.should.contain('FakeIOSApp.app');
48
+ let contents = await _support.fs.readFile(newAppPath, 'utf8');
49
+ contents.should.eql('this is not really an app\n');
50
+ });
51
+ it('should unzip and get the path for a local .ipa', async function () {
52
+ let newAppPath = await (0, _helpers.configureApp)(getFixture('FakeIOSApp.ipa'), '.app');
53
+ newAppPath.should.contain('FakeIOSApp.app');
54
+ let contents = await _support.fs.readFile(newAppPath, 'utf8');
55
+ contents.should.eql('this is not really an app\n');
56
+ });
57
+ it('should fail for a bad zip file', async function () {
58
+ await (0, _helpers.configureApp)(getFixture('BadZippedApp.zip'), '.app').should.be.rejectedWith(/PK/);
59
+ });
60
+ it('should fail if extensions do not match', async function () {
61
+ await (0, _helpers.configureApp)(getFixture('FakeIOSApp.app'), '.wrong').should.be.rejectedWith(/did not have extension/);
62
+ });
63
+ it('should fail if zip file does not contain an app whose extension matches', async function () {
64
+ await (0, _helpers.configureApp)(getFixture('FakeIOSApp.app.zip'), '.wrong').should.be.rejectedWith(/did not have extension/);
65
+ });
66
+ describe('should download an app from the web', function () {
67
+ let port;
68
+ let serverUrl;
69
+ before(async function () {
70
+ port = await (0, _helpers2.getTestPort)(true);
71
+ serverUrl = `http://${_helpers2.TEST_HOST}:${port}`;
72
+ });
73
+ describe('server not available', function () {
74
+ it('should handle server not available', async function () {
75
+ await (0, _helpers.configureApp)(`${serverUrl}/FakeIOSApp.app.zip`, '.app').should.eventually.be.rejectedWith(/ECONNREFUSED/);
76
+ });
77
+ });
78
+ describe('server available', function () {
79
+ let server;
80
+ before(function () {
81
+ const dir = _path.default.resolve(__dirname, '..', 'fixtures');
82
+
83
+ const serve = (0, _serveStatic.default)(dir, {
84
+ index: false,
85
+ setHeaders: (res, path) => {
86
+ res.setHeader('Content-Disposition', (0, _contentDisposition.default)(path));
87
+ }
88
+ });
89
+ server = _http.default.createServer(function (req, res) {
90
+ if (req.url.indexOf('missing') !== -1) {
91
+ res.writeHead(404);
92
+ res.end();
93
+ return;
94
+ }
95
+
96
+ const contentType = new URLSearchParams(_url.default.parse(req.url).search).get('content-type');
97
+
98
+ if (contentType !== null) {
99
+ res.setHeader('content-type', contentType);
100
+ }
101
+
102
+ serve(req, res, (0, _finalhandler.default)(req, res));
103
+ });
104
+ const close = server.close.bind(server);
105
+
106
+ server.close = async function () {
107
+ await _bluebird.default.delay(1000);
108
+ return await new _bluebird.default((resolve, reject) => {
109
+ server.on('close', resolve);
110
+ close(err => {
111
+ if (err) reject(err);
112
+ });
113
+ });
114
+ };
115
+
116
+ server.listen(port);
117
+ });
118
+ after(async function () {
119
+ await server.close();
120
+ });
121
+ it('should download zip file', async function () {
122
+ let newAppPath = await (0, _helpers.configureApp)(`${serverUrl}/FakeIOSApp.app.zip`, '.app');
123
+ newAppPath.should.contain('FakeIOSApp.app');
124
+ let contents = await _support.fs.readFile(newAppPath, 'utf8');
125
+ contents.should.eql('this is not really an app\n');
126
+ });
127
+ it('should download zip file with query string', async function () {
128
+ let newAppPath = await (0, _helpers.configureApp)(`${serverUrl}/FakeIOSApp.app.zip?sv=abc&sr=def`, '.app');
129
+ newAppPath.should.contain('.app');
130
+ let contents = await _support.fs.readFile(newAppPath, 'utf8');
131
+ contents.should.eql('this is not really an app\n');
132
+ });
133
+ it('should download an app file', async function () {
134
+ let newAppPath = await (0, _helpers.configureApp)(`${serverUrl}/FakeIOSApp.app`, '.app');
135
+ newAppPath.should.contain('.app');
136
+ let contents = await _support.fs.readFile(newAppPath, 'utf8');
137
+ contents.should.eql('this is not really an app\n');
138
+ });
139
+ it('should accept multiple extensions', async function () {
140
+ let newAppPath = await (0, _helpers.configureApp)(`${serverUrl}/FakeIOSApp.app.zip`, ['.app', '.aab']);
141
+ newAppPath.should.contain('FakeIOSApp.app');
142
+ let contents = await _support.fs.readFile(newAppPath, 'utf8');
143
+ contents.should.eql('this is not really an app\n');
144
+ });
145
+ it('should download an apk file', async function () {
146
+ let newAppPath = await (0, _helpers.configureApp)(`${serverUrl}/FakeAndroidApp.apk`, '.apk');
147
+ newAppPath.should.contain('.apk');
148
+ let contents = await _support.fs.readFile(newAppPath, 'utf8');
149
+ contents.should.eql('this is not really an apk\n');
150
+ });
151
+ it('should handle zip file that cannot be downloaded', async function () {
152
+ await (0, _helpers.configureApp)(`${serverUrl}/missing/FakeIOSApp.app.zip`, '.app').should.eventually.be.rejected;
153
+ });
154
+ it('should handle invalid protocol', async function () {
155
+ await (0, _helpers.configureApp)('file://C:/missing/FakeIOSApp.app.zip', '.app').should.eventually.be.rejectedWith(/is not supported/);
156
+ await (0, _helpers.configureApp)(`ftp://${_helpers2.TEST_HOST}:${port}/missing/FakeIOSApp.app.zip`, '.app').should.eventually.be.rejectedWith(/is not supported/);
157
+ });
158
+ it('should handle missing file in Windows path format', async function () {
159
+ await (0, _helpers.configureApp)('C:\\missing\\FakeIOSApp.app.zip', '.app').should.eventually.be.rejectedWith(/does not exist or is not accessible/);
160
+ });
161
+ it('should recognize zip mime types and unzip the downloaded file', async function () {
162
+ let newAppPath = await (0, _helpers.configureApp)(`${serverUrl}/FakeAndroidApp.asd?content-type=${encodeURIComponent('application/zip')}`, '.apk');
163
+ newAppPath.should.contain('FakeAndroidApp.apk');
164
+ newAppPath.should.not.contain('.asd');
165
+ let contents = await _support.fs.readFile(newAppPath, 'utf8');
166
+ contents.should.eql('this is not really an apk\n');
167
+ });
168
+ it('should recognize zip mime types with parameter and unzip the downloaded file', async function () {
169
+ let newAppPath = await (0, _helpers.configureApp)(`${serverUrl}/FakeAndroidApp.asd?content-type=${encodeURIComponent('application/zip; parameter=value')}`, '.apk');
170
+ newAppPath.should.contain('FakeAndroidApp.apk');
171
+ newAppPath.should.not.contain('.asd');
172
+ let contents = await _support.fs.readFile(newAppPath, 'utf8');
173
+ contents.should.eql('this is not really an apk\n');
174
+ });
175
+ it('should recognize zip mime types and unzip the downloaded file with query string', async function () {
176
+ let newAppPath = await (0, _helpers.configureApp)(`${serverUrl}/FakeAndroidApp.asd?content-type=${encodeURIComponent('application/zip')}&sv=abc&sr=def`, '.apk');
177
+ newAppPath.should.contain('FakeAndroidApp.apk');
178
+ newAppPath.should.not.contain('.asd');
179
+ let contents = await _support.fs.readFile(newAppPath, 'utf8');
180
+ contents.should.eql('this is not really an apk\n');
181
+ });
182
+ it('should treat an unknown mime type as an app', async function () {
183
+ let newAppPath = await (0, _helpers.configureApp)(`${serverUrl}/FakeAndroidApp.apk?content-type=${encodeURIComponent('application/bip')}`, '.apk');
184
+ newAppPath.should.contain('.apk');
185
+ let contents = await _support.fs.readFile(newAppPath, 'utf8');
186
+ contents.should.eql('this is not really an apk\n');
187
+ });
188
+ });
189
+ });
190
+ });
191
+ });
192
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvZTJlL2Jhc2Vkcml2ZXIvaGVscGVycy5lMmUuc3BlYy5qcyJdLCJuYW1lcyI6WyJnZXRGaXh0dXJlIiwiZmlsZSIsInBhdGgiLCJyZXNvbHZlIiwiX19kaXJuYW1lIiwiZGVzY3JpYmUiLCJpdCIsIm5ld0FwcFBhdGgiLCJzaG91bGQiLCJjb250YWluIiwiY29udGVudHMiLCJmcyIsInJlYWRGaWxlIiwiZXFsIiwiYmUiLCJyZWplY3RlZFdpdGgiLCJwb3J0Iiwic2VydmVyVXJsIiwiYmVmb3JlIiwiVEVTVF9IT1NUIiwiZXZlbnR1YWxseSIsInNlcnZlciIsImRpciIsInNlcnZlIiwiaW5kZXgiLCJzZXRIZWFkZXJzIiwicmVzIiwic2V0SGVhZGVyIiwiaHR0cCIsImNyZWF0ZVNlcnZlciIsInJlcSIsInVybCIsImluZGV4T2YiLCJ3cml0ZUhlYWQiLCJlbmQiLCJjb250ZW50VHlwZSIsIlVSTFNlYXJjaFBhcmFtcyIsInBhcnNlIiwic2VhcmNoIiwiZ2V0IiwiY2xvc2UiLCJiaW5kIiwiQiIsImRlbGF5IiwicmVqZWN0Iiwib24iLCJlcnIiLCJsaXN0ZW4iLCJhZnRlciIsInJlamVjdGVkIiwiZW5jb2RlVVJJQ29tcG9uZW50Iiwibm90Il0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFHQSxTQUFTQSxVQUFULENBQXFCQyxJQUFyQixFQUEyQjtBQUV6QixTQUFPQyxjQUFLQyxPQUFMLENBQWFDLFNBQWIsRUFBd0IsSUFBeEIsRUFBOEIsVUFBOUIsRUFBMENILElBQTFDLENBQVA7QUFDRDs7QUFFREksUUFBUSxDQUFDLGdDQUFELEVBQW1DLFlBQVk7QUFDckRBLEVBQUFBLFFBQVEsQ0FBQyxjQUFELEVBQWlCLFlBQVk7QUFDbkNDLElBQUFBLEVBQUUsQ0FBQyxzQ0FBRCxFQUF5QyxrQkFBa0I7QUFDM0QsVUFBSUMsVUFBVSxH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LENBQVIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB1cmwgZnJvbSAndXJsJztcbmltcG9ydCB7IGZzIH0gZnJvbSAnQGFwcGl1bS9zdXBwb3J0JztcbmltcG9ydCB7IGNvbmZpZ3VyZUFwcCB9IGZyb20gJy4uLy4uLy4uL2xpYi9iYXNlZHJpdmVyL2hlbHBlcnMnO1xuaW1wb3J0IGh0dHAgZnJvbSAnaHR0cCc7XG5pbXBvcnQgZmluYWxoYW5kbGVyIGZyb20gJ2ZpbmFsaGFuZGxlcic7XG5pbXBvcnQgc2VydmVTdGF0aWMgZnJvbSAnc2VydmUtc3RhdGljJztcbmltcG9ydCBjb250ZW50RGlzcG9zaXRpb24gZnJvbSAnY29udGVudC1kaXNwb3NpdGlvbic7XG5pbXBvcnQgQiBmcm9tICdibHVlYmlyZCc7XG5pbXBvcnQgeyBURVNUX0hPU1QsIGdldFRlc3RQb3J0IH0gZnJvbSAnLi4vLi4vaGVscGVycyc7XG5cblxuZnVuY3Rpb24gZ2V0Rml4dHVyZSAoZmlsZSkge1xuICAvLyBYWFg6IF9fZGlybmFtZSBkaXNhbGxvd2VkIGluIG5hdGl2ZSBFU01cbiAgcmV0dXJuIHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuLicsICdmaXh0dXJlcycsIGZpbGUpO1xufVxuXG5kZXNjcmliZSgnYXBwIGRvd25sb2FkIGFuZCBjb25maWd1cmF0aW9uJywgZnVuY3Rpb24gKCkge1xuICBkZXNjcmliZSgnY29uZmlndXJlQXBwJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgZ2V0IHRoZSBwYXRoIGZvciBhIGxvY2FsIC5hcHAnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgbmV3QXBwUGF0aCA9IGF3YWl0IGNvbmZpZ3VyZUFwcChnZXRGaXh0dXJlKCdGYWtlSU9TQXBwLmFwcCcpLCAnLmFwcCcpO1xuICAgICAgbmV3QXBwUGF0aC5zaG91bGQuY29udGFpbignRmFrZUlPU0FwcC5hcHAnKTtcbiAgICAgIGxldCBjb250ZW50cyA9IGF3YWl0IGZzLnJlYWRGaWxlKG5ld0FwcFBhdGgsICd1dGY4Jyk7XG4gICAgICBjb250ZW50cy5zaG91bGQuZXFsKCd0aGlzIGlzIG5vdCByZWFsbHkgYW4gYXBwXFxuJyk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBnZXQgdGhlIHBhdGggZm9yIGEgbG9jYWwgLmFwaycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCBuZXdBcHBQYXRoID0gYXdhaXQgY29uZmlndXJlQXBwKGdldEZpeHR1cmUoJ0Zha2VBbmRyb2lkQXBwLmFwaycpLCAnLmFwaycpO1xuICAgICAgbmV3QXBwUGF0aC5zaG91bGQuY29udGFpbignRmFrZUFuZHJvaWRBcHAuYXBrJyk7XG4gICAgICBsZXQgY29udGVudHMgPSBhd2FpdCBmcy5yZWFkRmlsZShuZXdBcHBQYXRoLCAndXRmOCcpO1xuICAgICAgY29udGVudHMuc2hvdWxkLmVxbCgndGhpcyBpcyBub3QgcmVhbGx5IGFuIGFwa1xcbicpO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgdW56aXAgYW5kIGdldCB0aGUgcGF0aCBmb3IgYSBsb2NhbCAuYXBwLnppcCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCBuZXdBcHBQYXRoID0gYXdhaXQgY29uZmlndXJlQXBwKGdldEZpeHR1cmUoJ0Zha2VJT1NBcHAuYXBwLnppcCcpLCAnLmFwcCcpO1xuICAgICAgbmV3QXBwUGF0aC5zaG91bGQuY29udGFpbignRmFrZUlPU0FwcC5hcHAnKTtcbiAgICAgIGxldCBjb250ZW50cyA9IGF3YWl0IGZzLnJlYWRGaWxlKG5ld0FwcFBhdGgsICd1dGY4Jyk7XG4gICAgICBjb250ZW50cy5zaG91bGQuZXFsKCd0aGlzIGlzIG5vdCByZWFsbHkgYW4gYXBwXFxuJyk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCB1bnppcCBhbmQgZ2V0IHRoZSBwYXRoIGZvciBhIGxvY2FsIC5pcGEnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgbmV3QXBwUGF0aCA9IGF3YWl0IGNvbmZpZ3VyZUFwcChnZXRGaXh0dXJlKCdGYWtlSU9TQXBwLmlwYScpLCAnLmFwcCcpO1xuICAgICAgbmV3QXBwUGF0aC5zaG91bGQuY29udGFpbignRmFrZUlPU0FwcC5hcHAnKTtcbiAgICAgIGxldCBjb250ZW50cyA9IGF3YWl0IGZzLnJlYWRGaWxlKG5ld0FwcFBhdGgsICd1dGY4Jyk7XG4gICAgICBjb250ZW50cy5zaG91bGQuZXFsKCd0aGlzIGlzIG5vdCByZWFsbHkgYW4gYXBwXFxuJyk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBmYWlsIGZvciBhIGJhZCB6aXAgZmlsZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGNvbmZpZ3VyZUFwcChnZXRGaXh0dXJlKCdCYWRaaXBwZWRBcHAuemlwJyksICcuYXBwJylcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL1BLLyk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBmYWlsIGlmIGV4dGVuc2lvbnMgZG8gbm90IG1hdGNoJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgY29uZmlndXJlQXBwKGdldEZpeHR1cmUoJ0Zha2VJT1NBcHAuYXBwJyksICcud3JvbmcnKVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvZGlkIG5vdCBoYXZlIGV4dGVuc2lvbi8pO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgZmFpbCBpZiB6aXAgZmlsZSBkb2VzIG5vdCBjb250YWluIGFuIGFwcCB3aG9zZSBleHRlbnNpb24gbWF0Y2hlcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGNvbmZpZ3VyZUFwcChnZXRGaXh0dXJlKCdGYWtlSU9TQXBwLmFwcC56aXAnKSwgJy53cm9uZycpXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9kaWQgbm90IGhhdmUgZXh0ZW5zaW9uLyk7XG4gICAgfSk7XG4gICAgZGVzY3JpYmUoJ3Nob3VsZCBkb3dubG9hZCBhbiBhcHAgZnJvbSB0aGUgd2ViJywgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IHBvcnQ7XG4gICAgICBsZXQgc2VydmVyVXJsO1xuXG4gICAgICBiZWZvcmUoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBwb3J0ID0gYXdhaXQgZ2V0VGVzdFBvcnQodHJ1ZSk7XG4gICAgICAgIHNlcnZlclVybCA9IGBodHRwOi8vJHtURVNUX0hPU1R9OiR7cG9ydH1gO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCdzZXJ2ZXIgbm90IGF2YWlsYWJsZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgc2VydmVyIG5vdCBhdmFpbGFibGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgYXdhaXQgY29uZmlndXJlQXBwKGAke3NlcnZlclVybH0vRmFrZUlPU0FwcC5hcHAuemlwYCwgJy5hcHAnKVxuICAgICAgICAgICAgLnNob3VsZC5ldmVudHVhbGx5LmJlLnJlamVjdGVkV2l0aCgvRUNPTk5SRUZVU0VELyk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgICBkZXNjcmliZSgnc2VydmVyIGF2YWlsYWJsZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gdXNlIGEgbG9jYWwgc2VydmVyIHNvIHRoZXJlIGlzIG5vIGRlcGVuZGVuY3kgb24gdGhlIGludGVybmV0XG4gICAgICAgIGxldCBzZXJ2ZXI7XG4gICAgICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgZGlyID0gcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4uJywgJ2ZpeHR1cmVzJyk7XG4gICAgICAgICAgY29uc3Qgc2VydmUgPSBzZXJ2ZVN0YXRpYyhkaXIsIHtcbiAgICAgICAgICAgIGluZGV4OiBmYWxzZSxcbiAgICAgICAgICAgIHNldEhlYWRlcnM6IChyZXMsIHBhdGgpID0+IHtcbiAgICAgICAgICAgICAgcmVzLnNldEhlYWRlcignQ29udGVudC1EaXNwb3NpdGlvbicsIGNvbnRlbnREaXNwb3NpdGlvbihwYXRoKSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgc2VydmVyID0gaHR0cC5jcmVhdGVTZXJ2ZXIoZnVuY3Rpb24gKHJlcSwgcmVzKSB7XG4gICAgICAgICAgICBpZiAocmVxLnVybC5pbmRleE9mKCdtaXNzaW5nJykgIT09IC0xKSB7XG4gICAgICAgICAgICAgIHJlcy53cml0ZUhlYWQoNDA0KTtcbiAgICAgICAgICAgICAgcmVzLmVuZCgpO1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBmb3IgdGVzdGluZyB6aXAgZmlsZSBjb250ZW50IHR5cGVzXG4gICAgICAgICAgICBjb25zdCBjb250ZW50VHlwZSA9IG5ldyBVUkxTZWFyY2hQYXJhbXModXJsLnBhcnNlKHJlcS51cmwpLnNlYXJjaCkuZ2V0KCdjb250ZW50LXR5cGUnKTtcbiAgICAgICAgICAgIGlmIChjb250ZW50VHlwZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICByZXMuc2V0SGVhZGVyKCdjb250ZW50LXR5cGUnLCBjb250ZW50VHlwZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzZXJ2ZShyZXEsIHJlcywgZmluYWxoYW5kbGVyKHJlcSwgcmVzKSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgY29uc3QgY2xvc2UgPSBzZXJ2ZXIuY2xvc2UuYmluZChzZXJ2ZXIpO1xuICAgICAgICAgIHNlcnZlci5jbG9zZSA9IGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIC8vIHBhdXNlIGEgbW9tZW50IG9yIHdlIGdldCBFQ09OUkVTRVQgZXJyb3JzXG4gICAgICAgICAgICBhd2FpdCBCLmRlbGF5KDEwMDApO1xuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IG5ldyBCKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgICAgc2VydmVyLm9uKCdjbG9zZScsIHJlc29sdmUpO1xuICAgICAgICAgICAgICBjbG9zZSgoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycikgcmVqZWN0KGVycik7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgY3VybHlcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9O1xuICAgICAgICAgIHNlcnZlci5saXN0ZW4ocG9ydCk7XG4gICAgICAgIH0pO1xuICAgICAgICBhZnRlcihhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgYXdhaXQgc2VydmVyLmNsb3NlKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgZG93bmxvYWQgemlwIGZpbGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgbGV0IG5ld0FwcFBhdGggPSBhd2FpdCBjb25maWd1cmVBcHAoYCR7c2VydmVyVXJsfS9GYWtlSU9TQXBwLmFwcC56aXBgLCAnLmFwcCcpO1xuICAgICAgICAgIG5ld0FwcFBhdGguc2hvdWxkLmNvbnRhaW4oJ0Zha2VJT1NBcHAuYXBwJyk7XG4gICAgICAgICAgbGV0IGNvbnRlbnRzID0gYXdhaXQgZnMucmVhZEZpbGUobmV3QXBwUGF0aCwgJ3V0ZjgnKTtcbiAgICAgICAgICBjb250ZW50cy5zaG91bGQuZXFsKCd0aGlzIGlzIG5vdCByZWFsbHkgYW4gYXBwXFxuJyk7XG4gICAgICAgIH0pO1xuICAgICAgICBpdCgnc2hvdWxkIGRvd25sb2FkIHppcCBmaWxlIHdpdGggcXVlcnkgc3RyaW5nJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGxldCBuZXdBcHBQYXRoID0gYXdhaXQgY29uZmlndXJlQXBwKGAke3NlcnZlclVybH0vRmFrZUlPU0FwcC5hcHAuemlwP3N2PWFiYyZzcj1kZWZgLCAnLmFwcCcpO1xuICAgICAgICAgIG5ld0FwcFBhdGguc2hvdWxkLmNvbnRhaW4oJy5hcHAnKTtcbiAgICAgICAgICBsZXQgY29udGVudHMgPSBhd2FpdCBmcy5yZWFkRmlsZShuZXdBcHBQYXRoLCAndXRmOCcpO1xuICAgICAgICAgIGNvbnRlbnRzLnNob3VsZC5lcWwoJ3RoaXMgaXMgbm90IHJlYWxseSBhbiBhcHBcXG4nKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGl0KCdzaG91bGQgZG93bmxvYWQgYW4gYXBwIGZpbGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgbGV0IG5ld0FwcFBhdGggPSBhd2FpdCBjb25maWd1cmVBcHAoYCR7c2VydmVyVXJsfS9GYWtlSU9TQXBwLmFwcGAsICcuYXBwJyk7XG4gICAgICAgICAgbmV3QXBwUGF0aC5zaG91bGQuY29udGFpbignLmFwcCcpO1xuICAgICAgICAgIGxldCBjb250ZW50cyA9IGF3YWl0IGZzLnJlYWRGaWxlKG5ld0FwcFBhdGgsICd1dGY4Jyk7XG4gICAgICAgICAgY29udGVudHMuc2hvdWxkLmVxbCgndGhpcyBpcyBub3QgcmVhbGx5IGFuIGFwcFxcbicpO1xuICAgICAgICB9KTtcbiAgICAgICAgaXQoJ3Nob3VsZCBhY2NlcHQgbXVsdGlwbGUgZXh0ZW5zaW9ucycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBsZXQgbmV3QXBwUGF0aCA9IGF3YWl0IGNvbmZpZ3VyZUFwcChgJHtzZXJ2ZXJVcmx9L0Zha2VJT1NBcHAuYXBwLnppcGAsIFsnLmFwcCcsICcuYWFiJ10pO1xuICAgICAgICAgIG5ld0FwcFBhdGguc2hvdWxkLmNvbnRhaW4oJ0Zha2VJT1NBcHAuYXBwJyk7XG4gICAgICAgICAgbGV0IGNvbnRlbnRzID0gYXdhaXQgZnMucmVhZEZpbGUobmV3QXBwUGF0aCwgJ3V0ZjgnKTtcbiAgICAgICAgICBjb250ZW50cy5zaG91bGQuZXFsKCd0aGlzIGlzIG5vdCByZWFsbHkgYW4gYXBwXFxuJyk7XG4gICAgICAgIH0pO1xuICAgICAgICBpdCgnc2hvdWxkIGRvd25sb2FkIGFuIGFwayBmaWxlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGxldCBuZXdBcHBQYXRoID0gYXdhaXQgY29uZmlndXJlQXBwKGAke3NlcnZlclVybH0vRmFrZUFuZHJvaWRBcHAuYXBrYCwgJy5hcGsnKTtcbiAgICAgICAgICBuZXdBcHBQYXRoLnNob3VsZC5jb250YWluKCcuYXBrJyk7XG4gICAgICAgICAgbGV0IGNvbnRlbnRzID0gYXdhaXQgZnMucmVhZEZpbGUobmV3QXBwUGF0aCwgJ3V0ZjgnKTtcbiAgICAgICAgICBjb250ZW50cy5zaG91bGQuZXFsKCd0aGlzIGlzIG5vdCByZWFsbHkgYW4gYXBrXFxuJyk7XG4gICAgICAgIH0pO1xuICAgICAgICBpdCgnc2hvdWxkIGhhbmRsZSB6aXAgZmlsZSB0aGF0IGNhbm5vdCBiZSBkb3dubG9hZGVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGF3YWl0IGNvbmZpZ3VyZUFwcChgJHtzZXJ2ZXJVcmx9L21pc3NpbmcvRmFrZUlPU0FwcC5hcHAuemlwYCwgJy5hcHAnKVxuICAgICAgICAgICAgLnNob3VsZC5ldmVudHVhbGx5LmJlLnJlamVjdGVkO1xuICAgICAgICB9KTtcbiAgICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgaW52YWxpZCBwcm90b2NvbCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBhd2FpdCBjb25maWd1cmVBcHAoJ2ZpbGU6Ly9DOi9taXNzaW5nL0Zha2VJT1NBcHAuYXBwLnppcCcsICcuYXBwJylcbiAgICAgICAgICAgIC5zaG91bGQuZXZlbnR1YWxseS5iZS5yZWplY3RlZFdpdGgoL2lzIG5vdCBzdXBwb3J0ZWQvKTtcbiAgICAgICAgICBhd2FpdCBjb25maWd1cmVBcHAoYGZ0cDovLyR7VEVTVF9IT1NUfToke3BvcnR9L21pc3NpbmcvRmFrZUlPU0FwcC5hcHAuemlwYCwgJy5hcHAnKVxuICAgICAgICAgICAgLnNob3VsZC5ldmVudHVhbGx5LmJlLnJlamVjdGVkV2l0aCgvaXMgbm90IHN1cHBvcnRlZC8pO1xuICAgICAgICB9KTtcbiAgICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgbWlzc2luZyBmaWxlIGluIFdpbmRvd3MgcGF0aCBmb3JtYXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgYXdhaXQgY29uZmlndXJlQXBwKCdDOlxcXFxtaXNzaW5nXFxcXEZha2VJT1NBcHAuYXBwLnppcCcsICcuYXBwJylcbiAgICAgICAgICAgIC5zaG91bGQuZXZlbnR1YWxseS5iZS5yZWplY3RlZFdpdGgoL2RvZXMgbm90IGV4aXN0IG9yIGlzIG5vdCBhY2Nlc3NpYmxlLyk7XG4gICAgICAgIH0pO1xuICAgICAgICBpdCgnc2hvdWxkIHJlY29nbml6ZSB6aXAgbWltZSB0eXBlcyBhbmQgdW56aXAgdGhlIGRvd25sb2FkZWQgZmlsZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBsZXQgbmV3QXBwUGF0aCA9IGF3YWl0IGNvbmZpZ3VyZUFwcChgJHtzZXJ2ZXJVcmx9L0Zha2VBbmRyb2lkQXBwLmFzZD9jb250ZW50LXR5cGU9JHtlbmNvZGVVUklDb21wb25lbnQoJ2FwcGxpY2F0aW9uL3ppcCcpfWAsICcuYXBrJyk7XG4gICAgICAgICAgbmV3QXBwUGF0aC5zaG91bGQuY29udGFpbignRmFrZUFuZHJvaWRBcHAuYXBrJyk7XG4gICAgICAgICAgbmV3QXBwUGF0aC5zaG91bGQubm90LmNvbnRhaW4oJy5hc2QnKTtcbiAgICAgICAgICBsZXQgY29udGVudHMgPSBhd2FpdCBmcy5yZWFkRmlsZShuZXdBcHBQYXRoLCAndXRmOCcpO1xuICAgICAgICAgIGNvbnRlbnRzLnNob3VsZC5lcWwoJ3RoaXMgaXMgbm90IHJlYWxseSBhbiBhcGtcXG4nKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGl0KCdzaG91bGQgcmVjb2duaXplIHppcCBtaW1lIHR5cGVzIHdpdGggcGFyYW1ldGVyIGFuZCB1bnppcCB0aGUgZG93bmxvYWRlZCBmaWxlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGxldCBuZXdBcHBQYXRoID0gYXdhaXQgY29uZmlndXJlQXBwKGAke3NlcnZlclVybH0vRmFrZUFuZHJvaWRBcHAuYXNkP2NvbnRlbnQtdHlwZT0ke2VuY29kZVVSSUNvbXBvbmVudCgnYXBwbGljYXRpb24vemlwOyBwYXJhbWV0ZXI9dmFsdWUnKX1gLCAnLmFwaycpO1xuICAgICAgICAgIG5ld0FwcFBhdGguc2hvdWxkLmNvbnRhaW4oJ0Zha2VBbmRyb2lkQXBwLmFwaycpO1xuICAgICAgICAgIG5ld0FwcFBhdGguc2hvdWxkLm5vdC5jb250YWluKCcuYXNkJyk7XG4gICAgICAgICAgbGV0IGNvbnRlbnRzID0gYXdhaXQgZnMucmVhZEZpbGUobmV3QXBwUGF0aCwgJ3V0ZjgnKTtcbiAgICAgICAgICBjb250ZW50cy5zaG91bGQuZXFsKCd0aGlzIGlzIG5vdCByZWFsbHkgYW4gYXBrXFxuJyk7XG4gICAgICAgIH0pO1xuICAgICAgICBpdCgnc2hvdWxkIHJlY29nbml6ZSB6aXAgbWltZSB0eXBlcyBhbmQgdW56aXAgdGhlIGRvd25sb2FkZWQgZmlsZSB3aXRoIHF1ZXJ5IHN0cmluZycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBsZXQgbmV3QXBwUGF0aCA9IGF3YWl0IGNvbmZpZ3VyZUFwcChgJHtzZXJ2ZXJVcmx9L0Zha2VBbmRyb2lkQXBwLmFzZD9jb250ZW50LXR5cGU9JHtlbmNvZGVVUklDb21wb25lbnQoJ2FwcGxpY2F0aW9uL3ppcCcpfSZzdj1hYmMmc3I9ZGVmYCwgJy5hcGsnKTtcbiAgICAgICAgICBuZXdBcHBQYXRoLnNob3VsZC5jb250YWluKCdGYWtlQW5kcm9pZEFwcC5hcGsnKTtcbiAgICAgICAgICBuZXdBcHBQYXRoLnNob3VsZC5ub3QuY29udGFpbignLmFzZCcpO1xuICAgICAgICAgIGxldCBjb250ZW50cyA9IGF3YWl0IGZzLnJlYWRGaWxlKG5ld0FwcFBhdGgsICd1dGY4Jyk7XG4gICAgICAgICAgY29udGVudHMuc2hvdWxkLmVxbCgndGhpcyBpcyBub3QgcmVhbGx5IGFuIGFwa1xcbicpO1xuICAgICAgICB9KTtcbiAgICAgICAgaXQoJ3Nob3VsZCB0cmVhdCBhbiB1bmtub3duIG1pbWUgdHlwZSBhcyBhbiBhcHAnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgbGV0IG5ld0FwcFBhdGggPSBhd2FpdCBjb25maWd1cmVBcHAoYCR7c2VydmVyVXJsfS9GYWtlQW5kcm9pZEFwcC5hcGs/Y29udGVudC10eXBlPSR7ZW5jb2RlVVJJQ29tcG9uZW50KCdhcHBsaWNhdGlvbi9iaXAnKX1gLCAnLmFwaycpO1xuICAgICAgICAgIG5ld0FwcFBhdGguc2hvdWxkLmNvbnRhaW4oJy5hcGsnKTtcbiAgICAgICAgICBsZXQgY29udGVudHMgPSBhd2FpdCBmcy5yZWFkRmlsZShuZXdBcHBQYXRoLCAndXRmOCcpO1xuICAgICAgICAgIGNvbnRlbnRzLnNob3VsZC5lcWwoJ3RoaXMgaXMgbm90IHJlYWxseSBhbiBhcGtcXG4nKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==
@@ -0,0 +1,82 @@
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 _lib = require("../../../lib");
10
+
11
+ var _fakeDriver = require("../protocol/fake-driver");
12
+
13
+ var _ws = _interopRequireDefault(require("ws"));
14
+
15
+ var _bluebird = _interopRequireDefault(require("bluebird"));
16
+
17
+ var _helpers = require("../../helpers");
18
+
19
+ describe('Websockets (e2e)', function () {
20
+ let baseServer;
21
+ let driver;
22
+ let port;
23
+ const SESSION_ID = 'foo';
24
+ const WS_DATA = 'Hello';
25
+ before(async function () {
26
+ driver = new _fakeDriver.FakeDriver();
27
+ driver.sessionId = SESSION_ID;
28
+ port = await (0, _helpers.getTestPort)();
29
+ baseServer = await (0, _lib.server)({
30
+ routeConfiguringFunction: (0, _lib.routeConfiguringFunction)(driver),
31
+ port
32
+ });
33
+ });
34
+ after(async function () {
35
+ await baseServer.close();
36
+ });
37
+ describe('web sockets support', function () {
38
+ it('should be able to add websocket handler and remove it', async function () {
39
+ const wss = new _ws.default.Server({
40
+ noServer: true
41
+ });
42
+ wss.on('connection', ws => {
43
+ if (ws && ws.readyState === _ws.default.OPEN) {
44
+ ws.send(WS_DATA);
45
+ }
46
+ });
47
+ const previousListenerCount = baseServer.listenerCount('upgrade');
48
+ const endpoint = `${_lib.DEFAULT_WS_PATHNAME_PREFIX}/hello`;
49
+ const timeout = 5000;
50
+ await baseServer.addWebSocketHandler(endpoint, wss);
51
+ baseServer.listenerCount('upgrade').should.be.above(previousListenerCount);
52
+
53
+ _lodash.default.keys(await baseServer.getWebSocketHandlers()).length.should.eql(1);
54
+
55
+ await new _bluebird.default((resolve, reject) => {
56
+ const client = new _ws.default(`ws://${_helpers.TEST_HOST}:${port}${endpoint}`);
57
+ client.on('connection', (ws, req) => {
58
+ ws.should.not.be.empty;
59
+ req.connection.remoteAddress.should.not.be.empty;
60
+ });
61
+ client.on('message', data => {
62
+ data.should.eql(WS_DATA);
63
+ resolve();
64
+ });
65
+ client.on('error', reject);
66
+ setTimeout(() => reject(new Error('No websocket messages have been received after the timeout')), timeout);
67
+ });
68
+ (await baseServer.removeWebSocketHandler(endpoint)).should.be.true;
69
+
70
+ _lodash.default.keys(await baseServer.getWebSocketHandlers()).length.should.eql(0);
71
+
72
+ await new _bluebird.default((resolve, reject) => {
73
+ const client = new _ws.default(`ws://${_helpers.TEST_HOST}:${port}${endpoint}`);
74
+ client.on('message', data => reject(new Error(`No websocket messages are expected after the handler ` + `has been removed. '${data}' is received instead. `)));
75
+ client.on('error', resolve);
76
+ setTimeout(resolve, timeout);
77
+ });
78
+ baseServer.listenerCount('upgrade').should.be.above(previousListenerCount);
79
+ });
80
+ });
81
+ });
82
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvZTJlL2Jhc2Vkcml2ZXIvd2Vic29ja2V0cy5lMmUuc3BlYy5qcyJdLCJuYW1lcyI6WyJkZXNjcmliZSIsImJhc2VTZXJ2ZXIiLCJkcml2ZXIiLCJwb3J0IiwiU0VTU0lPTl9JRCIsIldTX0RBVEEiLCJiZWZvcmUiLCJGYWtlRHJpdmVyIiwic2Vzc2lvbklkIiwicm91dGVDb25maWd1cmluZ0Z1bmN0aW9uIiwiYWZ0ZXIiLCJjbG9zZSIsIml0Iiwid3NzIiwiV2ViU29ja2V0IiwiU2VydmVyIiwibm9TZXJ2ZXIiLCJvbiIsIndzIiwicmVhZHlTdGF0ZSIsIk9QRU4iLCJzZW5kIiwicHJldmlvdXNMaXN0ZW5lckNvdW50IiwibGlzdGVuZXJDb3VudCIsImVuZHBvaW50IiwiREVGQVVMVF9XU19QQVRITkFNRV9QUkVGSVgiLCJ0aW1lb3V0IiwiYWRkV2ViU29ja2V0SGFuZGxlciIsInNob3VsZCIsImJlIiwiYWJvdmUiLCJfIiwia2V5cyIsImdldFdlYlNvY2tldEhhbmRsZXJzIiwibGVuZ3RoIiwiZXFsIiwiQiIsInJlc29sdmUiLCJyZWplY3QiLCJjbGllbnQiLCJURVNUX0hPU1QiLCJyZXEiLCJub3QiLCJlbXB0eSIsImNvbm5lY3Rpb24iLCJyZW1vdGVBZGRyZXNzIiwiZGF0YSIsInNldFRpbWVvdXQiLCJFcnJvciIsInJlbW92ZVdlYlNvY2tldEhhbmRsZXIiLCJ0cnVlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQTs7QUFDQTs7QUFFQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFHQUEsUUFBUSxDQUFDLGtCQUFELEVBQXFCLFlBQVk7QUFDdkMsTUFBSUMsVUFBSjtBQUNBLE1BQUlDLE1BQUo7QUFDQSxNQUFJQyxJQUFKO0FBQ0EsUUFBTUMsVUFBVSxHQUFHLEtBQW5CO0FBQ0EsUUFBTUMsT0FBTyxHQUFHLE9BQWhCO0FBRUFDLEVBQUFBLE1BQU0sQ0FBQyxrQkFBa0I7QUFDdkJKLElBQUFBLE1BQU0sR0FBRyxJQUFJSyxzQkFB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LENBQU8sTUFBTS9CLFVBQVUsQ0FBQ2dDLG9CQUFYLEVBQWIsRUFBZ0RDLE1BQWhELENBQXVETixNQUF2RCxDQUE4RE8sR0FBOUQsQ0FBa0UsQ0FBbEU7O0FBQ0EsWUFBTSxJQUFJQyxpQkFBSixDQUFNLENBQUNDLE9BQUQsRUFBVUMsTUFBVixLQUFxQjtBQUMvQixjQUFNQyxNQUFNLEdBQUcsSUFBSXpCLFdBQUosQ0FBZSxRQUFPMEIsa0JBQVUsSUFBR3JDLElBQUssR0FBRXFCLFFBQVMsRUFBbkQsQ0FBZjtBQUNBZSxRQUFBQSxNQUFNLENBQUN0QixFQUFQLENBQVUsU0FBVixFQUFzQjZCLElBQUQsSUFDbkJSLE1BQU0sQ0FBQyxJQUFJVSxLQUFKLENBQVcsdURBQUQsR0FDQyxzQkFBcUJGLElBQUsseUJBRHJDLENBQUQsQ0FEUjtBQUlBUCxRQUFBQSxNQUFNLENBQUN0QixFQUFQLENBQVUsT0FBVixFQUFtQm9CLE9BQW5CO0FBQ0FVLFFBQUFBLFVBQVUsQ0FBQ1YsT0FBRCxFQUFVWCxPQUFWLENBQVY7QUFDRCxPQVJLLENBQU47QUFTQXpCLE1BQUFBLFVBQVUsQ0FBQ3NCLGFBQVgsQ0FBeUIsU0FBekIsRUFBb0NLLE1BQXBDLENBQTJDQyxFQUEzQyxDQUE4Q0MsS0FBOUMsQ0FBb0RSLHFCQUFwRDtBQUNELEtBMUNDLENBQUY7QUEyQ0QsR0E1Q08sQ0FBUjtBQTZDRCxDQWpFTyxDQUFSIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IHNlcnZlciwgcm91dGVDb25maWd1cmluZ0Z1bmN0aW9uLFxuICAgICAgICAgREVGQVVMVF9XU19QQVRITkFNRV9QUkVGSVggfSBmcm9tICcuLi8uLi8uLi9saWInO1xuaW1wb3J0IHsgRmFrZURyaXZlciB9IGZyb20gJy4uL3Byb3RvY29sL2Zha2UtZHJpdmVyJztcbmltcG9ydCBXZWJTb2NrZXQgZnJvbSAnd3MnO1xuaW1wb3J0IEIgZnJvbSAnYmx1ZWJpcmQnO1xuaW1wb3J0IHtURVNUX0hPU1QsIGdldFRlc3RQb3J0fSBmcm9tICcuLi8uLi9oZWxwZXJzJztcblxuXG5kZXNjcmliZSgnV2Vic29ja2V0cyAoZTJlKScsIGZ1bmN0aW9uICgpIHtcbiAgbGV0IGJhc2VTZXJ2ZXI7XG4gIGxldCBkcml2ZXI7XG4gIGxldCBwb3J0O1xuICBjb25zdCBTRVNTSU9OX0lEID0gJ2Zvbyc7XG4gIGNvbnN0IFdTX0RBVEEgPSAnSGVsbG8nO1xuXG4gIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgZHJpdmVyID0gbmV3IEZha2VEcml2ZXIoKTtcbiAgICBkcml2ZXIuc2Vzc2lvbklkID0gU0VTU0lPTl9JRDtcbiAgICBwb3J0ID0gYXdhaXQgZ2V0VGVzdFBvcnQoKTtcbiAgICBiYXNlU2VydmVyID0gYXdhaXQgc2VydmVyKHtcbiAgICAgIHJvdXRlQ29uZmlndXJpbmdGdW5jdGlvbjogcm91dGVDb25maWd1cmluZ0Z1bmN0aW9uKGRyaXZlciksXG4gICAgICBwb3J0LFxuICAgIH0pO1xuICB9KTtcbiAgYWZ0ZXIoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGF3YWl0IGJhc2VTZXJ2ZXIuY2xvc2UoKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3dlYiBzb2NrZXRzIHN1cHBvcnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBiZSBhYmxlIHRvIGFkZCB3ZWJzb2NrZXQgaGFuZGxlciBhbmQgcmVtb3ZlIGl0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd3NzID0gbmV3IFdlYlNvY2tldC5TZXJ2ZXIoe1xuICAgICAgICBub1NlcnZlcjogdHJ1ZSxcbiAgICAgIH0pO1xuICAgICAgd3NzLm9uKCdjb25uZWN0aW9uJywgKHdzKSA9PiB7XG4gICAgICAgIGlmICh3cyAmJiB3cy5yZWFkeVN0YXRlID09PSBXZWJTb2NrZXQuT1BFTikge1xuICAgICAgICAgIHdzLnNlbmQoV1NfREFUQSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgY29uc3QgcHJldmlvdXNMaXN0ZW5lckNvdW50ID0gYmFzZVNlcnZlci5saXN0ZW5lckNvdW50KCd1cGdyYWRlJyk7XG4gICAgICBjb25zdCBlbmRwb2ludCA9IGAke0RFRkFVTFRfV1NfUEFUSE5BTUVfUFJFRklYfS9oZWxsb2A7XG4gICAgICBjb25zdCB0aW1lb3V0ID0gNTAwMDtcbiAgICAgIGF3YWl0IGJhc2VTZXJ2ZXIuYWRkV2ViU29ja2V0SGFuZGxlcihlbmRwb2ludCwgd3NzKTtcbiAgICAgIGJhc2VTZXJ2ZXIubGlzdGVuZXJDb3VudCgndXBncmFkZScpLnNob3VsZC5iZS5hYm92ZShwcmV2aW91c0xpc3RlbmVyQ291bnQpO1xuICAgICAgXy5rZXlzKGF3YWl0IGJhc2VTZXJ2ZXIuZ2V0V2ViU29ja2V0SGFuZGxlcnMoKSkubGVuZ3RoLnNob3VsZC5lcWwoMSk7XG4gICAgICBhd2FpdCBuZXcgQigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGNvbnN0IGNsaWVudCA9IG5ldyBXZWJTb2NrZXQoYHdzOi8vJHtURVNUX0hPU1R9OiR7cG9ydH0ke2VuZHBvaW50fWApO1xuICAgICAgICBjbGllbnQub24oJ2Nvbm5lY3Rpb24nLCAod3MsIHJlcSkgPT4ge1xuICAgICAgICAgIHdzLnNob3VsZC5ub3QuYmUuZW1wdHk7XG4gICAgICAgICAgcmVxLmNvbm5lY3Rpb24ucmVtb3RlQWRkcmVzcy5zaG91bGQubm90LmJlLmVtcHR5O1xuICAgICAgICB9KTtcbiAgICAgICAgY2xpZW50Lm9uKCdtZXNzYWdlJywgKGRhdGEpID0+IHtcbiAgICAgICAgICBkYXRhLnNob3VsZC5lcWwoV1NfREFUQSk7XG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9KTtcbiAgICAgICAgY2xpZW50Lm9uKCdlcnJvcicsIHJlamVjdCk7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4gcmVqZWN0KG5ldyBFcnJvcignTm8gd2Vic29ja2V0IG1lc3NhZ2VzIGhhdmUgYmVlbiByZWNlaXZlZCBhZnRlciB0aGUgdGltZW91dCcpKSxcbiAgICAgICAgICAgICAgICAgICB0aW1lb3V0KTtcbiAgICAgIH0pO1xuXG4gICAgICAoYXdhaXQgYmFzZVNlcnZlci5yZW1vdmVXZWJTb2NrZXRIYW5kbGVyKGVuZHBvaW50KSkuc2hvdWxkLmJlLnRydWU7XG4gICAgICBfLmtleXMoYXdhaXQgYmFzZVNlcnZlci5nZXRXZWJTb2NrZXRIYW5kbGVycygpKS5sZW5ndGguc2hvdWxkLmVxbCgwKTtcbiAgICAgIGF3YWl0IG5ldyBCKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gbmV3IFdlYlNvY2tldChgd3M6Ly8ke1RFU1RfSE9TVH06JHtwb3J0fSR7ZW5kcG9pbnR9YCk7XG4gICAgICAgIGNsaWVudC5vbignbWVzc2FnZScsIChkYXRhKSA9PlxuICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoYE5vIHdlYnNvY2tldCBtZXNzYWdlcyBhcmUgZXhwZWN0ZWQgYWZ0ZXIgdGhlIGhhbmRsZXIgYCArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBgaGFzIGJlZW4gcmVtb3ZlZC4gJyR7ZGF0YX0nIGlzIHJlY2VpdmVkIGluc3RlYWQuIGApKVxuICAgICAgICApO1xuICAgICAgICBjbGllbnQub24oJ2Vycm9yJywgcmVzb2x2ZSk7XG4gICAgICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgdGltZW91dCk7XG4gICAgICB9KTtcbiAgICAgIGJhc2VTZXJ2ZXIubGlzdGVuZXJDb3VudCgndXBncmFkZScpLnNob3VsZC5iZS5hYm92ZShwcmV2aW91c0xpc3RlbmVyQ291bnQpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19
@@ -0,0 +1,159 @@
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 _axios = _interopRequireDefault(require("axios"));
10
+
11
+ var _sinon = require("sinon");
12
+
13
+ var _bluebird = _interopRequireDefault(require("bluebird"));
14
+
15
+ var _lodash = _interopRequireDefault(require("lodash"));
16
+
17
+ var _helpers = require("../../helpers");
18
+
19
+ describe('server', function () {
20
+ let hwServer;
21
+ let port;
22
+ let sandbox;
23
+ before(async function () {
24
+ port = await (0, _helpers.getTestPort)(true);
25
+
26
+ function configureRoutes(app) {
27
+ app.get('/', (req, res) => {
28
+ res.header['content-type'] = 'text/html';
29
+ res.status(200).send('Hello World!');
30
+ });
31
+ app.get('/python', (req, res) => {
32
+ res.status(200).send(req.headers['content-type']);
33
+ });
34
+ app.get('/error', () => {
35
+ throw new Error('hahaha');
36
+ });
37
+ app.get('/pause', async (req, res) => {
38
+ res.header['content-type'] = 'text/html';
39
+ await _bluebird.default.delay(1000);
40
+ res.status(200).send('We have waited!');
41
+ });
42
+ }
43
+
44
+ hwServer = await (0, _lib.server)({
45
+ routeConfiguringFunction: configureRoutes,
46
+ port
47
+ });
48
+ });
49
+ beforeEach(function () {
50
+ sandbox = (0, _sinon.createSandbox)();
51
+ sandbox.stub(console, 'error');
52
+ });
53
+ after(async function () {
54
+ await hwServer.close();
55
+ });
56
+ afterEach(function () {
57
+ sandbox.restore();
58
+ });
59
+ it('should start up with our middleware', async function () {
60
+ const {
61
+ data
62
+ } = await _axios.default.get(`http://${_helpers.TEST_HOST}:${port}/`);
63
+ data.should.eql('Hello World!');
64
+ });
65
+ it('should fix broken context type', async function () {
66
+ const {
67
+ data
68
+ } = await (0, _axios.default)({
69
+ url: `http://${_helpers.TEST_HOST}:${port}/python`,
70
+ headers: {
71
+ 'user-agent': 'Python',
72
+ 'content-type': 'application/x-www-form-urlencoded'
73
+ }
74
+ });
75
+ data.should.eql('application/json; charset=utf-8');
76
+ });
77
+ it('should catch errors in the catchall', async function () {
78
+ await _axios.default.get(`http://${_helpers.TEST_HOST}:${port}/error`).should.be.rejected;
79
+ });
80
+ it('should error if we try to start again on a port that is used', async function () {
81
+ await (0, _lib.server)({
82
+ routeConfiguringFunction() {},
83
+
84
+ port
85
+ }).should.be.rejectedWith(/EADDRINUSE/);
86
+ });
87
+ it('should not wait for the server close connections before finishing closing', async function () {
88
+ let bodyPromise = _axios.default.get(`http://${_helpers.TEST_HOST}:${port}/pause`).catch(() => {});
89
+
90
+ await _bluebird.default.delay(100);
91
+ let before = Date.now();
92
+ await hwServer.close();
93
+ (Date.now() - before).should.not.be.above(800);
94
+ await bodyPromise;
95
+ });
96
+ it('should error if we try to start on a bad hostname', async function () {
97
+ this.timeout(60000);
98
+ await (0, _lib.server)({
99
+ routeConfiguringFunction: _lodash.default.noop,
100
+ port,
101
+ hostname: 'lolcathost'
102
+ }).should.be.rejectedWith(/ENOTFOUND|EADDRNOTAVAIL|EAI_AGAIN/);
103
+ await (0, _lib.server)({
104
+ routeConfiguringFunction: _lodash.default.noop,
105
+ port,
106
+ hostname: '1.1.1.1'
107
+ }).should.be.rejectedWith(/EADDRNOTAVAIL/);
108
+ });
109
+ });
110
+ describe('server plugins', function () {
111
+ let hwServer;
112
+ let port;
113
+ before(async function () {
114
+ port = await (0, _helpers.getTestPort)(true);
115
+ });
116
+ afterEach(async function () {
117
+ try {
118
+ await hwServer.close();
119
+ } catch (ign) {}
120
+ });
121
+
122
+ function updaterWithGetRoute(route, reply) {
123
+ return async (app, httpServer) => {
124
+ app.get(`/${route}`, (req, res) => {
125
+ res.header['content-type'] = 'text/html';
126
+ res.status(200).send(reply);
127
+ });
128
+ httpServer[`_updated_${route}`] = true;
129
+ };
130
+ }
131
+
132
+ it('should allow one or more plugins to update the server', async function () {
133
+ hwServer = await (0, _lib.server)({
134
+ routeConfiguringFunction: _lodash.default.noop,
135
+ port,
136
+ serverUpdaters: [updaterWithGetRoute('plugin1', 'res from plugin1 route'), updaterWithGetRoute('plugin2', 'res from plugin2 route')]
137
+ });
138
+ let {
139
+ data
140
+ } = await _axios.default.get(`http://${_helpers.TEST_HOST}:${port}/plugin1`);
141
+ data.should.eql('res from plugin1 route');
142
+ ({
143
+ data
144
+ } = await _axios.default.get(`http://${_helpers.TEST_HOST}:${port}/plugin2`));
145
+ data.should.eql('res from plugin2 route');
146
+ hwServer._updated_plugin1.should.be.true;
147
+ hwServer._updated_plugin2.should.be.true;
148
+ });
149
+ it('should pass on errors from the plugin updateServer method', async function () {
150
+ await (0, _lib.server)({
151
+ routeConfiguringFunction: _lodash.default.noop,
152
+ port,
153
+ serverUpdaters: [() => {
154
+ throw new Error('ugh');
155
+ }]
156
+ }).should.eventually.be.rejectedWith(/ugh/);
157
+ });
158
+ });
159
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvZTJlL2V4cHJlc3Mvc2VydmVyLmUyZS5zcGVjLmpzIl0sIm5hbWVzIjpbImRlc2NyaWJlIiwiaHdTZXJ2ZXIiLCJwb3J0Iiwic2FuZGJveCIsImJlZm9yZSIsImNvbmZpZ3VyZVJvdXRlcyIsImFwcCIsImdldCIsInJlcSIsInJlcyIsImhlYWRlciIsInN0YXR1cyIsInNlbmQiLCJoZWFkZXJzIiwiRXJyb3IiLCJCIiwiZGVsYXkiLCJyb3V0ZUNvbmZpZ3VyaW5nRnVuY3Rpb24iLCJiZWZvcmVFYWNoIiwic3R1YiIsImNvbnNvbGUiLCJhZnRlciIsImNsb3NlIiwiYWZ0ZXJFYWNoIiwicmVzdG9yZSIsIml0IiwiZGF0YSIsImF4aW9zIiwiVEVTVF9IT1NUIiwic2hvdWxkIiwiZXFsIiwidXJsIiwiYmUiLCJyZWplY3RlZCIsInJlamVjdGVkV2l0aCIsImJvZHlQcm9taXNlIiwiY2F0Y2giLCJEYXRlIiwibm93Iiwibm90IiwiYWJvdmUiLCJ0aW1lb3V0IiwiXyIsIm5vb3AiLCJob3N0bmFtZSIsImlnbiIsInVwZGF0ZXJXaXRoR2V0Um91dGUiLCJyb3V0ZSIsInJlcGx5IiwiaHR0cFNlcnZlciIsInNlcnZlclVwZGF0ZXJzIiwiX3VwZGF0ZWRfcGx1Z2luMSIsInRydWUiLCJfdXBkYXRlZF9wbHVnaW4yIiwiZXZlbnR1YWxseSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBR0FBLFFBQVEsQ0FBQyxRQUFELEVBQVcsWUFBWTtBQUM3QixNQUFJQyxRQUFKO0FBQ0EsTUFBSUMsSUFBSjtBQUNBLE1BQUlDLE9BQUo7QUFDQUMsRUFBQUEsTUFBTSxDQUFDLGtCQUFrQjtBQUN2QkYsSUFBQUEsSUFBSSxHQUFHLE1BQU0sMEJBQVksSUFBWixDQUFiOztBQUVBLGFBQVNHLGVBQVQsQ0FBMEJDLEdBQTFCLEVBQStCO0FBQzdCQSxNQUFBQSxHQUFHLENBQUNDLEdBQUosQ0FBUSxH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QUFQLENBQWpCO0FBUUEsUUFBSTtBQUFDcEIsTUFBQUE7QUFBRCxRQUFTLE1BQU1DLGVBQU1wQixHQUFOLENBQVcsVUFBU3FCLGtCQUFVLElBQUcxQixJQUFLLFVBQXRDLENBQW5CO0FBQ0F3QixJQUFBQSxJQUFJLENBQUNHLE1BQUwsQ0FBWUMsR0FBWixDQUFnQix3QkFBaEI7QUFDQSxLQUFDO0FBQUNKLE1BQUFBO0FBQUQsUUFBUyxNQUFNQyxlQUFNcEIsR0FBTixDQUFXLFVBQVNxQixrQkFBVSxJQUFHMUIsSUFBSyxVQUF0QyxDQUFoQjtBQUNBd0IsSUFBQUEsSUFBSSxDQUFDRyxNQUFMLENBQVlDLEdBQVosQ0FBZ0Isd0JBQWhCO0FBQ0E3QixJQUFBQSxRQUFRLENBQUNrRCxnQkFBVCxDQUEwQnRCLE1BQTFCLENBQWlDRyxFQUFqQyxDQUFvQ29CLElBQXBDO0FBQ0FuRCxJQUFBQSxRQUFRLENBQUNvRCxnQkFBVCxDQUEwQnhCLE1BQTFCLENBQWlDRyxFQUFqQyxDQUFvQ29CLElBQXBDO0FBQ0QsR0FmQyxDQUFGO0FBZ0JBM0IsRUFBQUEsRUFBRSxDQUFDLDJEQUFELEVBQThELGtCQUFrQjtBQUNoRixVQUFNLGlCQUFPO0FBQ1hSLE1BQUFBLHdCQUF3QixFQUFFeUIsZ0JBQUVDLElBRGpCO0FBRVh6QyxNQUFBQSxJQUZXO0FBR1hnRCxNQUFBQSxjQUFjLEVBQUUsQ0FBQyxNQUFNO0FBQUUsY0FBTSxJQUFJcEMsS0FBSixDQUFVLEtBQVYsQ0FBTjtBQUF3QixPQUFqQztBQUhMLEtBQVAsRUFJSGUsTUFKRyxDQUlJeUIsVUFKSixDQUlldEIsRUFKZixDQUlrQkUsWUFKbEIsQ0FJK0IsS0FKL0IsQ0FBTjtBQUtELEdBTkMsQ0FBRjtBQU9ELENBL0NPLENBQVIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyB0cmFuc3BpbGU6bW9jaGFcblxuaW1wb3J0IHsgc2VydmVyIH0gZnJvbSAnLi4vLi4vLi4vbGliJztcbmltcG9ydCBheGlvcyBmcm9tICdheGlvcyc7XG5pbXBvcnQgeyBjcmVhdGVTYW5kYm94IH0gZnJvbSAnc2lub24nO1xuaW1wb3J0IEIgZnJvbSAnYmx1ZWJpcmQnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7VEVTVF9IT1NULCBnZXRUZXN0UG9ydH0gZnJvbSAnLi4vLi4vaGVscGVycyc7XG5cblxuZGVzY3JpYmUoJ3NlcnZlcicsIGZ1bmN0aW9uICgpIHtcbiAgbGV0IGh3U2VydmVyO1xuICBsZXQgcG9ydDtcbiAgbGV0IHNhbmRib3g7XG4gIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgcG9ydCA9IGF3YWl0IGdldFRlc3RQb3J0KHRydWUpO1xuXG4gICAgZnVuY3Rpb24gY29uZmlndXJlUm91dGVzIChhcHApIHtcbiAgICAgIGFwcC5nZXQoJy8nLCAocmVxLCByZXMpID0+IHtcbiAgICAgICAgcmVzLmhlYWRlclsnY29udGVudC10eXBlJ10gPSAndGV4dC9odG1sJztcbiAgICAgICAgcmVzLnN0YXR1cygyMDApLnNlbmQoJ0hlbGxvIFdvcmxkIScpO1xuICAgICAgfSk7XG4gICAgICBhcHAuZ2V0KCcvcHl0aG9uJywgKHJlcSwgcmVzKSA9PiB7XG4gICAgICAgIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHJlcS5oZWFkZXJzWydjb250ZW50LXR5cGUnXSk7XG4gICAgICB9KTtcbiAgICAgIGFwcC5nZXQoJy9lcnJvcicsICgpID0+IHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdoYWhhaGEnKTtcbiAgICAgIH0pO1xuICAgICAgYXBwLmdldCgnL3BhdXNlJywgYXN5bmMgKHJlcSwgcmVzKSA9PiB7XG4gICAgICAgIHJlcy5oZWFkZXJbJ2NvbnRlbnQtdHlwZSddID0gJ3RleHQvaHRtbCc7XG4gICAgICAgIGF3YWl0IEIuZGVsYXkoMTAwMCk7XG4gICAgICAgIHJlcy5zdGF0dXMoMjAwKS5zZW5kKCdXZSBoYXZlIHdhaXRlZCEnKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBod1NlcnZlciA9IGF3YWl0IHNlcnZlcih7XG4gICAgICByb3V0ZUNvbmZpZ3VyaW5nRnVuY3Rpb246IGNvbmZpZ3VyZVJvdXRlcyxcbiAgICAgIHBvcnQsXG4gICAgfSk7XG4gIH0pO1xuICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICBzYW5kYm94ID0gY3JlYXRlU2FuZGJveCgpO1xuICAgIHNhbmRib3guc3R1Yihjb25zb2xlLCAnZXJyb3InKTtcbiAgfSk7XG4gIGFmdGVyKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBhd2FpdCBod1NlcnZlci5jbG9zZSgpO1xuICB9KTtcbiAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICBzYW5kYm94LnJlc3RvcmUoKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBzdGFydCB1cCB3aXRoIG91ciBtaWRkbGV3YXJlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHtkYXRhfSA9IGF3YWl0IGF4aW9zLmdldChgaHR0cDovLyR7VEVTVF9IT1NUfToke3BvcnR9L2ApO1xuICAgIGRhdGEuc2hvdWxkLmVxbCgnSGVsbG8gV29ybGQhJyk7XG4gIH0pO1xuICBpdCgnc2hvdWxkIGZpeCBicm9rZW4gY29udGV4dCB0eXBlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHtkYXRhfSA9IGF3YWl0IGF4aW9zKHtcbiAgICAgIHVybDogYGh0dHA6Ly8ke1RFU1RfSE9TVH06JHtwb3J0fS9weXRob25gLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICAndXNlci1hZ2VudCc6ICdQeXRob24nLFxuICAgICAgICAnY29udGVudC10eXBlJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCdcbiAgICAgIH1cbiAgICB9KTtcbiAgICBkYXRhLnNob3VsZC5lcWwoJ2FwcGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9dXRmLTgnKTtcbiAgfSk7XG4gIGl0KCdzaG91bGQgY2F0Y2ggZXJyb3JzIGluIHRoZSBjYXRjaGFsbCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBhd2FpdCBheGlvcy5nZXQoYGh0dHA6Ly8ke1RFU1RfSE9TVH06JHtwb3J0fS9lcnJvcmApLnNob3VsZC5iZS5yZWplY3RlZDtcbiAgfSk7XG4gIGl0KCdzaG91bGQgZXJyb3IgaWYgd2UgdHJ5IHRvIHN0YXJ0IGFnYWluIG9uIGEgcG9ydCB0aGF0IGlzIHVzZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgYXdhaXQgc2VydmVyKHtcbiAgICAgIHJvdXRlQ29uZmlndXJpbmdGdW5jdGlvbiAoKSB7fSxcbiAgICAgIHBvcnQsXG4gICAgfSkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvRUFERFJJTlVTRS8pO1xuICB9KTtcbiAgaXQoJ3Nob3VsZCBub3Qgd2FpdCBmb3IgdGhlIHNlcnZlciBjbG9zZSBjb25uZWN0aW9ucyBiZWZvcmUgZmluaXNoaW5nIGNsb3NpbmcnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IGJvZHlQcm9taXNlID0gYXhpb3MuZ2V0KGBodHRwOi8vJHtURVNUX0hPU1R9OiR7cG9ydH0vcGF1c2VgKS5jYXRjaCgoKSA9PiB7fSk7XG5cbiAgICAvLyByZWxpbnF1aXNoIGNvbnRyb2wgc28gdGhhdCB3ZSBkb24ndCBjbG9zZSBiZWZvcmUgdGhlIHJlcXVlc3QgaXMgcmVjZWl2ZWRcbiAgICBhd2FpdCBCLmRlbGF5KDEwMCk7XG5cbiAgICBsZXQgYmVmb3JlID0gRGF0ZS5ub3coKTtcbiAgICBhd2FpdCBod1NlcnZlci5jbG9zZSgpO1xuICAgIC8vIGV4cGVjdCBzbGlnaHRseSBsZXNzIHRoYW4gdGhlIHJlcXVlc3Qgd2FpdGVkLCBzaW5jZSB3ZSBwYXVzZWQgYWJvdmVcbiAgICAoRGF0ZS5ub3coKSAtIGJlZm9yZSkuc2hvdWxkLm5vdC5iZS5hYm92ZSg4MDApO1xuXG4gICAgYXdhaXQgYm9keVByb21pc2U7XG4gIH0pO1xuICBpdCgnc2hvdWxkIGVycm9yIGlmIHdlIHRyeSB0byBzdGFydCBvbiBhIGJhZCBob3N0bmFtZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnRpbWVvdXQoNjAwMDApO1xuICAgIGF3YWl0IHNlcnZlcih7XG4gICAgICByb3V0ZUNvbmZpZ3VyaW5nRnVuY3Rpb246IF8ubm9vcCxcbiAgICAgIHBvcnQsXG4gICAgICBob3N0bmFtZTogJ2xvbGNhdGhvc3QnLFxuICAgIH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL0VOT1RGT1VORHxFQUREUk5PVEFWQUlMfEVBSV9BR0FJTi8pO1xuICAgIGF3YWl0IHNlcnZlcih7XG4gICAgICByb3V0ZUNvbmZpZ3VyaW5nRnVuY3Rpb246IF8ubm9vcCxcbiAgICAgIHBvcnQsXG4gICAgICBob3N0bmFtZTogJzEuMS4xLjEnLFxuICAgIH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL0VBRERSTk9UQVZBSUwvKTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoJ3NlcnZlciBwbHVnaW5zJywgZnVuY3Rpb24gKCkge1xuICBsZXQgaHdTZXJ2ZXI7XG4gIGxldCBwb3J0O1xuXG4gIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgcG9ydCA9IGF3YWl0IGdldFRlc3RQb3J0KHRydWUpO1xuICB9KTtcblxuICBhZnRlckVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBod1NlcnZlci5jbG9zZSgpO1xuICAgIH0gY2F0Y2ggKGlnbikge31cbiAgfSk7XG5cbiAgZnVuY3Rpb24gdXBkYXRlcldpdGhHZXRSb3V0ZSAocm91dGUsIHJlcGx5KSB7XG4gICAgcmV0dXJuIGFzeW5jIChhcHAsIGh0dHBTZXJ2ZXIpID0+IHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSByZXF1aXJlLWF3YWl0XG4gICAgICBhcHAuZ2V0KGAvJHtyb3V0ZX1gLCAocmVxLCByZXMpID0+IHtcbiAgICAgICAgcmVzLmhlYWRlclsnY29udGVudC10eXBlJ10gPSAndGV4dC9odG1sJztcbiAgICAgICAgcmVzLnN0YXR1cygyMDApLnNlbmQocmVwbHkpO1xuICAgICAgfSk7XG4gICAgICBodHRwU2VydmVyW2BfdXBkYXRlZF8ke3JvdXRlfWBdID0gdHJ1ZTtcbiAgICB9O1xuICB9XG5cbiAgaXQoJ3Nob3VsZCBhbGxvdyBvbmUgb3IgbW9yZSBwbHVnaW5zIHRvIHVwZGF0ZSB0aGUgc2VydmVyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGh3U2VydmVyID0gYXdhaXQgc2VydmVyKHtcbiAgICAgIHJvdXRlQ29uZmlndXJpbmdGdW5jdGlvbjogXy5ub29wLFxuICAgICAgcG9ydCxcbiAgICAgIHNlcnZlclVwZGF0ZXJzOiBbXG4gICAgICAgIHVwZGF0ZXJXaXRoR2V0Um91dGUoJ3BsdWdpbjEnLCAncmVzIGZyb20gcGx1Z2luMSByb3V0ZScpLFxuICAgICAgICB1cGRhdGVyV2l0aEdldFJvdXRlKCdwbHVnaW4yJywgJ3JlcyBmcm9tIHBsdWdpbjIgcm91dGUnKSxcbiAgICAgIF1cbiAgICB9KTtcbiAgICBsZXQge2RhdGF9ID0gYXdhaXQgYXhpb3MuZ2V0KGBodHRwOi8vJHtURVNUX0hPU1R9OiR7cG9ydH0vcGx1Z2luMWApO1xuICAgIGRhdGEuc2hvdWxkLmVxbCgncmVzIGZyb20gcGx1Z2luMSByb3V0ZScpO1xuICAgICh7ZGF0YX0gPSBhd2FpdCBheGlvcy5nZXQoYGh0dHA6Ly8ke1RFU1RfSE9TVH06JHtwb3J0fS9wbHVnaW4yYCkpO1xuICAgIGRhdGEuc2hvdWxkLmVxbCgncmVzIGZyb20gcGx1Z2luMiByb3V0ZScpO1xuICAgIGh3U2VydmVyLl91cGRhdGVkX3BsdWdpbjEuc2hvdWxkLmJlLnRydWU7XG4gICAgaHdTZXJ2ZXIuX3VwZGF0ZWRfcGx1Z2luMi5zaG91bGQuYmUudHJ1ZTtcbiAgfSk7XG4gIGl0KCdzaG91bGQgcGFzcyBvbiBlcnJvcnMgZnJvbSB0aGUgcGx1Z2luIHVwZGF0ZVNlcnZlciBtZXRob2QnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgYXdhaXQgc2VydmVyKHtcbiAgICAgIHJvdXRlQ29uZmlndXJpbmdGdW5jdGlvbjogXy5ub29wLFxuICAgICAgcG9ydCxcbiAgICAgIHNlcnZlclVwZGF0ZXJzOiBbKCkgPT4geyB0aHJvdyBuZXcgRXJyb3IoJ3VnaCcpO31dXG4gICAgfSkuc2hvdWxkLmV2ZW50dWFsbHkuYmUucmVqZWN0ZWRXaXRoKC91Z2gvKTtcbiAgfSk7XG59KTtcbiJdfQ==
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+
3
+ require("source-map-support/register");
4
+
5
+ var _lib = require("../../../lib");
6
+
7
+ var _fakeDriver = require("../protocol/fake-driver");
8
+
9
+ describe('proxy', function () {
10
+ const jwproxy = new _lib.JWProxy();
11
+ let baseServer;
12
+ before(async function () {
13
+ baseServer = await (0, _lib.server)({
14
+ routeConfiguringFunction: (0, _lib.routeConfiguringFunction)(new _fakeDriver.FakeDriver()),
15
+ port: 4444
16
+ });
17
+ });
18
+ after(async function () {
19
+ await baseServer.close();
20
+ });
21
+ it('should proxy status straight', async function () {
22
+ let [res, resBody] = await jwproxy.proxy('/status', 'GET');
23
+ res.statusCode.should.equal(200);
24
+ resBody.value.should.equal(`I'm fine`);
25
+ });
26
+ it('should proxy status as command', async function () {
27
+ const res = await jwproxy.command('/status', 'GET');
28
+ res.should.eql(`I'm fine`);
29
+ });
30
+ describe('new session', function () {
31
+ afterEach(async function () {
32
+ await jwproxy.command('', 'DELETE');
33
+ });
34
+ it('should start a new session', async function () {
35
+ const caps = {
36
+ browserName: 'fake'
37
+ };
38
+ const res = await jwproxy.command('/session', 'POST', {
39
+ capabilities: {
40
+ alwaysMatch: caps
41
+ }
42
+ });
43
+ res.capabilities.alwaysMatch.should.have.property('browserName');
44
+ jwproxy.sessionId.should.have.length(48);
45
+ });
46
+ });
47
+ describe('delete session', function () {
48
+ beforeEach(async function () {
49
+ await jwproxy.command('/session', 'POST', {
50
+ desiredCapabilities: {}
51
+ });
52
+ });
53
+ it('should quit a session', async function () {
54
+ const res = await jwproxy.command('', 'DELETE');
55
+ should.not.exist(res);
56
+ });
57
+ });
58
+ });
59
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvZTJlL2pzb253cC1wcm94eS9wcm94eS5lMmUuc3BlYy5qcyJdLCJuYW1lcyI6WyJkZXNjcmliZSIsImp3cHJveHkiLCJKV1Byb3h5IiwiYmFzZVNlcnZlciIsImJlZm9yZSIsInJvdXRlQ29uZmlndXJpbmdGdW5jdGlvbiIsIkZha2VEcml2ZXIiLCJwb3J0IiwiYWZ0ZXIiLCJjbG9zZSIsIml0IiwicmVzIiwicmVzQm9keSIsInByb3h5Iiwic3RhdHVzQ29kZSIsInNob3VsZCIsImVxdWFsIiwidmFsdWUiLCJjb21tYW5kIiwiZXFsIiwiYWZ0ZXJFYWNoIiwiY2FwcyIsImJyb3dzZXJOYW1lIiwiY2FwYWJpbGl0aWVzIiwiYWx3YXlzTWF0Y2giLCJoYXZlIiwicHJvcGVydHkiLCJzZXNzaW9uSWQiLCJsZW5ndGgiLCJiZWZvcmVFYWNoIiwiZGVzaXJlZENhcGFiaWxpdGllcyIsIm5vdCIsImV4aXN0Il0sIm1hcHBpbmdzIjoiOzs7O0FBQUE7O0FBQ0E7O0FBRUFBLFFBQVEsQ0FBQyxPQUFELEVBQVUsWUFBWTtBQUM1QixRQUFNQyxPQUFPLEdBQUcsSUFBSUMsWUFBSixFQUFoQjtBQUNBLE1BQUlDLFVBQUo7QUFDQUMsRUFBQUEsTUFBTSxDQUFDLGtCQUFrQjtBQUN2QkQsSUFBQUEsVUFBVSxHQUFHLE1BQU0saUJBQU87QUFDeEJFLE1BQUFBLHdCQUF3QixFQUFFLG1DQUF5QixJQUFJQyxzQkFBSixFQUF6QixDQURGO0FBRXhCQyxNQUFBQSxJQUFJLEVBQUU7QUFGa0IsS0FBUCxDQUFuQjtBQUlELEdBTEssQ0FBTjtBQU1BQyxFQUFBQSxLQUFLLENBQUMsa0JBQWtCO0FBQ3RCLFVBQU1MLFVBQVUsQ0FBQ00sS0FBWCxFQUFOO0FBQ0QsR0FGSSxDQUFMO0FBSUFDLEVBQUFBLEVBQUUsQ0FBQyw4QkFBRCxFQUFpQyxrQkFBa0I7QUFDbkQsUUFBSSxDQUFDQyxHQUFELEVBQU1DLE9BQU4sSUFBaUIsTUFBTVgsT0FBTyxDQUFDWSxLQUFSLENBQWMsU0FBZCxFQUF5QixLQUF6QixDQUEzQjtBQUNBRixJQUFBQSxHQUFHLENBQUNHLFVBQUosQ0FBZUMsTUFBZixDQUFzQkMsS0FBdEIsQ0FBNEIsR0FBNUI7QUFDQUosSUFBQUEsT0FBTyxDQUFDSyxLQUFSLENBQWNGLE1BQWQsQ0FBcUJDLEtBQXJCLENBQTRCLFVBQTVCO0FBQ0QsR0FKQyxDQUFGO0FBS0FOLEVBQUFBLEVBQUUsQ0FBQyxnQ0FBRCxFQUFtQyxrQkFBa0I7QUFDckQsVUFBTUMsR0FBRyxHQUFHLE1BQU1WLE9BQU8sQ0FBQ2lCLE9BQVIsQ0FBZ0IsU0FBaEIsRUFBMkIsS0FBM0IsQ0FBbEI7QUFDQVAsSUFBQUEsR0FBRyxDQUFDSSxNQUFKLENBQVdJLEdBQVgsQ0FBZ0IsVUFBaEI7QUFDRCxHQUhDLENBQUY7QUFJQW5CLEVBQUFBLFFBQVEsQ0FBQyxhQUFELEVBQWdCLFlBQVk7QUFDbENvQixJQUFBQSxTQUFTLENBQUMsa0JBQWtCO0FBQzFCLFlBQU1uQixPQUFPLENBQUNpQixPQUFSLENBQWdCLEVBQWhCLEVBQW9CLFFBQXBCLENBQU47QUFDRCxLQUZRLENBQVQ7QUFHQVIsSUFBQUEsRUFBRSxDQUFDLDRCQUFELEVBQStCLGtCQUFrQjtBQUNqRCxZQUFNVyxJQUFJLEdBQUc7QUFBQ0MsUUFBQUEsV0FBVyxFQUFFO0FBQWQsT0FBYjtBQUNBLFlBQU1YLEdBQUcsR0FBRyxNQUFNVixPQUFPLENBQUNpQixPQUFSLENBQWdCLFVBQWhCLEVBQTRCLE1BQTVCLEVBQW9DO0FBQUNLLFFBQUFBLFlBQVksRUFBRTtBQUFDQyxVQUFBQSxXQUFXLEVBQUVIO0FBQWQ7QUFBZixPQUFwQyxDQUFsQjtBQUNBVixNQUFBQSxHQUFHLENBQUNZLFlBQUosQ0FBaUJDLFdBQWpCLENBQTZCVCxNQUE3QixDQUFvQ1UsSUFBcEMsQ0FBeUNDLFFBQXpDLENBQWtELGFBQWxEO0FBQ0F6QixNQUFBQSxPQUFPLENBQUMwQixTQUFSLENBQWtCWixNQUFsQixDQUF5QlUsSUFBekIsQ0FBOEJHLE1BQTlCLENBQXFDLEVBQXJDO0FBQ0QsS0FMQyxDQUFGO0FBTUQsR0FWTyxDQUFSO0FBV0E1QixFQUFBQSxRQUFRLENBQUMsZ0JBQUQsRUFBbUIsWUFBWTtBQUNyQzZCLElBQUFBLFVBQVUsQ0FBQyxrQkFBa0I7QUFDM0IsWUFBTTVCLE9BQU8sQ0FBQ2lCLE9BQVIsQ0FBZ0IsVUFBaEIsRUFBNEIsTUFBNUIsRUFBb0M7QUFBQ1ksUUFBQUEsbUJBQW1CLEVBQUU7QUFBdEIsT0FBcEMsQ0FBTjtBQUNELEtBRlMsQ0FBVjtBQUdBcEIsSUFBQUEsRUFBRSxDQUFDLHVCQUFELEVBQTBCLGtCQUFrQjtBQUM1QyxZQUFNQyxHQUFHLEdBQUcsTUFBTVYsT0FBTyxDQUFDaUIsT0FBUixDQUFnQixFQUFoQixFQUFvQixRQUFwQixDQUFsQjtBQUNBSCxNQUFBQSxNQUFNLENBQUNnQixHQUFQLENBQVdDLEtBQVgsQ0FBaUJyQixHQUFqQjtBQUNELEtBSEMsQ0FBRjtBQUlELEdBUk8sQ0FBUjtBQVNELENBMUNPLENBQVIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBKV1Byb3h5LCBzZXJ2ZXIsIHJvdXRlQ29uZmlndXJpbmdGdW5jdGlvbiB9IGZyb20gJy4uLy4uLy4uL2xpYic7XG5pbXBvcnQgeyBGYWtlRHJpdmVyIH0gZnJvbSAnLi4vcHJvdG9jb2wvZmFrZS1kcml2ZXInO1xuXG5kZXNjcmliZSgncHJveHknLCBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IGp3cHJveHkgPSBuZXcgSldQcm94eSgpO1xuICBsZXQgYmFzZVNlcnZlcjtcbiAgYmVmb3JlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBiYXNlU2VydmVyID0gYXdhaXQgc2VydmVyKHtcbiAgICAgIHJvdXRlQ29uZmlndXJpbmdGdW5jdGlvbjogcm91dGVDb25maWd1cmluZ0Z1bmN0aW9uKG5ldyBGYWtlRHJpdmVyKCkpLFxuICAgICAgcG9ydDogNDQ0NCxcbiAgICB9KTtcbiAgfSk7XG4gIGFmdGVyKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBhd2FpdCBiYXNlU2VydmVyLmNsb3NlKCk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcHJveHkgc3RhdHVzIHN0cmFpZ2h0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGxldCBbcmVzLCByZXNCb2R5XSA9IGF3YWl0IGp3cHJveHkucHJveHkoJy9zdGF0dXMnLCAnR0VUJyk7XG4gICAgcmVzLnN0YXR1c0NvZGUuc2hvdWxkLmVxdWFsKDIwMCk7XG4gICAgcmVzQm9keS52YWx1ZS5zaG91bGQuZXF1YWwoYEknbSBmaW5lYCk7XG4gIH0pO1xuICBpdCgnc2hvdWxkIHByb3h5IHN0YXR1cyBhcyBjb21tYW5kJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGp3cHJveHkuY29tbWFuZCgnL3N0YXR1cycsICdHRVQnKTtcbiAgICByZXMuc2hvdWxkLmVxbChgSSdtIGZpbmVgKTtcbiAgfSk7XG4gIGRlc2NyaWJlKCduZXcgc2Vzc2lvbicsIGZ1bmN0aW9uICgpIHtcbiAgICBhZnRlckVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgandwcm94eS5jb21tYW5kKCcnLCAnREVMRVRFJyk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBzdGFydCBhIG5ldyBzZXNzaW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY2FwcyA9IHticm93c2VyTmFtZTogJ2Zha2UnfTtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGp3cHJveHkuY29tbWFuZCgnL3Nlc3Npb24nLCAnUE9TVCcsIHtjYXBhYmlsaXRpZXM6IHthbHdheXNNYXRjaDogY2Fwc319KTtcbiAgICAgIHJlcy5jYXBhYmlsaXRpZXMuYWx3YXlzTWF0Y2guc2hvdWxkLmhhdmUucHJvcGVydHkoJ2Jyb3dzZXJOYW1lJyk7XG4gICAgICBqd3Byb3h5LnNlc3Npb25JZC5zaG91bGQuaGF2ZS5sZW5ndGgoNDgpO1xuICAgIH0pO1xuICB9KTtcbiAgZGVzY3JpYmUoJ2RlbGV0ZSBzZXNzaW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGJlZm9yZUVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgandwcm94eS5jb21tYW5kKCcvc2Vzc2lvbicsICdQT1NUJywge2Rlc2lyZWRDYXBhYmlsaXRpZXM6IHt9fSk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBxdWl0IGEgc2Vzc2lvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGp3cHJveHkuY29tbWFuZCgnJywgJ0RFTEVURScpO1xuICAgICAgc2hvdWxkLm5vdC5leGlzdChyZXMpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19