diff --git a/src/browser/telemetry.js b/src/browser/telemetry.js index 04a854710..e4e965781 100644 --- a/src/browser/telemetry.js +++ b/src/browser/telemetry.js @@ -179,7 +179,9 @@ Instrumenter.prototype.instrumentNetwork = function() { var xhrp = this._window.XMLHttpRequest.prototype; replace(xhrp, 'open', function(orig) { return function(method, url) { - if (_.isType(url, 'string')) { + var isUrlObject = _isUrlObject(url) + if (_.isType(url, 'string') || isUrlObject) { + url = isUrlObject ? url.toString() : url; if (this.__rollbar_xhr) { this.__rollbar_xhr.method = method; this.__rollbar_xhr.url = url; @@ -342,8 +344,9 @@ Instrumenter.prototype.instrumentNetwork = function() { var input = args[0]; var method = 'GET'; var url; - if (_.isType(input, 'string')) { - url = input; + var isUrlObject = _isUrlObject(input) + if (_.isType(input, 'string') || isUrlObject) { + url = isUrlObject ? input.toString() : input; } else if (input) { url = input.url; if (input.method) { @@ -770,4 +773,8 @@ Instrumenter.prototype.removeListeners = function(section) { } }; +function _isUrlObject(input) { + return typeof URL !== 'undefined' && input instanceof URL +} + module.exports = Instrumenter; diff --git a/test/browser.telemetry.test.js b/test/browser.telemetry.test.js new file mode 100644 index 000000000..cf2eafd22 --- /dev/null +++ b/test/browser.telemetry.test.js @@ -0,0 +1,69 @@ +/* globals expect */ +/* globals describe */ +/* globals it */ +/* globals sinon */ + +var Instrumenter = require('../src/browser/telemetry'); + +describe('instrumentNetwork', function () { + it('should capture XHR requests with string URL', function (done) { + var callback = sinon.spy(); + var windowMock = { + XMLHttpRequest: function () { } + } + + windowMock.XMLHttpRequest.prototype.open = function () { } + windowMock.XMLHttpRequest.prototype.send = function () { } + + var i = createInstrumenter(callback, windowMock) + i.instrumentNetwork() + + var xhr = new windowMock.XMLHttpRequest(); + xhr.open('GET', 'http://first.call') + xhr.send() + xhr.onreadystatechange() + + expect(callback.callCount).to.eql(1) + expect(callback.args[0][0].url).to.eql('http://first.call') + + i.deinstrumentNetwork() + i = createInstrumenter(callback, windowMock) + i.instrumentNetwork() + var xhr = new windowMock.XMLHttpRequest(); + xhr.open('GET', new URL('http://second.call')) + xhr.send() + xhr.onreadystatechange() + expect(callback.callCount).to.eql(2) + expect(callback.args[1][0].url).to.eql('http://second.call/') + + done() + }) + + it('should capture XHR requests with string URL', function (done) { + var callback = sinon.spy(); + var windowMock = { + fetch: function () { return Promise.resolve() } + } + + var i = createInstrumenter(callback, windowMock); + i.instrumentNetwork() + + windowMock.fetch('http://first.call') + expect(callback.callCount).to.eql(1) + expect(callback.args[0][0].url).to.eql('http://first.call') + + i.deinstrumentNetwork() + i = createInstrumenter(callback, windowMock) + i.instrumentNetwork() + + windowMock.fetch(new URL('http://second.call')) + expect(callback.callCount).to.eql(2) + expect(callback.args[1][0].url).to.eql('http://second.call/') + + done() + }) +}) + +function createInstrumenter(callback, windowMock) { + return new Instrumenter({ scrubFields: [] }, { captureNetwork: callback }, { wrap: function () { }, client: { notifier: { diagnostic: {} } } }, windowMock); +} \ No newline at end of file