From 7b1d045c6edce186843cd971af0fd729b5c8ab25 Mon Sep 17 00:00:00 2001 From: hamish taylor Date: Mon, 11 Sep 2023 08:41:35 +1200 Subject: [PATCH 1/6] Added global var to check rg initilisation --- src/raygun.loader.js | 2 +- src/umd.intro.js | 66 +++++++++++++++++++++++++------------------- 2 files changed, 38 insertions(+), 30 deletions(-) diff --git a/src/raygun.loader.js b/src/raygun.loader.js index d68231d1..ab2baeb0 100644 --- a/src/raygun.loader.js +++ b/src/raygun.loader.js @@ -222,7 +222,7 @@ window[window['RaygunObject']] = function() { return executor(arguments); }; - + window['RaygunInitialized'] = true; globalExecutorInstalled = true; }; diff --git a/src/umd.intro.js b/src/umd.intro.js index 929d766d..d864f1c7 100644 --- a/src/umd.intro.js +++ b/src/umd.intro.js @@ -1,9 +1,9 @@ // https://github.com/umdjs/umd/blob/master/templates/returnExportsGlobal.js -(function (root, factory) { +(function(root, factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. - define('raygun4js', function () { + define('raygun4js', function() { return (root.Raygun = factory()); }); } else if (typeof module === 'object' && module.exports) { @@ -15,34 +15,42 @@ // Browser globals root.Raygun = factory(); } -}(this, function () { +}(this, function() { - var windw = this || window || global; - var originalOnError = windw.onerror; - windw.onerror = function (msg, url, line, col, err) { - if (originalOnError) { - originalOnError(msg, url, line, col, err); - } + var windw = this || window || global; + var originalOnError = windw.onerror; + windw.onerror = function(msg, url, line, col, err) { + if (originalOnError) { + originalOnError(msg, url, line, col, err); + } - if (!err) { - err = new Error(msg); - } + if (!err) { + err = new Error(msg); + } + + windw['rg4js'].q = windw['rg4js'].q || []; + windw['rg4js'].q.push({ e: err }); + }; + let isWindowLoaded = false; - windw['rg4js'].q = windw['rg4js'].q || []; - windw['rg4js'].q.push({e: err}); - }; + window.onload = function() { + isWindowLoaded = true; + }; + // Similar approach as the snippet, creates the rg4js proxy function, which is exported in umd.outro.js once the + // script is executed, and later overwritten by the loader once it's finished + (function(wind) { + wind['RaygunObject'] = 'rg4js'; + wind[wind['RaygunObject']] = wind[wind['RaygunObject']] || function() { + if (wind && typeof wind['Raygun'] === 'undefined' || + (typeof document === 'undefined' || document.readyState !== 'complete') || (wind['RaygunInitialized'] || false) === false) { + // onload hasn't been called, cache the commands just like the snippet + (wind[wind['RaygunObject']].o = wind[wind['RaygunObject']].o || []).push(arguments) + } else { + // onload has been called and provider has executed, call the executor proxy function + var test = wind[wind['RaygunObject']]; + console.log(test); + return wind[wind['RaygunObject']](arguments[0], arguments[1]); + } - // Similar approach as the snippet, creates the rg4js proxy function, which is exported in umd.outro.js once the - // script is executed, and later overwritten by the loader once it's finished - (function(wind) { wind['RaygunObject'] = 'rg4js'; - wind[wind['RaygunObject']] = wind[wind['RaygunObject']] || function() { - if (wind && typeof wind['Raygun'] === 'undefined' || - (typeof document === 'undefined' || document.readyState !== 'complete')) { - // onload hasn't been called, cache the commands just like the snippet - (wind[wind['RaygunObject']].o = wind[wind['RaygunObject']].o || []).push(arguments) - } else { - // onload has been called and provider has executed, call the executor proxy function - return wind[wind['RaygunObject']](arguments[0], arguments[1]); - } - - }})(windw); + } + })(windw); From 166758cee2b61ceba5e216bc7a40adaf8fb52363 Mon Sep 17 00:00:00 2001 From: hamish taylor Date: Mon, 11 Sep 2023 08:54:52 +1200 Subject: [PATCH 2/6] Cleaned up test code --- src/umd.intro.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/umd.intro.js b/src/umd.intro.js index d864f1c7..03a3aec4 100644 --- a/src/umd.intro.js +++ b/src/umd.intro.js @@ -31,11 +31,6 @@ windw['rg4js'].q = windw['rg4js'].q || []; windw['rg4js'].q.push({ e: err }); }; - let isWindowLoaded = false; - - window.onload = function() { - isWindowLoaded = true; - }; // Similar approach as the snippet, creates the rg4js proxy function, which is exported in umd.outro.js once the // script is executed, and later overwritten by the loader once it's finished (function(wind) { @@ -47,8 +42,6 @@ (wind[wind['RaygunObject']].o = wind[wind['RaygunObject']].o || []).push(arguments) } else { // onload has been called and provider has executed, call the executor proxy function - var test = wind[wind['RaygunObject']]; - console.log(test); return wind[wind['RaygunObject']](arguments[0], arguments[1]); } From 88a5e0d8b0fed67b37a5bd321f465652dee5e740 Mon Sep 17 00:00:00 2001 From: Hamish Taylor <48536946+Hamish-taylor@users.noreply.github.com> Date: Mon, 11 Sep 2023 10:15:59 +1200 Subject: [PATCH 3/6] Update src/umd.intro.js Co-authored-by: Darcy --- src/umd.intro.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/umd.intro.js b/src/umd.intro.js index 03a3aec4..eccd6d0c 100644 --- a/src/umd.intro.js +++ b/src/umd.intro.js @@ -37,7 +37,7 @@ wind['RaygunObject'] = 'rg4js'; wind[wind['RaygunObject']] = wind[wind['RaygunObject']] || function() { if (wind && typeof wind['Raygun'] === 'undefined' || - (typeof document === 'undefined' || document.readyState !== 'complete') || (wind['RaygunInitialized'] || false) === false) { + (typeof document === 'undefined' || document.readyState !== 'complete') || (!wind['RaygunInitialized']) { // onload hasn't been called, cache the commands just like the snippet (wind[wind['RaygunObject']].o = wind[wind['RaygunObject']].o || []).push(arguments) } else { From af025c2b1df5fc79c37688ba50d4ba93f2f639c7 Mon Sep 17 00:00:00 2001 From: hamish taylor Date: Mon, 11 Sep 2023 10:17:04 +1200 Subject: [PATCH 4/6] added missing ')' --- src/umd.intro.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/umd.intro.js b/src/umd.intro.js index eccd6d0c..b47b5781 100644 --- a/src/umd.intro.js +++ b/src/umd.intro.js @@ -37,7 +37,7 @@ wind['RaygunObject'] = 'rg4js'; wind[wind['RaygunObject']] = wind[wind['RaygunObject']] || function() { if (wind && typeof wind['Raygun'] === 'undefined' || - (typeof document === 'undefined' || document.readyState !== 'complete') || (!wind['RaygunInitialized']) { + (typeof document === 'undefined' || document.readyState !== 'complete') || (!wind['RaygunInitialized'])) { // onload hasn't been called, cache the commands just like the snippet (wind[wind['RaygunObject']].o = wind[wind['RaygunObject']].o || []).push(arguments) } else { From 06f78f0f14801904cc106d328e898187cc14b292 Mon Sep 17 00:00:00 2001 From: hamish taylor Date: Mon, 11 Sep 2023 15:46:28 +1200 Subject: [PATCH 5/6] Added test --- tests/fixtures/v2/UMDInfiniteLoop.html | 33 ++++++++++++++++++++++++ tests/specs/v2/UMDInfiniteLoopTest.js | 35 ++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 tests/fixtures/v2/UMDInfiniteLoop.html create mode 100644 tests/specs/v2/UMDInfiniteLoopTest.js diff --git a/tests/fixtures/v2/UMDInfiniteLoop.html b/tests/fixtures/v2/UMDInfiniteLoop.html new file mode 100644 index 00000000..1f5427ee --- /dev/null +++ b/tests/fixtures/v2/UMDInfiniteLoop.html @@ -0,0 +1,33 @@ + + + + + Raygun4JS with V2 API + + + + + + + + + + + diff --git a/tests/specs/v2/UMDInfiniteLoopTest.js b/tests/specs/v2/UMDInfiniteLoopTest.js new file mode 100644 index 00000000..7c433773 --- /dev/null +++ b/tests/specs/v2/UMDInfiniteLoopTest.js @@ -0,0 +1,35 @@ +var webdriverio = require('webdriverio'); + +describe("UMD Infinite loop test", function() { + beforeEach(async function() { + /** + * Clears the session between tests to ensure + * that the sessionstart event is always fired + */ + await browser.reloadSession(); + }); + + describe('test infinite loop is not caused', function() { + beforeEach(async function() { + await browser.url('http://localhost:4567/fixtures/v2/UMDInfiniteLoop.html'); + await browser.pause(1000); + }); + + it('succesfully sends the event', async function() { + var customTimingData = await browser.execute(function() { + console.log(window.__requestPayloads) + return window.__requestPayloads[2]; + }); + console.log(customTimingData.eventData[0].data); + expect(JSON.parse(customTimingData.eventData[0].data)[0]).toEqual({ + timing: { + a: "0.00", + du: "100.00", + t: "t" + }, + url: "timingName", + parentResource: { url: 'http://localhost:4567/fixtures/v2/UMDInfiniteLoop.html', type: 'p' } + }); + }); + }); +}); From 143d78e5df451a9c665234f7f21b0ca7b236e81c Mon Sep 17 00:00:00 2001 From: taylorhami Date: Wed, 13 Sep 2023 11:31:17 +1200 Subject: [PATCH 6/6] rebase --- CHANGELOG.md | 6 ++++++ bower.json | 2 +- package-lock.json | 4 ++-- package.json | 2 +- raygun4js.nuspec | 2 +- tests/specs/v2/UMDInfiniteLoopTest.js | 14 ++++++++++++++ 6 files changed, 25 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e81c813..d44c337a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Unused normalize.css file --> +## [2.27.3] + +### Changed + +- Fixes a rare condition with UMD where we assume rg4js is initialised but it is not, causing an infinite loop. + ## [2.27.2] diff --git a/bower.json b/bower.json index 4eff7868..5f4ebce8 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "raygun4js", - "version": "2.27.2", + "version": "2.27.3", "homepage": "http://raygun.com", "authors": [ "Mindscape " diff --git a/package-lock.json b/package-lock.json index 237d91d6..2739af11 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "raygun4js", - "version": "2.27.0", + "version": "2.27.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "raygun4js", - "version": "2.27.0", + "version": "2.27.1", "license": "SEE LICENSE IN https://github.com/MindscapeHQ/raygun4js/blob/master/LICENSE", "devDependencies": { "@wdio/cli": "^8.11.2", diff --git a/package.json b/package.json index 3031e204..613a5393 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ ], "title": "Raygun4js", "description": "Raygun.com plugin for JavaScript", - "version": "2.27.2", + "version": "2.27.3", "homepage": "https://github.com/MindscapeHQ/raygun4js", "author": { "name": "MindscapeHQ", diff --git a/raygun4js.nuspec b/raygun4js.nuspec index 0baccbd2..4ae03cfc 100644 --- a/raygun4js.nuspec +++ b/raygun4js.nuspec @@ -2,7 +2,7 @@ raygun4js - 2.27.2 + 2.27.3 Raygun4js Raygun Limited Raygun Limited diff --git a/tests/specs/v2/UMDInfiniteLoopTest.js b/tests/specs/v2/UMDInfiniteLoopTest.js index 7c433773..777f8706 100644 --- a/tests/specs/v2/UMDInfiniteLoopTest.js +++ b/tests/specs/v2/UMDInfiniteLoopTest.js @@ -1,5 +1,19 @@ var webdriverio = require('webdriverio'); + + + +/** +* What does this test do? +* When using the UMD module, if raygun events are fired (e.g. rg4js('send', ...)) +* before raygun is fully loaded they are stored in an object on the window. +* When Raygun loads these are then processed. +* However a bug was found where we were assuming raygun was loaded when +* `document.readyState === complete` but it is not loaded until slightly +* after when the `load` event is fired. This means that if a rayugn event +* is processed in this gap an infinite loop can be caused. +* This test ensures graceful handling of this situation +*/ describe("UMD Infinite loop test", function() { beforeEach(async function() { /**