From cd5ab8d101b3723d2278ec40698c005c2526c5ac Mon Sep 17 00:00:00 2001 From: Andreas Marschke Date: Mon, 24 Apr 2017 16:40:01 +0200 Subject: [PATCH] History: Option to disable hard navigation in favor of BOOMR.page_ready() --- Gruntfile.js | 4 +- plugins/history.js | 8 +++- plugins/spa.js | 28 +++++++---- .../12-react/108-hard-nav-disable.html | 35 ++++++++++++++ .../12-react/108-hard-nav-disable.js | 46 +++++++++++++++++++ .../12-react/21-constant-mutations.html | 2 +- tests/page-templates/12-react/support/app.jsx | 10 +++- 7 files changed, 118 insertions(+), 15 deletions(-) create mode 100644 tests/page-templates/12-react/108-hard-nav-disable.html create mode 100644 tests/page-templates/12-react/108-hard-nav-disable.js diff --git a/Gruntfile.js b/Gruntfile.js index f1e0c7084..65c2a1091 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -642,7 +642,9 @@ module.exports = function() { "tests/unit/**/*", "tests/test-templates/**/*.js", "!tests/page-templates/12-react/support/*.jsx", - "!*.#*" + "!*.#*", + "!*~", + "!#*#" ], tasks: ["pages-builder"] }, diff --git a/plugins/history.js b/plugins/history.js index ff4f0e2f3..e985824d5 100644 --- a/plugins/history.js +++ b/plugins/history.js @@ -6,7 +6,8 @@ hooked: false, routeHooked: false, hadMissedRouteChange: false, - routeChangeInProgress: false + routeChangeInProgress: false, + disableHardNav: false }; // Checking for Plugins required and if already integrated @@ -154,6 +155,9 @@ return true; }, hook: function(history, hadRouteChange, options) { + options = options || {}; + options.disableHardNav = impl.disableHardNav; + if (impl.hooked) { return this; } @@ -166,7 +170,7 @@ return this; }, init: function(config) { - BOOMR.utils.pluginConfig(impl, config, "History", ["auto", "enabled"]); + BOOMR.utils.pluginConfig(impl, config, "History", ["auto", "enabled", "disableHardNav"]); if (impl.auto && impl.enabled) { this.hook(undefined, true, {}); diff --git a/plugins/spa.js b/plugins/spa.js index e5ae61f01..71d30ea3a 100644 --- a/plugins/spa.js +++ b/plugins/spa.js @@ -7,6 +7,7 @@ firstSpaNav = true, routeFilter = false, routeChangeWaitFilter = false, + disableHardNav = false, supported = [], latestResource, waitingOnHardMissedComplete = false; @@ -127,8 +128,13 @@ // ensure the beacon is held until this SPA hard beacon is ready waitingOnHardMissedComplete = true; - // Trigger a route change - BOOMR.plugins.SPA.route_change(impl.spaHardMissedOnComplete); + if (!disableHardNav) { + // Trigger a route change + BOOMR.plugins.SPA.route_change(impl.spaHardMissedOnComplete); + } + else { + waitingOnHardMissedComplete = false; + } }, /** * Called by a framework when it has hooked into the target SPA @@ -145,12 +151,6 @@ return this; } - if (hadRouteChange) { - // kick off onLoadSpaHardMissed once onload has fired, or immediately - // if onload has already fired - BOOMR.attach_page_ready(this.onLoadSpaHardMissed); - } - if (typeof options.routeFilter === "function") { routeFilter = options.routeFilter; } @@ -159,6 +159,16 @@ routeChangeWaitFilter = options.routeChangeWaitFilter; } + if (options.disableHardNav) { + disableHardNav = options.disableHardNav; + } + + if (hadRouteChange) { + // kick off onLoadSpaHardMissed once onload has fired, or immediately + // if onload has already fired + BOOMR.attach_page_ready(this.onLoadSpaHardMissed); + } + hooked = true; return this; @@ -196,7 +206,7 @@ timing: { requestStart: requestStart }, - initiator: firstSpaNav ? "spa_hard" : "spa", + initiator: firstSpaNav && !disableHardNav ? "spa_hard" : "spa", url: url }; diff --git a/tests/page-templates/12-react/108-hard-nav-disable.html b/tests/page-templates/12-react/108-hard-nav-disable.html new file mode 100644 index 000000000..1af02650d --- /dev/null +++ b/tests/page-templates/12-react/108-hard-nav-disable.html @@ -0,0 +1,35 @@ +<%= header %> +<%= boomerangScript %> + + + + + +
+ + + + +<%= footer %> diff --git a/tests/page-templates/12-react/108-hard-nav-disable.js b/tests/page-templates/12-react/108-hard-nav-disable.js new file mode 100644 index 000000000..bf588452b --- /dev/null +++ b/tests/page-templates/12-react/108-hard-nav-disable.js @@ -0,0 +1,46 @@ +/*eslint-env mocha*/ +/*global BOOMR_test,describe,it,assert*/ + +describe("e2e/12-react/108-hard-nav-disable", function() { + var tf = BOOMR.plugins.TestFramework; + var t = BOOMR_test; + + var pathName = window.location.pathname; + + it("Should pass basic beacon validation", function(done) { + t.validateBeaconWasSent(done); + }); + + it("Should have sent three beacons", function() { + assert.equal(tf.beacons.length, 3); + }); + + it("Should have first beacon be navigation beacon", function() { + var b = tf.beacons[0]; + if (t.isNavigationTimingSupported()) { + assert.equal(b["rt.start"], "navigation"); + } + else { + assert.equal(b["rt.start"], "none"); + } + assert.isUndefined(b["http.initiator"]); + }); + + it("Should have a t_done close to 'timestamp - navigationStart'", function() { + var b = tf.beacons[0]; + if (t.isNavigationTimingSupported()) { + var navStToBoomrTDoneDelta = window.boomr_t_done - window.performance.timing.navigationStart; + assert.closeTo(navStToBoomrTDoneDelta, b.t_done, 100); + } + }); + + it("Second beacon should be soft navigation beacon", function() { + var b = tf.beacons[1]; + assert.equal(b["http.initiator"], "spa"); + }); + + it("Third beacon should be soft navigation beacon", function() { + var b = tf.beacons[2]; + assert.equal(b["http.initiator"], "spa"); + }); +}); diff --git a/tests/page-templates/12-react/21-constant-mutations.html b/tests/page-templates/12-react/21-constant-mutations.html index e89f720c8..96a4257ff 100644 --- a/tests/page-templates/12-react/21-constant-mutations.html +++ b/tests/page-templates/12-react/21-constant-mutations.html @@ -26,5 +26,5 @@ document.getElementById("content").appendChild(node); }, 100); -<%= footer %> +<%= footer %> diff --git a/tests/page-templates/12-react/support/app.jsx b/tests/page-templates/12-react/support/app.jsx index 2325dde37..c76edfcdf 100644 --- a/tests/page-templates/12-react/support/app.jsx +++ b/tests/page-templates/12-react/support/app.jsx @@ -71,7 +71,7 @@ const App = React.createClass({ if (!subscribed) { BOOMR.subscribe("onbeacon", function(beacon) { // only continue for SPA beacons - if (!BOOMR.utils.inArray(beacon["http.initiator"], BOOMR.constants.BEACON_TYPE_SPAS)) { + if (!BOOMR.utils.inArray(beacon["http.initiator"], BOOMR.constants.BEACON_TYPE_SPAS) && !window.call_page_ready) { return; } @@ -154,6 +154,12 @@ const Home = React.createClass({ } return widgetsElements; }, + imageOnload() { + if (window.call_page_ready && !window.boomr_t_done) { + window.boomr_t_done = BOOMR.now(); + BOOMR.page_ready(); + } + }, render() { var widgetsElements = this.renderWidgets(); @@ -166,7 +172,7 @@ const Home = React.createClass({ }; var src = `/delay?delay=${this.state.imgs[delayIndex]}&file=pages/12-react/support/img.jpg&id=home&rnd=${this.state.rnd}`; images.push(
- +
); }