@ons/design-system 50.0.1 → 51.0.0

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 (164) hide show
  1. package/README.md +35 -13
  2. package/components/access-code/_macro.njk +1 -1
  3. package/components/access-code/_macro.spec.js +162 -0
  4. package/components/access-code/uac.spec.js +26 -0
  5. package/components/accordion/_macro.spec.js +224 -0
  6. package/components/accordion/accordion.spec.js +134 -0
  7. package/components/address-input/_macro.njk +1 -1
  8. package/components/address-input/_macro.spec.js +465 -0
  9. package/components/address-input/autosuggest.address.js +5 -4
  10. package/components/address-input/autosuggest.address.setter.js +3 -1
  11. package/components/address-input/autosuggest.address.spec.js +733 -0
  12. package/components/address-output/_macro.njk +6 -6
  13. package/components/address-output/_macro.spec.js +122 -0
  14. package/components/autosuggest/_macro.njk +1 -1
  15. package/components/autosuggest/_macro.spec.js +229 -0
  16. package/components/autosuggest/autosuggest.helpers.js +2 -3
  17. package/components/autosuggest/autosuggest.helpers.spec.js +85 -0
  18. package/components/autosuggest/autosuggest.js +4 -2
  19. package/components/autosuggest/autosuggest.spec.js +625 -0
  20. package/components/autosuggest/autosuggest.ui.js +6 -2
  21. package/components/breadcrumbs/_macro.spec.js +129 -0
  22. package/components/button/_macro.njk +5 -5
  23. package/components/button/_macro.spec.js +446 -0
  24. package/components/button/button.spec.js +290 -0
  25. package/components/call-to-action/_macro.njk +3 -1
  26. package/components/call-to-action/_macro.spec.js +52 -0
  27. package/components/card/_macro.njk +26 -19
  28. package/components/card/_macro.spec.js +261 -0
  29. package/components/char-check-limit/_macro.spec.js +73 -0
  30. package/components/char-check-limit/character-check.spec.js +196 -0
  31. package/components/char-check-limit/character-limit.js +1 -1
  32. package/components/checkboxes/_checkbox-macro.spec.js +419 -0
  33. package/components/checkboxes/_macro.njk +1 -3
  34. package/components/checkboxes/_macro.spec.js +306 -0
  35. package/components/checkboxes/checkboxes.spec.js +208 -0
  36. package/components/code-highlight/_macro.spec.js +56 -0
  37. package/components/code-highlight/code-highlight.spec.js +18 -0
  38. package/components/collapsible/_macro.spec.js +204 -0
  39. package/components/collapsible/collapsible.js +2 -1
  40. package/components/collapsible/collapsible.spec.js +236 -0
  41. package/components/content-pagination/_macro.spec.js +199 -0
  42. package/components/cookies-banner/_macro.njk +1 -1
  43. package/components/cookies-banner/_macro.spec.js +171 -0
  44. package/components/cookies-banner/cookies-banner.spec.js +90 -0
  45. package/components/date-input/_macro.njk +6 -3
  46. package/components/date-input/_macro.spec.js +286 -0
  47. package/components/document-list/_macro.njk +3 -5
  48. package/components/document-list/_macro.spec.js +491 -0
  49. package/components/download-resources/download-resources.spec.js +540 -0
  50. package/components/duration/_macro.njk +7 -6
  51. package/components/duration/_macro.spec.js +251 -0
  52. package/components/error/_macro.spec.js +97 -0
  53. package/components/external-link/_macro.spec.js +60 -0
  54. package/components/feedback/_macro.njk +5 -3
  55. package/components/feedback/_macro.spec.js +122 -0
  56. package/components/field/_macro.njk +2 -2
  57. package/components/field/_macro.spec.js +97 -0
  58. package/components/fieldset/_macro.njk +3 -3
  59. package/components/fieldset/_macro.spec.js +173 -0
  60. package/components/footer/_macro.njk +11 -48
  61. package/components/footer/_macro.spec.js +549 -0
  62. package/components/header/_macro.njk +2 -2
  63. package/components/header/_macro.spec.js +562 -0
  64. package/components/hero/_hero.scss +0 -3
  65. package/components/hero/_macro.njk +4 -4
  66. package/components/hero/_macro.spec.js +224 -0
  67. package/components/icons/_macro.njk +15 -15
  68. package/components/icons/_macro.spec.js +140 -0
  69. package/components/images/_macro.njk +1 -1
  70. package/components/images/_macro.spec.js +121 -0
  71. package/components/input/_input-type.scss +12 -5
  72. package/components/input/_macro.njk +4 -5
  73. package/components/input/_macro.spec.js +658 -0
  74. package/components/label/_macro.spec.js +189 -0
  75. package/components/language-selector/_macro.spec.js +129 -0
  76. package/components/lists/_list.scss +4 -0
  77. package/components/lists/_macro.njk +4 -7
  78. package/components/lists/_macro.spec.js +618 -0
  79. package/components/message/_macro.spec.js +137 -0
  80. package/components/message-list/_macro.njk +7 -7
  81. package/components/message-list/_macro.spec.js +159 -0
  82. package/components/metadata/_macro.spec.js +167 -0
  83. package/components/modal/_macro.njk +6 -6
  84. package/components/modal/_macro.spec.js +87 -0
  85. package/components/modal/modal.spec.js +59 -0
  86. package/components/mutually-exclusive/_macro.njk +1 -1
  87. package/components/mutually-exclusive/_macro.spec.js +182 -0
  88. package/components/mutually-exclusive/mutually-exclusive.checkboxes.spec.js +203 -0
  89. package/components/mutually-exclusive/mutually-exclusive.date.spec.js +142 -0
  90. package/components/mutually-exclusive/mutually-exclusive.duration.spec.js +141 -0
  91. package/components/mutually-exclusive/mutually-exclusive.email.spec.js +117 -0
  92. package/components/mutually-exclusive/mutually-exclusive.multiple-options.checkboxes.spec.js +213 -0
  93. package/components/mutually-exclusive/mutually-exclusive.number.spec.js +125 -0
  94. package/components/mutually-exclusive/mutually-exclusive.textarea.spec.js +131 -0
  95. package/components/navigation/_macro.njk +6 -6
  96. package/components/navigation/_macro.spec.js +327 -0
  97. package/components/navigation/navigation.dom.js +1 -1
  98. package/components/navigation/navigation.spec.js +232 -0
  99. package/components/pagination/_macro.njk +1 -1
  100. package/components/pagination/_macro.spec.js +411 -0
  101. package/components/panel/_macro.njk +6 -6
  102. package/components/panel/_macro.spec.js +423 -0
  103. package/components/password/_macro.spec.js +137 -0
  104. package/components/password/password.spec.js +40 -0
  105. package/components/phase-banner/_macro.spec.js +73 -0
  106. package/components/promotional-banner/_macro.spec.js +97 -0
  107. package/components/question/_macro.njk +25 -33
  108. package/components/question/_macro.spec.js +309 -0
  109. package/components/quote/_macro.spec.js +81 -0
  110. package/components/radios/_macro.njk +3 -6
  111. package/components/radios/_macro.spec.js +575 -0
  112. package/components/radios/radios.spec.js +180 -0
  113. package/components/related-content/_macro.njk +1 -0
  114. package/components/related-content/_macro.spec.js +142 -0
  115. package/components/relationships/_macro.spec.js +108 -0
  116. package/components/relationships/relationships.spec.js +84 -0
  117. package/components/reply/_macro.njk +2 -2
  118. package/components/reply/_macro.spec.js +69 -0
  119. package/components/reply/reply.spec.js +78 -0
  120. package/components/search/_macro.njk +14 -12
  121. package/components/search/_macro.spec.js +44 -0
  122. package/components/search/_search.scss +7 -7
  123. package/components/section-navigation/_macro.njk +7 -2
  124. package/components/section-navigation/_macro.spec.js +206 -0
  125. package/components/select/_macro.njk +3 -3
  126. package/components/select/_macro.spec.js +203 -0
  127. package/components/select/select.spec.js +56 -0
  128. package/components/share-page/_macro.njk +2 -2
  129. package/components/share-page/_macro.spec.js +110 -0
  130. package/components/skip-to-content/_macro.spec.js +57 -0
  131. package/components/skip-to-content/skip-to-content.spec.js +44 -0
  132. package/components/status/_macro.spec.js +77 -0
  133. package/components/summary/_macro.njk +5 -5
  134. package/components/summary/_macro.spec.js +472 -0
  135. package/components/table/_macro.njk +2 -2
  136. package/components/table/_macro.spec.js +557 -0
  137. package/components/table/table.spec.js +155 -0
  138. package/components/table-of-contents/_macro.njk +35 -35
  139. package/components/table-of-contents/_macro.spec.js +178 -0
  140. package/components/table-of-contents/toc.js +29 -25
  141. package/components/table-of-contents/toc.spec.js +61 -0
  142. package/components/tabs/_macro.njk +1 -1
  143. package/components/tabs/_macro.spec.js +79 -0
  144. package/components/tabs/tabs.spec.js +162 -0
  145. package/components/text-indent/_macro.spec.js +52 -0
  146. package/components/textarea/_macro.njk +5 -3
  147. package/components/textarea/_macro.spec.js +300 -0
  148. package/components/textarea/textarea.spec.js +98 -0
  149. package/components/timeline/_macro.njk +3 -3
  150. package/components/timeline/_macro.spec.js +81 -0
  151. package/components/timeout-modal/_macro.spec.js +68 -0
  152. package/components/timeout-modal/timeout-modal.spec.js +226 -0
  153. package/components/timeout-panel/_macro.njk +0 -1
  154. package/components/timeout-panel/_macro.spec.js +54 -0
  155. package/components/timeout-panel/timeout-panel.dom.js +1 -2
  156. package/components/timeout-panel/timeout-panel.spec.js +161 -0
  157. package/components/upload/_macro.spec.js +75 -0
  158. package/components/video/_macro.spec.js +34 -0
  159. package/css/census.css +1 -1
  160. package/css/main.css +1 -1
  161. package/js/cookies-settings.spec.js +154 -0
  162. package/package.json +10 -23
  163. package/scripts/main.es5.js +1 -1
  164. package/scripts/main.js +1 -1
@@ -0,0 +1,557 @@
1
+ /** @jest-environment jsdom */
2
+
3
+ import * as cheerio from 'cheerio';
4
+
5
+ import axe from '../../tests/helpers/axe';
6
+ import { mapAll } from '../../tests/helpers/cheerio';
7
+ import { renderComponent, templateFaker } from '../../tests/helpers/rendering';
8
+
9
+ const EXAMPLE_TABLE_MINIMAL = {
10
+ ths: [],
11
+ trs: [],
12
+ };
13
+
14
+ const EXAMPLE_TABLE = {
15
+ ...EXAMPLE_TABLE_MINIMAL,
16
+ ths: [{ value: 'Column 1' }, { value: 'Column 2' }, { value: 'Column 3' }],
17
+ trs: [
18
+ {
19
+ tds: [{ value: 'Row 1 Cell 1' }, { value: 'Row 1 Cell 2' }, { value: 'Row 1 Cell 3' }],
20
+ },
21
+ {
22
+ tds: [{ value: 'Row 2 Cell 1' }, { value: 'Row 2 Cell 2' }, { value: 'Row 2 Cell 3' }],
23
+ },
24
+ ],
25
+ };
26
+
27
+ describe('macro: table', () => {
28
+ it('passes jest-axe checks', async () => {
29
+ const $ = cheerio.load(renderComponent('table', EXAMPLE_TABLE));
30
+
31
+ const results = await axe($.html());
32
+ expect(results).toHaveNoViolations();
33
+ });
34
+
35
+ it('has the provided `id` attribute', () => {
36
+ const $ = cheerio.load(
37
+ renderComponent('table', {
38
+ ...EXAMPLE_TABLE,
39
+ id: 'example-table',
40
+ }),
41
+ );
42
+
43
+ expect($('.ons-table').attr('id')).toBe('example-table');
44
+ });
45
+
46
+ it('has additionally provided style classes', () => {
47
+ const $ = cheerio.load(
48
+ renderComponent('table', {
49
+ ...EXAMPLE_TABLE,
50
+ tableClasses: 'extra-class another-extra-class',
51
+ }),
52
+ );
53
+
54
+ expect($('.ons-table').hasClass('extra-class')).toBe(true);
55
+ expect($('.ons-table').hasClass('another-extra-class')).toBe(true);
56
+ });
57
+
58
+ describe('header row', () => {
59
+ it('renders header cells with expected text', () => {
60
+ const $ = cheerio.load(renderComponent('table', EXAMPLE_TABLE));
61
+
62
+ const headerCellValues = mapAll($('.ons-table__header'), node => node.text().trim());
63
+ expect(headerCellValues).toEqual(['Column 1', 'Column 2', 'Column 3']);
64
+ });
65
+
66
+ it('adds additionally provided class to column header', () => {
67
+ const $ = cheerio.load(
68
+ renderComponent('table', {
69
+ ...EXAMPLE_TABLE,
70
+ ths: [
71
+ {
72
+ value: 'Column 1',
73
+ thClasses: 'extra-column-class another-extra-column-class',
74
+ },
75
+ ],
76
+ }),
77
+ );
78
+
79
+ expect($('.ons-table__header').hasClass('extra-column-class')).toBe(true);
80
+ expect($('.ons-table__header').hasClass('another-extra-column-class')).toBe(true);
81
+ });
82
+
83
+ it('does not add "numeric" modifier class to column header when `td.numeric` is not provided', () => {
84
+ const $ = cheerio.load(renderComponent('table', EXAMPLE_TABLE));
85
+
86
+ expect($('.ons-table__header').hasClass('ons-table__header--numeric')).toBe(false);
87
+ });
88
+
89
+ it('adds "numeric" modifier class to column header when `th.numeric` is `true`', () => {
90
+ const $ = cheerio.load(
91
+ renderComponent('table', {
92
+ ...EXAMPLE_TABLE,
93
+ ths: [
94
+ {
95
+ value: 'Column 1',
96
+ numeric: true,
97
+ },
98
+ ],
99
+ }),
100
+ );
101
+
102
+ expect($('.ons-table__header').hasClass('ons-table__header--numeric')).toBe(true);
103
+ });
104
+
105
+ it('does not add visually hidden class to column headers', () => {
106
+ const $ = cheerio.load(renderComponent('table', EXAMPLE_TABLE));
107
+
108
+ const hasClass = mapAll($('.ons-table__header > span'), node => node.hasClass('ons-u-vh'));
109
+ expect(hasClass).toEqual([false, false, false]);
110
+ });
111
+
112
+ it('does not render "sort-sprite" icon', () => {
113
+ const faker = templateFaker();
114
+ const iconsSpy = faker.spy('icons');
115
+
116
+ faker.renderComponent('table', EXAMPLE_TABLE);
117
+
118
+ expect(iconsSpy.occurrences.length).toBe(0);
119
+ });
120
+ });
121
+
122
+ describe('row', () => {
123
+ it('renders expected row cells', () => {
124
+ const $ = cheerio.load(renderComponent('table', EXAMPLE_TABLE));
125
+
126
+ const row1Values = mapAll($('.ons-table__row:nth-child(1) .ons-table__cell'), node => node.text().trim());
127
+ expect(row1Values).toEqual(['Row 1 Cell 1', 'Row 1 Cell 2', 'Row 1 Cell 3']);
128
+ const row2Values = mapAll($('.ons-table__row:nth-child(2) .ons-table__cell'), node => node.text().trim());
129
+ expect(row2Values).toEqual(['Row 2 Cell 1', 'Row 2 Cell 2', 'Row 2 Cell 3']);
130
+ });
131
+
132
+ it('does not render `id` attribute on a cell when `id` is not provided', () => {
133
+ const $ = cheerio.load(renderComponent('table', EXAMPLE_TABLE));
134
+
135
+ expect($('.ons-table__cell').attr('id')).toBeUndefined();
136
+ });
137
+
138
+ it('renders provided `id` attribute on a cell', () => {
139
+ const $ = cheerio.load(
140
+ renderComponent('table', {
141
+ ...EXAMPLE_TABLE,
142
+ trs: [
143
+ {
144
+ tds: [
145
+ {
146
+ id: 'example-cell',
147
+ value: 'Example Cell',
148
+ },
149
+ ],
150
+ },
151
+ ],
152
+ }),
153
+ );
154
+
155
+ expect($('.ons-table__cell').attr('id')).toBe('example-cell');
156
+ });
157
+
158
+ it('does not render `data-th` attribute on a cell when `data` is not provided', () => {
159
+ const $ = cheerio.load(renderComponent('table', EXAMPLE_TABLE));
160
+
161
+ expect($('.ons-table__cell').attr('data-th')).toBeUndefined();
162
+ });
163
+
164
+ it('renders `data-th` attribute on a cell when `data` is provided', () => {
165
+ const $ = cheerio.load(
166
+ renderComponent('table', {
167
+ ...EXAMPLE_TABLE,
168
+ trs: [
169
+ {
170
+ tds: [
171
+ {
172
+ value: 'Example Cell',
173
+ data: '123',
174
+ },
175
+ ],
176
+ },
177
+ ],
178
+ }),
179
+ );
180
+
181
+ expect($('.ons-table__cell').attr('data-th')).toBe('123');
182
+ });
183
+
184
+ it('does not render `data-sort-value` attribute on a cell when `dataSort` is not provided', () => {
185
+ const $ = cheerio.load(renderComponent('table', EXAMPLE_TABLE));
186
+
187
+ expect($('.ons-table__cell').attr('data-sort-value')).toBeUndefined();
188
+ });
189
+
190
+ it('renders `data-sort-value` attribute on a cell when `dataSort` is provided', () => {
191
+ const $ = cheerio.load(
192
+ renderComponent('table', {
193
+ ...EXAMPLE_TABLE,
194
+ trs: [
195
+ {
196
+ tds: [
197
+ {
198
+ value: 'Example Cell',
199
+ dataSort: 42,
200
+ },
201
+ ],
202
+ },
203
+ ],
204
+ }),
205
+ );
206
+
207
+ expect($('.ons-table__cell').attr('data-sort-value')).toBe('42');
208
+ });
209
+
210
+ it('does not add highlight class to row when `highlight` is not provided', () => {
211
+ const $ = cheerio.load(renderComponent('table', EXAMPLE_TABLE));
212
+
213
+ expect($('.ons-table__row').hasClass('ons-table__row--highlight')).toBe(false);
214
+ });
215
+
216
+ it('adds highlight class to row when `highlight` is `true`', () => {
217
+ const $ = cheerio.load(
218
+ renderComponent('table', {
219
+ ...EXAMPLE_TABLE,
220
+ trs: [
221
+ {
222
+ tds: [{ value: 'Row 1 Cell 1' }, { value: 'Row 1 Cell 2' }, { value: 'Row 1 Cell 3' }],
223
+ highlight: true,
224
+ },
225
+ ],
226
+ }),
227
+ );
228
+
229
+ expect($('.ons-table__row').hasClass('ons-table__row--highlight')).toBe(true);
230
+ });
231
+
232
+ it('adds additionally provided class to cell', () => {
233
+ const $ = cheerio.load(
234
+ renderComponent('table', {
235
+ ...EXAMPLE_TABLE,
236
+ trs: [
237
+ {
238
+ tds: [
239
+ {
240
+ value: 'Column 1',
241
+ tdClasses: 'extra-cell-class another-extra-cell-class',
242
+ },
243
+ ],
244
+ },
245
+ ],
246
+ }),
247
+ );
248
+
249
+ expect($('.ons-table__cell').hasClass('extra-cell-class')).toBe(true);
250
+ expect($('.ons-table__cell').hasClass('another-extra-cell-class')).toBe(true);
251
+ });
252
+
253
+ it('does not add "numeric" modifier class to cell when `td.numeric` is not provided', () => {
254
+ const $ = cheerio.load(renderComponent('table', EXAMPLE_TABLE));
255
+
256
+ expect($('.ons-table__cell').hasClass('ons-table__cell--numeric')).toBe(false);
257
+ });
258
+
259
+ it('adds "numeric" modifier class to cell when `td.numeric` is `true`', () => {
260
+ const $ = cheerio.load(
261
+ renderComponent('table', {
262
+ ...EXAMPLE_TABLE,
263
+ trs: [
264
+ {
265
+ tds: [
266
+ {
267
+ value: 'Column 1',
268
+ numeric: true,
269
+ },
270
+ ],
271
+ },
272
+ ],
273
+ }),
274
+ );
275
+
276
+ expect($('.ons-table__cell').hasClass('ons-table__cell--numeric')).toBe(true);
277
+ });
278
+
279
+ describe('form', () => {
280
+ const params = {
281
+ ...EXAMPLE_TABLE,
282
+ trs: [
283
+ {
284
+ tds: [
285
+ {
286
+ form: {
287
+ action: 'https://example.com/form',
288
+ button: {
289
+ text: 'Submit form',
290
+ id: 'submit-form-button',
291
+ classes: 'custom-button-class',
292
+ url: 'https://example.com/link',
293
+ value: '42',
294
+ name: 'submit-form-button-name',
295
+ },
296
+ hiddenFormField: {
297
+ name: 'example-hidden-field-name',
298
+ value: '123',
299
+ },
300
+ },
301
+ },
302
+ ],
303
+ },
304
+ ],
305
+ };
306
+
307
+ it('does not render form section when `form` is not provided', () => {
308
+ const $ = cheerio.load(renderComponent('table', EXAMPLE_TABLE));
309
+
310
+ expect($('form').length).toBe(0);
311
+ });
312
+
313
+ it('renders form section when `form` is provided', () => {
314
+ const $ = cheerio.load(renderComponent('table', params));
315
+
316
+ expect($('form').length).toBe(1);
317
+ });
318
+
319
+ it('renders the provided `action` attribute', () => {
320
+ const $ = cheerio.load(renderComponent('table', params));
321
+
322
+ expect($('form').attr('action')).toBe('https://example.com/form');
323
+ });
324
+
325
+ it('renders a default value of "POST" for the `method` attribute', () => {
326
+ const $ = cheerio.load(renderComponent('table', params));
327
+
328
+ expect($('form').attr('method')).toBe('POST');
329
+ });
330
+
331
+ it('renders the provided `method` attribute', () => {
332
+ const $ = cheerio.load(
333
+ renderComponent('table', {
334
+ ...EXAMPLE_TABLE,
335
+ trs: [
336
+ {
337
+ tds: [
338
+ {
339
+ form: {
340
+ ...params.trs[0].tds[0].form,
341
+ method: 'PUT',
342
+ },
343
+ },
344
+ ],
345
+ },
346
+ ],
347
+ }),
348
+ );
349
+
350
+ expect($('form').attr('method')).toBe('PUT');
351
+ });
352
+
353
+ it('renders `button` component with the expected parameters', () => {
354
+ const faker = templateFaker();
355
+ const buttonSpy = faker.spy('button');
356
+
357
+ faker.renderComponent('table', params);
358
+
359
+ expect(buttonSpy.occurrences).toContainEqual({
360
+ text: 'Submit form',
361
+ id: 'submit-form-button',
362
+ classes: 'custom-button-class',
363
+ url: 'https://example.com/link',
364
+ value: new String('42'), // `| safe` filter is used in macro which makes a string
365
+ name: 'submit-form-button-name',
366
+ });
367
+ });
368
+ });
369
+ });
370
+
371
+ describe('footer row', () => {
372
+ it('does not render footer section when `tfoot` is not provided', () => {
373
+ const $ = cheerio.load(renderComponent('table', EXAMPLE_TABLE));
374
+
375
+ expect($('.ons-table__foot').length).toBe(0);
376
+ });
377
+
378
+ it('renders footer cells with expected text', () => {
379
+ const $ = cheerio.load(
380
+ renderComponent('table', {
381
+ ...EXAMPLE_TABLE,
382
+ tfoot: [{ value: 'Footer Cell 1' }, { value: 'Footer Cell 2' }, { value: 'Footer Cell 3' }],
383
+ }),
384
+ );
385
+
386
+ const footerCellValues = mapAll($('.ons-table__foot .ons-table__cell'), node => node.text().trim());
387
+ expect(footerCellValues).toEqual(['Footer Cell 1', 'Footer Cell 2', 'Footer Cell 3']);
388
+ });
389
+ });
390
+
391
+ describe('scrollable variant', () => {
392
+ const params = {
393
+ ...EXAMPLE_TABLE,
394
+ variants: ['scrollable'],
395
+ caption: 'Example table caption',
396
+ };
397
+
398
+ it('has the "scrollable" variant class', () => {
399
+ const $ = cheerio.load(renderComponent('table', params));
400
+
401
+ expect($('.ons-table').hasClass('ons-table--scrollable')).toBe(true);
402
+ });
403
+
404
+ it('renders "scrollable" container element', () => {
405
+ const $ = cheerio.load(renderComponent('table', params));
406
+
407
+ expect($('.ons-table-scrollable').length).toBe(1);
408
+ expect($('.ons-table-scrollable--on').length).toBe(1);
409
+ });
410
+
411
+ it('renders "content" container element', () => {
412
+ const $ = cheerio.load(renderComponent('table', params));
413
+
414
+ expect($('.ons-table-scrollable__content').length).toBe(1);
415
+ });
416
+
417
+ it('renders an appropriate `aria-label` attribute on the "content" container element', () => {
418
+ const $ = cheerio.load(renderComponent('table', params));
419
+
420
+ expect($('.ons-table-scrollable__content').attr('aria-label')).toBe('Example table caption. Scrollable table');
421
+ });
422
+
423
+ it('renders a custom `aria-label` attribute on the "content" container element', () => {
424
+ const $ = cheerio.load(
425
+ renderComponent('table', {
426
+ ...params,
427
+ ariaLabel: 'Special table',
428
+ }),
429
+ );
430
+
431
+ expect($('.ons-table-scrollable__content').attr('aria-label')).toBe('Example table caption. Special table');
432
+ });
433
+ });
434
+
435
+ describe('sortable variant', () => {
436
+ const params = {
437
+ ...EXAMPLE_TABLE,
438
+ variants: ['sortable'],
439
+ sortBy: 'Sort by',
440
+ ariaAsc: 'ascending',
441
+ ariaDesc: 'descending',
442
+ };
443
+
444
+ it('has the "sortable" variant class', () => {
445
+ const $ = cheerio.load(renderComponent('table', params));
446
+
447
+ expect($('.ons-table').hasClass('ons-table--sortable')).toBe(true);
448
+ });
449
+
450
+ it('has `data-aria-sort` attribute', () => {
451
+ const $ = cheerio.load(renderComponent('table', params));
452
+
453
+ expect($('.ons-table').attr('data-aria-sort')).toBe('Sort by');
454
+ });
455
+
456
+ it('adds `aria-sort` attribute when `ariaSort` is provided', () => {
457
+ const $ = cheerio.load(
458
+ renderComponent('table', {
459
+ ...params,
460
+ ths: [
461
+ {
462
+ value: 'Column 1',
463
+ ariaSort: 'ascending',
464
+ },
465
+ ],
466
+ }),
467
+ );
468
+
469
+ expect($('.ons-table__header').attr('aria-sort')).toBe('ascending');
470
+ });
471
+
472
+ it('has `data-aria-asc` attribute', () => {
473
+ const $ = cheerio.load(renderComponent('table', params));
474
+
475
+ expect($('.ons-table').attr('data-aria-asc')).toBe('ascending');
476
+ });
477
+
478
+ it('has `data-aria-desc` attribute', () => {
479
+ const $ = cheerio.load(renderComponent('table', params));
480
+
481
+ expect($('.ons-table').attr('data-aria-desc')).toBe('descending');
482
+ });
483
+
484
+ it('adds visually hidden class to column headers', () => {
485
+ const $ = cheerio.load(renderComponent('table', params));
486
+
487
+ const hasClass = mapAll($('.ons-table__header > span'), node => node.hasClass('ons-u-vh'));
488
+ expect(hasClass).toEqual([true, true, true]);
489
+ });
490
+
491
+ it('renders "sort-sprite" icon for each column header', () => {
492
+ const faker = templateFaker();
493
+ const iconsSpy = faker.spy('icons');
494
+
495
+ faker.renderComponent('table', params);
496
+
497
+ expect(iconsSpy.occurrences[0]).toEqual({
498
+ iconType: 'sort-sprite',
499
+ id: 'Column 1',
500
+ });
501
+ expect(iconsSpy.occurrences[1]).toEqual({
502
+ iconType: 'sort-sprite',
503
+ id: 'Column 2',
504
+ });
505
+ expect(iconsSpy.occurrences[2]).toEqual({
506
+ iconType: 'sort-sprite',
507
+ id: 'Column 3',
508
+ });
509
+ });
510
+ });
511
+
512
+ describe('table caption', () => {
513
+ it('does not render caption element when not provided', () => {
514
+ const $ = cheerio.load(renderComponent('table', EXAMPLE_TABLE));
515
+
516
+ expect($('.ons-table__caption').length).toBe(0);
517
+ });
518
+
519
+ it('renders caption element when provided', () => {
520
+ const $ = cheerio.load(
521
+ renderComponent('table', {
522
+ ...EXAMPLE_TABLE,
523
+ caption: 'Example table caption',
524
+ }),
525
+ );
526
+
527
+ expect(
528
+ $('.ons-table__caption')
529
+ .text()
530
+ .trim(),
531
+ ).toBe('Example table caption');
532
+ });
533
+
534
+ it('does not visually hide caption when `hideCaption` is not provided', () => {
535
+ const $ = cheerio.load(
536
+ renderComponent('table', {
537
+ ...EXAMPLE_TABLE,
538
+ caption: 'Example table caption',
539
+ }),
540
+ );
541
+
542
+ expect($('.ons-table__caption').hasClass('ons-u-vh')).toBe(false);
543
+ });
544
+
545
+ it('visually hides caption when `hideCaption` is `true`', () => {
546
+ const $ = cheerio.load(
547
+ renderComponent('table', {
548
+ ...EXAMPLE_TABLE,
549
+ caption: 'Example table caption',
550
+ hideCaption: true,
551
+ }),
552
+ );
553
+
554
+ expect($('.ons-table__caption').hasClass('ons-u-vh')).toBe(true);
555
+ });
556
+ });
557
+ });