rollbar 2.26.3 → 3.0.0-alpha.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 (186) hide show
  1. package/.cursor/rules/guidelines.mdc +154 -0
  2. package/.github/workflows/ci.yml +32 -12
  3. package/.lgtm.yml +7 -7
  4. package/.prettierignore +18 -0
  5. package/.vscode/settings.json +39 -0
  6. package/CHANGELOG.md +121 -35
  7. package/CLAUDE.md +201 -0
  8. package/Gruntfile.js +101 -48
  9. package/Makefile +3 -3
  10. package/README.md +2 -4
  11. package/SECURITY.md +5 -0
  12. package/babel.config.json +9 -0
  13. package/bower.json +1 -3
  14. package/codex.md +148 -0
  15. package/defaults.js +17 -5
  16. package/dist/plugins/jquery.min.js +1 -1
  17. package/dist/rollbar.js +18748 -5375
  18. package/dist/rollbar.js.map +1 -1
  19. package/dist/rollbar.min.js +2 -1
  20. package/dist/rollbar.min.js.LICENSE.txt +1 -0
  21. package/dist/rollbar.min.js.map +1 -1
  22. package/dist/rollbar.named-amd.js +19368 -6000
  23. package/dist/rollbar.named-amd.js.map +1 -1
  24. package/dist/rollbar.named-amd.min.js +3 -1
  25. package/dist/rollbar.named-amd.min.js.LICENSE.txt +1 -0
  26. package/dist/rollbar.named-amd.min.js.map +1 -1
  27. package/dist/rollbar.noconflict.umd.js +18749 -5380
  28. package/dist/rollbar.noconflict.umd.js.map +1 -1
  29. package/dist/rollbar.noconflict.umd.min.js +3 -1
  30. package/dist/rollbar.noconflict.umd.min.js.LICENSE.txt +1 -0
  31. package/dist/rollbar.noconflict.umd.min.js.map +1 -1
  32. package/dist/rollbar.snippet.js +1 -1
  33. package/dist/rollbar.umd.js +19367 -6000
  34. package/dist/rollbar.umd.js.map +1 -1
  35. package/dist/rollbar.umd.min.js +3 -1
  36. package/dist/rollbar.umd.min.js.LICENSE.txt +1 -0
  37. package/dist/rollbar.umd.min.js.map +1 -1
  38. package/docs/extension-exceptions.md +35 -30
  39. package/docs/migration_v0_to_v1.md +41 -38
  40. package/eslint.config.mjs +33 -0
  41. package/get_versions.js +33 -0
  42. package/index.d.ts +270 -231
  43. package/karma.conf.js +18 -27
  44. package/package.json +21 -21
  45. package/prettier.config.js +7 -0
  46. package/src/api.js +78 -14
  47. package/src/apiUtility.js +14 -11
  48. package/src/browser/core.js +138 -72
  49. package/src/browser/defaults/scrubFields.js +3 -3
  50. package/src/browser/detection.js +7 -8
  51. package/src/browser/domUtility.js +18 -8
  52. package/src/browser/globalSetup.js +12 -6
  53. package/src/browser/logger.js +1 -1
  54. package/src/browser/plugins/jquery.js +35 -35
  55. package/src/browser/predicates.js +1 -1
  56. package/src/browser/replay/defaults.js +71 -0
  57. package/src/browser/replay/recorder.js +193 -0
  58. package/src/browser/replay/replayMap.js +195 -0
  59. package/src/browser/rollbar.js +12 -8
  60. package/src/browser/rollbarWrapper.js +8 -5
  61. package/src/browser/shim.js +43 -19
  62. package/src/browser/snippet_callback.js +6 -4
  63. package/src/browser/telemetry.js +573 -361
  64. package/src/browser/transforms.js +46 -27
  65. package/src/browser/transport/fetch.js +26 -14
  66. package/src/browser/transport/xhr.js +41 -14
  67. package/src/browser/transport.js +93 -33
  68. package/src/browser/url.js +16 -8
  69. package/src/browser/wrapGlobals.js +27 -8
  70. package/src/defaults.js +3 -3
  71. package/src/errorParser.js +14 -11
  72. package/src/merge.js +32 -23
  73. package/src/notifier.js +16 -13
  74. package/src/predicates.js +43 -23
  75. package/src/queue.js +133 -40
  76. package/src/rateLimiter.js +59 -18
  77. package/src/react-native/logger.js +1 -1
  78. package/src/react-native/rollbar.js +59 -55
  79. package/src/react-native/transforms.js +13 -9
  80. package/src/react-native/transport.js +44 -34
  81. package/src/rollbar.js +72 -21
  82. package/src/scrub.js +0 -1
  83. package/src/server/locals.js +69 -39
  84. package/src/server/logger.js +4 -4
  85. package/src/server/parser.js +72 -47
  86. package/src/server/rollbar.js +135 -56
  87. package/src/server/sourceMap/stackTrace.js +33 -18
  88. package/src/server/telemetry/urlHelpers.js +9 -11
  89. package/src/server/telemetry.js +68 -45
  90. package/src/server/transforms.js +37 -21
  91. package/src/server/transport.js +62 -32
  92. package/src/telemetry.js +162 -33
  93. package/src/tracing/context.js +24 -0
  94. package/src/tracing/contextManager.js +37 -0
  95. package/src/tracing/defaults.js +7 -0
  96. package/src/tracing/exporter.js +188 -0
  97. package/src/tracing/hrtime.js +98 -0
  98. package/src/tracing/id.js +24 -0
  99. package/src/tracing/session.js +55 -0
  100. package/src/tracing/span.js +92 -0
  101. package/src/tracing/spanProcessor.js +15 -0
  102. package/src/tracing/tracer.js +46 -0
  103. package/src/tracing/tracing.js +89 -0
  104. package/src/transforms.js +33 -21
  105. package/src/truncation.js +8 -5
  106. package/src/utility/headers.js +43 -43
  107. package/src/utility/replace.js +9 -0
  108. package/src/utility/traverse.js +1 -1
  109. package/src/utility.js +123 -52
  110. package/test/api.test.js +88 -41
  111. package/test/apiUtility.test.js +48 -50
  112. package/test/browser.core.test.js +142 -141
  113. package/test/browser.domUtility.test.js +53 -36
  114. package/test/browser.predicates.test.js +14 -14
  115. package/test/browser.replay.recorder.test.js +416 -0
  116. package/test/browser.rollbar.test.js +655 -515
  117. package/test/browser.telemetry.test.js +46 -39
  118. package/test/browser.transforms.test.js +164 -139
  119. package/test/browser.transport.test.js +59 -50
  120. package/test/browser.url.test.js +13 -12
  121. package/test/fixtures/locals.fixtures.js +245 -126
  122. package/test/fixtures/replay/index.js +20 -0
  123. package/test/fixtures/replay/payloads.fixtures.js +229 -0
  124. package/test/fixtures/replay/rrwebEvents.fixtures.js +251 -0
  125. package/test/fixtures/replay/rrwebSyntheticEvents.fixtures.js +328 -0
  126. package/test/notifier.test.js +91 -79
  127. package/test/predicates.test.js +261 -215
  128. package/test/queue.test.js +231 -215
  129. package/test/rateLimiter.test.js +51 -43
  130. package/test/react-native.rollbar.test.js +150 -116
  131. package/test/react-native.transforms.test.js +23 -25
  132. package/test/react-native.transport.test.js +26 -14
  133. package/test/replay/index.js +2 -0
  134. package/test/replay/integration/api.spans.test.js +136 -0
  135. package/test/replay/integration/e2e.test.js +228 -0
  136. package/test/replay/integration/index.js +9 -0
  137. package/test/replay/integration/queue.replayMap.test.js +332 -0
  138. package/test/replay/integration/replayMap.test.js +163 -0
  139. package/test/replay/integration/sessionRecording.test.js +390 -0
  140. package/test/replay/unit/api.postSpans.test.js +150 -0
  141. package/test/replay/unit/index.js +7 -0
  142. package/test/replay/unit/queue.replayMap.test.js +225 -0
  143. package/test/replay/unit/replayMap.test.js +348 -0
  144. package/test/replay/util/index.js +5 -0
  145. package/test/replay/util/mockRecordFn.js +80 -0
  146. package/test/server.lambda.mocha.test.mjs +172 -0
  147. package/test/server.locals.constructor.mocha.test.mjs +80 -0
  148. package/test/server.locals.error-handling.mocha.test.mjs +387 -0
  149. package/test/server.locals.merge.mocha.test.mjs +267 -0
  150. package/test/server.locals.test-utils.mjs +114 -0
  151. package/test/server.parser.mocha.test.mjs +87 -0
  152. package/test/server.predicates.mocha.test.mjs +63 -0
  153. package/test/server.rollbar.constructor.mocha.test.mjs +199 -0
  154. package/test/server.rollbar.handlers.mocha.test.mjs +253 -0
  155. package/test/server.rollbar.logging.mocha.test.mjs +326 -0
  156. package/test/server.rollbar.misc.mocha.test.mjs +44 -0
  157. package/test/server.rollbar.test-utils.mjs +57 -0
  158. package/test/server.telemetry.mocha.test.mjs +377 -0
  159. package/test/server.transforms.data.mocha.test.mjs +163 -0
  160. package/test/server.transforms.error.mocha.test.mjs +199 -0
  161. package/test/server.transforms.request.mocha.test.mjs +208 -0
  162. package/test/server.transforms.scrub.mocha.test.mjs +140 -0
  163. package/test/server.transforms.sourcemaps.mocha.test.mjs +122 -0
  164. package/test/server.transforms.test-utils.mjs +62 -0
  165. package/test/server.transport.mocha.test.mjs +269 -0
  166. package/test/telemetry.test.js +178 -38
  167. package/test/tracing/contextManager.test.js +28 -0
  168. package/test/tracing/exporter.toPayload.test.js +400 -0
  169. package/test/tracing/id.test.js +24 -0
  170. package/test/tracing/span.test.js +183 -0
  171. package/test/tracing/spanProcessor.test.js +73 -0
  172. package/test/tracing/tracing.test.js +105 -0
  173. package/test/transforms.test.js +70 -68
  174. package/test/truncation.test.js +57 -55
  175. package/test/utility.test.js +310 -228
  176. package/webpack.config.js +36 -70
  177. package/.eslintignore +0 -7
  178. package/.gitmodules +0 -3
  179. package/test/server.lambda.test.js +0 -177
  180. package/test/server.locals.test.js +0 -841
  181. package/test/server.parser.test.js +0 -72
  182. package/test/server.predicates.test.js +0 -89
  183. package/test/server.rollbar.test.js +0 -676
  184. package/test/server.telemetry.test.js +0 -318
  185. package/test/server.transforms.test.js +0 -1099
  186. package/test/server.transport.test.js +0 -201
@@ -3,37 +3,37 @@
3
3
  /* globals it */
4
4
  /* globals sinon */
5
5
 
6
- var truncation = require('../src/truncation');
7
- var Transport = require('../src/browser/transport');
8
- var t = new Transport(truncation);
9
- var utility = require('../src/utility');
6
+ import truncation from '../src/truncation.js';
7
+ import Transport from '../src/browser/transport.js';
8
+ const t = new Transport(truncation);
9
+ import * as utility from '../src/utility.js';
10
10
  utility.setupJSON();
11
11
 
12
- describe('post', function() {
12
+ describe('post', function () {
13
13
  var accessToken = 'abc123';
14
14
  var options = {
15
15
  hostname: 'api.rollbar.com',
16
16
  protocol: 'https',
17
17
  path: '/api/1/item/',
18
- timeout: 2000
18
+ timeout: 2000,
19
19
  };
20
20
  var payload = {
21
21
  access_token: accessToken,
22
- data: {a: 1}
22
+ data: { a: 1 },
23
23
  };
24
- it('should handle a failure to make a request', function(done) {
25
- var requestFactory = function() {
24
+ it('should handle a failure to make a request', function (done) {
25
+ var requestFactory = function () {
26
26
  return null;
27
27
  };
28
- var callback = function(err, resp) {
28
+ var callback = function (err, resp) {
29
29
  expect(err).to.be.ok();
30
30
  done(resp);
31
31
  };
32
32
  t.post(accessToken, options, payload, callback, requestFactory);
33
33
  });
34
- it('should callback with the right value on success', function(done) {
34
+ it('should callback with the right value on success', function (done) {
35
35
  var requestFactory = requestGenerator('{"err": null, "result": true}', 200);
36
- var callback = function(err, resp) {
36
+ var callback = function (err, resp) {
37
37
  expect(resp).to.be.ok();
38
38
  expect(resp.result).to.be.ok();
39
39
  expect(requestFactory.getInstance().timeout).to.equal(options.timeout);
@@ -41,10 +41,11 @@ describe('post', function() {
41
41
  };
42
42
  t.post(accessToken, options, payload, callback, requestFactory.getInstance);
43
43
  });
44
- it('should callback with the server error if 403', function(done) {
45
- var response = '{"err": "bad request", "result": null, "message": "fail whale"}'
44
+ it('should callback with the server error if 403', function (done) {
45
+ var response =
46
+ '{"err": "bad request", "result": null, "message": "fail whale"}';
46
47
  var requestFactory = requestGenerator(response, 403);
47
- var callback = function(err, resp) {
48
+ var callback = function (err, resp) {
48
49
  expect(resp).to.not.be.ok();
49
50
  expect(err.message).to.eql('403');
50
51
  expect(requestFactory.getInstance().timeout).to.equal(options.timeout);
@@ -52,10 +53,11 @@ describe('post', function() {
52
53
  };
53
54
  t.post(accessToken, options, payload, callback, requestFactory.getInstance);
54
55
  });
55
- it('should callback with the server error if 500', function(done) {
56
- var response = '{"err": "bad request", "result": null, "message": "500!!!"}'
56
+ it('should callback with the server error if 500', function (done) {
57
+ var response =
58
+ '{"err": "bad request", "result": null, "message": "500!!!"}';
57
59
  var requestFactory = requestGenerator(response, 500);
58
- var callback = function(err, resp) {
60
+ var callback = function (err, resp) {
59
61
  expect(resp).to.not.be.ok();
60
62
  expect(err.message).to.eql('500');
61
63
  expect(requestFactory.getInstance().timeout).to.equal(options.timeout);
@@ -63,10 +65,10 @@ describe('post', function() {
63
65
  };
64
66
  t.post(accessToken, options, payload, callback, requestFactory.getInstance);
65
67
  });
66
- it('should callback with a retriable error with a weird status', function(done) {
67
- var response = '{"err": "bad request"}'
68
+ it('should callback with a retriable error with a weird status', function (done) {
69
+ var response = '{"err": "bad request"}';
68
70
  var requestFactory = requestGenerator(response, 12005);
69
- var callback = function(err, resp) {
71
+ var callback = function (err, resp) {
70
72
  expect(resp).to.not.be.ok();
71
73
  expect(err.message).to.match(/connection failure/);
72
74
  expect(err.code).to.eql('ENOTFOUND');
@@ -75,10 +77,10 @@ describe('post', function() {
75
77
  };
76
78
  t.post(accessToken, options, payload, callback, requestFactory.getInstance);
77
79
  });
78
- it('should callback with some error if normal sending throws', function(done) {
79
- var response = '{"err": "bad request"}'
80
+ it('should callback with some error if normal sending throws', function (done) {
81
+ var response = '{"err": "bad request"}';
80
82
  var requestFactory = requestGenerator(response, 500, true);
81
- var callback = function(err, resp) {
83
+ var callback = function (err, resp) {
82
84
  expect(resp).to.not.be.ok();
83
85
  expect(err.message).to.match(/Cannot find a method to transport/);
84
86
  expect(requestFactory.getInstance().timeout).to.equal(options.timeout);
@@ -86,7 +88,7 @@ describe('post', function() {
86
88
  };
87
89
  t.post(accessToken, options, payload, callback, requestFactory.getInstance);
88
90
  });
89
- describe('post', function() {
91
+ describe('post', function () {
90
92
  beforeEach(function (done) {
91
93
  window.fetchStub = sinon.stub(window, 'fetch');
92
94
  window.server = sinon.createFakeServer();
@@ -99,26 +101,32 @@ describe('post', function() {
99
101
  });
100
102
 
101
103
  function stubFetchResponse() {
102
- window.fetch.returns(Promise.resolve(new Response(
103
- JSON.stringify({ err: 0, message: 'OK', result: { uuid: uuid }}),
104
- { status: 200, statusText: 'OK', headers: { 'Content-Type': 'application/json' }}
105
- )));
104
+ window.fetch.returns(
105
+ Promise.resolve(
106
+ new Response(
107
+ JSON.stringify({ err: 0, message: 'OK', result: { uuid: uuid } }),
108
+ {
109
+ status: 200,
110
+ statusText: 'OK',
111
+ headers: { 'Content-Type': 'application/json' },
112
+ },
113
+ ),
114
+ ),
115
+ );
106
116
  }
107
117
 
108
118
  function stubXhrResponse() {
109
- window.server.respondWith(
110
- [
111
- 200,
112
- { 'Content-Type': 'application/json' },
113
- '{"err": 0, "result":{ "uuid": "d4c7acef55bf4c9ea95e4fe9428a8287"}}'
114
- ]
115
- );
119
+ window.server.respondWith([
120
+ 200,
121
+ { 'Content-Type': 'application/json' },
122
+ '{"err": 0, "result":{ "uuid": "d4c7acef55bf4c9ea95e4fe9428a8287"}}',
123
+ ]);
116
124
  }
117
125
 
118
126
  var uuid = 'd4c7acef55bf4c9ea95e4fe9428a8287';
119
127
 
120
- it('should use fetch when requested', function(done) {
121
- var callback = function(err, resp) {
128
+ it('should use fetch when requested', function (done) {
129
+ var callback = function (err, resp) {
122
130
  expect(window.fetchStub.called).to.be.ok();
123
131
  expect(server.requests.length).to.eql(0);
124
132
  done(err);
@@ -129,8 +137,8 @@ describe('post', function() {
129
137
  options.transport = 'fetch';
130
138
  t.post(accessToken, options, payload, callback);
131
139
  });
132
- it('should use xhr when requested', function(done) {
133
- var callback = function(err, resp) {
140
+ it('should use xhr when requested', function (done) {
141
+ var callback = function (err, resp) {
134
142
  expect(window.fetchStub.called).to.not.be.ok();
135
143
  expect(server.requests.length).to.eql(1);
136
144
  done(err);
@@ -140,14 +148,14 @@ describe('post', function() {
140
148
  server.requests.length = 0;
141
149
  options.transport = 'xhr';
142
150
  t.post(accessToken, options, payload, callback);
143
- setTimeout(function() {
151
+ setTimeout(function () {
144
152
  server.respond();
145
153
  }, 1);
146
154
  });
147
155
  });
148
156
  });
149
157
 
150
- var TestRequest = function(response, status, shouldThrowOnSend) {
158
+ var TestRequest = function (response, status, shouldThrowOnSend) {
151
159
  this.method = null;
152
160
  this.url = null;
153
161
  this.async = false;
@@ -158,16 +166,17 @@ var TestRequest = function(response, status, shouldThrowOnSend) {
158
166
  this.onreadystatechange = null;
159
167
  this.readyState = 0;
160
168
  this.shouldThrowOnSend = shouldThrowOnSend;
169
+ this.getResponseHeader = (key) => undefined;
161
170
  };
162
- TestRequest.prototype.open = function(m, u, a) {
171
+ TestRequest.prototype.open = function (m, u, a) {
163
172
  this.method = m;
164
173
  this.url = u;
165
174
  this.async = a;
166
175
  };
167
- TestRequest.prototype.setRequestHeader = function(key, value) {
176
+ TestRequest.prototype.setRequestHeader = function (key, value) {
168
177
  this.headers.push([key, value]);
169
178
  };
170
- TestRequest.prototype.send = function(data) {
179
+ TestRequest.prototype.send = function (data) {
171
180
  if (this.shouldThrowOnSend) {
172
181
  throw 'Bork Bork';
173
182
  }
@@ -178,14 +187,14 @@ TestRequest.prototype.send = function(data) {
178
187
  }
179
188
  };
180
189
 
181
- var requestGenerator = function(response, status, shouldThrow) {
190
+ var requestGenerator = function (response, status, shouldThrow) {
182
191
  var request;
183
192
  return {
184
- getInstance: function() {
185
- if(!request) {
193
+ getInstance: function () {
194
+ if (!request) {
186
195
  request = new TestRequest(response, status, shouldThrow);
187
196
  }
188
197
  return request;
189
- }
190
- }
198
+ },
199
+ };
191
200
  };
@@ -3,15 +3,15 @@
3
3
  /* globals it */
4
4
  /* globals sinon */
5
5
 
6
- var url = require('../src/browser/url');
6
+ import * as url from '../src/browser/url.js';
7
7
 
8
- describe('parse', function() {
9
- it('should return an object full of nulls for a blank url', function() {
8
+ describe('parse', function () {
9
+ it('should return an object full of nulls for a blank url', function () {
10
10
  var u = '';
11
11
  var parsed = url.parse(u);
12
12
  expect(parsed).to.be.ok();
13
13
  });
14
- it('should get the protocol', function() {
14
+ it('should get the protocol', function () {
15
15
  var http = 'http://something.com';
16
16
  var parsedHttp = url.parse(http);
17
17
  expect(parsedHttp.protocol).to.eql('http:');
@@ -19,8 +19,9 @@ describe('parse', function() {
19
19
  var parsedFile = url.parse(file);
20
20
  expect(parsedFile.protocol).to.eql('file:');
21
21
  });
22
- it('should get everything if it is there', function() {
23
- var u = 'https://me:you@fake.example.co.uk:85/a/path/object//with/crap?a=b&c=d#hashy!';
22
+ it('should get everything if it is there', function () {
23
+ var u =
24
+ 'https://me:you@fake.example.co.uk:85/a/path/object//with/crap?a=b&c=d#hashy!';
24
25
  var p = url.parse(u);
25
26
  expect(p.protocol).to.eql('https:');
26
27
  expect(p.auth).to.eql('me:you');
@@ -33,7 +34,7 @@ describe('parse', function() {
33
34
  expect(p.query).to.eql('a=b&c=d');
34
35
  expect(p.hash).to.eql('#hashy!');
35
36
  });
36
- it('should get stuff even if some things are missing', function() {
37
+ it('should get stuff even if some things are missing', function () {
37
38
  var u = 'https://fake.example.co.uk/a/path/object//with/crap#hashy!';
38
39
  var p = url.parse(u);
39
40
  expect(p.protocol).to.eql('https:');
@@ -47,7 +48,7 @@ describe('parse', function() {
47
48
  expect(p.query).to.not.be.ok();
48
49
  expect(p.hash).to.eql('#hashy!');
49
50
  });
50
- it('should get stuff even the path is missing', function() {
51
+ it('should get stuff even the path is missing', function () {
51
52
  var u = 'https://fake.example.co.uk#hashy!';
52
53
  var p = url.parse(u);
53
54
  expect(p.protocol).to.eql('https:');
@@ -61,7 +62,7 @@ describe('parse', function() {
61
62
  expect(p.query).to.not.be.ok();
62
63
  expect(p.hash).to.eql('#hashy!');
63
64
  });
64
- it('should get stuff with a query and no path', function() {
65
+ it('should get stuff with a query and no path', function () {
65
66
  var u = 'https://fake.example.co.uk?a=b';
66
67
  var p = url.parse(u);
67
68
  expect(p.protocol).to.eql('https:');
@@ -75,7 +76,7 @@ describe('parse', function() {
75
76
  expect(p.query).to.eql('a=b');
76
77
  expect(p.hash).to.not.be.ok();
77
78
  });
78
- it('should get stuff with a query and blank path', function() {
79
+ it('should get stuff with a query and blank path', function () {
79
80
  var u = 'https://fake.example.co.uk/?a=b';
80
81
  var p = url.parse(u);
81
82
  expect(p.protocol).to.eql('https:');
@@ -89,7 +90,7 @@ describe('parse', function() {
89
90
  expect(p.query).to.eql('a=b');
90
91
  expect(p.hash).to.not.be.ok();
91
92
  });
92
- it('should get stuff with a missing protocol', function() {
93
+ it('should get stuff with a missing protocol', function () {
93
94
  var u = '//fake.example.co.uk/v1/#hashash';
94
95
  var p = url.parse(u);
95
96
  expect(p.protocol).to.not.be.ok();
@@ -103,7 +104,7 @@ describe('parse', function() {
103
104
  expect(p.query).to.not.be.ok();
104
105
  expect(p.hash).to.eql('#hashash');
105
106
  });
106
- it('should handle missing protocol without slashes', function() {
107
+ it('should handle missing protocol without slashes', function () {
107
108
  var u = 'api.rollbar.com/api/1';
108
109
  var p = url.parse(u);
109
110
  expect(p.protocol).to.not.be.ok();