govuk_frontend_toolkit 7.6.0 → 8.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -32,6 +32,18 @@ describe('show-hide-content', function () {
32
32
  '<div id="show-hide-radios" class="panel js-hidden" />' +
33
33
  '</form>' +
34
34
 
35
+ '<form>' +
36
+ '<div class="multiple-choice" data-target="show-hide-radios--name-with-characters-to-escape">' +
37
+ '<input type="radio" name="test.single[option1=\'value1\'][option2=\'value2\']" value="yes">' +
38
+ '<label>Yes</label>' +
39
+ '</div>' +
40
+ '<div class="multiple-choice">' +
41
+ '<input type="radio" name="test.single[option1=\'value1\'][option2=\'value2\']" value="no">' +
42
+ '<label>No</label>' +
43
+ '</div>' +
44
+ '<div id="show-hide-radios--name-with-characters-to-escape" class="panel js-hidden" />' +
45
+ '</form>' +
46
+
35
47
  // Checkboxes (multiple values)
36
48
  '<form>' +
37
49
  '<div class="multiple-choice" data-target="show-hide-checkboxes">' +
@@ -58,6 +70,10 @@ describe('show-hide-content', function () {
58
70
  this.$radio1 = $radios.eq(0)
59
71
  this.$radio2 = $radios.eq(1)
60
72
 
73
+ // Two more radios, with name attributes that include periods
74
+ this.$radio3 = $radios.eq(2)
75
+ this.$radio4 = $radios.eq(3)
76
+
61
77
  // Three checkboxes
62
78
  this.$checkbox1 = $checkboxes.eq(0)
63
79
  this.$checkbox2 = $checkboxes.eq(1)
@@ -68,6 +84,7 @@ describe('show-hide-content', function () {
68
84
 
69
85
  // Show/Hide content
70
86
  this.$radioShowHide = $('#show-hide-radios')
87
+ this.$radioShowHide_nameWithCharactersToEscape = $('#show-hide-radios--name-with-characters-to-escape')
71
88
  this.$checkboxShowHide = $('#show-hide-checkboxes')
72
89
 
73
90
  // Add show/hide content support
@@ -79,25 +96,36 @@ describe('show-hide-content', function () {
79
96
  it('should add the aria attributes to inputs with show/hide content', function () {
80
97
  expect(this.$radio1.attr('aria-expanded')).toBe('false')
81
98
  expect(this.$radio1.attr('aria-controls')).toBe('show-hide-radios')
99
+
100
+ expect(this.$radio3.attr('aria-expanded')).toBe('false')
101
+ expect(this.$radio3.attr('aria-controls')).toBe('show-hide-radios--name-with-characters-to-escape')
82
102
  })
83
103
 
84
104
  it('should add the aria attributes to show/hide content', function () {
85
105
  expect(this.$radioShowHide.attr('aria-hidden')).toBe('true')
86
106
  expect(this.$radioShowHide.hasClass('js-hidden')).toEqual(true)
107
+
108
+ expect(this.$radioShowHide_nameWithCharactersToEscape.attr('aria-hidden')).toBe('true')
109
+ expect(this.$radioShowHide_nameWithCharactersToEscape.hasClass('js-hidden')).toEqual(true)
87
110
  })
88
111
 
89
112
  it('should hide the show/hide content visually', function () {
90
113
  expect(this.$radioShowHide.hasClass('js-hidden')).toEqual(true)
114
+ expect(this.$radioShowHide_nameWithCharactersToEscape.hasClass('js-hidden')).toEqual(true)
91
115
  })
92
116
 
93
117
  it('should do nothing if no radios are checked', function () {
94
118
  expect(this.$radio1.attr('aria-expanded')).toBe('false')
95
119
  expect(this.$radio2.attr('aria-expanded')).toBe(undefined)
120
+ expect(this.$radio3.attr('aria-expanded')).toBe('false')
121
+ expect(this.$radio4.attr('aria-expanded')).toBe(undefined)
96
122
  })
97
123
 
98
124
  it('should do nothing if no checkboxes are checked', function () {
99
125
  expect(this.$radio1.attr('aria-expanded')).toBe('false')
100
126
  expect(this.$radio2.attr('aria-expanded')).toBe(undefined)
127
+ expect(this.$radio3.attr('aria-expanded')).toBe('false')
128
+ expect(this.$radio4.attr('aria-expanded')).toBe(undefined)
101
129
  })
102
130
 
103
131
  describe('with non-default markup', function () {
@@ -107,12 +135,18 @@ describe('show-hide-content', function () {
107
135
 
108
136
  it('should do nothing if a radio without show/hide content is checked', function () {
109
137
  this.$radio2.prop('checked', true)
138
+ this.$radio4.prop('checked', true)
110
139
 
111
140
  // Defaults changed, initialise again
112
141
  this.showHideContent = new GOVUK.ShowHideContent().init()
113
142
  expect(this.$radio1.attr('aria-expanded')).toBe('false')
143
+ expect(this.$radio3.attr('aria-expanded')).toBe('false')
144
+
114
145
  expect(this.$radioShowHide.attr('aria-hidden')).toBe('true')
146
+ expect(this.$radioShowHide_nameWithCharactersToEscape.attr('aria-hidden')).toBe('true')
147
+
115
148
  expect(this.$radioShowHide.hasClass('js-hidden')).toEqual(true)
149
+ expect(this.$radioShowHide_nameWithCharactersToEscape.hasClass('js-hidden')).toEqual(true)
116
150
  })
117
151
 
118
152
  it('should do nothing if a checkbox without show/hide content is checked', function () {
@@ -138,12 +172,18 @@ describe('show-hide-content', function () {
138
172
 
139
173
  it('should make the show/hide content visible if its radio is checked', function () {
140
174
  this.$radio1.prop('checked', true)
175
+ this.$radio3.prop('checked', true)
141
176
 
142
177
  // Defaults changed, initialise again
143
178
  this.showHideContent = new GOVUK.ShowHideContent().init()
144
179
  expect(this.$radio1.attr('aria-expanded')).toBe('true')
180
+ expect(this.$radio3.attr('aria-expanded')).toBe('true')
181
+
145
182
  expect(this.$radioShowHide.attr('aria-hidden')).toBe('false')
183
+ expect(this.$radioShowHide_nameWithCharactersToEscape.attr('aria-hidden')).toBe('false')
184
+
146
185
  expect(this.$radioShowHide.hasClass('js-hidden')).toEqual(false)
186
+ expect(this.$radioShowHide_nameWithCharactersToEscape.hasClass('js-hidden')).toEqual(false)
147
187
  })
148
188
 
149
189
  it('should make the show/hide content visible if its checkbox is checked', function () {
@@ -160,14 +200,23 @@ describe('show-hide-content', function () {
160
200
  describe('and a show/hide radio receives a click', function () {
161
201
  it('should make the show/hide content visible', function () {
162
202
  this.$radio1.click()
203
+ this.$radio3.click()
163
204
  expect(this.$radioShowHide.hasClass('js-hidden')).toEqual(false)
205
+ expect(this.$radioShowHide_nameWithCharactersToEscape.hasClass('js-hidden')).toEqual(false)
164
206
  })
165
207
 
166
208
  it('should add the aria attributes to show/hide content', function () {
167
209
  this.$radio1.click()
210
+ this.$radio3.click()
211
+
168
212
  expect(this.$radio1.attr('aria-expanded')).toBe('true')
213
+ expect(this.$radio3.attr('aria-expanded')).toBe('true')
214
+
169
215
  expect(this.$radioShowHide.attr('aria-hidden')).toBe('false')
216
+ expect(this.$radioShowHide_nameWithCharactersToEscape.attr('aria-hidden')).toBe('false')
217
+
170
218
  expect(this.$radioShowHide.hasClass('js-hidden')).toEqual(false)
219
+ expect(this.$radioShowHide_nameWithCharactersToEscape.hasClass('js-hidden')).toEqual(false)
171
220
  })
172
221
  })
173
222
 
@@ -223,6 +272,10 @@ describe('show-hide-content', function () {
223
272
  namespace: 'ShowHideContent',
224
273
  selector: 'input[type="radio"][name="single"]'
225
274
  }))
275
+ expect(events && events.click).toContain(jasmine.objectContaining({
276
+ namespace: 'ShowHideContent',
277
+ selector: 'input[type="radio"][name="test.single[option1=\'value1\'][option2=\'value2\']"]'
278
+ }))
226
279
  expect(events && events.click).toContain(jasmine.objectContaining({
227
280
  namespace: 'ShowHideContent',
228
281
  selector: '[data-target] > input[type="checkbox"]'
@@ -241,6 +294,10 @@ describe('show-hide-content', function () {
241
294
  namespace: 'ShowHideContent',
242
295
  selector: 'input[type="radio"][name="single"]'
243
296
  }))
297
+ expect(events && events.click).not.toContain(jasmine.objectContaining({
298
+ namespace: 'ShowHideContent',
299
+ selector: 'input[type="radio"][name="test.single[option1=\'value1\'][option2=\'value2\']"]'
300
+ }))
244
301
  expect(events && events.click).not.toContain(jasmine.objectContaining({
245
302
  namespace: 'ShowHideContent',
246
303
  selector: '[data-target] > input[type="checkbox"]'
@@ -0,0 +1,170 @@
1
+ /* global describe it expect beforeEach afterEach jasmine */
2
+
3
+ var $ = window.jQuery
4
+
5
+ describe('stageprompt', function () {
6
+ 'use strict'
7
+ var GOVUK = window.GOVUK
8
+
9
+ var analyticsCallback
10
+
11
+ beforeEach(function () {
12
+ $('<div id="sandbox"></div>').appendTo('body')
13
+ })
14
+
15
+ afterEach(function () {
16
+ $('#sandbox').remove()
17
+ })
18
+
19
+ it('should exist in a namespace', function () {
20
+ expect(GOVUK.performance.stageprompt).not.toBeNull()
21
+ })
22
+
23
+ it('should not blow up if there are no data-journey tags', function () {
24
+ expect($('[data-journey]').length).toBe(0)
25
+ GOVUK.performance.stageprompt.setup(function () {})
26
+ })
27
+
28
+ describe('fire the analytics callback when a data-journey tag is found', function () {
29
+ beforeEach(function () {
30
+ analyticsCallback = jasmine.createSpy()
31
+ $('<div id="sandbox"></div>').appendTo('body')
32
+ })
33
+
34
+ afterEach(function () {
35
+ $('#sandbox').remove()
36
+ $('[data-journey]').removeAttr('data-journey')
37
+ })
38
+
39
+ it('should send an event if the page has a data-journey tag on the body', function () {
40
+ $('body').attr('data-journey', 'test-journey:someStage')
41
+ GOVUK.performance.stageprompt.setup(analyticsCallback)
42
+
43
+ expect(analyticsCallback).toHaveBeenCalledWith('test-journey', 'someStage')
44
+ })
45
+
46
+ it('should send an event if the page has a data-journey tag on another tag', function () {
47
+ $('#sandbox').attr('data-journey', 'test-journey:nextStep')
48
+
49
+ GOVUK.performance.stageprompt.setup(analyticsCallback)
50
+
51
+ expect(analyticsCallback).toHaveBeenCalledWith('test-journey', 'nextStep')
52
+ })
53
+
54
+ it('should send one event if the page has multiple elements with data-journey attribute', function () {
55
+ $('#sandbox').attr('data-journey', 'test-journey:stuff')
56
+ $('#sandbox').html('<p id="foo" data-journey="test-journey:moreStuff">something</p>')
57
+
58
+ GOVUK.performance.stageprompt.setup(analyticsCallback)
59
+
60
+ expect(analyticsCallback.calls.count()).toBe(1)
61
+ })
62
+ })
63
+
64
+ describe('callback arguments', function () {
65
+ var analyticsCallback
66
+
67
+ beforeEach(function () {
68
+ analyticsCallback = jasmine.createSpy()
69
+ $('<div id="sandbox"></div>').appendTo('body')
70
+ })
71
+
72
+ afterEach(function () {
73
+ $('#sandbox').remove()
74
+ $('[data-journey]').removeAttr('data-journey')
75
+ })
76
+
77
+ it('should pass action parts as separate arguments to the callback', function () {
78
+ $('#sandbox').attr('data-journey', 'part-1:part-2')
79
+
80
+ GOVUK.performance.stageprompt.setup(analyticsCallback)
81
+
82
+ expect(analyticsCallback).toHaveBeenCalledWith('part-1', 'part-2')
83
+ })
84
+
85
+ it('should pass a single-part action as one argument', function () {
86
+ $('#sandbox').attr('data-journey', 'single-part')
87
+
88
+ GOVUK.performance.stageprompt.setup(analyticsCallback)
89
+
90
+ expect(analyticsCallback).toHaveBeenCalledWith('single-part')
91
+ })
92
+
93
+ it('should pass at most three arguments to the callback', function () {
94
+ $('#sandbox').attr('data-journey', 'part-1:part-2:part-3:additional-content')
95
+
96
+ GOVUK.performance.stageprompt.setup(analyticsCallback)
97
+
98
+ expect(analyticsCallback).toHaveBeenCalledWith('part-1', 'part-2', 'part-3:additional-content')
99
+ })
100
+ })
101
+
102
+ describe('sending events for click actions', function () {
103
+ beforeEach(function () {
104
+ analyticsCallback = jasmine.createSpy()
105
+ $('<div id="sandbox"></div>').appendTo('body')
106
+ })
107
+
108
+ afterEach(function () {
109
+ $('#sandbox').remove()
110
+ })
111
+
112
+ it('should send an event when a help link is clicked', function () {
113
+ $('#sandbox').attr('data-journey-click', 'test-journey:stuff:help')
114
+ GOVUK.performance.stageprompt.setup(analyticsCallback)
115
+
116
+ $('#sandbox').click()
117
+
118
+ expect(analyticsCallback).toHaveBeenCalledWith('test-journey', 'stuff', 'help')
119
+ })
120
+
121
+ it('should send events for multiple help elements on the same page', function () {
122
+ $('#sandbox').append('<a href="#" id="1" data-journey-click="a">foo</a>')
123
+ $('#sandbox').append('<a href="#" id="2" data-journey-click="b">bar</a>')
124
+
125
+ GOVUK.performance.stageprompt.setup(analyticsCallback)
126
+ $('#1').click()
127
+ $('#2').click()
128
+
129
+ expect(analyticsCallback).toHaveBeenCalledWith('a')
130
+ expect(analyticsCallback).toHaveBeenCalledWith('b')
131
+ })
132
+
133
+ it('should send one event per click on tagged item', function () {
134
+ $('#sandbox').append('<a href="#" id="1" data-journey-click="a">foo</a>')
135
+ GOVUK.performance.stageprompt.setup(analyticsCallback)
136
+
137
+ $('#1').click()
138
+ $('#1').click()
139
+
140
+ expect(analyticsCallback.calls.count()).toBe(2)
141
+ })
142
+ })
143
+
144
+ describe('out-of-the-box Google Analytics setup', function () {
145
+ beforeEach(function () {
146
+ $('<div id="gaTest" data-journey="thisIsATest"></div>').appendTo('body')
147
+ })
148
+
149
+ afterEach(function () {
150
+ $('#gaTest').remove()
151
+ })
152
+
153
+ it('should get set up to send events to google analytics using ga() if it exists', function () {
154
+ window.ga = jasmine.createSpy('ga')
155
+
156
+ GOVUK.performance.stageprompt.setupForGoogleAnalytics()
157
+
158
+ expect(window.ga).toHaveBeenCalledWith('send', 'event', 'thisIsATest', undefined, undefined, { nonInteraction: true })
159
+ })
160
+
161
+ it('should get set up to send events to google analytics using gaq.push() if ga() does not exist', function () {
162
+ delete window.ga
163
+ window._gaq = {push: jasmine.createSpy('_gaq.push')}
164
+
165
+ GOVUK.performance.stageprompt.setupForGoogleAnalytics()
166
+
167
+ expect(window._gaq.push).toHaveBeenCalledWith(['_trackEvent', 'thisIsATest', undefined, undefined, undefined, true])
168
+ })
169
+ })
170
+ })
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: govuk_frontend_toolkit
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.6.0
4
+ version: 8.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Government Digital Service
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-18 00:00:00.000000000 Z
11
+ date: 2018-09-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -238,6 +238,7 @@ files:
238
238
  - app/assets/javascripts/stageprompt.js
239
239
  - app/assets/javascripts/vendor/jquery/jquery.player.min.js
240
240
  - app/assets/javascripts/vendor/polyfills/bind.js
241
+ - app/assets/package-lock.json
241
242
  - app/assets/package.json
242
243
  - app/assets/spec/manifest.js
243
244
  - app/assets/spec/stylesheets/_colour_contrast_spec.scss
@@ -259,6 +260,7 @@ files:
259
260
  - app/assets/spec/unit/selection-button.spec.js
260
261
  - app/assets/spec/unit/shim-links-with-button-role.spec.js
261
262
  - app/assets/spec/unit/show-hide-content.spec.js
263
+ - app/assets/spec/unit/stageprompt.spec.js
262
264
  - app/assets/spec/unit/stick-at-top-when-scrolling.spec.js
263
265
  - app/assets/stylesheets/.gitkeep
264
266
  - app/assets/stylesheets/_colours.scss