diff --git a/boomerang.js b/boomerang.js
index 0ab0ce655..94e567c9e 100644
--- a/boomerang.js
+++ b/boomerang.js
@@ -1453,6 +1453,24 @@ BOOMR_check_doc_domain();
}
},
+ /**
+ * MutationObserver feature detection
+ *
+ * @returns {boolean} Returns true if MutationObserver is supported.
+ * Always returns false for IE 11 due several bugs in it's implementation that MS flagged as Won't Fix.
+ * In IE11, XHR responseXML might be malformed if MO is enabled (where extra newlines get added in nodes with UTF-8 content).
+ * Another IE 11 MO bug can cause the process to crash when certain mutations occur.
+ * For the process crash issue, see https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8137215/ and
+ * https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/15167323/
+ *
+ * @memberof BOOMR.utils
+ */
+ isMutationObserverSupported: function() {
+ // We can only detect IE 11 bugs by UA sniffing.
+ var ie11 = (w && w.navigator && w.navigator.userAgent && w.navigator.userAgent.match(/Trident.*rv[ :]*11\./));
+ return (!ie11 && w && w.MutationObserver && typeof w.MutationObserver === "function");
+ },
+
/**
* The callback function may return a falsy value to disconnect the
* observer after it returns, or a truthy value to keep watching for
@@ -1492,7 +1510,7 @@ BOOMR_check_doc_domain();
addObserver: function(el, config, timeout, callback, callback_data, callback_ctx) {
var o = {observer: null, timer: null};
- if (!BOOMR.window || !BOOMR.window.MutationObserver || !callback || !el) {
+ if (!this.isMutationObserverSupported() || !callback || !el) {
return null;
}
diff --git a/plugins/auto-xhr.js b/plugins/auto-xhr.js
index a93d7224b..8a94c2cfd 100644
--- a/plugins/auto-xhr.js
+++ b/plugins/auto-xhr.js
@@ -77,6 +77,9 @@
* [MutationObserver]{@link https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver}
* and [XMLHttpRequest]{@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest}.
*
+ * We will not use MutationObserver in IE 11 due to several browser bugs.
+ * See {@link BOOMR.utils.isMutationObserverSupported} for details.
+ *
* ## Excluding Certain Requests From Instrumentation
*
* Whenever Boomerang intercepts an `XMLHttpRequest`, it will check if that request
@@ -222,8 +225,7 @@
singlePageApp = false,
autoXhrEnabled = false,
alwaysSendXhr = false,
- readyStateMap = ["uninitialized", "open", "responseStart", "domInteractive", "responseEnd"],
- ie10or11;
+ readyStateMap = ["uninitialized", "open", "responseStart", "domInteractive", "responseEnd"];
/**
* Single Page Applications get an additional timeout for all XHR Requests to settle in.
@@ -315,14 +317,6 @@
return;
}
- // User-agent sniff IE 10 and IE 11 to apply a workaround for an XHR bug (see below when
- // this variable is used). We can only detect this bug by UA sniffing. IE 11 requires a
- // different way of detection than IE 11.
- ie10or11 = (w.navigator && w.navigator.appVersion && w.navigator.appVersion.indexOf("MSIE 10") !== -1) ||
- (w.navigator && w.navigator.userAgent && w.navigator.userAgent.match(/Trident.*rv[ :]*11\./));
-
-
-
function log(msg) {
BOOMR.debug(msg, "AutoXHR");
}
@@ -1546,19 +1540,6 @@
if (ename === "readystatechange") {
resource.timing[readyStateMap[req.readyState]] = BOOMR.now();
- // For IE 10 and 11, we need to turn off the MutationObserver before responseXML
- // is first referenced, otherwise responseXML might be malformed due to a browser
- // bug (where extra newlines get added in nodes with UTF-8 content)
- if (impl.ie1011fix && ie10or11 && req.readyState === 4) {
- MutationHandler.pause();
-
- // this reference to responseXML with MO off is enough to ensure the browser
- // bug is not triggered
- var nop = req.responseXML;
-
- MutationHandler.resume();
- }
-
// Listen here as well, as DOM changes might happen on other listeners
// of readyState = 4 (complete), and we want to make sure we've
// started the addEvent() if so. Only listen if the status is non-zero,
@@ -1702,8 +1683,6 @@
* Container for AutoXHR plugin Closure specific state configuration data
*
* @property {string[]} spaBackendResources Default resources to count as Back-End during a SPA nav
- * @property {boolean} ie1011fix If true, the MutationObserver will be paused on
- * IE10/11 to avoid delayed processing, see {@link ProxyXHRImplementation#addListener} for more info
* @property {FilterObject[]} filters Array of {@link FilterObject} that is used to apply filters on XHR Requests
* @property {boolean} initialized Set to true after the first run of
* @property {string[]} addedVars Vars added to the next beacon only
@@ -1711,7 +1690,6 @@
*/
impl = {
spaBackEndResources: SPA_RESOURCES_BACK_END,
- ie1011fix: true,
excludeFilters: [],
initialized: false,
addedVars: [],
@@ -1788,8 +1766,6 @@
* @param {boolean} [config.instrument_xhr] Whether or not to instrument XHR
* @param {string[]} [config.AutoXHR.spaBackEndResources] Default resources to count as
* Back-End during a SPA nav
- * @param {boolean} [config.AutoXHR.ie1011fix] If true, the MutationObserver will be paused on
- * IE10/11 to avoid delayed processing
* @param {boolean} [config.AutoXHR.alwaysSendXhr] Whether or not to send XHR
* beacons for every XHR.
*
@@ -1808,7 +1784,7 @@
a = BOOMR.window.document.createElement("A");
// gather config and config overrides
- BOOMR.utils.pluginConfig(impl, config, "AutoXHR", ["spaBackEndResources", "ie1011fix"]);
+ BOOMR.utils.pluginConfig(impl, config, "AutoXHR", ["spaBackEndResources"]);
BOOMR.instrumentXHR = instrumentXHR;
BOOMR.uninstrumentXHR = uninstrumentXHR;
diff --git a/tests/boomerang-test-framework.js b/tests/boomerang-test-framework.js
index 72095a14b..bfb454975 100644
--- a/tests/boomerang-test-framework.js
+++ b/tests/boomerang-test-framework.js
@@ -407,7 +407,11 @@
};
t.isMutationObserverSupported = function() {
- return (window.MutationObserver && typeof window.MutationObserver === "function");
+ var w = window;
+ // Use the same logic as BOOM.utils.isMutationObserverSupported.
+ // Boomerang will not use MO in IE 11 due to browser bugs
+ var ie11 = (w && w.navigator && w.navigator.userAgent && w.navigator.userAgent.match(/Trident.*rv[ :]*11\./));
+ return (!ie11 && w && w.MutationObserver && typeof w.MutationObserver === "function");
};
t.validateBeaconWasXhr = function(done) {
diff --git a/tests/page-templates/05-angular/03-ng-app.js b/tests/page-templates/05-angular/03-ng-app.js
index 717ed87e6..b2497ff2e 100644
--- a/tests/page-templates/05-angular/03-ng-app.js
+++ b/tests/page-templates/05-angular/03-ng-app.js
@@ -18,26 +18,26 @@ describe("e2e/05-angular/03-ng-app", function() {
});
it("Should take as long as the longest img load (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
t.validateBeaconWasSentAfter(0, "img.jpg", 100, 3000, 30000, true);
}
});
it("Should not have a load time (if MutationObserver is supported but NavigationTiming is not)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() === "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() === "undefined") {
var b = tf.lastBeacon();
assert.equal(b.t_done, undefined);
}
});
it("Should take as long as the XHRs (if MutationObserver is not supported but NavigationTiming is)", function() {
- if (typeof window.MutationObserver === "undefined" && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (!t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
t.validateBeaconWasSentAfter(0, "widgets.json", 100, 0, 30000, true);
}
});
it("Shouldn't have a load time (if MutationObserver and NavigationTiming are not supported)", function() {
- if (typeof window.MutationObserver === "undefined" && typeof BOOMR.plugins.RT.navigationStart() === "undefined") {
+ if (!t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() === "undefined") {
var b = tf.lastBeacon();
assert.equal(b.t_done, undefined);
assert.equal(b["rt.start"], "none");
diff --git a/tests/page-templates/05-angular/102-ui-router.js b/tests/page-templates/05-angular/102-ui-router.js
index fe7a113c2..be6b43df8 100644
--- a/tests/page-templates/05-angular/102-ui-router.js
+++ b/tests/page-templates/05-angular/102-ui-router.js
@@ -33,26 +33,26 @@ describe("e2e/05-angular/102-ui-router", function() {
});
it("Should take as long as the longest img load (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
t.validateBeaconWasSentAfter(0, "img.jpg&id=home", 500, 3000, 30000, 0);
}
});
it("Should not have a load time (if MutationObserver is supported but NavigationTiming is not)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() === "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() === "undefined") {
var b = tf.beacons[0];
assert.equal(b.t_done, undefined);
}
});
it("Should take as long as the XHRs (if MutationObserver is not supported but NavigationTiming is)", function() {
- if (typeof window.MutationObserver === "undefined" && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (!t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
t.validateBeaconWasSentAfter(0, "widgets.json", 500, 0, 30000, false);
}
});
it("Shouldn't have a load time (if MutationObserver and NavigationTiming are not supported)", function() {
- if (typeof window.MutationObserver === "undefined" && typeof BOOMR.plugins.RT.navigationStart() === "undefined") {
+ if (!t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() === "undefined") {
var b = tf.beacons[0];
assert.equal(b.t_done, undefined);
assert.equal(b["rt.start"], "none");
@@ -68,7 +68,7 @@ describe("e2e/05-angular/102-ui-router", function() {
});
it("Should have sent the second beacon with a timestamp of at least 1 second (if MutationObserver is supported)", function() {
- if (window.MutationObserver) {
+ if (t.isMutationObserverSupported()) {
// because of the widget IMG delaying 1 second
var b = tf.beacons[1];
assert.operator(b.t_done, ">=", 1000);
@@ -76,7 +76,7 @@ describe("e2e/05-angular/102-ui-router", function() {
});
it("Should have sent the second beacon with a timestamp of at least 1 millisecond (if MutationObserver is not supported)", function() {
- if (typeof window.MutationObserver === "undefined") {
+ if (!t.isMutationObserverSupported()) {
// because of the widget IMG delaying 1 second but we couldn't track it because no MO support
var b = tf.beacons[1];
assert.operator(b.t_done, ">=", 0);
@@ -92,14 +92,14 @@ describe("e2e/05-angular/102-ui-router", function() {
});
it("Should have sent the third with a timestamp of at least 3 seconds (if MutationObserver is supported)", function() {
- if (window.MutationObserver) {
+ if (t.isMutationObserverSupported()) {
var b = tf.beacons[2];
assert.operator(b.t_done, ">=", 3000);
}
});
it("Should have sent the third with a timestamp of under 1 second (if MutationObserver is not supported)", function() {
- if (!window.MutationObserver) {
+ if (!t.isMutationObserverSupported()) {
var b = tf.beacons[2];
assert.operator(b.t_done, "<=", 1000);
}
diff --git a/tests/page-templates/05-angular/108-location-change-only.js b/tests/page-templates/05-angular/108-location-change-only.js
index 775a14331..5db71710b 100644
--- a/tests/page-templates/05-angular/108-location-change-only.js
+++ b/tests/page-templates/05-angular/108-location-change-only.js
@@ -55,27 +55,27 @@ describe("e2e/05-angular/108-location-change-only", function() {
});
it("Should have a load time (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
var b = tf.beacons[0];
assert.isDefined(b.t_done);
}
});
it("Should not have a load time (if MutationObserver is supported but NavigationTiming is not)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() === "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() === "undefined") {
var b = tf.beacons[0];
assert.equal(b.t_done, undefined);
}
});
it("Should take as long as the XHRs (if MutationObserver is not supported but NavigationTiming is)", function() {
- if (typeof window.MutationObserver === "undefined" && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (!t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
t.validateBeaconWasSentAfter(0, "widgets.json", 500, 0, 30000, false);
}
});
it("Shouldn't have a load time (if MutationObserver and NavigationTiming are not supported)", function() {
- if (typeof window.MutationObserver === "undefined" && typeof BOOMR.plugins.RT.navigationStart() === "undefined") {
+ if (!t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() === "undefined") {
var b = tf.beacons[0];
assert.equal(b.t_done, undefined);
assert.equal(b["rt.start"], "none");
@@ -83,7 +83,7 @@ describe("e2e/05-angular/108-location-change-only", function() {
});
it("Should have a t_resp of the root page (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
var pt = window.performance.timing;
var b = tf.beacons[0];
assert.equal(b.t_resp, pt.responseStart - pt.navigationStart);
@@ -91,7 +91,7 @@ describe("e2e/05-angular/108-location-change-only", function() {
});
it("Should have a t_page of total - t_resp (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
var pt = window.performance.timing;
var b = tf.beacons[0];
assert.equal(b.t_page, b.t_done - b.t_resp);
@@ -107,7 +107,7 @@ describe("e2e/05-angular/108-location-change-only", function() {
});
it("Should have sent the second beacon with a timestamp of ~0 seconds (if MutationObserver is supported)", function() {
- if (window.MutationObserver) {
+ if (t.isMutationObserverSupported()) {
var b = tf.beacons[1];
assert.closeTo(b.t_done, 0, 50);
}
@@ -122,7 +122,7 @@ describe("e2e/05-angular/108-location-change-only", function() {
});
it("Should have sent the third with a timestamp of at around 0 seconds (if MutationObserver is supported)", function() {
- if (window.MutationObserver) {
+ if (t.isMutationObserverSupported()) {
var b = tf.beacons[2];
assert.closeTo(b.t_done, 0, 50);
}
diff --git a/tests/page-templates/05-angular/109-multiple-iframes.html b/tests/page-templates/05-angular/109-multiple-iframes.html
index 80e5a8a5d..8686d1d2a 100644
--- a/tests/page-templates/05-angular/109-multiple-iframes.html
+++ b/tests/page-templates/05-angular/109-multiple-iframes.html
@@ -2,8 +2,8 @@
<%= boomerangScript %>
-
-
+
+
+
+
<%= footer %>
diff --git a/tests/page-templates/05-angular/113-late-locationchangestart.js b/tests/page-templates/05-angular/113-late-locationchangestart.js
index 2caf142aa..cf43d6196 100644
--- a/tests/page-templates/05-angular/113-late-locationchangestart.js
+++ b/tests/page-templates/05-angular/113-late-locationchangestart.js
@@ -33,26 +33,26 @@ describe("e2e/05-angular/113-late-locationchangestart", function() {
});
it("Should take as long as the longest img load (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
t.validateBeaconWasSentAfter(0, "img.jpg&id=home", 500, 3000, 30000, 0);
}
});
it("Should not have a load time (if MutationObserver is supported but NavigationTiming is not)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() === "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() === "undefined") {
var b = tf.beacons[0];
assert.equal(b.t_done, undefined);
}
});
it("Should take as long as the XHRs (if MutationObserver is not supported but NavigationTiming is)", function() {
- if (typeof window.MutationObserver === "undefined" && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (!t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
t.validateBeaconWasSentAfter(0, "widgets.json", 500, 0, 30000, false);
}
});
it("Shouldn't have a load time (if MutationObserver and NavigationTiming are not supported)", function() {
- if (typeof window.MutationObserver === "undefined" && typeof BOOMR.plugins.RT.navigationStart() === "undefined") {
+ if (!t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() === "undefined") {
var b = tf.beacons[0];
assert.equal(b.t_done, undefined);
assert.equal(b["rt.start"], "none");
@@ -68,7 +68,7 @@ describe("e2e/05-angular/113-late-locationchangestart", function() {
});
it("Should have sent the second beacon with a timestamp of at least 1 second (if MutationObserver is supported)", function() {
- if (window.MutationObserver) {
+ if (t.isMutationObserverSupported()) {
// because of the widget IMG delaying 1 second
var b = tf.beacons[1];
assert.operator(b.t_done, ">=", 1000);
@@ -76,7 +76,7 @@ describe("e2e/05-angular/113-late-locationchangestart", function() {
});
it("Should have sent the second beacon with a timestamp of at least 1 millisecond (if MutationObserver is not supported)", function() {
- if (typeof window.MutationObserver === "undefined") {
+ if (!t.isMutationObserverSupported()) {
// because of the widget IMG delaying 1 second but we couldn't track it because no MO support
var b = tf.beacons[1];
assert.operator(b.t_done, ">=", 0);
@@ -92,14 +92,14 @@ describe("e2e/05-angular/113-late-locationchangestart", function() {
});
it("Should have sent the third with a timestamp of at least 3 seconds (if MutationObserver is supported)", function() {
- if (window.MutationObserver) {
+ if (t.isMutationObserverSupported()) {
var b = tf.beacons[2];
assert.operator(b.t_done, ">=", 3000);
}
});
it("Should have sent the third with a timestamp of under 1 second (if MutationObserver is not supported)", function() {
- if (!window.MutationObserver) {
+ if (!t.isMutationObserverSupported()) {
var b = tf.beacons[2];
assert.operator(b.t_done, "<=", 1000);
}
diff --git a/tests/page-templates/05-angular/114-route-change-abld.js b/tests/page-templates/05-angular/114-route-change-abld.js
index 54ddcbfd5..c1e12636b 100644
--- a/tests/page-templates/05-angular/114-route-change-abld.js
+++ b/tests/page-templates/05-angular/114-route-change-abld.js
@@ -65,13 +65,13 @@ describe("e2e/05-angular/114-route-change-abld", function() {
});
it("Should have sent the first beacon with a load time of when the abort happened (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
assert.closeTo(tf.beacons[0].t_done, window.nav1time - BOOMR.plugins.RT.navigationStart(), 100);
}
});
it("Should have sent the first beacon without a load time (if MutationObserver is supported but NavigationTiming is not)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() === "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() === "undefined") {
var b = tf.beacons[0];
assert.equal(b.t_done, undefined);
assert.equal(b["rt.start"], "none");
@@ -79,7 +79,7 @@ describe("e2e/05-angular/114-route-change-abld", function() {
});
it("Should have sent the first beacon with a t_resp of the root page (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
var pt = window.performance.timing;
var b = tf.beacons[0];
assert.equal(b.t_resp, pt.responseStart - pt.navigationStart);
@@ -87,7 +87,7 @@ describe("e2e/05-angular/114-route-change-abld", function() {
});
it("Should have sent the first beacon with a t_page of total - t_resp (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
var pt = window.performance.timing;
var b = tf.beacons[0];
assert.equal(b.t_page, b.t_done - b.t_resp);
@@ -95,7 +95,7 @@ describe("e2e/05-angular/114-route-change-abld", function() {
});
it("Should have sent the first beacon with rt.quit and rt.abld (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
var b = tf.beacons[0];
assert.equal(b["rt.quit"], "");
assert.equal(b["rt.abld"], "");
@@ -137,14 +137,14 @@ describe("e2e/05-angular/114-route-change-abld", function() {
});
it("Should have sent the second beacon with a timestamp of when the abort happened (if MutationObserver is supported)", function() {
- if (window.MutationObserver) {
+ if (t.isMutationObserverSupported()) {
var b = tf.beacons[1];
assert.closeTo(b.t_done, window.nav2time - b["rt.tstart"], 100);
}
});
it("Should have sent the second beacon with a timestamp of at least 1 millisecond (if MutationObserver is not supported)", function() {
- if (typeof window.MutationObserver === "undefined") {
+ if (!t.isMutationObserverSupported()) {
// because of the widget IMG delaying 1 second but we couldn't track it because no MO support
var b = tf.beacons[1];
assert.operator(b.t_done, ">=", 0);
@@ -152,7 +152,7 @@ describe("e2e/05-angular/114-route-change-abld", function() {
});
it("Should have sent the second beacon with a t_resp value (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
var pt = window.performance.timing;
var b = tf.beacons[1];
@@ -161,7 +161,7 @@ describe("e2e/05-angular/114-route-change-abld", function() {
});
it("Should have sent the second beacon with a t_page of total - t_resp (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
var pt = window.performance.timing;
var b = tf.beacons[1];
assert.equal(b.t_page, b.t_done - b.t_resp);
@@ -169,7 +169,7 @@ describe("e2e/05-angular/114-route-change-abld", function() {
});
it("Should have sent the second beacon with rt.quit and rt.abld (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
var b = tf.beacons[1];
assert.equal(b["rt.quit"], "");
assert.equal(b["rt.abld"], "");
@@ -211,21 +211,21 @@ describe("e2e/05-angular/114-route-change-abld", function() {
});
it("Should have sent the third with a timestamp of at least 3 seconds (if MutationObserver is supported)", function() {
- if (window.MutationObserver) {
+ if (t.isMutationObserverSupported()) {
var b = tf.beacons[2];
assert.operator(b.t_done, ">=", 3000);
}
});
it("Should have sent the third with a timestamp of under 1 second (if MutationObserver is not supported)", function() {
- if (!window.MutationObserver) {
+ if (!t.isMutationObserverSupported()) {
var b = tf.beacons[2];
assert.operator(b.t_done, "<=", 1000);
}
});
it("Should have sent the third beacon with a t_resp value (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
var pt = window.performance.timing;
var b = tf.beacons[2];
@@ -234,7 +234,7 @@ describe("e2e/05-angular/114-route-change-abld", function() {
});
it("Should have sent the third beacon with a t_page of total - t_resp (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
var pt = window.performance.timing;
var b = tf.beacons[2];
assert.equal(b.t_page, b.t_done - b.t_resp);
diff --git a/tests/page-templates/05-angular/115-no-url-change.js b/tests/page-templates/05-angular/115-no-url-change.js
index 13dd30384..3f18c792e 100644
--- a/tests/page-templates/05-angular/115-no-url-change.js
+++ b/tests/page-templates/05-angular/115-no-url-change.js
@@ -38,26 +38,26 @@ describe("e2e/05-angular/115-no-url-change", function() {
});
it("Should take as long as the longest img load (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
t.validateBeaconWasSentAfter(0, "img.jpg&id=home", 500, 3000, 30000, 0);
}
});
it("Should not have a load time (if MutationObserver is supported but NavigationTiming is not)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() === "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() === "undefined") {
var b = tf.beacons[0];
assert.equal(b.t_done, undefined);
}
});
it("Should take as long as the XHRs (if MutationObserver is not supported but NavigationTiming is)", function() {
- if (typeof window.MutationObserver === "undefined" && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (!t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
t.validateBeaconWasSentAfter(0, "widgets.json", 500, 0, 30000, false);
}
});
it("Shouldn't have a load time (if MutationObserver and NavigationTiming are not supported)", function() {
- if (typeof window.MutationObserver === "undefined" && typeof BOOMR.plugins.RT.navigationStart() === "undefined") {
+ if (!t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() === "undefined") {
var b = tf.beacons[0];
assert.equal(b.t_done, undefined);
assert.equal(b["rt.start"], "none");
@@ -73,7 +73,7 @@ describe("e2e/05-angular/115-no-url-change", function() {
});
it("Should have sent the second beacon with a timestamp of at least 1 second (if MutationObserver is supported)", function() {
- if (window.MutationObserver) {
+ if (t.isMutationObserverSupported()) {
// because of the widget IMG delaying 1 second
var b = tf.beacons[1];
assert.operator(b.t_done, ">=", 1000);
@@ -81,7 +81,7 @@ describe("e2e/05-angular/115-no-url-change", function() {
});
it("Should have sent the second beacon with a timestamp of at least 1 millisecond (if MutationObserver is not supported)", function() {
- if (typeof window.MutationObserver === "undefined") {
+ if (!t.isMutationObserverSupported()) {
// because of the widget IMG delaying 1 second but we couldn't track it because no MO support
var b = tf.beacons[1];
assert.operator(b.t_done, ">=", 0);
@@ -97,14 +97,14 @@ describe("e2e/05-angular/115-no-url-change", function() {
});
it("Should have sent the third with a timestamp of at least 3 seconds (if MutationObserver is supported)", function() {
- if (window.MutationObserver) {
+ if (t.isMutationObserverSupported()) {
var b = tf.beacons[2];
assert.operator(b.t_done, ">=", 3000);
}
});
it("Should have sent the third with a timestamp of under 1 second (if MutationObserver is not supported)", function() {
- if (!window.MutationObserver) {
+ if (!t.isMutationObserverSupported()) {
var b = tf.beacons[2];
assert.operator(b.t_done, "<=", 1000);
}
diff --git a/tests/page-templates/05-angular/117-route-change-markcomplete.js b/tests/page-templates/05-angular/117-route-change-markcomplete.js
index 3d1200cc4..056315e99 100644
--- a/tests/page-templates/05-angular/117-route-change-markcomplete.js
+++ b/tests/page-templates/05-angular/117-route-change-markcomplete.js
@@ -65,13 +65,13 @@ describe("e2e/05-angular/117-route-change-markcomplete", function() {
});
it("Should have sent the first beacon with a load time of when the completion happened (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
assert.closeTo(tf.beacons[0].t_done, window.nav1time - BOOMR.plugins.RT.navigationStart(), 100);
}
});
it("Should have sent the first beacon without a load time (if MutationObserver is supported but NavigationTiming is not)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() === "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() === "undefined") {
var b = tf.beacons[0];
assert.equal(b.t_done, undefined);
assert.equal(b["rt.start"], "none");
@@ -79,7 +79,7 @@ describe("e2e/05-angular/117-route-change-markcomplete", function() {
});
it("Should have sent the first beacon with a t_resp of the root page (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
var pt = window.performance.timing;
var b = tf.beacons[0];
assert.equal(b.t_resp, pt.responseStart - pt.navigationStart);
@@ -87,7 +87,7 @@ describe("e2e/05-angular/117-route-change-markcomplete", function() {
});
it("Should have sent the first beacon with a t_page of total - t_resp (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
var pt = window.performance.timing;
var b = tf.beacons[0];
assert.equal(b.t_page, b.t_done - b.t_resp);
@@ -95,7 +95,7 @@ describe("e2e/05-angular/117-route-change-markcomplete", function() {
});
it("Should have sent the first beacon without rt.quit or rt.abld (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
var b = tf.beacons[0];
assert.isUndefined(b["rt.quit"]);
assert.isUndefined(b["rt.abld"]);
@@ -103,14 +103,14 @@ describe("e2e/05-angular/117-route-change-markcomplete", function() {
});
it("Should have sent the first beacon with spa.forced (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
var b = tf.beacons[0];
assert.equal(b["spa.forced"], "1");
}
});
it("Should have sent the first beacon with spa.waiting (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
var b = tf.beacons[0];
assert.operator(parseInt(b["spa.forced"], 10), ">=", 1);
}
@@ -151,14 +151,14 @@ describe("e2e/05-angular/117-route-change-markcomplete", function() {
});
it("Should have sent the second beacon with a timestamp of when the completion happened (if MutationObserver is supported)", function() {
- if (window.MutationObserver) {
+ if (t.isMutationObserverSupported()) {
var b = tf.beacons[1];
assert.closeTo(b.t_done, window.nav2time - b["rt.tstart"], 100);
}
});
it("Should have sent the second beacon with a timestamp of around 1 second (if MutationObserver is not supported)", function() {
- if (typeof window.MutationObserver === "undefined") {
+ if (!t.isMutationObserverSupported()) {
// because of the widget IMG delaying 1 second but we couldn't track it because no MO support
var b = tf.beacons[1];
assert.closeTo(parseInt(b.t_done, 10), 1000, 50);
@@ -166,7 +166,7 @@ describe("e2e/05-angular/117-route-change-markcomplete", function() {
});
it("Should have sent the second beacon with a t_resp value (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
var pt = window.performance.timing;
var b = tf.beacons[1];
@@ -175,7 +175,7 @@ describe("e2e/05-angular/117-route-change-markcomplete", function() {
});
it("Should have sent the second beacon with a t_page of total - t_resp (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
var pt = window.performance.timing;
var b = tf.beacons[1];
assert.equal(b.t_page, b.t_done - b.t_resp);
@@ -183,7 +183,7 @@ describe("e2e/05-angular/117-route-change-markcomplete", function() {
});
it("Should have sent the second beacon without rt.quit and rt.abld (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
var b = tf.beacons[1];
assert.isUndefined(b["rt.quit"]);
assert.isUndefined(b["rt.abld"]);
@@ -191,14 +191,14 @@ describe("e2e/05-angular/117-route-change-markcomplete", function() {
});
it("Should have sent the second beacon with spa.forced (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
var b = tf.beacons[1];
assert.equal(b["spa.forced"], "1");
}
});
it("Should have sent the second beacon with spa.waiting (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
var b = tf.beacons[1];
assert.operator(parseInt(b["spa.forced"], 10), ">=", 1);
}
@@ -239,21 +239,21 @@ describe("e2e/05-angular/117-route-change-markcomplete", function() {
});
it("Should have sent the third with a timestamp of at least 3 seconds (if MutationObserver is supported)", function() {
- if (window.MutationObserver) {
+ if (t.isMutationObserverSupported()) {
var b = tf.beacons[2];
assert.operator(parseInt(b.t_done, 10), ">=", 3000);
}
});
it("Should have sent the third with a timestamp of under 1 second (if MutationObserver is not supported)", function() {
- if (!window.MutationObserver) {
+ if (!t.isMutationObserverSupported()) {
var b = tf.beacons[2];
assert.operator(parseInt(b.t_done, 10), "<=", 1000);
}
});
it("Should have sent the third beacon with a t_resp value (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
var pt = window.performance.timing;
var b = tf.beacons[2];
@@ -262,7 +262,7 @@ describe("e2e/05-angular/117-route-change-markcomplete", function() {
});
it("Should have sent the third beacon with a t_page of total - t_resp (if MutationObserver and NavigationTiming are supported)", function() {
- if (window.MutationObserver && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
+ if (t.isMutationObserverSupported() && typeof BOOMR.plugins.RT.navigationStart() !== "undefined") {
var pt = window.performance.timing;
var b = tf.beacons[2];
assert.equal(b.t_page, b.t_done - b.t_resp);
diff --git a/tests/page-templates/07-autoxhr/01-img-src-change.html b/tests/page-templates/07-autoxhr/01-img-src-change.html
index 06dcc8470..e90086cb6 100644
--- a/tests/page-templates/07-autoxhr/01-img-src-change.html
+++ b/tests/page-templates/07-autoxhr/01-img-src-change.html
@@ -4,7 +4,7 @@
<%= boomerangScript %>