@ons/design-system 70.0.13 → 70.0.14

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.
package/README.md CHANGED
@@ -106,13 +106,13 @@ _Note_: This command is of limited use since JavaScript and SCSS files will only
106
106
 
107
107
  It is sometimes useful to adjust the following settings when writing tests or diagnosing issues:
108
108
 
109
- - `headless` in 'jest-puppeteer.config.js' - when set to `false` will show web browser whilst running tests. Many browser windows open since jest runs tests in parallel so it is useful to also adjust the `test` script inside 'package.json' such that it targets a specific test file. `await page.waitForTimeout(100000)` can be temporarily added to a test to allow yourself time to inspect the browser that appears.
109
+ - `headless` in 'jest-puppeteer.config.js' - when set to `false` will show web browser whilst running tests. Many browser windows open since jest runs tests in parallel so it is useful to also adjust the `test` script inside 'package.json' such that it targets a specific test file. `await new Promise(r => setTimeout(r, 100000));` can be temporarily added to a test to allow yourself time to inspect the browser that appears.
110
110
 
111
111
  - `testTimeout` in 'jest.config.js' - set to a high value such as `1000000` to prevent tests from timing out when doing the above.
112
112
 
113
113
  ## Testing - Visual regression tests
114
114
 
115
- This project uses [Backstop JS](https://github.com/garris/BackstopJS) for visual regression testing. The tests run in Chrome headless using pupeteer inside docker and run in three viewports; 1920 (desktop), 768 (tablet) and 375 (mobile). Reference images are stored in Git LFS and any approved changes will automatically be stored in Git LFS when pushed to the repository.
115
+ This project uses [Backstop JS](https://github.com/garris/BackstopJS) for visual regression testing. The tests run in Chrome headless using Pupeteer inside docker and run in three viewports; 1920 (desktop), 768 (tablet) and 375 (mobile). Reference images are stored in Git LFS and any approved changes will automatically be stored in Git LFS when pushed to the repository.
116
116
 
117
117
  The visual tests will run automatically on pull requests and the result will be available in the Github Action logs. If the tests fail, the process for viewing the failures and approving changes will need to be handled locally using the following workflow and commands.
118
118
 
@@ -5,150 +5,184 @@ import * as cheerio from 'cheerio';
5
5
  import axe from '../../tests/helpers/axe';
6
6
  import { renderComponent } from '../../tests/helpers/rendering';
7
7
 
8
- describe('macro: access-code', () => {
9
- it('passes jest-axe checks', async () => {
10
- const $ = cheerio.load(
11
- renderComponent('access-code', {
12
- id: 'example-access-code',
13
- label: {
14
- text: 'Enter your 16-character access code',
15
- description: 'Keep this code safe. You will need to enter it every time you access your study',
16
- },
17
- }),
18
- );
19
-
20
- const results = await axe($.html());
21
- expect(results).toHaveNoViolations();
8
+ describe('FOR: access-code', () => {
9
+ describe('GIVEN: Params: required', () => {
10
+ describe('WHEN: all required params are provided', () => {
11
+ const $ = cheerio.load(
12
+ renderComponent('access-code', {
13
+ id: 'example-access-code',
14
+ label: {
15
+ text: 'Enter your 16-character access code',
16
+ description: 'Keep this code safe. You will need to enter it every time you access your study',
17
+ },
18
+ }),
19
+ );
20
+ test('THEN: jest-axe tests pass', async () => {
21
+ const results = await axe($.html());
22
+ expect(results).toHaveNoViolations();
23
+ });
24
+ test('THEN: autocomplete is disabled on text input', () => {
25
+ expect($('input').attr('autocomplete')).toBe('off');
26
+ });
27
+ test('THEN: text input has automatic capitalisation', () => {
28
+ expect($('input').attr('autocapitalize')).toBe('characters');
29
+ });
30
+ });
22
31
  });
23
-
24
- it('has the provided `id` attribute', () => {
25
- const $ = cheerio.load(
26
- renderComponent('access-code', {
27
- id: 'example-id',
28
- }),
29
- );
30
-
31
- expect($('#example-id').length).toBe(1);
32
+ describe('GIVEN: Params: id', () => {
33
+ describe('WHEN: id is provided', () => {
34
+ const $ = cheerio.load(
35
+ renderComponent('access-code', {
36
+ id: 'example-id',
37
+ }),
38
+ );
39
+ test('THEN: renders with id provided', () => {
40
+ expect($('#example-id').length).toBe(1);
41
+ });
42
+ });
32
43
  });
33
-
34
- it('has the provided `name` attribute', () => {
35
- const $ = cheerio.load(
36
- renderComponent('access-code', {
37
- name: 'special-name',
38
- }),
39
- );
40
-
41
- expect($('input').attr('name')).toBe('special-name');
44
+ describe('GIVEN: Params: classes', () => {
45
+ describe('WHEN: additional style classes are provided', () => {
46
+ const $ = cheerio.load(
47
+ renderComponent('access-code', {
48
+ classes: 'extra-class another-extra-class',
49
+ }),
50
+ );
51
+ test('THEN: renders with additional classes provided', () => {
52
+ expect($('.ons-panel--info').hasClass('extra-class')).toBe(true);
53
+ expect($('.ons-panel--info').hasClass('another-extra-class')).toBe(true);
54
+ });
55
+ });
42
56
  });
43
-
44
- it('has a default `type` of "text"', () => {
45
- const $ = cheerio.load(renderComponent('access-code'));
46
-
47
- expect($('input').attr('type')).toBe('text');
57
+ describe('GIVEN: Params: label', () => {
58
+ describe('WHEN: label text and description params are provided', () => {
59
+ const $ = cheerio.load(
60
+ renderComponent('access-code', {
61
+ label: {
62
+ text: 'Enter your 16-character access code',
63
+ description: 'Keep this code safe. You will need to enter it every time you access your study',
64
+ },
65
+ }),
66
+ );
67
+ test('THEN: renders with provided text and description', () => {
68
+ expect($('.ons-label--with-description').text()).toBe('Enter your 16-character access code');
69
+ expect($('.ons-input--with-description').text()).toBe(
70
+ 'Keep this code safe. You will need to enter it every time you access your study',
71
+ );
72
+ });
73
+ });
48
74
  });
49
-
50
- it('has the provided `type` attribute', () => {
51
- const $ = cheerio.load(
52
- renderComponent('access-code', {
53
- type: 'number',
54
- }),
55
- );
56
-
57
- expect($('input').attr('inputmode')).toBe('numeric');
75
+ describe('GIVEN: Params: type', () => {
76
+ describe('WHEN: param is at default state', () => {
77
+ const $ = cheerio.load(renderComponent('access-code'));
78
+ test('THEN: renders with default type of "text"', () => {
79
+ expect($('input').attr('type')).toBe('text');
80
+ });
81
+ });
82
+ describe('WHEN: type param is provided', () => {
83
+ const $ = cheerio.load(
84
+ renderComponent('access-code', {
85
+ type: 'number',
86
+ }),
87
+ );
88
+ test('THEN: renders with provided type', () => {
89
+ expect($('input').attr('inputmode')).toBe('numeric');
90
+ });
91
+ });
58
92
  });
59
-
60
- it('has additionally provided style classes', () => {
61
- const $ = cheerio.load(
62
- renderComponent('access-code', {
63
- classes: 'extra-class another-extra-class',
64
- }),
65
- );
66
-
67
- expect($('.ons-panel--info').hasClass('extra-class')).toBe(true);
68
- expect($('.ons-panel--info').hasClass('another-extra-class')).toBe(true);
93
+ describe('GIVEN: Params: name', () => {
94
+ describe('WHEN: name param is provided', () => {
95
+ const $ = cheerio.load(
96
+ renderComponent('access-code', {
97
+ name: 'special-name',
98
+ }),
99
+ );
100
+ test('THEN: renders with provided name', () => {
101
+ expect($('input').attr('name')).toBe('special-name');
102
+ });
103
+ });
69
104
  });
70
-
71
- it('has provided label text and description', () => {
72
- const $ = cheerio.load(
73
- renderComponent('access-code', {
74
- label: {
75
- text: 'Enter your 16-character access code',
76
- description: 'Keep this code safe. You will need to enter it every time you access your study',
77
- },
78
- }),
79
- );
80
-
81
- expect($('.ons-label--with-description').text()).toBe('Enter your 16-character access code');
82
- expect($('.ons-input--with-description').text()).toBe(
83
- 'Keep this code safe. You will need to enter it every time you access your study',
84
- );
105
+ describe('GIVEN: Params: maxlength & groupSize', () => {
106
+ describe('WHEN: params are at default state', () => {
107
+ const $ = cheerio.load(renderComponent('access-code'));
108
+ test('THEN: renders input with total maxlength of 19', () => {
109
+ expect($('input').attr('maxlength')).toBe('19');
110
+ });
111
+ test('THEN: renders input with groupSize of 4', () => {
112
+ expect($('input').attr('data-group-size')).toBe('4');
113
+ });
114
+ });
115
+ describe('WHEN: maxlength param is provided', () => {
116
+ const $ = cheerio.load(
117
+ renderComponent('access-code', {
118
+ maxlength: 8,
119
+ }),
120
+ );
121
+ test('THEN: renders input with provided maxlength', () => {
122
+ expect($('input').attr('maxlength')).toBe('9');
123
+ });
124
+ });
125
+ describe('WHEN: groupSize param is provided', () => {
126
+ const $ = cheerio.load(
127
+ renderComponent('access-code', {
128
+ groupSize: 2,
129
+ }),
130
+ );
131
+ test('THEN: renders input with provided groupSize', () => {
132
+ expect($('input').attr('data-group-size')).toBe('2');
133
+ });
134
+ });
135
+ describe('WHEN: maxlength and groupSize params are provided', () => {
136
+ const $ = cheerio.load(
137
+ renderComponent('access-code', {
138
+ maxlength: 6,
139
+ groupSize: 3,
140
+ }),
141
+ );
142
+ test('THEN: renders input with provided maxlength accounting for provided groupSize', () => {
143
+ expect($('input').attr('maxlength')).toBe('7');
144
+ });
145
+ });
85
146
  });
86
-
87
- it('has provided maximum length attribute including spaces required for groupSize', () => {
88
- const $ = cheerio.load(
89
- renderComponent('access-code', {
90
- maxlength: 6,
91
- groupSize: 3,
92
- }),
93
- );
94
-
95
- expect($('input').attr('maxlength')).toBe('7');
147
+ describe('GIVEN: Params: securityMessage', () => {
148
+ describe('WHEN: securityMessage param is provided', () => {
149
+ const $ = cheerio.load(
150
+ renderComponent('access-code', {
151
+ securityMessage: 'Example security message.',
152
+ }),
153
+ );
154
+ test('THEN: renders with provided security message', () => {
155
+ expect($('.ons-panel__body').text().trim()).toBe('Example security message.');
156
+ });
157
+ });
96
158
  });
97
-
98
- it('has provided group size attribute', () => {
99
- const $ = cheerio.load(
100
- renderComponent('access-code', {
101
- groupSize: 2,
102
- }),
103
- );
104
-
105
- expect($('input').attr('data-group-size')).toBe('2');
106
- });
107
-
108
- it('has autocomplete disabled on its text input', () => {
109
- const $ = cheerio.load(renderComponent('access-code'));
110
-
111
- expect($('input').attr('autocomplete')).toBe('off');
159
+ describe('GIVEN: Params: postTextboxLinkText & postTextBoxLinkUrl', () => {
160
+ describe('WHEN: postTextboxLinkText & postTextBoxLinkUrl params are provided', () => {
161
+ const $ = cheerio.load(
162
+ renderComponent('access-code', {
163
+ postTextboxLinkText: 'Example link text',
164
+ postTextboxLinkUrl: '#3',
165
+ }),
166
+ );
167
+ test('THEN: renders link with provided link and text', () => {
168
+ expect($('a[href="#3"]').text().trim()).toBe('Example link text');
169
+ });
170
+ });
112
171
  });
113
-
114
- it('has automatic capitalization on its text input', () => {
115
- const $ = cheerio.load(renderComponent('access-code'));
116
-
117
- expect($('input').attr('autocapitalize')).toBe('characters');
118
- });
119
-
120
- it('has provided security message text', () => {
121
- const $ = cheerio.load(
122
- renderComponent('access-code', {
123
- securityMessage: 'Example security message.',
124
- }),
125
- );
126
-
127
- expect($('.ons-panel__body').text().trim()).toBe('Example security message.');
128
- });
129
-
130
- it('has provided `postTextBoxLinkText` and `postTextBoxLinkUrl`', () => {
131
- const $ = cheerio.load(
132
- renderComponent('access-code', {
133
- postTextboxLinkText: 'Example link text',
134
- postTextboxLinkUrl: '#3',
135
- }),
136
- );
137
-
138
- expect($('a[href="#3"]').text().trim()).toBe('Example link text');
139
- });
140
-
141
- it('has provided `error` output', () => {
142
- const $ = cheerio.load(
143
- renderComponent('access-code', {
144
- error: {
145
- id: 'access-code-error',
146
- text: 'Enter an access code',
147
- },
148
- }),
149
- );
150
-
151
- expect($('#access-code-error').length).toBe(1);
152
- expect($('.ons-panel__error > strong').text()).toBe('Enter an access code');
172
+ describe('GIVEN: Params: error', () => {
173
+ describe('WHEN: error id & text params are provided', () => {
174
+ const $ = cheerio.load(
175
+ renderComponent('access-code', {
176
+ error: {
177
+ id: 'access-code-error',
178
+ text: 'Enter an access code',
179
+ },
180
+ }),
181
+ );
182
+ test('THEN: renders error with provided id and text', () => {
183
+ expect($('#access-code-error').length).toBe(1);
184
+ expect($('.ons-panel__error > strong').text()).toBe('Enter an access code');
185
+ });
186
+ });
153
187
  });
154
188
  });
@@ -62,6 +62,8 @@ const EXAMPLE_ADDRESS_INPUT_WITH_API = {
62
62
  externalInitialiser: true,
63
63
  };
64
64
 
65
+ const { setTimeout } = require('node:timers/promises');
66
+
65
67
  describe('script: address-input', () => {
66
68
  const apiFaker = new PuppeteerEndpointFaker(EXAMPLE_ADDRESS_INPUT_WITH_API.APIDomain);
67
69
 
@@ -184,7 +186,7 @@ describe('script: address-input', () => {
184
186
  describe('When the component initializes', () => {
185
187
  it('checks api status by trying a request', async () => {
186
188
  await setTestPage('/test', renderComponent('address-input', EXAMPLE_ADDRESS_INPUT_WITH_API));
187
- await page.waitForTimeout(50);
189
+ await setTimeout(50);
188
190
 
189
191
  expect(apiFaker.getRequestCount('/addresses/eq?input=cf142&limit=10')).toBe(1);
190
192
  });
@@ -192,7 +194,7 @@ describe('script: address-input', () => {
192
194
  describe('when api status is okay', () => {
193
195
  beforeEach(async () => {
194
196
  await setTestPage('/test', renderComponent('address-input', EXAMPLE_ADDRESS_INPUT_WITH_API));
195
- await page.waitForTimeout(50);
197
+ await setTimeout(50);
196
198
  });
197
199
 
198
200
  it('does not switch to manual input', async () => {
@@ -216,7 +218,7 @@ describe('script: address-input', () => {
216
218
  });
217
219
 
218
220
  await setTestPage('/test', renderComponent('address-input', EXAMPLE_ADDRESS_INPUT_WITH_API));
219
- await page.waitForTimeout(50);
221
+ await setTimeout(50);
220
222
  });
221
223
 
222
224
  it('switches to manual input', async () => {
@@ -271,6 +273,7 @@ describe('script: address-input', () => {
271
273
  });
272
274
 
273
275
  it('has expected suggestion entries', async () => {
276
+ await setTimeout(100);
274
277
  const suggestions = await page.$$eval('.ons-autosuggest__option', (nodes) => nodes.map((node) => node.textContent.trim()));
275
278
  expect(suggestions).toEqual(['196 College Road, Birmingham, B44 8HF', '196 College Road, Whitchurch, Cardiff, CF14 2NZ']);
276
279
  });
@@ -305,7 +308,7 @@ describe('script: address-input', () => {
305
308
 
306
309
  await page.$eval('.ons-js-autosuggest-input', (node) => (node.value = 'Penlline Road, Whitchurch, Cardiff, CF14 2N'));
307
310
  await page.type('.ons-js-autosuggest-input', 'Z');
308
- await page.waitForTimeout(100);
311
+ await setTimeout(100);
309
312
  });
310
313
 
311
314
  it('provides expected parameters to the address API', async () => {
@@ -328,7 +331,7 @@ describe('script: address-input', () => {
328
331
  beforeEach(async () => {
329
332
  await page.keyboard.press('ArrowDown');
330
333
  await page.keyboard.press('Enter');
331
- await page.waitForTimeout(100);
334
+ await setTimeout(100);
332
335
  });
333
336
 
334
337
  it('makes expected request when a suggestion is selected', async () => {
@@ -352,7 +355,7 @@ describe('script: address-input', () => {
352
355
 
353
356
  await page.$eval('.ons-js-autosuggest-input', (node) => (node.value = 'CF14 '));
354
357
  await page.type('.ons-js-autosuggest-input', '2');
355
- await page.waitForTimeout(200);
358
+ await setTimeout(200);
356
359
  });
357
360
 
358
361
  it('provides expected parameters to the address API', async () => {
@@ -371,7 +374,7 @@ describe('script: address-input', () => {
371
374
  beforeEach(async () => {
372
375
  await page.keyboard.press('ArrowDown');
373
376
  await page.keyboard.press('Enter');
374
- await page.waitForTimeout(200);
377
+ await setTimeout(200);
375
378
  });
376
379
 
377
380
  it('makes expected request', async () => {
@@ -393,7 +396,7 @@ describe('script: address-input', () => {
393
396
  beforeEach(async () => {
394
397
  await page.keyboard.press('ArrowDown');
395
398
  await page.keyboard.press('Enter');
396
- await page.waitForTimeout(200);
399
+ await setTimeout(200);
397
400
  });
398
401
 
399
402
  it('populates manual input fields with address from selection', async () => {
@@ -437,7 +440,7 @@ describe('script: address-input', () => {
437
440
  await page.type('.ons-js-autosuggest-input', '2', { delay: 20 });
438
441
  await page.keyboard.press('ArrowDown');
439
442
  await page.keyboard.press('Enter');
440
- await page.waitForTimeout(100);
443
+ await setTimeout(100);
441
444
 
442
445
  const isManualElementHidden = await page.$eval('.ons-js-address-input__manual', (node) =>
443
446
  node.classList.contains('ons-u-db-no-js_enabled'),
@@ -480,7 +483,7 @@ describe('script: address-input', () => {
480
483
  await page.type('.ons-js-autosuggest-input', 'T', { delay: 20 });
481
484
  await page.keyboard.press('ArrowDown');
482
485
  await page.keyboard.press('Enter');
483
- await page.waitForTimeout(100);
486
+ await setTimeout(100);
484
487
 
485
488
  const urpnValueBefore = await page.$eval('.ons-js-hidden-uprn', (node) => node.value);
486
489
  expect(urpnValueBefore).toBe('100070332099');
@@ -619,7 +622,7 @@ describe('script: address-input', () => {
619
622
  await page.keyboard.press('ArrowDown');
620
623
  await page.keyboard.press('Enter');
621
624
 
622
- await page.waitForTimeout(50);
625
+ await setTimeout(50);
623
626
  });
624
627
 
625
628
  it('then the retrieveAddress function will be called', async () => {
@@ -730,6 +733,8 @@ describe('script: address-input', () => {
730
733
  await page.$eval('.ons-js-autosuggest-input', (node) => (node.value = '196 coll'));
731
734
  await page.type('.ons-js-autosuggest-input', 'e');
732
735
 
736
+ await setTimeout(50);
737
+
733
738
  expect(apiFaker.getRequestCount(searchEndpoint)).toBe(1);
734
739
  });
735
740
 
@@ -739,7 +744,7 @@ describe('script: address-input', () => {
739
744
  await page.keyboard.press('ArrowDown');
740
745
  await page.keyboard.press('Enter');
741
746
 
742
- await page.waitForTimeout(50);
747
+ await setTimeout(50);
743
748
 
744
749
  expect(apiFaker.getRequestCount(uprnEndpoint)).toBe(1);
745
750
  });
@@ -53,6 +53,8 @@ const EXAMPLE_AUTOSUGGEST_WITH_LANGUAGE = {
53
53
  language: 'en-gb',
54
54
  };
55
55
 
56
+ const { setTimeout } = require('node:timers/promises');
57
+
56
58
  describe('script: autosuggest', () => {
57
59
  const apiFaker = new PuppeteerEndpointFaker('/test/fake/api');
58
60
 
@@ -298,11 +300,11 @@ describe('script: autosuggest', () => {
298
300
  const suggestionCountSample1 = await page.$$eval('.ons-autosuggest__option', (nodes) => nodes.length);
299
301
  expect(suggestionCountSample1).toBe(2);
300
302
 
301
- await page.waitForTimeout(200);
303
+ await setTimeout(200);
302
304
  const suggestionCountSample2 = await page.$$eval('.ons-autosuggest__option', (nodes) => nodes.length);
303
305
  expect(suggestionCountSample2).toBe(2);
304
306
 
305
- await page.waitForTimeout(320);
307
+ await setTimeout(320);
306
308
  const suggestionCountSample3 = await page.$$eval('.ons-autosuggest__option', (nodes) => nodes.length);
307
309
  expect(suggestionCountSample3).toBe(0);
308
310
  });
@@ -312,7 +314,7 @@ describe('script: autosuggest', () => {
312
314
 
313
315
  await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
314
316
  await page.keyboard.press('Tab');
315
- await page.waitForTimeout(320);
317
+ await setTimeout(320);
316
318
 
317
319
  const listboxInnerHTML = await page.$eval('.ons-js-autosuggest-listbox', (node) => node.innerHTML);
318
320
  expect(listboxInnerHTML).toBe('');
@@ -323,7 +325,7 @@ describe('script: autosuggest', () => {
323
325
 
324
326
  await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
325
327
  await page.keyboard.press('Tab');
326
- await page.waitForTimeout(320);
328
+ await setTimeout(320);
327
329
 
328
330
  const hasClass = await page.$eval('.ons-autosuggest', (node) => node.classList.contains('ons-autosuggest--has-results'));
329
331
  expect(hasClass).toBe(false);
@@ -334,7 +336,7 @@ describe('script: autosuggest', () => {
334
336
 
335
337
  await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
336
338
  await page.keyboard.press('Tab');
337
- await page.waitForTimeout(320);
339
+ await setTimeout(320);
338
340
 
339
341
  const attributes = await getNodeAttributes(page, '.ons-js-autosuggest-input');
340
342
  expect(attributes['aria-activedescendant']).toBeUndefined();
@@ -5,56 +5,50 @@ import * as cheerio from 'cheerio';
5
5
  import axe from '../../tests/helpers/axe';
6
6
  import { renderComponent } from '../../tests/helpers/rendering';
7
7
 
8
- describe('macro: back-to-top', () => {
9
- it('passes jest-axe checks', async () => {
10
- const $ = cheerio.load(
11
- renderComponent('back-to-top', {
12
- description: 'Back to top',
13
- anchor: 'example-target',
14
- }),
15
- );
16
-
17
- const results = await axe($.html());
18
- expect(results).toHaveNoViolations();
19
- });
20
-
21
- it('has back to top link with the provided description', async () => {
22
- const $ = cheerio.load(
23
- renderComponent('back-to-top', {
24
- description: 'Scroll to top',
25
- anchor: 'example-target',
26
- }),
27
- );
28
- expect($('.ons-back-to-top .ons-back-to-top__link').text().trim()).toBe('Scroll to top');
29
- });
30
-
31
- it('has back to top link with the provided anchor', async () => {
32
- const $ = cheerio.load(
33
- renderComponent('back-to-top', {
34
- description: 'Back to top',
35
- anchor: 'example-target',
36
- }),
37
- );
38
-
39
- expect($('.ons-back-to-top .ons-back-to-top__link').attr('href')).toBe('#example-target');
8
+ describe('FOR: Back-to-top', () => {
9
+ describe('GIVEN: Params: default', () => {
10
+ describe('WHEN: params are at default', () => {
11
+ const $ = cheerio.load(renderComponent('back-to-top'));
12
+ test('THEN: jest-axe tests pass', async () => {
13
+ const results = await axe($.html());
14
+ expect(results).toHaveNoViolations();
15
+ });
16
+ });
40
17
  });
41
-
42
- it('has back to top link with the default description if no description provided', async () => {
43
- const $ = cheerio.load(
44
- renderComponent('back-to-top', {
45
- anchor: 'example-target',
46
- }),
47
- );
48
-
49
- expect($('.ons-back-to-top .ons-back-to-top__link').text().trim()).toBe('Back to top');
18
+ describe('GIVEN: Params: description', () => {
19
+ describe('WHEN: description text is not provided', () => {
20
+ const $ = cheerio.load(renderComponent('back-to-top'));
21
+ test('THEN: renders with default description text', () => {
22
+ expect($('.ons-back-to-top .ons-back-to-top__link').text().trim()).toBe('Back to top');
23
+ });
24
+ });
25
+ describe('WHEN: description text is provided', () => {
26
+ const $ = cheerio.load(
27
+ renderComponent('back-to-top', {
28
+ description: 'Scroll to top',
29
+ }),
30
+ );
31
+ test('THEN: renders button with provided text', () => {
32
+ expect($('.ons-back-to-top .ons-back-to-top__link').text().trim()).toBe('Scroll to top');
33
+ });
34
+ });
50
35
  });
51
-
52
- it('has back to top link with the default anchor if no anchor provided', async () => {
53
- const renderedComponent = renderComponent('back-to-top', {
54
- description: 'Back to top',
36
+ describe('GIVEN: Params: anchor', () => {
37
+ describe('WHEN: anchor is not provided', () => {
38
+ const $ = cheerio.load(renderComponent('back-to-top'));
39
+ test('THEN: renders with default anchor id', () => {
40
+ expect($('.ons-back-to-top .ons-back-to-top__link').attr('href')).toBe('#top');
41
+ });
42
+ });
43
+ describe('WHEN: anchor is provided', () => {
44
+ const $ = cheerio.load(
45
+ renderComponent('back-to-top', {
46
+ anchor: 'example-target',
47
+ }),
48
+ );
49
+ test('THEN: renders button with provided anchor id', () => {
50
+ expect($('.ons-back-to-top .ons-back-to-top__link').attr('href')).toBe('#example-target');
51
+ });
55
52
  });
56
- const $ = cheerio.load(renderedComponent);
57
-
58
- expect($('.ons-back-to-top .ons-back-to-top__link').attr('href')).toBe('#top');
59
53
  });
60
54
  });
@@ -1,5 +1,7 @@
1
1
  import { renderComponent, setTestPage } from '../../tests/helpers/rendering';
2
2
 
3
+ const { setTimeout } = require('node:timers/promises');
4
+
3
5
  describe('script: back-to-top', () => {
4
6
  beforeEach(async () => {
5
7
  await setTestPage(
@@ -98,7 +100,7 @@ describe('script: back-to-top', () => {
98
100
  await page.evaluate(() => {
99
101
  window.scrollTo(0, window.innerHeight * 2);
100
102
  });
101
- await new Promise((r) => setTimeout(r, 250));
103
+ await setTimeout(250);
102
104
  const previousWidth = await page.evaluate(() => {
103
105
  const node = document.querySelector('.ons-back-to-top > .ons-back-to-top__link').children[0];
104
106
  return window.getComputedStyle(node).marginLeft;
@@ -107,7 +109,7 @@ describe('script: back-to-top', () => {
107
109
  await page.evaluate(() => {
108
110
  window.scrollTo(0, window.innerHeight * 2);
109
111
  });
110
- await new Promise((r) => setTimeout(r, 250));
112
+ await setTimeout(250);
111
113
  const newWidth = await page.evaluate(() => {
112
114
  const node = document.querySelector('.ons-back-to-top > .ons-back-to-top__link').children[0];
113
115
  return window.getComputedStyle(node).marginLeft;