govuk_frontend_toolkit 3.1.0 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,124 @@
1
+ describe("GOVUK.GoogleAnalyticsClassicTracker", function() {
2
+ var classic;
3
+
4
+ beforeEach(function() {
5
+ window._gaq = [];
6
+ classic = new GOVUK.GoogleAnalyticsClassicTracker('id', 'cookie-domain.com');
7
+ });
8
+
9
+ it('can load the libraries needed to run classic Google Analytics', function() {
10
+ delete window._gaq;
11
+ $('[src*="google-analytics.com/ga.js"]').remove();
12
+
13
+ GOVUK.GoogleAnalyticsClassicTracker.load();
14
+ expect($('script[async][src*="google-analytics.com/ga.js"]').length).toBe(1);
15
+ });
16
+
17
+ describe('when created', function() {
18
+ it('configures a Google tracker using the provided profile ID and cookie domain', function() {
19
+ expect(window._gaq[0]).toEqual(['_setAccount', 'id']);
20
+ expect(window._gaq[1]).toEqual(['_setDomainName', 'cookie-domain.com']);
21
+ });
22
+
23
+ it('allows cross site linking', function() {
24
+ expect(window._gaq[2]).toEqual(['_setAllowLinker', true]);
25
+ });
26
+
27
+ it('anonymises the IP', function() {
28
+ expect(window._gaq[3]).toEqual(['_gat._anonymizeIp']);
29
+ });
30
+ });
31
+
32
+ describe('when pageviews are tracked', function() {
33
+ beforeEach(function() {
34
+ // reset queue after setup
35
+ window._gaq = [];
36
+ });
37
+
38
+ it('sends them to Google Analytics', function() {
39
+ classic.trackPageview();
40
+ expect(window._gaq[0]).toEqual(['_trackPageview']);
41
+ });
42
+
43
+ it('can track a virtual pageview', function() {
44
+ classic.trackPageview('/nicholas-page');
45
+ expect(window._gaq[0]).toEqual(['_trackPageview', '/nicholas-page']);
46
+ });
47
+ });
48
+
49
+ describe('when events are tracked', function() {
50
+ beforeEach(function() {
51
+ // reset queue after setup
52
+ window._gaq = [];
53
+ });
54
+
55
+ it('sends them to Google Analytics', function() {
56
+ classic.trackEvent('category', 'action', {label: 'label'});
57
+ expect(window._gaq[0]).toEqual(['_trackEvent', 'category', 'action', 'label']);
58
+ });
59
+
60
+ it('the label is optional', function() {
61
+ classic.trackEvent('category', 'action');
62
+ expect(window._gaq[0]).toEqual(['_trackEvent', 'category', 'action']);
63
+ });
64
+
65
+ it('a value can be tracked if the label is omitted', function() {
66
+ classic.trackEvent('category', 'action', {value: 10});
67
+ expect(window._gaq[0]).toEqual(['_trackEvent', 'category', 'action', '', 10]);
68
+ });
69
+
70
+ it('only sends values if they are parseable as numbers', function() {
71
+ classic.trackEvent('category', 'action', {label: 'label', value: '10'});
72
+ expect(window._gaq[0]).toEqual(['_trackEvent', 'category', 'action', 'label', 10]);
73
+
74
+ classic.trackEvent('category', 'action', {label: 'label', value: 10});
75
+ expect(window._gaq[1]).toEqual(['_trackEvent', 'category', 'action', 'label', 10]);
76
+
77
+ classic.trackEvent('category', 'action', {label: 'label', value: 'not a number'});
78
+ expect(window._gaq[2]).toEqual(['_trackEvent', 'category', 'action', 'label']);
79
+ });
80
+
81
+ it('can mark an event as non interactive', function() {
82
+ classic.trackEvent('category', 'action', {label: 'label', value: 1, nonInteraction: true});
83
+ expect(window._gaq[0]).toEqual(['_trackEvent', 'category', 'action', 'label', 1, true]);
84
+ });
85
+
86
+ it('can mark an event as non interactive without a value', function() {
87
+ classic.trackEvent('category', 'action', {label: 'label', nonInteraction: true});
88
+ expect(window._gaq[0]).toEqual(['_trackEvent', 'category', 'action', 'label', 0, true]);
89
+ });
90
+
91
+ it('can mark an event as non interactive without a label or value', function() {
92
+ classic.trackEvent('category', 'action', {nonInteraction: true});
93
+ expect(window._gaq[0]).toEqual(['_trackEvent', 'category', 'action', '', 0, true]);
94
+ });
95
+ });
96
+
97
+ describe('when social events are tracked', function() {
98
+ beforeEach(function() {
99
+ window._gaq = [];
100
+ });
101
+
102
+ it('sends them to Google Analytics', function() {
103
+ classic.trackSocial('network', 'action', 'target');
104
+ expect(window._gaq[0]).toEqual(['_trackSocial', 'network', 'action', 'target']);
105
+ });
106
+ });
107
+
108
+ describe('when setting a custom variable', function() {
109
+ beforeEach(function() {
110
+ // reset queue after setup
111
+ window._gaq = [];
112
+ });
113
+
114
+ it('sends the variable to Google Analytics', function() {
115
+ classic.setCustomVariable(1, 'value', 'name', 10);
116
+ expect(window._gaq[0]).toEqual(['_setCustomVar', 1, 'name', 'value', 10]);
117
+ });
118
+
119
+ it('coerces the value to a string', function() {
120
+ classic.setCustomVariable(1, 100, 'name', 10);
121
+ expect(window._gaq[0]).toEqual(['_setCustomVar', 1, 'name', '100', 10]);
122
+ });
123
+ });
124
+ });
@@ -0,0 +1,122 @@
1
+ describe("GOVUK.GoogleAnalyticsUniversalTracker", function() {
2
+ var universal;
3
+
4
+ beforeEach(function() {
5
+ window.ga = function() {};
6
+ spyOn(window, 'ga');
7
+ universal = new GOVUK.GoogleAnalyticsUniversalTracker('id', 'cookie-domain.com');
8
+ });
9
+
10
+ it('can load the libraries needed to run universal Google Analytics', function() {
11
+ delete window.ga;
12
+ $('[src="//www.google-analytics.com/analytics.js"]').remove();
13
+ GOVUK.GoogleAnalyticsUniversalTracker.load();
14
+ expect($('script[async][src="//www.google-analytics.com/analytics.js"]').length).toBe(1);
15
+ expect(typeof window.ga).toBe('function');
16
+
17
+ window.ga('send message');
18
+ expect(window.ga.q[0]).toEqual(jasmine.any(Object));
19
+ });
20
+
21
+ describe('when created', function() {
22
+ var setupArguments;
23
+
24
+ beforeEach(function() {
25
+ setupArguments = window.ga.calls.allArgs();
26
+ });
27
+
28
+ it('configures a Google tracker using the provided profile ID and cookie domain', function() {
29
+ expect(setupArguments[0]).toEqual(['create', 'id', {'cookieDomain': 'cookie-domain.com'}]);
30
+ });
31
+
32
+ it('anonymises the IP', function() {
33
+ expect(setupArguments[1]).toEqual(['set', 'anonymizeIp', true]);
34
+ });
35
+ });
36
+
37
+ describe('when pageviews are tracked', function() {
38
+ it('sends them to Google Analytics', function() {
39
+ universal.trackPageview();
40
+ expect(window.ga.calls.mostRecent().args).toEqual(['send', 'pageview']);
41
+ });
42
+
43
+ it('can track a virtual pageview', function() {
44
+ universal.trackPageview('/nicholas-page');
45
+ expect(window.ga.calls.mostRecent().args).toEqual(['send', 'pageview', {page: '/nicholas-page'}]);
46
+ });
47
+
48
+ it('can track a virtual pageview with a custom title', function() {
49
+ universal.trackPageview('/nicholas-page', 'Nicholas Page');
50
+ expect(window.ga.calls.mostRecent().args).toEqual(['send', 'pageview', {page: '/nicholas-page', title: 'Nicholas Page'}]);
51
+ });
52
+ });
53
+
54
+ describe('when events are tracked', function() {
55
+ function eventObjectFromSpy() {
56
+ return window.ga.calls.mostRecent().args[1];
57
+ }
58
+
59
+ it('sends them to Google Analytics', function() {
60
+ universal.trackEvent('category', 'action', {label: 'label'});
61
+ expect(window.ga.calls.mostRecent().args).toEqual(
62
+ ['send', {hitType: 'event', eventCategory: 'category', eventAction: 'action', eventLabel: 'label'}]
63
+ );
64
+ });
65
+
66
+ it('the label is optional', function() {
67
+ universal.trackEvent('category', 'action');
68
+ expect(window.ga.calls.mostRecent().args).toEqual(
69
+ ['send', {hitType: 'event', eventCategory: 'category', eventAction: 'action'}]
70
+ );
71
+ });
72
+
73
+ it('only sends values if they are parseable as numbers', function() {
74
+ universal.trackEvent('category', 'action', {label: 'label', value: '10'});
75
+ expect(eventObjectFromSpy()['eventValue']).toEqual(10);
76
+
77
+ universal.trackEvent('category', 'action', {label: 'label', value: 10});
78
+ expect(eventObjectFromSpy()['eventValue']).toEqual(10);
79
+
80
+ universal.trackEvent('category', 'action', {label: 'label', value: 'not a number'});
81
+ expect(eventObjectFromSpy()['eventValue']).toEqual(undefined);
82
+ });
83
+
84
+ it('can mark an event as non interactive', function() {
85
+ universal.trackEvent('category', 'action', {label: 'label', value: 0, nonInteraction: true});
86
+ expect(window.ga.calls.mostRecent().args).toEqual(
87
+ ['send', {
88
+ hitType: 'event',
89
+ eventCategory: 'category',
90
+ eventAction: 'action',
91
+ eventLabel: 'label',
92
+ eventValue: 0,
93
+ nonInteraction: 1
94
+ }]
95
+ );
96
+ });
97
+ });
98
+
99
+ describe('when social events are tracked', function() {
100
+ it('sends them to Google Analytics', function() {
101
+ universal.trackSocial('network', 'action', 'target');
102
+ expect(window.ga.calls.mostRecent().args).toEqual(['send', {
103
+ 'hitType': 'social',
104
+ 'socialNetwork': 'network',
105
+ 'socialAction': 'action',
106
+ 'socialTarget': 'target'
107
+ }]);
108
+ });
109
+ });
110
+
111
+ describe('when setting a custom dimension', function() {
112
+ it('sends the dimension to Google Analytics with the specified index and value', function() {
113
+ universal.setDimension(1, 'value');
114
+ expect(window.ga.calls.mostRecent().args).toEqual(['set', 'dimension1', 'value']);
115
+ });
116
+
117
+ it('coerces the value to a string', function() {
118
+ universal.setDimension(1, 10);
119
+ expect(window.ga.calls.mostRecent().args).toEqual(['set', 'dimension1', '10']);
120
+ });
121
+ });
122
+ });
@@ -0,0 +1,74 @@
1
+ describe("GOVUK.Tracker", function() {
2
+ var tracker;
3
+
4
+ beforeEach(function() {
5
+ window._gaq = [];
6
+ window.ga = function() {};
7
+ spyOn(window, 'ga');
8
+ this.config = {
9
+ universalId: 'universal-id',
10
+ classicId: 'classic-id',
11
+ cookieDomain: '.www.gov.uk'
12
+ };
13
+ });
14
+
15
+ describe('when created', function() {
16
+ var universalSetupArguments;
17
+
18
+ beforeEach(function () {
19
+ tracker = new GOVUK.Tracker(this.config);
20
+ universalSetupArguments = window.ga.calls.allArgs();
21
+ });
22
+
23
+ it('configures classic and universal trackers', function () {
24
+ expect(window._gaq[0]).toEqual(['_setAccount', 'classic-id']);
25
+ expect(window._gaq[1]).toEqual(['_setDomainName', '.www.gov.uk']);
26
+ expect(universalSetupArguments[0]).toEqual(['create', 'universal-id', {'cookieDomain': '.www.gov.uk'}]);
27
+ });
28
+ });
29
+
30
+ describe('when tracking pageviews, events and custom dimensions', function() {
31
+
32
+ beforeEach(function() {
33
+ tracker = new GOVUK.Tracker(this.config);
34
+ });
35
+
36
+ it('tracks in both classic and universal', function() {
37
+ window._gaq = [];
38
+ tracker.trackPageview('/path', 'Title');
39
+ expect(window._gaq[0]).toEqual(['_trackPageview', '/path']);
40
+ expect(window.ga.calls.mostRecent().args).toEqual(['send', 'pageview', {page: '/path', title: 'Title'}]);
41
+
42
+ window._gaq = [];
43
+ tracker.trackEvent('category', 'action');
44
+ expect(window._gaq[0]).toEqual(['_trackEvent', 'category', 'action']);
45
+ expect(window.ga.calls.mostRecent().args).toEqual(['send', {hitType: 'event', eventCategory: 'category', eventAction: 'action'}]);
46
+
47
+ window._gaq = [];
48
+ tracker.setDimension(1, 'value', 'name');
49
+ expect(window._gaq[0]).toEqual(['_setCustomVar', 1, 'name', 'value', 3]);
50
+ expect(window.ga.calls.mostRecent().args).toEqual(['set', 'dimension1', 'value']);
51
+ });
52
+ });
53
+
54
+ describe('when tracking social media shares', function() {
55
+
56
+ beforeEach(function() {
57
+ tracker = new GOVUK.Tracker(this.config);
58
+ });
59
+
60
+ it('tracks in both classic and universal', function() {
61
+ window._gaq = [];
62
+ tracker.trackShare('network');
63
+
64
+ expect(window._gaq[0]).toEqual(['_trackSocial', 'network', 'share', jasmine.any(String)]);
65
+ expect(window.ga.calls.mostRecent().args).toEqual(['send', {
66
+ hitType: 'social',
67
+ socialNetwork: 'network',
68
+ socialAction: 'share',
69
+ socialTarget: jasmine.any(String)
70
+ }]);
71
+ });
72
+ });
73
+
74
+ });
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: govuk_frontend_toolkit
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 3.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-12-02 00:00:00.000000000 Z
12
+ date: 2015-03-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
- requirement: &11238300 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,15 @@ dependencies:
21
21
  version: 3.1.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *11238300
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 3.1.0
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: sass
27
- requirement: &11236700 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ! '>='
@@ -32,29 +37,44 @@ dependencies:
32
37
  version: 3.2.0
33
38
  type: :runtime
34
39
  prerelease: false
35
- version_requirements: *11236700
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 3.2.0
36
46
  - !ruby/object:Gem::Dependency
37
47
  name: gem_publisher
38
- requirement: &11235360 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
39
49
  none: false
40
50
  requirements:
41
- - - =
51
+ - - '='
42
52
  - !ruby/object:Gem::Version
43
53
  version: 1.3.1
44
54
  type: :development
45
55
  prerelease: false
46
- version_requirements: *11235360
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 1.3.1
47
62
  - !ruby/object:Gem::Dependency
48
63
  name: rake
49
- requirement: &11234200 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
50
65
  none: false
51
66
  requirements:
52
- - - =
67
+ - - '='
53
68
  - !ruby/object:Gem::Version
54
69
  version: 0.9.2.2
55
70
  type: :development
56
71
  prerelease: false
57
- version_requirements: *11234200
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - '='
76
+ - !ruby/object:Gem::Version
77
+ version: 0.9.2.2
58
78
  description:
59
79
  email: bradley.wright@digital.cabinet-office.gov.uk
60
80
  executables: []
@@ -84,6 +104,9 @@ files:
84
104
  - app/assets/LICENCE
85
105
  - app/assets/README.md
86
106
  - app/assets/VERSION.txt
107
+ - app/assets/docs/analytics.md
108
+ - app/assets/docs/javascript.md
109
+ - app/assets/docs/mixins.md
87
110
  - app/assets/images/accordian-arrow-2x.png
88
111
  - app/assets/images/accordian-arrow.png
89
112
  - app/assets/images/arrow-sprite.png
@@ -207,6 +230,11 @@ files:
207
230
  - app/assets/images/player-icon-play.png
208
231
  - app/assets/images/player-icon-rewind.png
209
232
  - app/assets/images/player-icon-volume.png
233
+ - app/assets/javascripts/govuk/analytics/error-tracking.js
234
+ - app/assets/javascripts/govuk/analytics/google-analytics-classic-tracker.js
235
+ - app/assets/javascripts/govuk/analytics/google-analytics-universal-tracker.js
236
+ - app/assets/javascripts/govuk/analytics/print-intent.js
237
+ - app/assets/javascripts/govuk/analytics/tracker.js
210
238
  - app/assets/javascripts/govuk/multivariate-test.js
211
239
  - app/assets/javascripts/govuk/primary-links.js
212
240
  - app/assets/javascripts/govuk/selection-buttons.js
@@ -227,6 +255,9 @@ files:
227
255
  - app/assets/spec/unit/PrimaryLinksSpec.js
228
256
  - app/assets/spec/unit/SelectionButtonSpec.js
229
257
  - app/assets/spec/unit/StickAtTopWhenScrollingSpec.js
258
+ - app/assets/spec/unit/analytics/GoogleAnalyticsClassicTrackerSpec.js
259
+ - app/assets/spec/unit/analytics/GoogleAnalyticsUniversalTrackerSpec.js
260
+ - app/assets/spec/unit/analytics/TrackerSpec.js
230
261
  - app/assets/stylesheets/.gitkeep
231
262
  - app/assets/stylesheets/_colours.scss
232
263
  - app/assets/stylesheets/_conditionals.scss
@@ -257,7 +288,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
257
288
  version: '0'
258
289
  segments:
259
290
  - 0
260
- hash: -4114693619292822888
291
+ hash: -1949845834061421958
261
292
  required_rubygems_version: !ruby/object:Gem::Requirement
262
293
  none: false
263
294
  requirements:
@@ -266,10 +297,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
266
297
  version: '0'
267
298
  segments:
268
299
  - 0
269
- hash: -4114693619292822888
300
+ hash: -1949845834061421958
270
301
  requirements: []
271
302
  rubyforge_project:
272
- rubygems_version: 1.8.11
303
+ rubygems_version: 1.8.23
273
304
  signing_key:
274
305
  specification_version: 3
275
306
  summary: Tools for building frontend applications