diff --git a/CHANGELOG.md b/CHANGELOG.md index 37a8225a..700c7186 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,15 @@ # Unreleased -- Fix: Add support to show-hide-content.js for form fields with more varied characters: ([PR 403](https://github.com/alphagov/govuk_frontend_toolkit/pull/403)) +- Breaking change: Add support for Google Analytics Universal in stageprompt.js + + This is a breaking change since while we allow for the old behaviour, Google Analytics Universal is used by the default, which could change behaviour in applications. + + Also ensures that events triggered via GA Universal do not impact bounce-rate calculations, + which mirrors the original implementation. + + ([PR 421](https://github.com/alphagov/govuk_frontend_toolkit/pull/421)). + +- Fix: Add support to show-hide-content.js for form fields with more varied characters: ([PR 403](https://github.com/alphagov/govuk_frontend_toolkit/pull/403)). # 7.6.0 diff --git a/javascripts/stageprompt.js b/javascripts/stageprompt.js index c6310635..0a391afb 100644 --- a/javascripts/stageprompt.js +++ b/javascripts/stageprompt.js @@ -62,7 +62,13 @@ }()) GOVUK.performance.sendGoogleAnalyticsEvent = function (category, event, label) { - global._gaq.push(['_trackEvent', category, event, label, undefined, true]) + if (global.ga && typeof global.ga === 'function') { + global.ga('send', 'event', category, event, label, { + nonInteraction: true + }) + } else { + global._gaq.push(['_trackEvent', category, event, label, undefined, true]) + } } global.GOVUK = GOVUK diff --git a/spec/unit/stageprompt.spec.js b/spec/unit/stageprompt.spec.js new file mode 100644 index 00000000..373f116d --- /dev/null +++ b/spec/unit/stageprompt.spec.js @@ -0,0 +1,170 @@ +/* global describe it expect beforeEach afterEach jasmine */ + +var $ = window.jQuery + +describe('stageprompt', function () { + 'use strict' + var GOVUK = window.GOVUK + + var analyticsCallback + + beforeEach(function () { + $('
').appendTo('body') + }) + + afterEach(function () { + $('#sandbox').remove() + }) + + it('should exist in a namespace', function () { + expect(GOVUK.performance.stageprompt).not.toBeNull() + }) + + it('should not blow up if there are no data-journey tags', function () { + expect($('[data-journey]').length).toBe(0) + GOVUK.performance.stageprompt.setup(function () {}) + }) + + describe('fire the analytics callback when a data-journey tag is found', function () { + beforeEach(function () { + analyticsCallback = jasmine.createSpy() + $('
').appendTo('body') + }) + + afterEach(function () { + $('#sandbox').remove() + $('[data-journey]').removeAttr('data-journey') + }) + + it('should send an event if the page has a data-journey tag on the body', function () { + $('body').attr('data-journey', 'test-journey:someStage') + GOVUK.performance.stageprompt.setup(analyticsCallback) + + expect(analyticsCallback).toHaveBeenCalledWith('test-journey', 'someStage') + }) + + it('should send an event if the page has a data-journey tag on another tag', function () { + $('#sandbox').attr('data-journey', 'test-journey:nextStep') + + GOVUK.performance.stageprompt.setup(analyticsCallback) + + expect(analyticsCallback).toHaveBeenCalledWith('test-journey', 'nextStep') + }) + + it('should send one event if the page has multiple elements with data-journey attribute', function () { + $('#sandbox').attr('data-journey', 'test-journey:stuff') + $('#sandbox').html('

something

') + + GOVUK.performance.stageprompt.setup(analyticsCallback) + + expect(analyticsCallback.calls.count()).toBe(1) + }) + }) + + describe('callback arguments', function () { + var analyticsCallback + + beforeEach(function () { + analyticsCallback = jasmine.createSpy() + $('
').appendTo('body') + }) + + afterEach(function () { + $('#sandbox').remove() + $('[data-journey]').removeAttr('data-journey') + }) + + it('should pass action parts as separate arguments to the callback', function () { + $('#sandbox').attr('data-journey', 'part-1:part-2') + + GOVUK.performance.stageprompt.setup(analyticsCallback) + + expect(analyticsCallback).toHaveBeenCalledWith('part-1', 'part-2') + }) + + it('should pass a single-part action as one argument', function () { + $('#sandbox').attr('data-journey', 'single-part') + + GOVUK.performance.stageprompt.setup(analyticsCallback) + + expect(analyticsCallback).toHaveBeenCalledWith('single-part') + }) + + it('should pass at most three arguments to the callback', function () { + $('#sandbox').attr('data-journey', 'part-1:part-2:part-3:additional-content') + + GOVUK.performance.stageprompt.setup(analyticsCallback) + + expect(analyticsCallback).toHaveBeenCalledWith('part-1', 'part-2', 'part-3:additional-content') + }) + }) + + describe('sending events for click actions', function () { + beforeEach(function () { + analyticsCallback = jasmine.createSpy() + $('
').appendTo('body') + }) + + afterEach(function () { + $('#sandbox').remove() + }) + + it('should send an event when a help link is clicked', function () { + $('#sandbox').attr('data-journey-click', 'test-journey:stuff:help') + GOVUK.performance.stageprompt.setup(analyticsCallback) + + $('#sandbox').click() + + expect(analyticsCallback).toHaveBeenCalledWith('test-journey', 'stuff', 'help') + }) + + it('should send events for multiple help elements on the same page', function () { + $('#sandbox').append('foo') + $('#sandbox').append('bar') + + GOVUK.performance.stageprompt.setup(analyticsCallback) + $('#1').click() + $('#2').click() + + expect(analyticsCallback).toHaveBeenCalledWith('a') + expect(analyticsCallback).toHaveBeenCalledWith('b') + }) + + it('should send one event per click on tagged item', function () { + $('#sandbox').append('foo') + GOVUK.performance.stageprompt.setup(analyticsCallback) + + $('#1').click() + $('#1').click() + + expect(analyticsCallback.calls.count()).toBe(2) + }) + }) + + describe('out-of-the-box Google Analytics setup', function () { + beforeEach(function () { + $('
').appendTo('body') + }) + + afterEach(function () { + $('#gaTest').remove() + }) + + it('should get set up to send events to google analytics using ga() if it exists', function () { + window.ga = jasmine.createSpy('ga') + + GOVUK.performance.stageprompt.setupForGoogleAnalytics() + + expect(window.ga).toHaveBeenCalledWith('send', 'event', 'thisIsATest', undefined, undefined, { nonInteraction: true }) + }) + + it('should get set up to send events to google analytics using gaq.push() if ga() does not exist', function () { + delete window.ga + window._gaq = {push: jasmine.createSpy('_gaq.push')} + + GOVUK.performance.stageprompt.setupForGoogleAnalytics() + + expect(window._gaq.push).toHaveBeenCalledWith(['_trackEvent', 'thisIsATest', undefined, undefined, undefined, true]) + }) + }) +})