@ons/design-system 70.0.10 → 70.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +36 -0
  2. package/components/address-output/example-address-output.njk +11 -0
  3. package/components/card/_macro.njk +1 -1
  4. package/components/document-list/{document-list.scss → _document-list.scss} +4 -4
  5. package/components/header/_macro.spec.js +513 -721
  6. package/components/header/_test_examples.js +157 -0
  7. package/components/hero/_macro.njk +1 -1
  8. package/components/input/_macro.njk +1 -1
  9. package/components/label/_label.scss +1 -1
  10. package/components/list/_list.scss +20 -11
  11. package/components/list/_macro.njk +11 -6
  12. package/components/list/_macro.spec.js +29 -6
  13. package/components/list/example-bare-list.njk +21 -0
  14. package/components/list/example-bulleted-list.njk +17 -0
  15. package/components/list/example-dashed-list.njk +20 -0
  16. package/components/list/example-inline-list-with-social-icon-prefix.njk +42 -0
  17. package/components/list/example-inline-list.njk +20 -0
  18. package/components/list/example-list-with-icon-prefix.njk +18 -0
  19. package/components/list/example-list-with-icon-suffix.njk +18 -0
  20. package/components/list/example-nested-list.njk +39 -0
  21. package/components/list/example-numbered-list.njk +17 -0
  22. package/components/list/example-prefixed-list.njk +19 -0
  23. package/components/list/example-suffixed-list.njk +19 -0
  24. package/components/list/example-summary-list.njk +17 -0
  25. package/components/navigation/_macro.njk +1 -1
  26. package/components/navigation/_macro.spec.js +1 -1
  27. package/components/quote/example-quote.njk +7 -0
  28. package/components/related-content/example-related-content-social-media.njk +0 -1
  29. package/components/summary/_macro.njk +1 -1
  30. package/components/text-indent/example-text-indent.njk +6 -0
  31. package/css/main.css +1 -1
  32. package/img/large/placeholder-card.png +0 -0
  33. package/img/small/placeholder-card.png +0 -0
  34. package/layout/_dsTemplate.njk +1 -1
  35. package/package.json +1 -1
  36. package/scss/main.scss +1 -1
  37. package/scss/utilities/_index.scss +1 -1
  38. package/scss/utilities/{_pad.scss → _padding.scss} +6 -6
  39. package/scss/vars/_colors.scss +1 -2
  40. package/components/back-link/example-back-link.njk +0 -17
  41. package/components/helpers/_grid.scss +0 -6
  42. package/components/helpers/grid.njk +0 -20
@@ -6,525 +6,348 @@ import axe from '../../tests/helpers/axe';
6
6
  import { renderComponent, templateFaker } from '../../tests/helpers/rendering';
7
7
  import { mapAll } from '../../tests/helpers/cheerio';
8
8
 
9
- const EXAMPLE_HEADER_BASIC = {
10
- title: 'Header title',
11
- };
12
-
13
- const EXAMPLE_SERVICE_LINKS_CONFIG = {
14
- id: 'service-links',
15
- ariaLabel: 'Services menu',
16
- classes: 'custom-class',
17
- toggleServicesButton: {
18
- text: 'Menu',
19
- ariaLabel: 'Toggle services menu',
20
- },
21
- };
22
-
23
- const EXAMPLE_HEADER_SERVICE_LIST_ITEMS = {
24
- ...EXAMPLE_HEADER_BASIC,
25
- serviceLinks: {
26
- ...EXAMPLE_SERVICE_LINKS_CONFIG,
27
- itemsList: [
28
- {
29
- title: 'Title 1',
30
- },
31
- {
32
- title: 'Title 2',
33
- },
34
- {
35
- title: 'Title 3',
36
- },
37
- ],
38
- },
39
- };
40
-
41
- const EXAMPLE_HEADER_SERVICE_LINKS_MULTIPLE = {
42
- ...EXAMPLE_HEADER_BASIC,
43
- serviceLinks: {
44
- ...EXAMPLE_SERVICE_LINKS_CONFIG,
45
- itemsList: [
46
- {
47
- title: 'Title 1',
48
- url: '#1',
49
- },
50
- {
51
- title: 'Title 2',
52
- url: '#2',
53
- },
54
- {
55
- title: 'Title 3',
56
- url: '#3',
57
- },
58
- ],
59
- },
60
- };
61
-
62
- const EXAMPLE_HEADER_SERVICE_LINKS_SINGLE = {
63
- ...EXAMPLE_HEADER_BASIC,
64
- serviceLinks: {
65
- ...EXAMPLE_SERVICE_LINKS_CONFIG,
66
- itemsList: [
67
- {
68
- title: 'Title',
69
- url: '#0',
70
- },
71
- ],
72
- },
73
- };
74
-
75
- const EXAMPLE_HEADER_LANGUAGE_CONFIG = {
76
- language: {
77
- languages: [
78
- {
79
- url: '#0',
80
- ISOCode: 'en',
81
- text: 'English',
82
- buttonAriaLabel: 'Language selector. Current language: English',
83
- chooseLanguage: 'Choose language',
84
- current: true,
85
- },
86
- {
87
- url: '#0',
88
- ISOCode: 'cy',
89
- text: 'Cymraeg',
90
- buttonAriaLabel: 'Dewisydd iaith. Iaith gyfredol: Cymraeg',
91
- chooseLanguage: 'Dewiswch iaith',
92
- current: false,
93
- },
94
- ],
95
- },
96
- };
97
-
98
- const EXAMPLE_HEADER_NAVIGATION_CONFIG = {
99
- navigation: {
100
- id: 'main-nav',
101
- ariaLabel: 'Main menu',
102
- currentPath: '#home',
103
- itemsList: [
104
- {
105
- title: 'Home',
106
- url: '#home',
107
- },
108
- {
109
- title: 'Guidance',
110
- url: '#0',
111
- },
112
- ],
113
- toggleNavigationButton: {
114
- text: 'Menu',
115
- ariaLabel: 'Toggle main menu',
116
- },
117
- },
118
- };
119
-
120
- const EXAMPLE_HEADER_NAVIGATION_WITH_SUBNAVIGATION_CONFIG = {
121
- navigation: {
122
- id: 'main-nav',
123
- ariaLabel: 'Main menu',
124
- currentPath: '#1',
125
- currentPageTitle: 'Guidance',
126
- itemsList: [
127
- {
128
- title: 'Home',
129
- url: '#0',
130
- },
131
- {
132
- title: 'Guidance',
133
- url: '#1',
134
- },
135
- ],
136
- toggleNavigationButton: {
137
- text: 'Menu',
138
- ariaLabel: 'Toggle main menu',
139
- },
140
- subNavigation: {
141
- id: 'sub-nav',
142
- overviewURL: '#overview',
143
- overviewText: 'Overview',
144
- ariaLabel: 'Section menu',
145
- currentPath: '#1',
146
- itemsList: [
147
- {
148
- title: 'Sub nav item 1',
149
- url: '#0',
150
- classes: 'custom-class-sub-item-1',
151
- id: 'sub-item-1',
152
- },
153
- {
154
- title: 'Sub nav item 2',
155
- url: '#1',
156
- classes: 'custom-class-sub-item-2',
157
- id: 'sub-item-2',
158
- },
159
- ],
160
- },
161
- },
162
- };
163
-
164
- const EXAMPLE_HEADER_NAVIGATION_WITH_SITESEARCHAUTOSUGGEST = {
165
- navigation: {
166
- id: 'main-nav',
167
- ariaLabel: 'Main menu',
168
- currentPath: '#home',
169
- itemsList: [
170
- {
171
- title: 'Home',
172
- url: '#home',
173
- },
174
- {
175
- title: 'Guidance',
176
- url: '#0',
177
- },
178
- ],
179
- toggleNavigationButton: {
180
- text: 'Menu',
181
- ariaLabel: 'Toggle main menu',
182
- },
183
- },
184
- siteSearchAutosuggest: {
185
- label: 'label',
186
- instructions: 'Use up and down keys to navigate.',
187
- ariaYouHaveSelected: 'You have selected',
188
- ariaMinChars: 'Enter 3 or more characters for suggestions.',
189
- minChars: 3,
190
- ariaResultsLabel: 'Country suggestions',
191
- ariaOneResult: 'There is one suggestion available.',
192
- ariaNResults: 'There are {n} suggestions available.',
193
- ariaLimitedResults: 'Type more characters to improve your search',
194
- moreResults: 'Continue entering to improve suggestions',
195
- resultsTitle: 'Suggestions',
196
- resultsTitleId: 'country-of-birth-suggestions',
197
- noResults: 'No suggestions found.',
198
- typeMore: 'Continue entering to get suggestions',
199
- language: 'en-gb',
200
- },
201
- };
202
-
203
- describe('macro: header', () => {
204
- describe('mode: basic', () => {
205
- it('passes jest-axe checks', async () => {
206
- const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_BASIC));
207
-
208
- const results = await axe($.html());
209
- expect(results).toHaveNoViolations();
9
+ import {
10
+ EXAMPLE_HEADER_BASIC,
11
+ EXAMPLE_SERVICE_LINKS_CONFIG,
12
+ EXAMPLE_HEADER_SERVICE_LINKS_MULTIPLE,
13
+ EXAMPLE_HEADER_SERVICE_LINKS_SINGLE,
14
+ EXAMPLE_HEADER_LANGUAGE_CONFIG,
15
+ EXAMPLE_HEADER_NAVIGATION_WITH_SUBNAVIGATION_CONFIG,
16
+ EXAMPLE_HEADER_NAVIGATION_WITH_SITESEARCHAUTOSUGGEST,
17
+ } from './_test_examples';
18
+
19
+ describe('FOR: Header', () => {
20
+ describe('GIVEN: Params: none', () => {
21
+ describe('WHEN: All params are at default state', () => {
22
+ const $ = cheerio.load(
23
+ renderComponent('header', {
24
+ ...EXAMPLE_HEADER_BASIC,
25
+ }),
26
+ );
27
+ test('THEN: jest-axe tests pass', async () => {
28
+ const results = await axe($.html());
29
+ expect(results).toHaveNoViolations();
30
+ });
210
31
  });
211
-
212
- it('has provided variant style classes', () => {
32
+ });
33
+ describe('GIVEN: Params: variants', () => {
34
+ describe('WHEN: variants are provided', () => {
213
35
  const $ = cheerio.load(
214
36
  renderComponent('header', {
215
37
  ...EXAMPLE_HEADER_BASIC,
216
38
  variants: ['variant-a', 'variant-b'],
217
39
  }),
218
40
  );
219
-
220
- expect($('.ons-header--variant-a').length).toBe(1);
221
- expect($('.ons-header--variant-b').length).toBe(1);
41
+ test('THEN: renders with variant style classes matching variant provided', () => {
42
+ expect($('.ons-header--variant-a').length).toBe(1);
43
+ expect($('.ons-header--variant-b').length).toBe(1);
44
+ });
222
45
  });
223
-
224
- it('has additionally provided `classes`', () => {
46
+ });
47
+ describe('GIVEN: Params: classes', () => {
48
+ describe('WHEN: classes are provided', () => {
225
49
  const $ = cheerio.load(
226
50
  renderComponent('header', {
227
51
  ...EXAMPLE_HEADER_BASIC,
228
52
  classes: 'extra-class another-extra-class',
229
53
  }),
230
54
  );
231
-
232
- expect($('.ons-header').hasClass('extra-class')).toBe(true);
233
- expect($('.ons-header').hasClass('another-extra-class')).toBe(true);
234
- });
235
-
236
- it('has the correct container if `fullWidth`', () => {
237
- const $ = cheerio.load(renderComponent('header', { ...EXAMPLE_HEADER_BASIC, fullWidth: true }));
238
-
239
- expect($('.ons-container').hasClass('ons-container--full-width')).toBe(true);
240
- });
241
-
242
- it('has the correct container if `wide`', () => {
243
- const $ = cheerio.load(renderComponent('header', { ...EXAMPLE_HEADER_BASIC, wide: true }));
244
-
245
- expect($('.ons-container').hasClass('ons-container--wide')).toBe(true);
246
- });
247
-
248
- it('has the correct masthead logo link', () => {
249
- const $ = cheerio.load(renderComponent('header', { ...EXAMPLE_HEADER_BASIC, mastheadLogoUrl: '#0' }));
250
-
251
- expect($('.ons-header__org-logo-link').attr('href')).toBe('#0');
252
- });
253
-
254
- it('has the default masthead logo icon', () => {
255
- const faker = templateFaker();
256
- const iconsSpy = faker.spy('icon');
257
-
258
- faker.renderComponent('header', EXAMPLE_HEADER_BASIC);
259
-
260
- expect(iconsSpy.occurrences[0].iconType).toBe('ons-logo-en');
55
+ test('THEN: renders with correct additional classes', () => {
56
+ expect($('.ons-header').hasClass('extra-class')).toBe(true);
57
+ expect($('.ons-header').hasClass('another-extra-class')).toBe(true);
58
+ });
261
59
  });
262
-
263
- it('has the default masthead mobile logo icon', () => {
264
- const faker = templateFaker();
265
- const iconsSpy = faker.spy('icon');
266
-
267
- faker.renderComponent('header', EXAMPLE_HEADER_BASIC);
268
-
269
- expect(iconsSpy.occurrences[1].iconType).toBe('ons-logo-stacked-en');
60
+ });
61
+ describe('GIVEN: Params: fullWidth & wide', () => {
62
+ describe('WHEN: fullWidth parameter is set to true', () => {
63
+ const $ = cheerio.load(
64
+ renderComponent('header', {
65
+ ...EXAMPLE_HEADER_BASIC,
66
+ fullWidth: true,
67
+ }),
68
+ );
69
+ test('THEN: renders container with fullWidth class', () => {
70
+ expect($('.ons-container').hasClass('ons-container--full-width')).toBe(true);
71
+ });
270
72
  });
271
-
272
- it('has the default masthead logo icon alt text', () => {
273
- const faker = templateFaker();
274
- const iconsSpy = faker.spy('icon');
275
-
276
- faker.renderComponent('header', EXAMPLE_HEADER_BASIC);
277
-
278
- expect(iconsSpy.occurrences[0].altText).toBe('Office for National Statistics homepage');
73
+ describe('WHEN: wide parameter is set to true', () => {
74
+ const $ = cheerio.load(
75
+ renderComponent('header', {
76
+ ...EXAMPLE_HEADER_BASIC,
77
+ wide: true,
78
+ }),
79
+ );
80
+ test('THEN: renders container with wide class', () => {
81
+ expect($('.ons-container').hasClass('ons-container--wide')).toBe(true);
82
+ });
279
83
  });
280
-
281
- it('has the default masthead mobile logo icon alt text', () => {
84
+ });
85
+ describe('GIVEN: Params: mastheadLogo', () => {
86
+ describe('WHEN: default params are provided', () => {
282
87
  const faker = templateFaker();
283
88
  const iconsSpy = faker.spy('icon');
284
-
285
89
  faker.renderComponent('header', EXAMPLE_HEADER_BASIC);
286
90
 
287
- expect(iconsSpy.occurrences[1].altText).toBe('Office for National Statistics logo');
91
+ test('THEN: renders default large logo on large screen', () => {
92
+ expect(iconsSpy.occurrences[0].iconType).toBe('ons-logo-en');
93
+ });
94
+ test('THEN: renders logo with correct default alt-text on large screen', () => {
95
+ expect(iconsSpy.occurrences[0].altText).toBe('Office for National Statistics homepage');
96
+ });
97
+ test('THEN: renders default small logo on small screen', () => {
98
+ expect(iconsSpy.occurrences[1].iconType).toBe('ons-logo-stacked-en');
99
+ });
100
+ test('THEN: renders logo with correct default alt-text on small screen', () => {
101
+ expect(iconsSpy.occurrences[1].altText).toBe('Office for National Statistics logo');
102
+ });
288
103
  });
289
-
290
- it('has the provided large masthead logo', () => {
104
+ describe('WHEN: large & small parameters are provided', () => {
291
105
  const $ = cheerio.load(
292
- renderComponent('header', { ...EXAMPLE_HEADER_BASIC, mastheadLogo: { large: '<img src="another-logo.svg">' } }),
106
+ renderComponent('header', {
107
+ ...EXAMPLE_HEADER_BASIC,
108
+ mastheadLogo: { large: '<img src="another-logo.svg">', small: '<img src="another-logo-small.svg">' },
109
+ }),
293
110
  );
294
-
295
- expect($('.ons-header__org-logo--large img').attr('src')).toBe('another-logo.svg');
111
+ test('THEN: renders provided large logo on large screen', () => {
112
+ expect($('.ons-header__org-logo--large img').attr('src')).toBe('another-logo.svg');
113
+ });
114
+ test('THEN: renders provided small logo on small screen', () => {
115
+ expect($('.ons-header__org-logo--small img').attr('src')).toBe('another-logo-small.svg');
116
+ });
296
117
  });
297
-
298
- it('has the provided masthead logo custom classes', () => {
118
+ describe('WHEN: classes parameter is provided', () => {
299
119
  const $ = cheerio.load(
300
120
  renderComponent('header', {
301
121
  ...EXAMPLE_HEADER_BASIC,
302
122
  mastheadLogo: { large: '<img src="another-logo.svg">', classes: 'custom-class another-custom-class' },
303
123
  }),
304
124
  );
305
-
306
- expect($('.ons-header__grid-top').hasClass('custom-class')).toBe(true);
307
- expect($('.ons-header__grid-top').hasClass('another-custom-class')).toBe(true);
125
+ test('THEN: renders logo with provided additional classes', () => {
126
+ expect($('.ons-header__grid-top').hasClass('custom-class')).toBe(true);
127
+ expect($('.ons-header__grid-top').hasClass('another-custom-class')).toBe(true);
128
+ });
308
129
  });
309
-
310
- it('has the provided small masthead logo', () => {
130
+ describe('WHEN: mastheadLogoUrl parameter is provided', () => {
311
131
  const $ = cheerio.load(
312
132
  renderComponent('header', {
313
133
  ...EXAMPLE_HEADER_BASIC,
314
- mastheadLogo: { large: 'another-logo.svg', small: '<img src="another-logo-small.svg">' },
134
+ mastheadLogoUrl: '#0',
315
135
  }),
316
136
  );
317
-
318
- expect($('.ons-header__org-logo--small img').attr('src')).toBe('another-logo-small.svg');
137
+ test('THEN: renders logo with provided URL', () => {
138
+ expect($('.ons-header__org-logo-link').attr('href')).toBe('#0');
139
+ });
319
140
  });
141
+ });
142
+ describe('GIVEN: Params: multipleLogos', () => {
143
+ describe('WHEN: logoImage parameter is set to "ONS Logo"', () => {
144
+ const faker = templateFaker();
145
+ const iconsSpy = faker.spy('icon');
320
146
 
321
- describe('mode: with multiple logos', () => {
322
- it('has the default ONS icon when requested', () => {
323
- const faker = templateFaker();
324
- const iconsSpy = faker.spy('icon');
325
-
326
- faker.renderComponent('header', {
147
+ faker.renderComponent('header', {
148
+ ...EXAMPLE_HEADER_BASIC,
149
+ mastheadLogo: {
150
+ multipleLogos: {
151
+ logo1: {
152
+ logoImage: 'ONS Logo',
153
+ },
154
+ },
155
+ },
156
+ });
157
+ test('THEN: renders default ONS icon', () => {
158
+ expect(iconsSpy.occurrences[0].iconType).toBe('ons-logo-stacked-en');
159
+ });
160
+ });
161
+ describe('WHEN: logoURL parameter is set ', () => {
162
+ const $ = cheerio.load(
163
+ renderComponent('header', {
327
164
  ...EXAMPLE_HEADER_BASIC,
328
165
  mastheadLogo: {
329
166
  multipleLogos: {
330
167
  logo1: {
331
- logoImage: 'ONS Logo',
168
+ logoImage: '<img src="a-logo.svg">',
169
+ logoURL: '#0',
332
170
  },
333
171
  },
334
172
  },
335
- });
336
- expect(iconsSpy.occurrences[0].iconType).toBe('ons-logo-stacked-en');
337
- });
338
-
339
- it('has the provided link', () => {
340
- const $ = cheerio.load(
341
- renderComponent('header', {
342
- ...EXAMPLE_HEADER_BASIC,
343
- mastheadLogo: {
344
- multipleLogos: {
345
- logo1: {
346
- logoImage: '<img src="a-logo.svg">',
347
- logoURL: '#0',
348
- },
349
- },
350
- },
351
- }),
352
- );
353
-
173
+ }),
174
+ );
175
+ test('THEN: renders provided link', () => {
354
176
  expect($('.ons-header__org-logo-link').attr('href')).toBe('#0');
355
177
  });
356
-
357
- it('when multiple images are provided all show', () => {
358
- const $ = cheerio.load(
359
- renderComponent('header', {
360
- ...EXAMPLE_HEADER_BASIC,
361
- mastheadLogo: {
362
- multipleLogos: {
363
- logo1: {
364
- logoImage: '<img src="a-logo.svg">',
365
- },
366
- logo2: {
367
- logoImage: '<img src="a-second-logo.svg">',
368
- },
369
- logo3: {
370
- logoImage: '<img src="a-third-logo.svg">',
371
- },
178
+ });
179
+ describe('WHEN: logo1, logo2, logo3 image parameters are all provided', () => {
180
+ const $ = cheerio.load(
181
+ renderComponent('header', {
182
+ ...EXAMPLE_HEADER_BASIC,
183
+ mastheadLogo: {
184
+ multipleLogos: {
185
+ logo1: {
186
+ logoImage: '<img src="a-logo.svg">',
187
+ },
188
+ logo2: {
189
+ logoImage: '<img src="a-second-logo.svg">',
190
+ },
191
+ logo3: {
192
+ logoImage: '<img src="a-third-logo.svg">',
372
193
  },
373
194
  },
374
- }),
375
- );
376
-
195
+ },
196
+ }),
197
+ );
198
+ test('THEN: renders all provided logos', () => {
377
199
  expect($('.ons-header__org-logo--multi img').attr('src')).toBe('a-logo.svg');
378
200
  expect($('.ons-header__org-logo--multi img:nth-of-type(2)').attr('src')).toBe('a-second-logo.svg');
379
201
  expect($('.ons-header__org-logo--multi img:nth-of-type(3)').attr('src')).toBe('a-third-logo.svg');
380
202
  });
381
-
382
- it('renders multiple logos even when small/large parameters are used', () => {
383
- const $ = cheerio.load(
384
- renderComponent('header', {
385
- ...EXAMPLE_HEADER_BASIC,
386
- mastheadLogo: {
387
- small: '<img src="small-logo.svg">',
388
- large: '<img src="big-logo.svg">',
389
- multipleLogos: {
390
- logo1: {
391
- logoImage: '<img src="a-logo.svg">',
392
- },
393
- logo2: {
394
- logoImage: '<img src="a-second-logo.svg">',
395
- },
396
- logo3: {
397
- logoImage: '<img src="a-third-logo.svg">',
398
- },
203
+ });
204
+ describe('WHEN: multipleLogos & mastheadLogo:Large parameters are both provided', () => {
205
+ const $ = cheerio.load(
206
+ renderComponent('header', {
207
+ ...EXAMPLE_HEADER_BASIC,
208
+ mastheadLogo: {
209
+ large: '<img src="big-logo.svg">',
210
+ multipleLogos: {
211
+ logo1: {
212
+ logoImage: '<img src="a-logo.svg">',
399
213
  },
400
214
  },
401
- }),
402
- );
215
+ },
216
+ }),
217
+ );
218
+ test('THEN: renders only logos provided via multipleLogos parameter', () => {
403
219
  expect($('.ons-header__org-logo--large').attr('src')).toBe(undefined);
404
220
  expect($('.ons-header__org-logo--multi img').attr('src')).toBe('a-logo.svg');
405
221
  });
406
222
  });
407
-
408
- it('displays the `title` text', () => {
409
- const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_BASIC));
410
-
411
- expect($('.ons-header__title').text()).toBe('Header title');
412
- });
413
-
414
- it('displays the `title` using the default tag', () => {
223
+ });
224
+ describe('GIVEN: Params: title', () => {
225
+ describe('WHEN: title parameter is provided', () => {
415
226
  const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_BASIC));
416
-
417
- expect($('.ons-header__title')[0].tagName).toBe('div');
227
+ test('THEN: renders provided title text', () => {
228
+ expect($('.ons-header__title').text()).toBe('Header title');
229
+ });
230
+ test('THEN: renders title with default title tag', () => {
231
+ expect($('.ons-header__title')[0].tagName).toBe('div');
232
+ });
418
233
  });
419
-
420
- it('displays the `title` using a H1 if `titleAsH1`', () => {
421
- const $ = cheerio.load(renderComponent('header', { ...EXAMPLE_HEADER_BASIC, titleAsH1: true }));
422
-
423
- expect($('.ons-header__title')[0].tagName).toBe('h1');
234
+ describe('WHEN: titleAsH1 parameter is set to true', () => {
235
+ const $ = cheerio.load(
236
+ renderComponent('header', {
237
+ ...EXAMPLE_HEADER_BASIC,
238
+ titleAsH1: true,
239
+ }),
240
+ );
241
+ test('THEN: renders title with H1 title tag', () => {
242
+ expect($('.ons-header__title')[0].tagName).toBe('h1');
243
+ });
424
244
  });
425
-
426
- it('has the correct `title` link', () => {
427
- const $ = cheerio.load(renderComponent('header', { ...EXAMPLE_HEADER_BASIC, titleUrl: '#0' }));
428
-
429
- expect($('.ons-header__title-link').attr('href')).toBe('#0');
245
+ describe('WHEN: titleURL param is provided', () => {
246
+ const $ = cheerio.load(
247
+ renderComponent('header', {
248
+ ...EXAMPLE_HEADER_BASIC,
249
+ titleUrl: '#0',
250
+ }),
251
+ );
252
+ test('THEN: renders title with provided link', () => {
253
+ expect($('.ons-header__title-link').attr('href')).toBe('#0');
254
+ });
430
255
  });
431
-
432
- it('has the provided large title logo', () => {
256
+ describe('WHEN: titleLogo: large and small are provided', () => {
433
257
  const $ = cheerio.load(
434
- renderComponent('header', { ...EXAMPLE_HEADER_BASIC, titleLogo: { large: '<img src="another-logo.svg">' } }),
258
+ renderComponent('header', {
259
+ ...EXAMPLE_HEADER_BASIC,
260
+ titleLogo: { large: '<img src="another-logo.svg">', small: '<img src="another-logo-small.svg">' },
261
+ }),
435
262
  );
436
-
437
- expect($('.ons-header__title-logo--large img').attr('src')).toBe('another-logo.svg');
263
+ test('THEN: renders provided large title logo on large screen', () => {
264
+ expect($('.ons-header__title-logo--large img').attr('src')).toBe('another-logo.svg');
265
+ });
266
+ test('THEN: renders provided small title logo on small screen', () => {
267
+ expect($('.ons-header__title-logo--small img').attr('src')).toBe('another-logo-small.svg');
268
+ });
438
269
  });
439
-
440
- it('has the provided title logo custom classes', () => {
270
+ describe('WHEN: titleLogo: classes parameter is provided', () => {
441
271
  const $ = cheerio.load(
442
272
  renderComponent('header', {
443
273
  ...EXAMPLE_HEADER_BASIC,
444
274
  titleLogo: { large: 'another-logo.svg', classes: 'custom-class another-custom-class' },
445
275
  }),
446
276
  );
447
-
448
- expect($('.ons-header__title-logo--large').hasClass('custom-class')).toBe(true);
449
- expect($('.ons-header__title-logo--large').hasClass('another-custom-class')).toBe(true);
277
+ test('THEN: renders title logo with provided additional classes', () => {
278
+ expect($('.ons-header__title-logo--large').hasClass('custom-class')).toBe(true);
279
+ expect($('.ons-header__title-logo--large').hasClass('another-custom-class')).toBe(true);
280
+ });
450
281
  });
451
-
452
- it('has the provided small title logo', () => {
282
+ describe('WHEN: description parameter is provided', () => {
453
283
  const $ = cheerio.load(
454
284
  renderComponent('header', {
455
285
  ...EXAMPLE_HEADER_BASIC,
456
- titleLogo: { large: '<img src="another-logo.svg">', small: '<img src="another-logo-small.svg">' },
286
+ description: 'Header description',
457
287
  }),
458
288
  );
459
-
460
- expect($('.ons-header__title-logo--small img').attr('src')).toBe('another-logo-small.svg');
461
- });
462
-
463
- it('displays the `description` text', () => {
464
- const $ = cheerio.load(renderComponent('header', { ...EXAMPLE_HEADER_BASIC, description: 'Header description' }));
465
-
466
- expect($('.ons-header__description').text()).toBe('Header description');
289
+ test('THEN: renders title with provided description', () => {
290
+ expect($('.ons-header__description').text()).toBe('Header description');
291
+ });
467
292
  });
468
-
469
- it('renders a button with expected parameters', () => {
470
- const faker = templateFaker();
471
- const buttonSpy = faker.spy('button', { suppressOutput: true });
472
-
473
- faker.renderComponent('header', {
474
- ...EXAMPLE_HEADER_BASIC,
475
- button: {
476
- text: 'Save and sign out',
477
- name: 'button-name',
478
- attributes: {
479
- a: 'b',
480
- },
481
- url: '#0',
482
- },
293
+ });
294
+ describe('GIVEN: Params: button: SignOutButton', () => {
295
+ describe('WHEN: no button parameters are provided', () => {
296
+ const $ = cheerio.load(
297
+ renderComponent('header', {
298
+ ...EXAMPLE_HEADER_BASIC,
299
+ }),
300
+ );
301
+ test('THEN: renders title grid with gutterless class', () => {
302
+ const titleGridDiv = $('.ons-header__main .ons-container .ons-grid');
303
+ expect($(titleGridDiv).hasClass('ons-grid--gutterless')).toBe(true);
483
304
  });
484
-
485
- expect(buttonSpy.occurrences).toContainEqual({
305
+ });
306
+ describe('WHEN: signOutButton parameters are provided', () => {
307
+ const button = {
486
308
  text: 'Save and sign out',
487
- classes: 'ons-u-d-no@xxs@m',
488
- variants: 'ghost',
489
309
  name: 'button-name',
490
310
  attributes: {
491
311
  a: 'b',
492
312
  },
493
313
  url: '#0',
494
- iconType: 'exit',
495
- iconPosition: 'after',
496
- });
497
- });
314
+ };
498
315
 
499
- it('has gutterless class if there is no button present', () => {
500
316
  const $ = cheerio.load(
501
317
  renderComponent('header', {
502
318
  ...EXAMPLE_HEADER_BASIC,
319
+ button,
503
320
  }),
504
321
  );
505
322
 
506
- const titleGridDiv = $('.ons-header__main .ons-container .ons-grid');
507
- expect($(titleGridDiv).hasClass('ons-grid--gutterless')).toBe(true);
508
- });
509
-
510
- it('has does not have gutterless class if there is a button present', () => {
511
- const $ = cheerio.load(
512
- renderComponent('header', {
513
- ...EXAMPLE_HEADER_BASIC,
514
- button: {
515
- text: 'Save and sign out',
516
- url: '#0',
517
- iconType: 'exit',
518
- iconPosition: 'after',
323
+ const faker = templateFaker();
324
+ const buttonSpy = faker.spy('button', { suppressOutput: true });
325
+ faker.renderComponent('header', {
326
+ ...EXAMPLE_HEADER_BASIC,
327
+ button,
328
+ });
329
+ test('THEN: renders button with provided parameters', () => {
330
+ expect(buttonSpy.occurrences).toContainEqual({
331
+ text: 'Save and sign out',
332
+ classes: 'ons-u-d-no@xxs@m',
333
+ variants: 'ghost',
334
+ name: 'button-name',
335
+ attributes: {
336
+ a: 'b',
519
337
  },
520
- }),
521
- );
522
-
523
- const titleGridDiv = $('.ons-header__main .ons-container .ons-grid');
524
- expect($(titleGridDiv).hasClass('ons-grid--gutterless')).toBe(false);
338
+ url: '#0',
339
+ iconType: 'exit',
340
+ iconPosition: 'after',
341
+ });
342
+ });
343
+ test('THEN: renders title grid without gutterless class', () => {
344
+ const titleGridDiv = $('.ons-header__main .ons-container .ons-grid');
345
+ expect($(titleGridDiv).hasClass('ons-grid--gutterless')).toBe(false);
346
+ });
525
347
  });
526
-
527
- it('renders the phase banner with expected parameters', () => {
348
+ });
349
+ describe('GIVEN: Params: PhaseBanner', () => {
350
+ describe('WHEN: phaseBanner parameters are provided', () => {
528
351
  const faker = templateFaker();
529
352
  const phaseSpy = faker.spy('phase-banner');
530
353
 
@@ -535,14 +358,14 @@ describe('macro: header', () => {
535
358
  html: 'Example content with a <a href="#">link</a>',
536
359
  },
537
360
  });
538
-
539
- expect(phaseSpy.occurrences).toContainEqual({
540
- badge: 'Example',
541
- html: 'Example content with a <a href="#">link</a>',
361
+ test('THEN: renders phase banner with provided parameters', () => {
362
+ expect(phaseSpy.occurrences).toContainEqual({
363
+ badge: 'Example',
364
+ html: 'Example content with a <a href="#">link</a>',
365
+ });
542
366
  });
543
367
  });
544
-
545
- it('renders the phase banner in the correct container if `wide`', () => {
368
+ describe('WHEN: wide parameter is set to true', () => {
546
369
  const $ = cheerio.load(
547
370
  renderComponent('header', {
548
371
  ...EXAMPLE_HEADER_BASIC,
@@ -553,12 +376,12 @@ describe('macro: header', () => {
553
376
  },
554
377
  }),
555
378
  );
556
-
557
- const phaseContainer = $('.ons-phase-banner .ons-container');
558
- expect($(phaseContainer).hasClass('ons-container--wide')).toBe(true);
379
+ test('THEN: renders container with wide class', () => {
380
+ const phaseContainer = $('.ons-phase-banner .ons-container');
381
+ expect($(phaseContainer).hasClass('ons-container--wide')).toBe(true);
382
+ });
559
383
  });
560
-
561
- it('renders the phase banner in the correct container if `fullWidth`', () => {
384
+ describe('WHEN: fullWidth parameter is set to true', () => {
562
385
  const $ = cheerio.load(
563
386
  renderComponent('header', {
564
387
  ...EXAMPLE_HEADER_BASIC,
@@ -569,112 +392,51 @@ describe('macro: header', () => {
569
392
  },
570
393
  }),
571
394
  );
572
-
573
- const phaseContainer = $('.ons-phase-banner .ons-container');
574
- expect($(phaseContainer).hasClass('ons-container--full-width')).toBe(true);
395
+ test('THEN: renders container with fullWidth class', () => {
396
+ const phaseContainer = $('.ons-phase-banner .ons-container');
397
+ expect($(phaseContainer).hasClass('ons-container--full-width')).toBe(true);
398
+ });
575
399
  });
576
400
  });
577
-
578
- describe('mode: with service links', () => {
579
- it('has the correct display class when multiple links are provided', () => {
401
+ describe('GIVEN: Params: serviceLinks', () => {
402
+ describe('WHEN: multiple items are provided to itemsList parameter', () => {
580
403
  const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_MULTIPLE));
581
404
 
582
- expect($('.ons-header__links .ons-grid__col').hasClass('ons-u-d-no@xxs@m')).toBe(true);
583
- });
584
-
585
- it('has the correct display class when a single link and language is provided', () => {
586
- const $ = cheerio.load(
587
- renderComponent('header', { ...EXAMPLE_HEADER_SERVICE_LINKS_SINGLE, ...EXAMPLE_HEADER_LANGUAGE_CONFIG }),
588
- );
589
-
590
- expect($('.ons-header__links .ons-grid__col').hasClass('ons-u-d-no@xxs@xs')).toBe(true);
591
- });
592
-
593
- it('does not have the display class when only single link is provided', () => {
594
- const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_SINGLE));
595
-
596
- expect($('.ons-header__links .ons-grid__col').hasClass('ons-u-d-no@xxs@')).toBe(false);
597
- });
598
-
599
- it('has the provided custom class', () => {
600
- const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_SINGLE));
601
-
602
- expect($('.ons-header-service-nav--main').hasClass('custom-class')).toBe(true);
603
- });
604
-
605
- it('has the provided `aria-label`', () => {
606
- const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_SINGLE));
607
-
608
- expect($('.ons-header-service-nav--main').attr('aria-label')).toBe('Services menu');
609
- });
610
-
611
- it('has the text for each list item', () => {
612
- const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LIST_ITEMS));
613
-
614
- const values = mapAll($('.ons-header-service-nav--main .ons-header-service-nav__item'), (node) => node.text().trim());
615
- expect(values).toEqual(['Title 1', 'Title 2', 'Title 3']);
616
- });
617
-
618
- it('has the link text for each list item', () => {
619
- const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_MULTIPLE));
620
-
621
- const values = mapAll($('.ons-header-service-nav--main .ons-header-service-nav__link'), (node) => node.text().trim());
622
- expect(values).toEqual(['Title 1', 'Title 2', 'Title 3']);
623
- });
624
-
625
- it('has the link href for each list item', () => {
626
- const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_MULTIPLE));
627
-
628
- const values = mapAll($('.ons-header-service-nav--main .ons-header-service-nav__link'), (node) => node.attr('href'));
629
- expect(values).toEqual(['#1', '#2', '#3']);
630
- });
631
-
632
- it('has the provided custom class', () => {
633
- const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_SINGLE));
634
-
635
- expect($('.ons-header-service-nav--main').hasClass('custom-class')).toBe(true);
636
- });
637
-
638
- it('has the provided `aria-label` for the list for mobile', () => {
639
- const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_SINGLE));
640
-
641
- expect($('.ons-header-service-nav--mobile').attr('aria-label')).toBe('Services menu');
642
- });
643
-
644
- it('has the link text for each list item for mobile', () => {
645
- const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_MULTIPLE));
646
-
647
- const values = mapAll($('.ons-header-service-nav--mobile .ons-header-service-nav__link'), (node) => node.text().trim());
648
- expect(values).toEqual(['Title 1', 'Title 2', 'Title 3']);
649
- });
650
-
651
- it('has the link href for each list item for mobile', () => {
652
- const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_MULTIPLE));
653
-
654
- const values = mapAll($('.ons-header-service-nav--mobile .ons-header-service-nav__link'), (node) => node.attr('href'));
655
- expect(values).toEqual(['#1', '#2', '#3']);
656
- });
657
-
658
- it('renders a button with expected parameters', () => {
659
405
  const faker = templateFaker();
660
406
  const buttonSpy = faker.spy('button', { suppressOutput: true });
661
-
662
407
  faker.renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_MULTIPLE);
663
408
 
664
- expect(buttonSpy.occurrences).toContainEqual({
665
- text: 'Menu',
666
- classes: 'ons-u-d-no ons-js-toggle-services',
667
- type: 'button',
668
- variants: ['mobile', 'text-link'],
669
- attributes: {
670
- 'aria-label': 'Toggle services menu',
671
- 'aria-controls': 'service-links',
672
- 'aria-expanded': 'false',
673
- },
409
+ test('THEN: renders with correct display class on large screen', () => {
410
+ expect($('.ons-header__links .ons-grid__col').hasClass('ons-u-d-no@xxs@m')).toBe(true);
411
+ });
412
+ test('THEN: renders button on small screen', () => {
413
+ expect(buttonSpy.occurrences).toContainEqual({
414
+ text: 'Menu',
415
+ classes: 'ons-u-d-no ons-js-toggle-services',
416
+ type: 'button',
417
+ variants: ['mobile', 'text-link'],
418
+ attributes: {
419
+ 'aria-label': 'Toggle services menu',
420
+ 'aria-controls': 'service-links',
421
+ 'aria-expanded': 'false',
422
+ },
423
+ });
674
424
  });
675
425
  });
676
-
677
- it('renders a button with correct variant if `internal`', () => {
426
+ describe('WHEN: one item is provided to the itemsList parameter', () => {
427
+ const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_SINGLE));
428
+ test('THEN: renders without multiple link display class on large screen', () => {
429
+ expect($('.ons-header__links .ons-grid__col').hasClass('ons-u-d-no@xxs@m')).toBe(false);
430
+ expect($('.ons-header__links .ons-grid__col').hasClass('ons-u-d-no@xxs@xs')).toBe(false);
431
+ });
432
+ test('THEN: does not render button on small screen', () => {
433
+ expect($('.ons-js-toggle-services').length).toBe(0);
434
+ });
435
+ test('THEN: renders with provided ariaLabel on small screen', () => {
436
+ expect($('.ons-header-service-nav--mobile').attr('aria-label')).toBe('Services menu');
437
+ });
438
+ });
439
+ describe('WHEN: internal is provided to the variant parameter', () => {
678
440
  const faker = templateFaker();
679
441
  const buttonSpy = faker.spy('button');
680
442
 
@@ -695,17 +457,37 @@ describe('macro: header', () => {
695
457
  ],
696
458
  },
697
459
  });
698
-
699
- expect(buttonSpy.occurrences[0]).toHaveProperty('variants', ['mobile', 'text-link', 'text-link-inverse']);
460
+ test('THEN: renders button with corresponding variants', () => {
461
+ expect(buttonSpy.occurrences[0]).toHaveProperty('variants', ['mobile', 'text-link', 'text-link-inverse']);
462
+ });
700
463
  });
701
-
702
- it('does not render a button for a single services link', () => {
464
+ describe('WHEN: classes parameter is provided', () => {
703
465
  const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_SINGLE));
704
-
705
- expect($('.ons-js-toggle-services').length).toBe(0);
466
+ test('THEN: renders with provided additional classes', () => {
467
+ expect($('.ons-header-service-nav--main').hasClass('custom-class')).toBe(true);
468
+ });
706
469
  });
470
+ describe('WHEN: item title and url parameters are provided', () => {
471
+ const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_MULTIPLE));
707
472
 
708
- it('has the correct list item icon', () => {
473
+ test('THEN: renders item with provided title on large screen', () => {
474
+ const values = mapAll($('.ons-header-service-nav--main .ons-header-service-nav__link'), (node) => node.text().trim());
475
+ expect(values).toEqual(['Title 1', 'Title 2', 'Title 3']);
476
+ });
477
+ test('THEN: renders item with provided title on small screen', () => {
478
+ const values = mapAll($('.ons-header-service-nav--mobile .ons-header-service-nav__link'), (node) => node.text().trim());
479
+ expect(values).toEqual(['Title 1', 'Title 2', 'Title 3']);
480
+ });
481
+ test('THEN: renders item with provided url on large screen', () => {
482
+ const values = mapAll($('.ons-header-service-nav--main .ons-header-service-nav__link'), (node) => node.attr('href'));
483
+ expect(values).toEqual(['#1', '#2', '#3']);
484
+ });
485
+ test('THEN: renders item with provided url on small screen', () => {
486
+ const values = mapAll($('.ons-header-service-nav--mobile .ons-header-service-nav__link'), (node) => node.attr('href'));
487
+ expect(values).toEqual(['#1', '#2', '#3']);
488
+ });
489
+ });
490
+ describe('WHEN: item iconType parameter is provided', () => {
709
491
  const faker = templateFaker();
710
492
  const iconsSpy = faker.spy('icon');
711
493
 
@@ -721,49 +503,30 @@ describe('macro: header', () => {
721
503
  ],
722
504
  },
723
505
  });
724
-
725
- expect(iconsSpy.occurrences[2].iconType).toBe('check');
506
+ test('THEN: renders item with provided iconType', () => {
507
+ expect(iconsSpy.occurrences[2].iconType).toBe('check');
508
+ });
726
509
  });
727
- });
728
-
729
- describe('mode: with language selector', () => {
730
- it('displays the language selector with expected parameters', () => {
731
- const faker = templateFaker();
732
- const languageSpy = faker.spy('language-selector', { suppressOutput: true });
733
-
734
- faker.renderComponent('header', { ...EXAMPLE_HEADER_BASIC, ...EXAMPLE_HEADER_LANGUAGE_CONFIG });
735
-
736
- expect(languageSpy.occurrences).toContainEqual({
737
- languages: [
738
- {
739
- url: '#0',
740
- ISOCode: 'en',
741
- text: 'English',
742
- buttonAriaLabel: 'Language selector. Current language: English',
743
- chooseLanguage: 'Choose language',
744
- current: true,
745
- },
746
- {
747
- url: '#0',
748
- ISOCode: 'cy',
749
- text: 'Cymraeg',
750
- buttonAriaLabel: 'Dewisydd iaith. Iaith gyfredol: Cymraeg',
751
- chooseLanguage: 'Dewiswch iaith',
752
- current: false,
753
- },
754
- ],
510
+ describe('WHEN: language and a single item itemsList parameters are provided', () => {
511
+ const $ = cheerio.load(
512
+ renderComponent('header', {
513
+ ...EXAMPLE_HEADER_SERVICE_LINKS_SINGLE,
514
+ ...EXAMPLE_HEADER_LANGUAGE_CONFIG,
515
+ }),
516
+ );
517
+ test('THEN: renders with correct display class', () => {
518
+ expect($('.ons-header__links .ons-grid__col').hasClass('ons-u-d-no@xxs@xs')).toBe(true);
755
519
  });
756
520
  });
757
521
  });
758
-
759
- describe('mode: with navigation', () => {
760
- it('renders the navigation with expected parameters', () => {
522
+ describe('GIVEN: Params: navigation', () => {
523
+ describe('WHEN: navigation parameters are provided', () => {
761
524
  const faker = templateFaker();
762
525
  const navigationSpy = faker.spy('navigation', { suppressOutput: true });
526
+ const buttonSpy = faker.spy('button');
763
527
 
764
- faker.renderComponent('header', { ...EXAMPLE_HEADER_BASIC, ...EXAMPLE_HEADER_NAVIGATION_CONFIG });
765
-
766
- expect(navigationSpy.occurrences[0]).toEqual({
528
+ faker.renderComponent('header', {
529
+ ...EXAMPLE_HEADER_BASIC,
767
530
  navigation: {
768
531
  id: 'main-nav',
769
532
  ariaLabel: 'Main menu',
@@ -783,32 +546,81 @@ describe('macro: header', () => {
783
546
  ariaLabel: 'Toggle main menu',
784
547
  },
785
548
  },
786
- title: 'Header title',
549
+ });
550
+ test('THEN: renders navigation with provided parameters', () => {
551
+ expect(navigationSpy.occurrences[0]).toEqual({
552
+ navigation: {
553
+ id: 'main-nav',
554
+ ariaLabel: 'Main menu',
555
+ currentPath: '#home',
556
+ itemsList: [
557
+ {
558
+ title: 'Home',
559
+ url: '#home',
560
+ },
561
+ {
562
+ title: 'Guidance',
563
+ url: '#0',
564
+ },
565
+ ],
566
+ toggleNavigationButton: {
567
+ text: 'Menu',
568
+ ariaLabel: 'Toggle main menu',
569
+ },
570
+ },
571
+ title: 'Header title',
572
+ });
573
+ });
574
+ test('THEN: renders button to toggle menu on small screen', () => {
575
+ expect(buttonSpy.occurrences[0]).toEqual({
576
+ text: 'Menu',
577
+ classes: 'ons-u-ml-xs ons-u-d-no ons-js-navigation-button ons-u-d-no@l',
578
+ variants: ['mobile', 'ghost'],
579
+ attributes: {
580
+ 'aria-label': 'Toggle main menu',
581
+ 'aria-controls': 'main-nav',
582
+ 'aria-expanded': 'false',
583
+ },
584
+ });
787
585
  });
788
586
  });
789
-
790
- it('renders a button to toggle the menu on mobile', () => {
791
- const faker = templateFaker();
792
- const buttonSpy = faker.spy('button');
793
-
794
- faker.renderComponent('header', { ...EXAMPLE_HEADER_BASIC, ...EXAMPLE_HEADER_NAVIGATION_CONFIG });
795
-
796
- expect(buttonSpy.occurrences[0]).toEqual({
797
- text: 'Menu',
798
- classes: 'ons-u-ml-xs ons-u-d-no ons-js-navigation-button ons-u-d-no@l',
799
- variants: ['mobile', 'ghost'],
800
- attributes: {
801
- 'aria-label': 'Toggle main menu',
802
- 'aria-controls': 'main-nav',
803
- 'aria-expanded': 'false',
804
- },
587
+ describe('WHEN: fullWidth parameter is set to true', () => {
588
+ const $ = cheerio.load(
589
+ renderComponent('header', {
590
+ ...EXAMPLE_HEADER_BASIC,
591
+ fullWidth: true,
592
+ ...EXAMPLE_HEADER_NAVIGATION_WITH_SUBNAVIGATION_CONFIG,
593
+ }),
594
+ );
595
+ test('THEN: renders navigation container with fullWidth class', () => {
596
+ const navContainer = $('.ons-navigation-wrapper .ons-container');
597
+ expect($(navContainer).hasClass('ons-container--full-width')).toBe(true);
598
+ });
599
+ test('THEN: renders sub-navigation container with fullWidth class', () => {
600
+ const subNavContainer = $('.ons-navigation--sub .ons-container');
601
+ expect($(subNavContainer).hasClass('ons-container--full-width')).toBe(true);
805
602
  });
806
603
  });
807
-
808
- it('renders a button to toggle the search on mobile', () => {
604
+ describe('WHEN: wide parameter is set to true', () => {
605
+ const $ = cheerio.load(
606
+ renderComponent('header', {
607
+ ...EXAMPLE_HEADER_BASIC,
608
+ wide: true,
609
+ ...EXAMPLE_HEADER_NAVIGATION_WITH_SUBNAVIGATION_CONFIG,
610
+ }),
611
+ );
612
+ test('THEN: renders navigation container with wide class', () => {
613
+ const navContainer = $('.ons-navigation-wrapper .ons-container');
614
+ expect($(navContainer).hasClass('ons-container--wide')).toBe(true);
615
+ });
616
+ test('THEN: renders sub-navigation container with wide class', () => {
617
+ const subNavContainer = $('.ons-navigation--sub .ons-container');
618
+ expect($(subNavContainer).hasClass('ons-container--wide')).toBe(true);
619
+ });
620
+ });
621
+ describe('WHEN: navigation and siteSearchAutosuggest parameters are provided', () => {
809
622
  const faker = templateFaker();
810
623
  const buttonSpy = faker.spy('button');
811
-
812
624
  faker.renderComponent('header', {
813
625
  ...EXAMPLE_HEADER_BASIC,
814
626
  navigation: {
@@ -832,114 +644,52 @@ describe('macro: header', () => {
832
644
  },
833
645
  siteSearchAutosuggest: {},
834
646
  });
835
-
836
- expect(buttonSpy.occurrences[0]).toEqual({
837
- text: 'Search',
838
- classes: 'ons-btn--search ons-u-ml-xs ons-u-d-no ons-js-toggle-search',
839
- variants: ['small', 'ghost'],
840
- iconType: 'search',
841
- iconPosition: 'only',
842
- attributes: {
843
- 'aria-label': 'Toggle search',
844
- 'aria-controls': 'ons-site-search',
845
- 'aria-expanded': 'false',
846
- },
647
+ test('THEN: renders button to toggle search on small screen', () => {
648
+ expect(buttonSpy.occurrences[0]).toEqual({
649
+ text: 'Search',
650
+ classes: 'ons-btn--search ons-u-ml-xs ons-u-d-no ons-js-toggle-search',
651
+ variants: ['small', 'ghost'],
652
+ iconType: 'search',
653
+ iconPosition: 'only',
654
+ attributes: {
655
+ 'aria-label': 'Toggle search',
656
+ 'aria-controls': 'ons-site-search',
657
+ 'aria-expanded': 'false',
658
+ },
659
+ });
847
660
  });
848
661
  });
849
-
850
- it('renders the navigation in the correct container if `wide`', () => {
851
- const $ = cheerio.load(
852
- renderComponent('header', {
853
- ...EXAMPLE_HEADER_BASIC,
854
- wide: true,
855
- ...EXAMPLE_HEADER_NAVIGATION_CONFIG,
856
- }),
857
- );
858
-
859
- const navContainer = $('.ons-navigation-wrapper .ons-container');
860
- expect($(navContainer).hasClass('ons-container--wide')).toBe(true);
861
- });
862
-
863
- it('renders the navigation in the correct container if `fullWidth`', () => {
864
- const $ = cheerio.load(
865
- renderComponent('header', {
866
- ...EXAMPLE_HEADER_BASIC,
867
- fullWidth: true,
868
- ...EXAMPLE_HEADER_NAVIGATION_CONFIG,
869
- }),
870
- );
871
-
872
- const navContainer = $('.ons-navigation-wrapper .ons-container');
873
- expect($(navContainer).hasClass('ons-container--full-width')).toBe(true);
874
- });
875
-
876
- it('renders the sub-navigation in the correct container if `wide`', () => {
877
- const $ = cheerio.load(
878
- renderComponent('header', {
879
- ...EXAMPLE_HEADER_BASIC,
880
- wide: true,
881
- ...EXAMPLE_HEADER_NAVIGATION_WITH_SUBNAVIGATION_CONFIG,
882
- }),
883
- );
884
-
885
- const subNavContainer = $('.ons-navigation--sub .ons-container');
886
- expect($(subNavContainer).hasClass('ons-container--wide')).toBe(true);
887
- });
888
-
889
- it('renders the sub-navigation in the correct container if `fullWidth`', () => {
890
- const $ = cheerio.load(
891
- renderComponent('header', {
892
- ...EXAMPLE_HEADER_BASIC,
893
- fullWidth: true,
894
- ...EXAMPLE_HEADER_NAVIGATION_WITH_SUBNAVIGATION_CONFIG,
895
- }),
896
- );
897
-
898
- const subNavContainer = $('.ons-navigation--sub .ons-container');
899
- expect($(subNavContainer).hasClass('ons-container--full-width')).toBe(true);
900
- });
901
662
  });
902
- });
903
-
904
- describe('mode: with site search autosuggest', () => {
905
- it('renders the search with expected parameters', () => {
906
- const faker = templateFaker();
907
- const buttonSpy = faker.spy('autosuggest');
908
-
909
- faker.renderComponent('header', EXAMPLE_HEADER_NAVIGATION_WITH_SITESEARCHAUTOSUGGEST);
910
-
911
- expect(buttonSpy.occurrences[0]).toEqual({
912
- ariaLimitedResults: 'Type more characters to improve your search',
913
- minChars: 3,
914
- language: 'en-gb',
915
- ariaMinChars: 'Enter 3 or more characters for suggestions.',
916
- ariaNResults: 'There are {n} suggestions available.',
917
- ariaOneResult: 'There is one suggestion available.',
918
- ariaResultsLabel: 'Country suggestions',
919
- ariaYouHaveSelected: 'You have selected',
920
- containerClasses: 'ons-autosuggest--header',
921
- id: 'ons-site-search',
922
- input: {
923
- accessiblePlaceholder: true,
924
- autocomplete: 'off',
925
- classes: 'ons-input-search ons-input-search--icon',
926
- label: {
927
- classes: 'ons-u-pl-m ons-label--white',
928
- id: 'ons-site-search-label',
929
- text: 'label',
930
- },
931
- },
932
- instructions: 'Use up and down keys to navigate.',
933
- moreResults: 'Continue entering to improve suggestions',
934
- noResults: 'No suggestions found.',
935
- resultsTitle: 'Suggestions',
936
- typeMore: 'Continue entering to get suggestions',
663
+ describe('GIVEN: params: languages', () => {
664
+ describe('WHEN: language parameters are provided', () => {
665
+ const faker = templateFaker();
666
+ const languageSpy = faker.spy('language-selector', { suppressOutput: true });
667
+ faker.renderComponent('header', { ...EXAMPLE_HEADER_BASIC, ...EXAMPLE_HEADER_LANGUAGE_CONFIG });
668
+ test('THEN: renders language selector with provided language options', () => {
669
+ expect(languageSpy.occurrences).toContainEqual({
670
+ languages: [
671
+ {
672
+ url: '#0',
673
+ ISOCode: 'en',
674
+ text: 'English',
675
+ buttonAriaLabel: 'Language selector. Current language: English',
676
+ chooseLanguage: 'Choose language',
677
+ current: true,
678
+ },
679
+ {
680
+ url: '#0',
681
+ ISOCode: 'cy',
682
+ text: 'Cymraeg',
683
+ buttonAriaLabel: 'Dewisydd iaith. Iaith gyfredol: Cymraeg',
684
+ chooseLanguage: 'Dewiswch iaith',
685
+ current: false,
686
+ },
687
+ ],
688
+ });
689
+ });
937
690
  });
938
691
  });
939
-
940
- describe('when the user inputs text', () => {
941
- let $; // Initialize a Cheerio instance
942
-
692
+ describe('GIVEN: Params: siteSearchAutosuggest', () => {
943
693
  const mockData = [
944
694
  { en: 'England' },
945
695
  { en: 'Wales' },
@@ -949,38 +699,80 @@ describe('mode: with site search autosuggest', () => {
949
699
  { en: 'Åland Islands' },
950
700
  ];
951
701
 
952
- beforeEach(() => {
953
- $ = cheerio.load(
702
+ describe('WHEN: autosuggest parameters are provided', () => {
703
+ const faker = templateFaker();
704
+ const buttonSpy = faker.spy('autosuggest');
705
+
706
+ faker.renderComponent('header', EXAMPLE_HEADER_NAVIGATION_WITH_SITESEARCHAUTOSUGGEST);
707
+
708
+ test('THEN: renders search with provided parameters', () => {
709
+ expect(buttonSpy.occurrences[0]).toEqual({
710
+ ariaLimitedResults: 'Type more characters to improve your search',
711
+ minChars: 3,
712
+ language: 'en-gb',
713
+ ariaMinChars: 'Enter 3 or more characters for suggestions.',
714
+ ariaNResults: 'There are {n} suggestions available.',
715
+ ariaOneResult: 'There is one suggestion available.',
716
+ ariaResultsLabel: 'Country suggestions',
717
+ ariaYouHaveSelected: 'You have selected',
718
+ containerClasses: 'ons-autosuggest--header',
719
+ id: 'ons-site-search',
720
+ input: {
721
+ accessiblePlaceholder: true,
722
+ autocomplete: 'off',
723
+ classes: 'ons-input-search ons-input-search--icon',
724
+ label: {
725
+ classes: 'ons-u-pl-l ons-label--white',
726
+ id: 'ons-site-search-label',
727
+ text: 'label',
728
+ },
729
+ },
730
+ instructions: 'Use up and down keys to navigate.',
731
+ moreResults: 'Continue entering to improve suggestions',
732
+ noResults: 'No suggestions found.',
733
+ resultsTitle: 'Suggestions',
734
+ typeMore: 'Continue entering to get suggestions',
735
+ });
736
+ });
737
+ });
738
+ describe('WHEN: language is set', () => {
739
+ const $ = cheerio.load(
954
740
  renderComponent('header', {
955
741
  ...EXAMPLE_HEADER_NAVIGATION_WITH_SITESEARCHAUTOSUGGEST,
956
742
  autosuggestData: mockData,
957
743
  }),
958
744
  );
745
+ test('THEN: rendered search component accesses set language', () => {
746
+ $('.ons-js-autosuggest-input').val('Eng');
747
+ const autosuggestElement = $('.ons-js-autosuggest').attr('data-lang');
748
+ expect(autosuggestElement).toBe('en-gb');
749
+ });
959
750
  });
751
+ describe('WHEN: user enters text', () => {
752
+ let $; // Initialize a Cheerio instance
960
753
 
961
- it('does not show suggestions when input length < minimum characters', () => {
962
- $('.ons-js-autosuggest-input').val('En');
963
-
964
- setTimeout(() => {
965
- const suggestionCount = $('.ons-autosuggest__option').length;
966
- expect(suggestionCount).toBe(0);
967
- }, 20);
968
- });
969
-
970
- it('shows suggestions when input length >= minimum characters', () => {
971
- $('.ons-js-autosuggest-input').val('Eng');
972
-
973
- setTimeout(() => {
974
- const suggestionCount = $('.ons-autosuggest__option').length;
975
- expect(suggestionCount).toBe(1);
976
- }, 20);
977
- });
978
-
979
- it('gets the language if set', () => {
980
- $('.ons-js-autosuggest-input').val('Eng');
981
-
982
- const autosuggestElement = $('.ons-js-autosuggest').attr('data-lang');
983
- expect(autosuggestElement).toBe('en-gb');
754
+ beforeEach(() => {
755
+ $ = cheerio.load(
756
+ renderComponent('header', {
757
+ ...EXAMPLE_HEADER_NAVIGATION_WITH_SITESEARCHAUTOSUGGEST,
758
+ autosuggestData: mockData,
759
+ }),
760
+ );
761
+ });
762
+ test('THEN: displays no suggestions when input length < minimum characters', () => {
763
+ $('.ons-js-autosuggest-input').val('En');
764
+ setTimeout(() => {
765
+ const suggestionCount = $('.ons-autosuggest__option').length;
766
+ expect(suggestionCount).toBe(0);
767
+ }, 20);
768
+ });
769
+ test('THEN: displays suggestions when input length >= minimum characters', () => {
770
+ $('.ons-js-autosuggest-input').val('Eng');
771
+ setTimeout(() => {
772
+ const suggestionCount = $('.ons-autosuggest__option').length;
773
+ expect(suggestionCount).toBe(1);
774
+ }, 20);
775
+ });
984
776
  });
985
777
  });
986
778
  });