govuk_frontend_toolkit 7.6.0 → 9.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -0
  3. data/app/assets/.ruby-version +1 -1
  4. data/app/assets/CHANGELOG.md +37 -0
  5. data/app/assets/Gemfile +0 -1
  6. data/app/assets/Gruntfile.js +0 -3
  7. data/app/assets/README.md +7 -21
  8. data/app/assets/VERSION.txt +1 -1
  9. data/app/assets/docs/mixins.md +1 -1
  10. data/app/assets/javascripts/govuk/show-hide-content.js +1 -7
  11. data/app/assets/javascripts/stageprompt.js +7 -1
  12. data/app/assets/package-lock.json +2471 -0
  13. data/app/assets/spec/unit/show-hide-content.spec.js +57 -0
  14. data/app/assets/spec/unit/stageprompt.spec.js +170 -0
  15. data/app/assets/stylesheets/colours/_organisation.scss +1 -1
  16. data/govuk_frontend_toolkit.gemspec +0 -3
  17. data/publish.sh +1 -2
  18. metadata +5 -49
  19. data/Rakefile +0 -10
  20. data/app/assets/docs/analytics.md +0 -272
  21. data/app/assets/javascripts/govuk/analytics/analytics.js +0 -153
  22. data/app/assets/javascripts/govuk/analytics/download-link-tracker.js +0 -41
  23. data/app/assets/javascripts/govuk/analytics/error-tracking.js +0 -51
  24. data/app/assets/javascripts/govuk/analytics/external-link-tracker.js +0 -56
  25. data/app/assets/javascripts/govuk/analytics/google-analytics-universal-tracker.js +0 -176
  26. data/app/assets/javascripts/govuk/analytics/govuk-tracker.js +0 -134
  27. data/app/assets/javascripts/govuk/analytics/mailto-link-tracker.js +0 -38
  28. data/app/assets/javascripts/govuk/analytics/print-intent.js +0 -39
  29. data/app/assets/spec/unit/analytics/analytics.spec.js +0 -403
  30. data/app/assets/spec/unit/analytics/download-link-tracker.spec.js +0 -72
  31. data/app/assets/spec/unit/analytics/error-tracking.spec.js +0 -65
  32. data/app/assets/spec/unit/analytics/external-link-tracker.spec.js +0 -109
  33. data/app/assets/spec/unit/analytics/google-analytics-universal-tracker.spec.js +0 -187
  34. data/app/assets/spec/unit/analytics/govuk-tracker.spec.js +0 -171
  35. data/app/assets/spec/unit/analytics/mailto-link-tracker.spec.js +0 -62
@@ -1,65 +0,0 @@
1
- /* global describe it expect beforeEach afterEach spyOn */
2
-
3
- describe('GOVUK.analyticsPlugins.error', function () {
4
- 'use strict'
5
- var GOVUK = window.GOVUK
6
-
7
- GOVUK.analyticsPlugins.error({filenameMustMatch: /gov\.uk/})
8
-
9
- beforeEach(function () {
10
- GOVUK.analytics = {trackEvent: function () {}}
11
- spyOn(GOVUK.analytics, 'trackEvent')
12
- })
13
-
14
- afterEach(function () {
15
- delete GOVUK.analytics
16
- })
17
-
18
- it('sends errors to Google Analytics', function () {
19
- triggerError('https://www.gov.uk/filename.js', 2, 'Error message')
20
-
21
- expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith(
22
- 'JavaScript Error',
23
- 'Error message',
24
- { label: 'https://www.gov.uk/filename.js: 2', value: 1, nonInteraction: true })
25
- })
26
-
27
- it('tracks only errors with a matching or blank filename', function () {
28
- triggerError('http://www.gov.uk/somefile.js', 2, 'Error message')
29
- triggerError('', 2, 'In page error')
30
- triggerError('http://www.broken-external-plugin-site.com/horrible.js', 2, 'Error message')
31
-
32
- expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith(
33
- 'JavaScript Error',
34
- 'Error message',
35
- {
36
- label: 'http://www.gov.uk/somefile.js: 2',
37
- value: 1,
38
- nonInteraction: true })
39
-
40
- expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith(
41
- 'JavaScript Error',
42
- 'In page error',
43
- {
44
- label: ': 2',
45
- value: 1,
46
- nonInteraction: true })
47
-
48
- expect(GOVUK.analytics.trackEvent).not.toHaveBeenCalledWith(
49
- 'JavaScript Error',
50
- 'Error message',
51
- {
52
- label: 'http://www.broken-external-plugin-site.com/horrible.js: 2',
53
- value: 1,
54
- nonInteraction: true })
55
- })
56
-
57
- function triggerError (filename, lineno, message) {
58
- var event = document.createEvent('Event')
59
- event.initEvent('error', true, true)
60
- event.filename = filename
61
- event.lineno = lineno
62
- event.message = message
63
- window.dispatchEvent(event)
64
- }
65
- })
@@ -1,109 +0,0 @@
1
- /* global describe it expect beforeEach afterEach spyOn */
2
-
3
- var $ = window.jQuery
4
-
5
- describe('GOVUK.analyticsPlugins.externalLinkTracker', function () {
6
- 'use strict'
7
- var GOVUK = window.GOVUK
8
-
9
- var $links
10
-
11
- beforeEach(function () {
12
- $links = $(
13
- '<div class="external-links">' +
14
- '<a href="http://www.nationalarchives.gov.uk"> National Archives </a>' +
15
- '<a href="https://www.nationalarchives.gov.uk"></a>' +
16
- '<a href="https://www.nationalarchives.gov.uk/one.pdf">National Archives PDF</a>' +
17
- '<a href="https://www.nationalarchives.gov.uk/an/image/link.png"><img src="/img" /></a>' +
18
- '</div>' +
19
- '<div class="internal-links">' +
20
- '<a href="/some-path">Local link</a>' +
21
- '<a href="http://fake-hostname.com/some-path">Another local link</a>' +
22
- '</div>'
23
- )
24
-
25
- $('html').on('click', function (evt) { evt.preventDefault() })
26
- $('body').append($links)
27
- GOVUK.analytics = {
28
- trackEvent: function () {},
29
- setDimension: function () {}
30
- }
31
-
32
- spyOn(GOVUK.analyticsPlugins.externalLinkTracker, 'getHostname').and.returnValue('fake-hostname.com')
33
- })
34
-
35
- afterEach(function () {
36
- $('html').off()
37
- $('body').off()
38
- $links.remove()
39
- delete GOVUK.analytics
40
- })
41
-
42
- it('listens to click events on only external links', function () {
43
- GOVUK.analyticsPlugins.externalLinkTracker({externalLinkUploadCustomDimension: 36})
44
-
45
- spyOn(GOVUK.analytics, 'trackEvent')
46
-
47
- $('.external-links a').each(function () {
48
- $(this).trigger('click')
49
- expect(GOVUK.analytics.trackEvent).toHaveBeenCalled()
50
- GOVUK.analytics.trackEvent.calls.reset()
51
- })
52
-
53
- $('.internal-links a').each(function () {
54
- $(this).trigger('click')
55
- expect(GOVUK.analytics.trackEvent).not.toHaveBeenCalled()
56
- GOVUK.analytics.trackEvent.calls.reset()
57
- })
58
- })
59
-
60
- it('listens to click events on elements within external links', function () {
61
- GOVUK.analyticsPlugins.externalLinkTracker({externalLinkUploadCustomDimension: 36})
62
-
63
- spyOn(GOVUK.analytics, 'trackEvent')
64
-
65
- $('.external-links a img').trigger('click')
66
- expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith(
67
- 'External Link Clicked', 'https://www.nationalarchives.gov.uk/an/image/link.png', {transport: 'beacon'})
68
- })
69
-
70
- it('tracks an external link\'s href and link text', function () {
71
- GOVUK.analyticsPlugins.externalLinkTracker({externalLinkUploadCustomDimension: 36})
72
-
73
- spyOn(GOVUK.analytics, 'trackEvent')
74
- $('.external-links a').trigger('click')
75
-
76
- expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith(
77
- 'External Link Clicked', 'http://www.nationalarchives.gov.uk', {transport: 'beacon', label: 'National Archives'})
78
-
79
- expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith(
80
- 'External Link Clicked', 'https://www.nationalarchives.gov.uk', {transport: 'beacon'})
81
-
82
- expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith(
83
- 'External Link Clicked', 'https://www.nationalarchives.gov.uk/one.pdf', {transport: 'beacon', label: 'National Archives PDF'})
84
- })
85
-
86
- it('duplicates the url info in a custom dimension to be used to join with a Google Analytics upload', function () {
87
- GOVUK.analyticsPlugins.externalLinkTracker({externalLinkUploadCustomDimension: 36})
88
-
89
- spyOn(GOVUK.analytics, 'setDimension')
90
- spyOn(GOVUK.analytics, 'trackEvent')
91
- $('.external-links a').trigger('click')
92
-
93
- expect(GOVUK.analytics.setDimension).toHaveBeenCalledWith(36, 'http://www.nationalarchives.gov.uk')
94
- expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith(
95
- 'External Link Clicked', 'http://www.nationalarchives.gov.uk', {transport: 'beacon', label: 'National Archives'})
96
- })
97
-
98
- it('does not duplicate the url info if a custom dimension is not provided', function () {
99
- GOVUK.analyticsPlugins.externalLinkTracker()
100
-
101
- spyOn(GOVUK.analytics, 'setDimension')
102
- spyOn(GOVUK.analytics, 'trackEvent')
103
- $('.external-links a').trigger('click')
104
-
105
- expect(GOVUK.analytics.setDimension).not.toHaveBeenCalled()
106
- expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith(
107
- 'External Link Clicked', 'http://www.nationalarchives.gov.uk', {transport: 'beacon', label: 'National Archives'})
108
- })
109
- })
@@ -1,187 +0,0 @@
1
- /* global describe it expect beforeEach spyOn jasmine */
2
-
3
- var $ = window.jQuery
4
-
5
- describe('GOVUK.GoogleAnalyticsUniversalTracker', function () {
6
- 'use strict'
7
- var GOVUK = window.GOVUK
8
-
9
- function addGoogleAnalyticsSpy () {
10
- window.ga = function () {}
11
- spyOn(window, 'ga')
12
- }
13
-
14
- var universal
15
- var setupArguments
16
-
17
- beforeEach(function () {
18
- addGoogleAnalyticsSpy()
19
-
20
- universal = new GOVUK.GoogleAnalyticsUniversalTracker('id', {
21
- cookieDomain: 'cookie-domain.com',
22
- siteSpeedSampleRate: 100
23
- })
24
- })
25
-
26
- it('can load the libraries needed to run universal Google Analytics', function () {
27
- delete window.ga
28
- $('[src="https://www.google-analytics.com/analytics.js"]').remove()
29
- GOVUK.GoogleAnalyticsUniversalTracker.load()
30
- expect($('script[async][src="https://www.google-analytics.com/analytics.js"]').length).toBe(1)
31
- expect(typeof window.ga).toBe('function')
32
-
33
- window.ga('send message')
34
- expect(window.ga.q[0]).toEqual(jasmine.any(Object))
35
- })
36
-
37
- describe('when created', function () {
38
- beforeEach(function () {
39
- setupArguments = window.ga.calls.allArgs()
40
- })
41
-
42
- it('configures a Google tracker using the provided profile ID and config', function () {
43
- expect(setupArguments[0]).toEqual(['create', 'id', {cookieDomain: 'cookie-domain.com', siteSpeedSampleRate: 100}])
44
- })
45
-
46
- it('anonymises the IP', function () {
47
- expect(setupArguments[1]).toEqual(['set', 'anonymizeIp', true])
48
- })
49
- })
50
-
51
- describe('when created (with legacy non-object syntax)', function () {
52
- beforeEach(function () {
53
- addGoogleAnalyticsSpy()
54
-
55
- universal = new GOVUK.GoogleAnalyticsUniversalTracker('id', 'cookie-domain.com')
56
- setupArguments = window.ga.calls.allArgs()
57
- })
58
-
59
- it('configures a Google tracker using the provided profile ID and cookie domain', function () {
60
- expect(setupArguments[0]).toEqual(['create', 'id', {cookieDomain: 'cookie-domain.com'}])
61
- })
62
- })
63
-
64
- describe('when pageviews are tracked', function () {
65
- it('sends them to Google Analytics', function () {
66
- universal.trackPageview()
67
- expect(window.ga.calls.mostRecent().args).toEqual(['send', 'pageview'])
68
- })
69
-
70
- it('sends them to Google Analytics, forcing a new session', function () {
71
- universal.trackPageview(undefined, undefined, { sessionControl: 'start' })
72
- expect(window.ga.calls.mostRecent().args).toEqual(['send', 'pageview', {sessionControl: 'start'}])
73
- })
74
-
75
- it('can track a virtual pageview', function () {
76
- universal.trackPageview('/nicholas-page')
77
- expect(window.ga.calls.mostRecent().args).toEqual(['send', 'pageview', {page: '/nicholas-page'}])
78
- })
79
-
80
- it('can track a virtual pageview with a custom title', function () {
81
- universal.trackPageview('/nicholas-page', 'Nicholas Page')
82
- expect(window.ga.calls.mostRecent().args).toEqual(['send', 'pageview', {page: '/nicholas-page', title: 'Nicholas Page'}])
83
- })
84
-
85
- it('can set the transport method on a pageview', function () {
86
- universal.trackPageview('/t', 'T', {transport: 'beacon'})
87
- expect(window.ga.calls.mostRecent().args).toEqual(['send', 'pageview', {page: '/t', title: 'T', transport: 'beacon'}])
88
- })
89
- })
90
-
91
- describe('when events are tracked', function () {
92
- function eventObjectFromSpy () {
93
- return window.ga.calls.mostRecent().args[1]
94
- }
95
-
96
- it('sends them to Google Analytics', function () {
97
- universal.trackEvent('category', 'action', {label: 'label'})
98
- expect(window.ga.calls.mostRecent().args).toEqual(
99
- ['send', {hitType: 'event', eventCategory: 'category', eventAction: 'action', eventLabel: 'label'}]
100
- )
101
- })
102
-
103
- it('tracks custom dimensions', function () {
104
- universal.trackEvent('category', 'action', {dimension29: 'Home'})
105
- expect(window.ga.calls.mostRecent().args).toEqual(
106
- ['send', {hitType: 'event', eventCategory: 'category', eventAction: 'action', dimension29: 'Home'}]
107
- )
108
- })
109
-
110
- it('the label is optional', function () {
111
- universal.trackEvent('category', 'action')
112
- expect(window.ga.calls.mostRecent().args).toEqual(
113
- ['send', {hitType: 'event', eventCategory: 'category', eventAction: 'action'}]
114
- )
115
- })
116
-
117
- it('only sends values if they are parseable as numbers', function () {
118
- universal.trackEvent('category', 'action', {label: 'label', value: '10'})
119
- expect(eventObjectFromSpy()['eventValue']).toEqual(10)
120
-
121
- universal.trackEvent('category', 'action', {label: 'label', value: 10})
122
- expect(eventObjectFromSpy()['eventValue']).toEqual(10)
123
-
124
- universal.trackEvent('category', 'action', {label: 'label', value: 'not a number'})
125
- expect(eventObjectFromSpy()['eventValue']).toEqual(undefined)
126
- })
127
-
128
- it('can mark an event as non interactive', function () {
129
- universal.trackEvent('category', 'action', {label: 'label', value: 0, nonInteraction: true})
130
- expect(window.ga.calls.mostRecent().args).toEqual(
131
- ['send', {
132
- hitType: 'event',
133
- eventCategory: 'category',
134
- eventAction: 'action',
135
- eventLabel: 'label',
136
- eventValue: 0,
137
- nonInteraction: 1
138
- }]
139
- )
140
- })
141
-
142
- it('sends the page if supplied', function () {
143
- universal.trackEvent('category', 'action', {page: '/path/to/page'})
144
- expect(window.ga.calls.mostRecent().args).toEqual(
145
- ['send', {hitType: 'event', eventCategory: 'category', eventAction: 'action', page: '/path/to/page'}]
146
- )
147
- })
148
-
149
- it('can set the transport method on an event', function () {
150
- universal.trackEvent('category', 'action', {transport: 'beacon'})
151
- expect(window.ga.calls.mostRecent().args).toEqual(
152
- ['send', {hitType: 'event', eventCategory: 'category', eventAction: 'action', transport: 'beacon'}]
153
- )
154
- })
155
- })
156
-
157
- describe('when social events are tracked', function () {
158
- it('sends them to Google Analytics', function () {
159
- universal.trackSocial('network', 'action', 'target')
160
- expect(window.ga.calls.mostRecent().args).toEqual(['send', {
161
- 'hitType': 'social',
162
- 'socialNetwork': 'network',
163
- 'socialAction': 'action',
164
- 'socialTarget': 'target'
165
- }])
166
- })
167
- })
168
-
169
- describe('when setting a custom dimension', function () {
170
- it('sends the dimension to Google Analytics with the specified index and value', function () {
171
- universal.setDimension(1, 'value')
172
- expect(window.ga.calls.mostRecent().args).toEqual(['set', 'dimension1', 'value'])
173
- })
174
-
175
- it('coerces the value to a string', function () {
176
- universal.setDimension(1, 10)
177
- expect(window.ga.calls.mostRecent().args).toEqual(['set', 'dimension1', '10'])
178
- })
179
- })
180
-
181
- describe('when tracking all events', function () {
182
- window.history.replaceState(null, null, '?address=an.email@digital.cabinet-office.gov.uk')
183
- it('removes any email address from the location', function () {
184
- expect(window.ga.calls.mostRecent().args[2]).toContain('address=[email]')
185
- })
186
- })
187
- })
@@ -1,171 +0,0 @@
1
- /* global describe it expect beforeEach spyOn jasmine */
2
-
3
- var $ = window.jQuery
4
-
5
- describe('GOVUK.GOVUKTracker', function () {
6
- 'use strict'
7
- var GOVUK = window.GOVUK
8
-
9
- var tracker
10
-
11
- function setupFakeGa (clientId) {
12
- window.ga = function (cb) {
13
- cb({
14
- get: function () { return clientId }
15
- })
16
- }
17
- }
18
-
19
- beforeEach(function () {
20
- tracker = new GOVUK.GOVUKTracker('http://www.example.com/a.gif')
21
- })
22
-
23
- describe('sendData', function () {
24
- it('sends the data using AJAX', function () {
25
- spyOn($, 'get')
26
-
27
- tracker.sendData({foo: 'bar'})
28
- expect($.get).toHaveBeenCalledWith('http://www.example.com/a.gif?foo=bar')
29
- })
30
- })
31
-
32
- describe('payloadParams', function () {
33
- it('adds the event type', function () {
34
- var params = tracker.payloadParams('foo', {bar: 'qux'})
35
-
36
- expect(params.eventType).toEqual('foo')
37
- expect(params.bar).toEqual('qux')
38
- })
39
-
40
- it('adds the GA Client ID', function () {
41
- tracker.gaClientId = '123456.789012'
42
- var params = tracker.payloadParams('foo')
43
-
44
- expect(params.gaClientId).toEqual('123456.789012')
45
- })
46
-
47
- it('adds the referrer', function () {
48
- var params = tracker.payloadParams('foo')
49
-
50
- // Can't stub window.referrer so just test that we got a string, not undefined
51
- expect(typeof params.referrer).toEqual('string')
52
- })
53
-
54
- it('adds performance data', function () {
55
- var params = tracker.payloadParams('foo')
56
-
57
- expect(params.navigationType).toEqual('0')
58
- expect(params.redirectCount).toEqual('0')
59
-
60
- expect(params.timing_domComplete).toEqual(window.performance.timing.domComplete.toString())
61
- })
62
-
63
- it('adds custom dimensions', function () {
64
- tracker.setDimension(1, 'foo')
65
- tracker.setDimension(10, 'bar')
66
- var params = tracker.payloadParams('foo')
67
-
68
- expect(params.dimension1).toEqual('foo')
69
- expect(params.dimension10).toEqual('bar')
70
- })
71
-
72
- it('adds screen and window measurements', function () {
73
- var params = tracker.payloadParams('foo')
74
-
75
- expect(params.screenWidth).toEqual(window.screen.width)
76
- expect(params.screenHeight).toEqual(window.screen.height)
77
- expect(params.windowWidth).toEqual(window.innerWidth)
78
- expect(params.windowHeight).toEqual(window.innerHeight)
79
- expect(params.colorDepth).toEqual(window.screen.colorDepth)
80
- })
81
- })
82
-
83
- describe('sendToTracker', function () {
84
- it('sends when the DOM is complete', function () {
85
- setupFakeGa('123456.789012')
86
-
87
- spyOn(tracker, 'sendData')
88
- tracker.sendToTracker('foo')
89
-
90
- expect(tracker.sendData).toHaveBeenCalledWith(jasmine.any(Object))
91
- })
92
-
93
- it('sets the ga Client ID', function () {
94
- setupFakeGa('123456.789012')
95
-
96
- spyOn(tracker, 'sendData')
97
- tracker.sendToTracker('foo')
98
-
99
- expect(tracker.gaClientId).toEqual('123456.789012')
100
- })
101
- })
102
-
103
- describe('tracking', function () {
104
- beforeEach(function () {
105
- spyOn(tracker, 'sendToTracker')
106
- })
107
-
108
- describe('when pageviews are tracked', function () {
109
- it('sends them to the tracker', function () {
110
- tracker.trackPageview()
111
- expect(tracker.sendToTracker.calls.mostRecent().args).toEqual(['pageview'])
112
- })
113
- })
114
-
115
- describe('when events are tracked', function () {
116
- it('sends them to the tracker', function () {
117
- tracker.trackEvent('category', 'action', {label: 'label'})
118
- expect(tracker.sendToTracker.calls.mostRecent().args).toEqual(
119
- ['event', {eventCategory: 'category', eventAction: 'action', eventLabel: 'label'}]
120
- )
121
- })
122
-
123
- it('tracks custom dimensions', function () {
124
- tracker.trackEvent('category', 'action', {dimension29: 'Home'})
125
- expect(tracker.sendToTracker.calls.mostRecent().args).toEqual(
126
- ['event', {eventCategory: 'category', eventAction: 'action', dimension29: 'Home'}]
127
- )
128
- })
129
-
130
- it('the label is optional', function () {
131
- tracker.trackEvent('category', 'action')
132
- expect(tracker.sendToTracker.calls.mostRecent().args).toEqual(
133
- ['event', {eventCategory: 'category', eventAction: 'action'}]
134
- )
135
- })
136
-
137
- it('sends the page if supplied', function () {
138
- tracker.trackEvent('category', 'action', {page: '/path/to/page'})
139
- expect(tracker.sendToTracker.calls.mostRecent().args).toEqual(
140
- ['event', {eventCategory: 'category', eventAction: 'action', page: '/path/to/page'}]
141
- )
142
- })
143
-
144
- it('tracks multiple events', function () {
145
- tracker.trackEvent('category', 'action', {label: 'foo'})
146
- tracker.trackEvent('category', 'action', {label: 'bar'})
147
-
148
- expect(tracker.sendToTracker).toHaveBeenCalledWith(
149
- 'event', {eventCategory: 'category', eventAction: 'action', eventLabel: 'foo'}
150
- )
151
- expect(tracker.sendToTracker).toHaveBeenCalledWith(
152
- 'event', {eventCategory: 'category', eventAction: 'action', eventLabel: 'bar'}
153
- )
154
- })
155
- })
156
-
157
- describe('when social events are tracked', function () {
158
- it('sends them to Google Analytics', function () {
159
- tracker.trackSocial('network', 'action', 'target')
160
- expect(tracker.sendToTracker.calls.mostRecent().args).toEqual([
161
- 'social',
162
- {
163
- 'socialNetwork': 'network',
164
- 'socialAction': 'action',
165
- 'socialTarget': 'target'
166
- }
167
- ])
168
- })
169
- })
170
- })
171
- })