@justeattakeaway/pie-modal 0.17.0 → 0.18.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.
- package/dist/{types/packages/components/pie-modal/src/index.d.ts → index.d.ts} +241 -126
- package/dist/index.js +4 -0
- package/dist/react.d.ts +249 -0
- package/dist/react.js +213 -206
- package/package.json +7 -2
- package/src/index.ts +1 -1
- package/.eslintignore +0 -5
- package/.turbo/turbo-build.log +0 -14
- package/CHANGELOG.md +0 -209
- package/dist/types/index.d.ts +0 -1
- package/dist/types/packages/components/pie-modal/src/defs.d.ts +0 -110
- package/dist/types/packages/components/pie-modal/src/defs.d.ts.map +0 -1
- package/dist/types/packages/components/pie-modal/src/index.d.ts.map +0 -1
- package/dist/types/packages/components/pie-modal/src/react.d.ts +0 -8
- package/dist/types/packages/components/pie-modal/src/react.d.ts.map +0 -1
- package/dist/types/react.d.ts +0 -1
- package/playwright/index.html +0 -56
- package/playwright/index.ts +0 -1
- package/playwright-lit-visual.config.ts +0 -4
- package/playwright-lit.config.ts +0 -4
- package/test/component/pie-modal.spec.ts +0 -816
- package/test/helpers/index.ts +0 -31
- package/test/visual/pie-modal.spec.ts +0 -494
- package/tsconfig.json +0 -8
- package/vite.config.js +0 -3
|
@@ -1,816 +0,0 @@
|
|
|
1
|
-
import { test, expect } from '@sand4rt/experimental-ct-web';
|
|
2
|
-
import { type Page } from '@playwright/test';
|
|
3
|
-
import { PieButton } from '@justeattakeaway/pie-button';
|
|
4
|
-
import { PieIconButton } from '@justeattakeaway/pie-icon-button';
|
|
5
|
-
import {
|
|
6
|
-
WebComponentTestWrapper,
|
|
7
|
-
} from '@justeattakeaway/pie-webc-testing/src/helpers/components/web-component-test-wrapper/WebComponentTestWrapper.ts';
|
|
8
|
-
import { createScrollablePageHTML, renderTestPieModal } from '../helpers/index.ts';
|
|
9
|
-
|
|
10
|
-
import { PieModal } from '@/index';
|
|
11
|
-
import {
|
|
12
|
-
ON_MODAL_BACK_EVENT,
|
|
13
|
-
ON_MODAL_CLOSE_EVENT,
|
|
14
|
-
headingLevels,
|
|
15
|
-
} from '@/defs';
|
|
16
|
-
|
|
17
|
-
const componentSelector = '[data-test-id="pie-modal"]';
|
|
18
|
-
const backButtonSelector = '[data-test-id="modal-back-button"]';
|
|
19
|
-
const closeButtonSelector = '[data-test-id="modal-close-button"]';
|
|
20
|
-
|
|
21
|
-
// Mount then unmount any components that are used inside of pie-modal so that
|
|
22
|
-
// they have been registered with the browser before the tests run.
|
|
23
|
-
// There is likely a nicer way to do this but this will temporarily
|
|
24
|
-
// unblock tests.
|
|
25
|
-
test.beforeEach(async ({ mount }) => {
|
|
26
|
-
await (await mount(PieButton)).unmount();
|
|
27
|
-
await (await mount(PieIconButton)).unmount();
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
test.describe('modal', () => {
|
|
31
|
-
test('should be visible when opened', async ({ mount, page }) => {
|
|
32
|
-
// Arrange
|
|
33
|
-
await mount(PieModal, {
|
|
34
|
-
props: {
|
|
35
|
-
heading: 'Modal heading',
|
|
36
|
-
isOpen: true,
|
|
37
|
-
},
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
// Act
|
|
41
|
-
const modal = page.locator(componentSelector);
|
|
42
|
-
|
|
43
|
-
// Assert
|
|
44
|
-
expect(modal).toBeVisible();
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
headingLevels.forEach((headingLevel) => test(`should render the correct heading tag based on the value of headingLevel: ${headingLevel}`, async ({ mount }) => {
|
|
49
|
-
// Arrange
|
|
50
|
-
const props = {
|
|
51
|
-
heading: 'Modal Header',
|
|
52
|
-
headingLevel,
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
// Act
|
|
56
|
-
const component = await mount(PieModal, { props });
|
|
57
|
-
|
|
58
|
-
// Assert
|
|
59
|
-
await expect(component.locator(`${props.headingLevel}.c-modal-heading`)).toContainText(props.heading);
|
|
60
|
-
}));
|
|
61
|
-
|
|
62
|
-
['span', 'section'].forEach((headingLevel) => test(`should render the fallback heading level 'h2' if invalid headingLevel: ${headingLevel} is passed`, async ({ mount }) => {
|
|
63
|
-
// Arrange
|
|
64
|
-
const props = {
|
|
65
|
-
heading: 'Modal Header',
|
|
66
|
-
headingLevel,
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
// Act
|
|
70
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
71
|
-
// @ts-ignore // Added this as we want to deliberately test with invalid headingLevel (which is an invalid type based on ModalProps)
|
|
72
|
-
const component = await mount(PieModal, { props });
|
|
73
|
-
|
|
74
|
-
// Assert
|
|
75
|
-
await expect(component.locator('h2.c-modal-heading')).toContainText(props.heading);
|
|
76
|
-
}));
|
|
77
|
-
|
|
78
|
-
test.describe('When modal is closed', () => {
|
|
79
|
-
test.describe('by clicking the close button', () => {
|
|
80
|
-
test('should dispatch event `pie-modal-close`', async ({ mount, page }) => {
|
|
81
|
-
// Arrange
|
|
82
|
-
const events : Array<Event> = [];
|
|
83
|
-
|
|
84
|
-
await mount(
|
|
85
|
-
PieModal,
|
|
86
|
-
{
|
|
87
|
-
props: {
|
|
88
|
-
isOpen: true,
|
|
89
|
-
isDismissible: true,
|
|
90
|
-
},
|
|
91
|
-
on: {
|
|
92
|
-
[ON_MODAL_CLOSE_EVENT]: (event: Event) => events.push(event),
|
|
93
|
-
},
|
|
94
|
-
},
|
|
95
|
-
);
|
|
96
|
-
|
|
97
|
-
await page.click(closeButtonSelector);
|
|
98
|
-
|
|
99
|
-
// Assert
|
|
100
|
-
expect(events).toHaveLength(1);
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
test('should close the modal', async ({ mount, page }) => {
|
|
104
|
-
// Arrange
|
|
105
|
-
await mount(PieModal, {
|
|
106
|
-
props: {
|
|
107
|
-
isOpen: true,
|
|
108
|
-
isDismissible: true,
|
|
109
|
-
},
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
const modal = page.locator(componentSelector);
|
|
113
|
-
|
|
114
|
-
// Act
|
|
115
|
-
await page.click(closeButtonSelector);
|
|
116
|
-
|
|
117
|
-
// Assert
|
|
118
|
-
expect(modal).not.toBeVisible();
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
test.describe('by clicking the back button', () => {
|
|
123
|
-
test('should dispatch event `pie-modal-back`', async ({ mount, page }) => {
|
|
124
|
-
// Arrange
|
|
125
|
-
const events: Event[] = [];
|
|
126
|
-
await mount(
|
|
127
|
-
PieModal,
|
|
128
|
-
{
|
|
129
|
-
props: {
|
|
130
|
-
isOpen: true,
|
|
131
|
-
hasBackButton: true,
|
|
132
|
-
},
|
|
133
|
-
on: {
|
|
134
|
-
[ON_MODAL_BACK_EVENT]: (event: Event) => events.push(event),
|
|
135
|
-
},
|
|
136
|
-
},
|
|
137
|
-
);
|
|
138
|
-
|
|
139
|
-
await page.locator(backButtonSelector).click();
|
|
140
|
-
|
|
141
|
-
// Assert
|
|
142
|
-
expect(events).toHaveLength(1);
|
|
143
|
-
});
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
test.describe('by clicking the backdrop', () => {
|
|
147
|
-
test('should dispatch event `pie-modal-close`', async ({ mount, page }) => {
|
|
148
|
-
// Arrange
|
|
149
|
-
const events : Array<Event> = [];
|
|
150
|
-
|
|
151
|
-
await mount(PieModal, {
|
|
152
|
-
props: {
|
|
153
|
-
isOpen: true,
|
|
154
|
-
isDismissible: true,
|
|
155
|
-
},
|
|
156
|
-
on: {
|
|
157
|
-
[ON_MODAL_CLOSE_EVENT]: (event: Event) => events.push(event),
|
|
158
|
-
},
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
// Act
|
|
162
|
-
await page.click(componentSelector, { position: { x: -10, y: -10 } }); // Click outside dialog
|
|
163
|
-
|
|
164
|
-
// Assert
|
|
165
|
-
expect(events).toHaveLength(1); // TODO - Event object is null for this test
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
test('should close the modal', async ({ mount, page }) => {
|
|
169
|
-
// Arrange
|
|
170
|
-
await mount(PieModal, {
|
|
171
|
-
props: {
|
|
172
|
-
isOpen: true,
|
|
173
|
-
isDismissible: true,
|
|
174
|
-
},
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
const modal = await page.locator(componentSelector);
|
|
178
|
-
|
|
179
|
-
// Act
|
|
180
|
-
await modal.click({ position: { x: -10, y: -10 } }); // Click outside dialog
|
|
181
|
-
|
|
182
|
-
// Assert
|
|
183
|
-
expect(modal).not.toBeVisible();
|
|
184
|
-
});
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
test.describe('`returnFocusAfterCloseSelector` prop', () => {
|
|
188
|
-
test.describe('when given', () => {
|
|
189
|
-
test('should return focus to specified element', async ({ mount, page }) => {
|
|
190
|
-
// Arrange
|
|
191
|
-
const component = renderTestPieModal({
|
|
192
|
-
returnFocusAfterCloseSelector: '#focus-me',
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
await mount(WebComponentTestWrapper, {
|
|
196
|
-
props: {
|
|
197
|
-
pageMode: true,
|
|
198
|
-
},
|
|
199
|
-
slots: {
|
|
200
|
-
component,
|
|
201
|
-
pageMarkup: `<div>
|
|
202
|
-
<button id="default"></button>
|
|
203
|
-
<button id="focus-me"></button>
|
|
204
|
-
<button id="not-me"></button>
|
|
205
|
-
</div>`,
|
|
206
|
-
},
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
// Act
|
|
210
|
-
await page.click(closeButtonSelector);
|
|
211
|
-
|
|
212
|
-
const focusedElement = await page.locator(':focus');
|
|
213
|
-
const focusedElementId = await focusedElement.getAttribute('id');
|
|
214
|
-
|
|
215
|
-
// Assert
|
|
216
|
-
expect(focusedElementId).toBe('focus-me');
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
test('should return focus to first matching element', async ({ page, mount }) => {
|
|
220
|
-
// Arrange
|
|
221
|
-
const component = renderTestPieModal({
|
|
222
|
-
returnFocusAfterCloseSelector: '[data-test-id="focus-me"]',
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
await mount(WebComponentTestWrapper, {
|
|
226
|
-
props: {
|
|
227
|
-
pageMode: true,
|
|
228
|
-
},
|
|
229
|
-
slots: {
|
|
230
|
-
component,
|
|
231
|
-
pageMarkup: `<div>
|
|
232
|
-
<button id="default"></button>
|
|
233
|
-
<button data-test-id="focus-me" id="actual-focus"></button>
|
|
234
|
-
<button data-test-id="focus-me"></button>
|
|
235
|
-
</div>`,
|
|
236
|
-
},
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
// Act
|
|
240
|
-
await page.click(closeButtonSelector);
|
|
241
|
-
|
|
242
|
-
const focusedElement = await page.locator(':focus');
|
|
243
|
-
const focusedElementId = await focusedElement.getAttribute('id');
|
|
244
|
-
|
|
245
|
-
// Assert
|
|
246
|
-
expect(focusedElementId).toBe('actual-focus');
|
|
247
|
-
});
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
test.describe('when not given', () => {
|
|
251
|
-
[{
|
|
252
|
-
mechanism: 'close button',
|
|
253
|
-
modalCloseFunction: async (page : Page) => {
|
|
254
|
-
await page.click(closeButtonSelector);
|
|
255
|
-
},
|
|
256
|
-
}, {
|
|
257
|
-
mechanism: 'Esc key',
|
|
258
|
-
modalCloseFunction: async (page : Page) => {
|
|
259
|
-
await page.keyboard.press('Escape');
|
|
260
|
-
},
|
|
261
|
-
}].forEach(({ mechanism, modalCloseFunction }) => {
|
|
262
|
-
test.describe(`and closed by the ${mechanism}`, () => {
|
|
263
|
-
test('should return focus to the element that opens the modal', async ({ page, mount }) => {
|
|
264
|
-
// Arrange
|
|
265
|
-
const component = renderTestPieModal({ isOpen: false });
|
|
266
|
-
|
|
267
|
-
await mount(WebComponentTestWrapper, {
|
|
268
|
-
props: {
|
|
269
|
-
pageMode: true,
|
|
270
|
-
},
|
|
271
|
-
slots: {
|
|
272
|
-
component,
|
|
273
|
-
pageMarkup: `<div>
|
|
274
|
-
<button id="not-me"></button>
|
|
275
|
-
<button data-test-id="open-modal" id="default"></button>
|
|
276
|
-
</div>`,
|
|
277
|
-
},
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
await page.evaluate(() => {
|
|
281
|
-
// Set up a button which opens the modal when clicked
|
|
282
|
-
document.querySelector('[data-test-id="open-modal"]')?.addEventListener('click', () => {
|
|
283
|
-
document.querySelector('pie-modal')?.setAttribute('isOpen', 'true');
|
|
284
|
-
});
|
|
285
|
-
});
|
|
286
|
-
|
|
287
|
-
// Act
|
|
288
|
-
await page.click('[data-test-id="open-modal"]');
|
|
289
|
-
await modalCloseFunction(page);
|
|
290
|
-
|
|
291
|
-
const focusedElement = await page.locator(':focus');
|
|
292
|
-
const focusedElementId = await focusedElement.getAttribute('id');
|
|
293
|
-
|
|
294
|
-
// Assert
|
|
295
|
-
expect(focusedElementId).toBe('default');
|
|
296
|
-
});
|
|
297
|
-
});
|
|
298
|
-
});
|
|
299
|
-
});
|
|
300
|
-
});
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
test.describe('`isDismissible` prop', () => {
|
|
304
|
-
test.describe('when `true`', () => {
|
|
305
|
-
test('should make the modal contain a close button', async ({ mount }) => {
|
|
306
|
-
// Arrange
|
|
307
|
-
const component = await mount(
|
|
308
|
-
PieModal,
|
|
309
|
-
{
|
|
310
|
-
props: {
|
|
311
|
-
isOpen: true,
|
|
312
|
-
isDismissible: true,
|
|
313
|
-
},
|
|
314
|
-
},
|
|
315
|
-
);
|
|
316
|
-
|
|
317
|
-
// Act
|
|
318
|
-
const closeButton = component.locator(closeButtonSelector);
|
|
319
|
-
|
|
320
|
-
// Assert
|
|
321
|
-
await expect(closeButton).toBeVisible();
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
test('should close the modal when the close button is clicked', async ({ mount, page }) => {
|
|
325
|
-
// Arrange
|
|
326
|
-
const component = await mount(
|
|
327
|
-
PieModal,
|
|
328
|
-
{
|
|
329
|
-
props: {
|
|
330
|
-
isOpen: true,
|
|
331
|
-
isDismissible: true,
|
|
332
|
-
},
|
|
333
|
-
},
|
|
334
|
-
);
|
|
335
|
-
|
|
336
|
-
// Act
|
|
337
|
-
await page.click('[data-test-id="modal-close-button"]');
|
|
338
|
-
|
|
339
|
-
// Assert
|
|
340
|
-
await expect(component).not.toBeVisible();
|
|
341
|
-
});
|
|
342
|
-
|
|
343
|
-
test('should close the modal when the backdrop is clicked', async ({ mount, page }) => {
|
|
344
|
-
// Arrange
|
|
345
|
-
await mount(
|
|
346
|
-
PieModal,
|
|
347
|
-
{
|
|
348
|
-
props: {
|
|
349
|
-
isOpen: true,
|
|
350
|
-
isDismissible: true,
|
|
351
|
-
},
|
|
352
|
-
},
|
|
353
|
-
);
|
|
354
|
-
|
|
355
|
-
// Act
|
|
356
|
-
await page.click('body');
|
|
357
|
-
|
|
358
|
-
const element = await page.locator(componentSelector);
|
|
359
|
-
|
|
360
|
-
const styles = await element.evaluate((modal) => {
|
|
361
|
-
const computedStyles = window.getComputedStyle(modal);
|
|
362
|
-
return {
|
|
363
|
-
display: computedStyles.getPropertyValue('display'),
|
|
364
|
-
};
|
|
365
|
-
});
|
|
366
|
-
|
|
367
|
-
// Assert
|
|
368
|
-
expect(styles.display).toBe('none');
|
|
369
|
-
});
|
|
370
|
-
|
|
371
|
-
test('should close the modal when the Escape key is pressed', async ({ mount, page }) => {
|
|
372
|
-
// Arrange
|
|
373
|
-
await mount(PieModal, {
|
|
374
|
-
props: {
|
|
375
|
-
isOpen: true,
|
|
376
|
-
isDismissible: true,
|
|
377
|
-
},
|
|
378
|
-
});
|
|
379
|
-
|
|
380
|
-
const modal = await page.locator(componentSelector);
|
|
381
|
-
|
|
382
|
-
// Act
|
|
383
|
-
await page.keyboard.press('Escape');
|
|
384
|
-
|
|
385
|
-
// Assert
|
|
386
|
-
await expect(modal).not.toBeVisible();
|
|
387
|
-
});
|
|
388
|
-
});
|
|
389
|
-
|
|
390
|
-
test.describe('when `isDismissible` is `false`', () => {
|
|
391
|
-
test('should make the modal NOT contain a close button', async ({ mount }) => {
|
|
392
|
-
// Arrange
|
|
393
|
-
const component = await mount(PieModal, {
|
|
394
|
-
props: {
|
|
395
|
-
isOpen: true,
|
|
396
|
-
isDismissible: false,
|
|
397
|
-
},
|
|
398
|
-
});
|
|
399
|
-
|
|
400
|
-
// Act
|
|
401
|
-
const closeButton = await component.locator(closeButtonSelector);
|
|
402
|
-
|
|
403
|
-
// Assert
|
|
404
|
-
await expect(closeButton).not.toBeVisible();
|
|
405
|
-
});
|
|
406
|
-
|
|
407
|
-
test('should NOT close the modal when the backdrop is clicked', async ({ mount, page }) => {
|
|
408
|
-
// Arrange
|
|
409
|
-
await mount(
|
|
410
|
-
PieModal,
|
|
411
|
-
{
|
|
412
|
-
props: {
|
|
413
|
-
isOpen: true,
|
|
414
|
-
isDismissible: false,
|
|
415
|
-
},
|
|
416
|
-
},
|
|
417
|
-
);
|
|
418
|
-
|
|
419
|
-
// Act
|
|
420
|
-
await page.locator('body').click();
|
|
421
|
-
|
|
422
|
-
const element = await page.locator(componentSelector);
|
|
423
|
-
|
|
424
|
-
const styles = await element.evaluate((modal) => {
|
|
425
|
-
const computedStyles = window.getComputedStyle(modal);
|
|
426
|
-
return {
|
|
427
|
-
display: computedStyles.getPropertyValue('display'),
|
|
428
|
-
};
|
|
429
|
-
});
|
|
430
|
-
|
|
431
|
-
// Assert
|
|
432
|
-
expect(styles.display).toBe('flex');
|
|
433
|
-
});
|
|
434
|
-
|
|
435
|
-
test('should NOT close the modal when the Escape key is pressed', async ({ mount, page }) => {
|
|
436
|
-
// Arrange
|
|
437
|
-
await mount(PieModal, {
|
|
438
|
-
props: {
|
|
439
|
-
isOpen: true,
|
|
440
|
-
isDismissible: false,
|
|
441
|
-
},
|
|
442
|
-
});
|
|
443
|
-
|
|
444
|
-
// Act
|
|
445
|
-
await page.keyboard.press('Escape');
|
|
446
|
-
const modal = await page.locator(componentSelector);
|
|
447
|
-
|
|
448
|
-
// Assert
|
|
449
|
-
await expect(modal).toBeVisible();
|
|
450
|
-
});
|
|
451
|
-
});
|
|
452
|
-
});
|
|
453
|
-
|
|
454
|
-
test.describe('isOpen prop', () => {
|
|
455
|
-
test('should not render open when isOpen = false', async ({ mount, page }) => {
|
|
456
|
-
// Arrange
|
|
457
|
-
await mount(PieModal, {
|
|
458
|
-
props: {
|
|
459
|
-
isOpen: false,
|
|
460
|
-
},
|
|
461
|
-
});
|
|
462
|
-
|
|
463
|
-
// Assert
|
|
464
|
-
await expect(page.locator(componentSelector)).not.toBeVisible();
|
|
465
|
-
});
|
|
466
|
-
|
|
467
|
-
test('should render open when isOpen = true', async ({ mount, page }) => {
|
|
468
|
-
// Arrange
|
|
469
|
-
await mount(PieModal, {
|
|
470
|
-
props: {
|
|
471
|
-
isOpen: true,
|
|
472
|
-
},
|
|
473
|
-
});
|
|
474
|
-
|
|
475
|
-
// Assert
|
|
476
|
-
await expect(page.locator(componentSelector)).toBeVisible();
|
|
477
|
-
});
|
|
478
|
-
});
|
|
479
|
-
|
|
480
|
-
test.describe('scrolling logic', () => {
|
|
481
|
-
test('Should not be able to scroll when isOpen = true', async ({ page, mount }) => {
|
|
482
|
-
// Arrange
|
|
483
|
-
const modalComponent = renderTestPieModal();
|
|
484
|
-
|
|
485
|
-
await mount(
|
|
486
|
-
WebComponentTestWrapper,
|
|
487
|
-
{
|
|
488
|
-
props: {
|
|
489
|
-
pageMode: true,
|
|
490
|
-
},
|
|
491
|
-
slots: {
|
|
492
|
-
component: modalComponent,
|
|
493
|
-
pageMarkup: createScrollablePageHTML(),
|
|
494
|
-
},
|
|
495
|
-
},
|
|
496
|
-
);
|
|
497
|
-
|
|
498
|
-
// Act
|
|
499
|
-
// Scroll 800 pixels down the page
|
|
500
|
-
await page.mouse.wheel(0, 5000);
|
|
501
|
-
|
|
502
|
-
// The mouse.wheel function causes scrolling, but doesn't wait for the scroll to finish before returning.
|
|
503
|
-
await page.waitForTimeout(3000);
|
|
504
|
-
|
|
505
|
-
// Assert
|
|
506
|
-
await expect.soft(page.getByText('Top of page copy')).toBeInViewport();
|
|
507
|
-
await expect(page.getByText('Bottom of page copy')).not.toBeInViewport();
|
|
508
|
-
});
|
|
509
|
-
|
|
510
|
-
test('Should scroll to the bottom when Pie Modal is closed', async ({ page, mount }) => {
|
|
511
|
-
// Arrange
|
|
512
|
-
const modalComponent = renderTestPieModal();
|
|
513
|
-
|
|
514
|
-
await mount(
|
|
515
|
-
WebComponentTestWrapper,
|
|
516
|
-
{
|
|
517
|
-
props: {
|
|
518
|
-
pageMode: true,
|
|
519
|
-
},
|
|
520
|
-
slots: {
|
|
521
|
-
component: modalComponent,
|
|
522
|
-
pageMarkup: createScrollablePageHTML(),
|
|
523
|
-
},
|
|
524
|
-
},
|
|
525
|
-
);
|
|
526
|
-
|
|
527
|
-
// Act
|
|
528
|
-
await page.locator('[data-test-id="modal-close-button"]').click();
|
|
529
|
-
|
|
530
|
-
// Scroll 800 pixels down the page
|
|
531
|
-
await page.mouse.wheel(0, 5000);
|
|
532
|
-
|
|
533
|
-
// The mouse.wheel function causes scrolling, but doesn't wait for the scroll to finish before returning.
|
|
534
|
-
await page.waitForTimeout(3000);
|
|
535
|
-
|
|
536
|
-
// Assert
|
|
537
|
-
await expect.soft(page.getByText('Top of page copy')).not.toBeInViewport();
|
|
538
|
-
await expect(page.getByText('Bottom of page copy')).toBeInViewport();
|
|
539
|
-
});
|
|
540
|
-
});
|
|
541
|
-
|
|
542
|
-
test.describe('`hasBackButton` prop', () => {
|
|
543
|
-
test.describe('when `true`', () => {
|
|
544
|
-
test('should make the modal contain a back button', async ({ mount }) => {
|
|
545
|
-
// Arrange
|
|
546
|
-
const component = await mount(
|
|
547
|
-
PieModal,
|
|
548
|
-
{
|
|
549
|
-
props: {
|
|
550
|
-
isOpen: true,
|
|
551
|
-
hasBackButton: true,
|
|
552
|
-
},
|
|
553
|
-
},
|
|
554
|
-
);
|
|
555
|
-
|
|
556
|
-
// Act & Assert
|
|
557
|
-
await expect(component.locator(backButtonSelector)).toBeVisible();
|
|
558
|
-
});
|
|
559
|
-
|
|
560
|
-
test('should close the modal when the back button is clicked', async ({ mount }) => {
|
|
561
|
-
// Arrange
|
|
562
|
-
const component = await mount(
|
|
563
|
-
PieModal,
|
|
564
|
-
{
|
|
565
|
-
props: {
|
|
566
|
-
isOpen: true,
|
|
567
|
-
hasBackButton: true,
|
|
568
|
-
},
|
|
569
|
-
},
|
|
570
|
-
);
|
|
571
|
-
|
|
572
|
-
// Act
|
|
573
|
-
await component.locator(backButtonSelector).click();
|
|
574
|
-
|
|
575
|
-
// Assert
|
|
576
|
-
await expect(component).not.toBeVisible();
|
|
577
|
-
});
|
|
578
|
-
});
|
|
579
|
-
|
|
580
|
-
test.describe('when `hasBackButton` is `false`', () => {
|
|
581
|
-
test('should make the modal NOT contain a back button', async ({ mount }) => {
|
|
582
|
-
// Arrange
|
|
583
|
-
const component = await mount(
|
|
584
|
-
PieModal,
|
|
585
|
-
{
|
|
586
|
-
props: {
|
|
587
|
-
isOpen: true,
|
|
588
|
-
hasBackButton: false,
|
|
589
|
-
},
|
|
590
|
-
},
|
|
591
|
-
);
|
|
592
|
-
|
|
593
|
-
// Act & Assert
|
|
594
|
-
await expect(component.locator(backButtonSelector)).not.toBeVisible();
|
|
595
|
-
});
|
|
596
|
-
});
|
|
597
|
-
});
|
|
598
|
-
|
|
599
|
-
test.describe('actions', () => {
|
|
600
|
-
['leading', 'supporting'].forEach((actionName) => {
|
|
601
|
-
test.describe(`${actionName} action, when clicked`, () => {
|
|
602
|
-
const buttonSelector = `[data-test-id="modal-${actionName}-action"]`;
|
|
603
|
-
|
|
604
|
-
test('should close the modal', async ({ page, mount }) => {
|
|
605
|
-
// Arrange
|
|
606
|
-
await mount(PieModal, {
|
|
607
|
-
props: {
|
|
608
|
-
heading: 'Modal Header',
|
|
609
|
-
isOpen: true,
|
|
610
|
-
leadingAction: {
|
|
611
|
-
text: 'Confirm',
|
|
612
|
-
variant: 'primary',
|
|
613
|
-
ariaLabel: 'Descriptive message',
|
|
614
|
-
},
|
|
615
|
-
supportingAction: {
|
|
616
|
-
text: 'Cancel',
|
|
617
|
-
variant: 'ghost',
|
|
618
|
-
ariaLabel: 'Descriptive message',
|
|
619
|
-
},
|
|
620
|
-
},
|
|
621
|
-
});
|
|
622
|
-
|
|
623
|
-
const modal = await page.locator(componentSelector);
|
|
624
|
-
|
|
625
|
-
// Act
|
|
626
|
-
await page.click(buttonSelector);
|
|
627
|
-
|
|
628
|
-
// Assert
|
|
629
|
-
expect(modal).not.toBeVisible();
|
|
630
|
-
});
|
|
631
|
-
|
|
632
|
-
test('should submit the correct return value', async ({ page, mount }) => {
|
|
633
|
-
// Arrange
|
|
634
|
-
await mount(PieModal, {
|
|
635
|
-
props: {
|
|
636
|
-
heading: 'Modal Header',
|
|
637
|
-
isOpen: true,
|
|
638
|
-
leadingAction: {
|
|
639
|
-
text: 'Confirm',
|
|
640
|
-
variant: 'primary',
|
|
641
|
-
ariaLabel: 'Descriptive message',
|
|
642
|
-
},
|
|
643
|
-
supportingAction: {
|
|
644
|
-
text: 'Cancel',
|
|
645
|
-
variant: 'ghost',
|
|
646
|
-
ariaLabel: 'Descriptive message',
|
|
647
|
-
},
|
|
648
|
-
},
|
|
649
|
-
});
|
|
650
|
-
|
|
651
|
-
// Act
|
|
652
|
-
await page.click(buttonSelector);
|
|
653
|
-
const returnValue = await page.$eval(
|
|
654
|
-
componentSelector,
|
|
655
|
-
(dialog : HTMLDialogElement) => dialog.returnValue,
|
|
656
|
-
);
|
|
657
|
-
|
|
658
|
-
// Assert
|
|
659
|
-
expect(returnValue).toBe(actionName);
|
|
660
|
-
});
|
|
661
|
-
});
|
|
662
|
-
});
|
|
663
|
-
});
|
|
664
|
-
|
|
665
|
-
test.describe('Props: `aria`', () => {
|
|
666
|
-
test.describe('when aria exist', () => {
|
|
667
|
-
test('should render component elements with the correct aria-labels', async ({ mount }) => {
|
|
668
|
-
// Arrange
|
|
669
|
-
const component = await mount(PieModal, {
|
|
670
|
-
props: {
|
|
671
|
-
isOpen: true,
|
|
672
|
-
isDismissible: true,
|
|
673
|
-
isLoading: true,
|
|
674
|
-
hasBackButton: true,
|
|
675
|
-
aria: {
|
|
676
|
-
close: 'Close label info',
|
|
677
|
-
back: 'Back label info',
|
|
678
|
-
loading: 'Loading label info',
|
|
679
|
-
},
|
|
680
|
-
},
|
|
681
|
-
});
|
|
682
|
-
|
|
683
|
-
// Act
|
|
684
|
-
// Close button
|
|
685
|
-
const closeButton = await component.locator(closeButtonSelector);
|
|
686
|
-
const ariaCloseLabel = await closeButton.getAttribute('aria-label');
|
|
687
|
-
|
|
688
|
-
// Back button
|
|
689
|
-
const backButton = await component.locator(backButtonSelector);
|
|
690
|
-
const ariaBackLabel = await backButton.getAttribute('aria-label');
|
|
691
|
-
|
|
692
|
-
// Assert
|
|
693
|
-
await expect(ariaCloseLabel).toBe('Close label info');
|
|
694
|
-
await expect(ariaBackLabel).toBe('Back label info');
|
|
695
|
-
});
|
|
696
|
-
|
|
697
|
-
test.describe('when modal `isloading` is true', () => {
|
|
698
|
-
test('should render component with the correct aria values: `aria-label` & `aria-busy`', async ({ mount }) => {
|
|
699
|
-
// Arrange
|
|
700
|
-
const component = await mount(PieModal, {
|
|
701
|
-
props: {
|
|
702
|
-
isOpen: true,
|
|
703
|
-
isLoading: true,
|
|
704
|
-
aria: {
|
|
705
|
-
loading: 'Loading label info',
|
|
706
|
-
},
|
|
707
|
-
},
|
|
708
|
-
});
|
|
709
|
-
|
|
710
|
-
// Loading state
|
|
711
|
-
const pieModalComponent = await component.locator(componentSelector);
|
|
712
|
-
const ariaLoadingLabel = await pieModalComponent.getAttribute('aria-label');
|
|
713
|
-
const ariaLoadingBusy = await pieModalComponent.getAttribute('aria-busy');
|
|
714
|
-
|
|
715
|
-
// Assert
|
|
716
|
-
await expect(ariaLoadingLabel).toBe('Loading label info');
|
|
717
|
-
await expect(ariaLoadingBusy).toBe('true');
|
|
718
|
-
});
|
|
719
|
-
});
|
|
720
|
-
|
|
721
|
-
test.describe('when modal `isLoading` is dynamically changing from `isLoading: true` to `isLoading: false`', () => {
|
|
722
|
-
test('should dynamically add, remove, and update `arial-label` & `aria-busy` labels', async ({ mount }) => {
|
|
723
|
-
// Arrange
|
|
724
|
-
const component = await mount(PieModal, {
|
|
725
|
-
props: {
|
|
726
|
-
isOpen: true,
|
|
727
|
-
isLoading: true,
|
|
728
|
-
aria: {
|
|
729
|
-
loading: 'Loading label info',
|
|
730
|
-
},
|
|
731
|
-
},
|
|
732
|
-
});
|
|
733
|
-
|
|
734
|
-
const pieModalComponent = await component.locator(componentSelector);
|
|
735
|
-
let ariaLoadingLabel = await pieModalComponent.getAttribute('aria-label');
|
|
736
|
-
let ariaLoadingBusy = await pieModalComponent.getAttribute('aria-busy');
|
|
737
|
-
|
|
738
|
-
// Assert: When `isLoading: true`
|
|
739
|
-
await expect(ariaLoadingLabel).toBe('Loading label info');
|
|
740
|
-
await expect(ariaLoadingBusy).toBe('true');
|
|
741
|
-
|
|
742
|
-
await component.update({ props: { isLoading: false } });
|
|
743
|
-
|
|
744
|
-
ariaLoadingLabel = await pieModalComponent.getAttribute('aria-label');
|
|
745
|
-
ariaLoadingBusy = await pieModalComponent.getAttribute('aria-busy');
|
|
746
|
-
|
|
747
|
-
// Assert: When `isLoading: false`
|
|
748
|
-
await expect(ariaLoadingLabel).toBeNull();
|
|
749
|
-
await expect(ariaLoadingBusy).toBe('false');
|
|
750
|
-
});
|
|
751
|
-
});
|
|
752
|
-
});
|
|
753
|
-
|
|
754
|
-
test.describe('when aria does not exist', () => {
|
|
755
|
-
test('should not render the aria-labels', async ({ mount }) => {
|
|
756
|
-
// Arrange
|
|
757
|
-
const component = await mount(PieModal, {
|
|
758
|
-
props: {
|
|
759
|
-
isOpen: true,
|
|
760
|
-
isDismissible: true,
|
|
761
|
-
hasBackButton: true,
|
|
762
|
-
},
|
|
763
|
-
});
|
|
764
|
-
|
|
765
|
-
// Act
|
|
766
|
-
// Close button
|
|
767
|
-
const closeButton = await component.locator(closeButtonSelector);
|
|
768
|
-
const ariaCloseLabel = await closeButton.getAttribute('aria-label');
|
|
769
|
-
|
|
770
|
-
// Back button
|
|
771
|
-
const backButton = await component.locator(backButtonSelector);
|
|
772
|
-
const ariaBackLabel = await backButton.getAttribute('aria-label');
|
|
773
|
-
|
|
774
|
-
// Assert
|
|
775
|
-
await expect(ariaCloseLabel).toBe(null);
|
|
776
|
-
await expect(ariaBackLabel).toBe(null);
|
|
777
|
-
});
|
|
778
|
-
});
|
|
779
|
-
|
|
780
|
-
test.describe('when modal `isloading` is false', () => {
|
|
781
|
-
test('should not render aria-label', async ({ mount }) => {
|
|
782
|
-
// Arrange
|
|
783
|
-
const component = await mount(PieModal, {
|
|
784
|
-
props: {
|
|
785
|
-
isOpen: true,
|
|
786
|
-
isLoading: false,
|
|
787
|
-
},
|
|
788
|
-
});
|
|
789
|
-
|
|
790
|
-
// Loading state
|
|
791
|
-
const pieModalComponent = await component.locator(componentSelector);
|
|
792
|
-
const ariaLoadingLabel = await pieModalComponent.getAttribute('aria-label');
|
|
793
|
-
|
|
794
|
-
// Assert
|
|
795
|
-
await expect(ariaLoadingLabel).toBe(null);
|
|
796
|
-
});
|
|
797
|
-
|
|
798
|
-
test('should set `aria-busy` to `false`', async ({ mount }) => {
|
|
799
|
-
// Arrange
|
|
800
|
-
const component = await mount(PieModal, {
|
|
801
|
-
props: {
|
|
802
|
-
isOpen: true,
|
|
803
|
-
isLoading: false,
|
|
804
|
-
},
|
|
805
|
-
});
|
|
806
|
-
|
|
807
|
-
// Loading state
|
|
808
|
-
const pieModalComponent = await component.locator(componentSelector);
|
|
809
|
-
const ariaLoadingBusy = await pieModalComponent.getAttribute('aria-busy');
|
|
810
|
-
|
|
811
|
-
// Assert
|
|
812
|
-
await expect(ariaLoadingBusy).toBe('false');
|
|
813
|
-
});
|
|
814
|
-
});
|
|
815
|
-
});
|
|
816
|
-
|