From 7994eb774064744b57e42002ba3295855c45ce98 Mon Sep 17 00:00:00 2001 From: Nigel Heron Date: Thu, 1 Dec 2022 16:54:57 -0500 Subject: [PATCH] Continuity: fix TTFI when EventTiming plugin is missing --- plugins/continuity.js | 11 ++-- .../45-interaction-no-eventtiming.html | 43 ++++++++++++ .../45-interaction-no-eventtiming.js | 66 +++++++++++++++++++ 3 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 tests/page-templates/21-continuity/45-interaction-no-eventtiming.html create mode 100644 tests/page-templates/21-continuity/45-interaction-no-eventtiming.js diff --git a/plugins/continuity.js b/plugins/continuity.js index d941e1ded..c348bf3db 100644 --- a/plugins/continuity.js +++ b/plugins/continuity.js @@ -3348,7 +3348,7 @@ * Analyzes Interactions */ function analyze(startTime) { - var fid; + var fid, ttfi, ET; impl.addToBeacon("c.i.dc", externalMetrics.interactionDelayed()); impl.addToBeacon("c.i.dt", externalMetrics.interactionDelayedTime()); @@ -3357,9 +3357,10 @@ // Only send FID and TTFI Timers once if (!sentTimers) { // defer to EventTiming's FID if available - if (BOOMR.plugins.EventTiming && - BOOMR.plugins.EventTiming.is_enabled()) { - fid = BOOMR.plugins.EventTiming.metrics.firstInputDelay(); + ET = BOOMR.plugins.EventTiming; + if (ET && ET.is_enabled()) { + fid = ET.metrics.firstInputDelay(); + ttfi = ET.metrics.timeToFirstInteraction(); } if (!fid && firstInputDelay !== null) { @@ -3369,7 +3370,7 @@ if (fid) { impl.addToBeacon("c.fid", Math.ceil(fid), true); - impl.addToBeacon("c.ttfi", BOOMR.plugins.EventTiming.metrics.timeToFirstInteraction() || + impl.addToBeacon("c.ttfi", ttfi || externalMetrics.timeToFirstInteraction()); sentTimers = true; diff --git a/tests/page-templates/21-continuity/45-interaction-no-eventtiming.html b/tests/page-templates/21-continuity/45-interaction-no-eventtiming.html new file mode 100644 index 000000000..8f89080ef --- /dev/null +++ b/tests/page-templates/21-continuity/45-interaction-no-eventtiming.html @@ -0,0 +1,43 @@ +<%= header %> + +<%= boomerangScript %> +

45-interaction-no-eventtiming loading...

+ + + +<%= footer %> diff --git a/tests/page-templates/21-continuity/45-interaction-no-eventtiming.js b/tests/page-templates/21-continuity/45-interaction-no-eventtiming.js new file mode 100644 index 000000000..1898cfb12 --- /dev/null +++ b/tests/page-templates/21-continuity/45-interaction-no-eventtiming.js @@ -0,0 +1,66 @@ +/*eslint-env mocha*/ +/*global BOOMR_test,assert*/ + +const {assert} = require("chai"); + +describe("e2e/21-continuity/45-interaction-no-eventtiming", function() { + var tf = BOOMR.plugins.TestFramework; + var t = BOOMR_test; + + it("Should have sent a single beacon validation", function(done) { + t.validateBeaconWasSent(done); + }); + + it("Should not have the EventTiming plugin", function(done) { + assert.isUndefined(BOOMR.plugins.EventTiming); + }); + + it("Should have sent the Time to First Interaction (c.ttfi)", function() { + var b = tf.lastBeacon(); + + assert.isDefined(b["c.ttfi"]); + var ttfi = parseInt(b["c.ttfi"], 10); + + if (t.isNavigationTimingSupported()) { + var st = parseInt(b["rt.tstart"], 10); + assert.closeTo(st + ttfi, window.ttfi, 20); + } + else { + assert.operator(ttfi, ">=", 0); + } + }); + + it("Should have the interaction timeline (c.t.inter)", function() { + var b = tf.lastBeacon(); + + assert.isDefined(b["c.t.inter"]); + assert.operator(b["c.t.inter"].length, ">=", 1); + }); + + it("Could have the interaction delay timeline (c.t.interdly)", function() { + var b = tf.lastBeacon(); + + if (b["c.i.a"]) { + assert.isDefined(b["c.t.interdly"]); + assert.operator(b["c.t.interdly"].length, ">=", 1); + } + }); + + it("Could have interaction delay metrics (c.i.a, c.i.dc and c.i.dt)", function() { + var b = tf.lastBeacon(); + + if (!b["c.i.a"]) { + assert.operator(parseInt(b["c.i.a"], 10), ">=", 1); + assert.operator(parseInt(b["c.i.dc"], 10), ">=", 1); + assert.operator(parseInt(b["c.i.dc"], 10), "<=", 10); + assert.operator(parseInt(b["c.i.dt"], 10), ">=", 1); + } + }); + + it("Should have First Input Delay (c.fid)", function() { + var b = tf.lastBeacon(); + + assert.isDefined(b["c.fid"]); + assert.operator(parseInt(b["c.fid"], 10), ">=", 19); // we had a 20ms busy wait, allow for some fuzzing + }); +});