@@ -21,7 +21,7 @@ test('@Visual diff', async ({ page }) => {
21
21
} ) ;
22
22
23
23
test . describe ( 'Mouse Behavior' , ( ) => {
24
- test ( `GIVEN a closed popover
24
+ test ( `GIVEN a closed hero popover
25
25
WHEN clicking on the trigger
26
26
THEN the popover should be opened ` , async ( { page } ) => {
27
27
const { driver : d } = await setup ( page , 'hero' ) ;
@@ -31,4 +31,333 @@ test.describe('Mouse Behavior', () => {
31
31
32
32
await expect ( d . getPopover ( ) ) . toBeVisible ( ) ;
33
33
} ) ;
34
+
35
+ test ( `GIVEN an open hero popover
36
+ WHEN clicking elsewhere on the page
37
+ THEN the popover should close` , async ( { page } ) => {
38
+ const { driver : d } = await setup ( page , 'hero' ) ;
39
+
40
+ await expect ( d . getPopover ( ) ) . toBeHidden ( ) ;
41
+ await d . getTrigger ( ) . click ( ) ;
42
+
43
+ // If I use `toBeVisible` here, the test fails that the `toBeHidden` check below????
44
+ await expect ( d . getPopover ( ) ) . toHaveCSS ( 'opacity' , '1' ) ;
45
+
46
+ await page . mouse . click ( 0 , 0 ) ;
47
+
48
+ await expect ( d . getPopover ( ) ) . toBeHidden ( ) ;
49
+ } ) ;
50
+
51
+ test ( `GIVEN an open auto popover
52
+ WHEN clicking the first trigger on the page and then clicking the second trigger
53
+ THEN the first popover should close and the second one appear` , async ( { page } ) => {
54
+ const { driver : d } = await setup ( page , 'auto' ) ;
55
+ //ask shai: is it good to use nth here???
56
+ const [ firstPopOver , secondPopOver ] = await d . getAllPopovers ( ) ;
57
+ const [ firstPopoverTrigger , secondPopoverTrigger ] = await d . getAllTriggers ( ) ;
58
+
59
+ await expect ( firstPopOver ) . toBeHidden ( ) ;
60
+ await expect ( secondPopOver ) . toBeHidden ( ) ;
61
+
62
+ await firstPopoverTrigger . click ( { position : { x : 1 , y : 1 } } ) ;
63
+ await expect ( firstPopOver ) . toBeVisible ( ) ;
64
+
65
+ await secondPopoverTrigger . click ( { position : { x : 1 , y : 1 } } ) ;
66
+ await expect ( secondPopOver ) . toBeVisible ( ) ;
67
+
68
+ await expect ( firstPopOver ) . toBeHidden ( ) ;
69
+ } ) ;
70
+
71
+ test ( `GIVEN a pair of manual popovers
72
+ WHEN clicking the first trigger on the page and then clicking the second trigger
73
+ THEN then both popovers should be opened` , async ( { page } ) => {
74
+ const { driver : d } = await setup ( page , 'manual' ) ;
75
+
76
+ //ask shai: is it good to use nth here???
77
+ const [ firstPopOver , secondPopOver ] = await d . getAllPopovers ( ) ;
78
+ const [ firstPopoverTrigger , secondPopoverTrigger ] = await d . getAllTriggers ( ) ;
79
+
80
+ await expect ( firstPopOver ) . toBeHidden ( ) ;
81
+ await expect ( secondPopOver ) . toBeHidden ( ) ;
82
+
83
+ await firstPopoverTrigger . click ( { position : { x : 1 , y : 1 } } ) ;
84
+ await secondPopoverTrigger . click ( { position : { x : 1 , y : 1 } } ) ;
85
+
86
+ await expect ( firstPopOver ) . toBeVisible ( ) ;
87
+ await expect ( secondPopOver ) . toBeVisible ( ) ;
88
+ } ) ;
89
+
90
+ test ( `GIVEN a pair of manual opened popovers
91
+ WHEN clicking the first trigger on the page and then clicking the second trigger
92
+ THEN then both popovers should be closed` , async ( { page } ) => {
93
+ const { driver : d } = await setup ( page , 'manual' ) ;
94
+
95
+ const [ firstPopOver , secondPopOver ] = await d . getAllPopovers ( ) ;
96
+ const [ firstPopoverTrigger , secondPopoverTrigger ] = await d . getAllTriggers ( ) ;
97
+
98
+ // Arrange
99
+ await firstPopoverTrigger . click ( { position : { x : 1 , y : 1 } } ) ;
100
+ await secondPopoverTrigger . click ( { position : { x : 1 , y : 1 } } ) ;
101
+
102
+ await expect ( firstPopOver ) . toBeVisible ( ) ;
103
+ await expect ( secondPopOver ) . toBeVisible ( ) ;
104
+
105
+ // Need to be explicit about where we're clicking. By default
106
+ // the click action tries to click the center of the element
107
+ // but in this case, the popover is covering it.
108
+ await firstPopoverTrigger . click ( { position : { x : 1 , y : 1 } } ) ;
109
+ await secondPopoverTrigger . click ( { position : { x : 1 , y : 1 } } ) ;
110
+
111
+ // Assert
112
+ await expect ( firstPopOver ) . toBeHidden ( ) ;
113
+ await expect ( secondPopOver ) . toBeHidden ( ) ;
114
+ } ) ;
115
+
116
+ test ( `GIVEN a popover with placement set to top
117
+ WHEN opening the popover
118
+ THEN the popover should appear to the right of the trigger` , async ( { page } ) => {
119
+ const { driver : d } = await setup ( page , 'placement' ) ;
120
+
121
+ const popover = d . getPopover ( ) ;
122
+ const trigger = d . getTrigger ( ) ;
123
+
124
+ await trigger . hover ( ) ;
125
+
126
+ await expect ( popover ) . toBeVisible ( ) ;
127
+
128
+ const popoverBoundingBox = await popover . boundingBox ( ) ;
129
+ const triggerBoundingBox = await trigger . boundingBox ( ) ;
130
+
131
+ expect ( popoverBoundingBox ?. x ) . toBeGreaterThan (
132
+ ( triggerBoundingBox ?. x ?? Number . MAX_VALUE ) +
133
+ ( triggerBoundingBox ?. width ?? Number . MAX_VALUE ) ,
134
+ ) ;
135
+ } ) ;
136
+
137
+ test ( `GIVEN a popover with a gutter configured
138
+ WHEN opening the popover
139
+ THEN the popover should be spaced 40px from the popover` , async ( { page } ) => {
140
+ const { driver : d } = await setup ( page , 'gutter' ) ;
141
+
142
+ const popover = d . getPopover ( ) ;
143
+ const trigger = d . getTrigger ( ) ;
144
+
145
+ await trigger . click ( ) ;
146
+
147
+ await expect ( popover ) . toBeVisible ( ) ;
148
+
149
+ const popoverBoundingBox = await popover . boundingBox ( ) ;
150
+ const triggerBoundingBox = await trigger . boundingBox ( ) ;
151
+
152
+ expect (
153
+ ( triggerBoundingBox ?. y ?? 0 ) -
154
+ ( ( popoverBoundingBox ?. y ?? 0 ) + ( popoverBoundingBox ?. height ?? 0 ) ) ,
155
+ ) . toBe ( 40 ) ;
156
+ } ) ;
157
+
158
+ // test(`GIVEN a combobox with a flip configured
159
+ // WHEN scrolling the page
160
+ // THEN the popover flip to the opposite end once space runs out`, async ({ page }) => {
161
+ // const { driver: d } = await setup(page, 'flip');
162
+
163
+ // const popover = d.getPopover();
164
+ // const trigger = d.getTrigger();
165
+
166
+ // // Introduce artificial spacing
167
+ // await trigger.evaluate((element) => (element.style.top = '800px'));
168
+
169
+ // await trigger.click();
170
+
171
+ // await expect(popover).toBeVisible();
172
+
173
+ // const popoverBoundingBox = await popover.boundingBox();
174
+ // const triggerBoundingBox = await trigger.boundingBox();
175
+
176
+ // console.log(triggerBoundingBox, popoverBoundingBox);
177
+
178
+ // const triggerBottomAbsolutePosition =
179
+ // (triggerBoundingBox?.y ?? 0) + (triggerBoundingBox?.height ?? 0);
180
+
181
+ // expect((popoverBoundingBox?.y ?? 0) - triggerBottomAbsolutePosition).toBe(24);
182
+ // });
183
+ } ) ;
184
+
185
+ test . describe ( 'Keyboard Behavior' , ( ) => {
186
+ for ( const key of [ 'Enter' , 'Space' ] ) {
187
+ test ( `GIVEN a closed hero popover
188
+ WHEN focusing on the button and pressing the '${ key } ' key
189
+ THEN the popover should open` , async ( { page } ) => {
190
+ const { driver : d } = await setup ( page , 'hero' ) ;
191
+ await expect ( d . getPopover ( ) ) . toBeHidden ( ) ;
192
+
193
+ await d . getTrigger ( ) . press ( key ) ;
194
+
195
+ await expect ( d . getPopover ( ) ) . toBeVisible ( ) ;
196
+ } ) ;
197
+
198
+ test ( `GIVEN a open hero popover
199
+ WHEN focusing on the button and pressing the '${ key } ' key
200
+ THEN the popover should close` , async ( { page } ) => {
201
+ const { driver : d } = await setup ( page , 'hero' ) ;
202
+
203
+ // Open the popover
204
+ await d . getTrigger ( ) . press ( key ) ;
205
+
206
+ await expect ( d . getPopover ( ) ) . toBeVisible ( ) ;
207
+
208
+ // Close the popover
209
+ await d . getTrigger ( ) . press ( key ) ;
210
+
211
+ await expect ( d . getPopover ( ) ) . toBeHidden ( ) ;
212
+ } ) ;
213
+ }
214
+
215
+ test ( `GIVEN a open hero popover
216
+ WHEN focusing on the button and pressing the 'Escape' key
217
+ THEN the popover should close and the trigger be focused` , async ( { page } ) => {
218
+ const { driver : d } = await setup ( page , 'hero' ) ;
219
+
220
+ // Open the popover
221
+ await d . getTrigger ( ) . press ( 'Enter' ) ;
222
+
223
+ await expect ( d . getPopover ( ) ) . toBeVisible ( ) ;
224
+
225
+ // Close the popover
226
+ page . keyboard . press ( 'Escape' ) ;
227
+
228
+ await expect ( d . getPopover ( ) ) . toBeHidden ( ) ;
229
+ await expect ( d . getTrigger ( ) ) . toBeFocused ( ) ;
230
+ } ) ;
231
+
232
+ test ( `GIVEN a programmatic popover with a programmatic trigger
233
+ WHEN focusing on the button and pressing the 'o' key
234
+ THEN the popover should open` , async ( { page } ) => {
235
+ const { driver : d } = await setup ( page , 'programmatic' ) ;
236
+
237
+ await expect ( d . getPopover ( ) ) . toBeHidden ( ) ;
238
+
239
+ // Using `page` here because driver is scoped to the popover
240
+ await page . getByRole ( 'button' , { name : "Focus me and press the 'o'" } ) . focus ( ) ;
241
+ await page . keyboard . type ( 'o' ) ;
242
+
243
+ await expect ( d . getPopover ( ) ) . toBeVisible ( ) ;
244
+ } ) ;
245
+ test ( `GIVEN an open auto popover
246
+ WHEN the first trigger open and the focus changes to the second popover
247
+ THEN the first popover should close and the second one appear` , async ( { page } ) => {
248
+ const { driver : d } = await setup ( page , 'auto' ) ;
249
+
250
+ const [ firstPopOver , secondPopOver ] = await d . getAllPopovers ( ) ;
251
+ const [ firstPopoverTrigger , secondPopoverTrigger ] = await d . getAllTriggers ( ) ;
252
+
253
+ await expect ( firstPopOver ) . toBeHidden ( ) ;
254
+ await expect ( secondPopOver ) . toBeHidden ( ) ;
255
+
256
+ await firstPopoverTrigger . press ( 'Enter' ) ;
257
+ await expect ( firstPopOver ) . toBeVisible ( ) ;
258
+ await firstPopoverTrigger . press ( 'Tab' ) ;
259
+ await expect ( secondPopoverTrigger ) . toBeFocused ( ) ;
260
+
261
+ await secondPopoverTrigger . press ( 'Enter' ) ;
262
+ await expect ( secondPopOver ) . toBeVisible ( ) ;
263
+
264
+ await expect ( firstPopOver ) . toBeHidden ( ) ;
265
+ } ) ;
266
+
267
+ test ( `GIVEN a pair of manual popovers
268
+ WHEN clicking the first trigger on the page and then clicking the second trigger
269
+ THEN then both popovers should be opened` , async ( { page } ) => {
270
+ const { driver : d } = await setup ( page , 'manual' ) ;
271
+
272
+ const [ firstPopOver , secondPopOver ] = await d . getAllPopovers ( ) ;
273
+ const [ firstPopoverTrigger , secondPopoverTrigger ] = await d . getAllTriggers ( ) ;
274
+
275
+ await expect ( firstPopOver ) . toBeHidden ( ) ;
276
+ await expect ( secondPopOver ) . toBeHidden ( ) ;
277
+
278
+ await firstPopoverTrigger . press ( 'Enter' ) ;
279
+
280
+ await secondPopoverTrigger . press ( 'Enter' ) ;
281
+
282
+ await expect ( firstPopOver ) . toBeVisible ( ) ;
283
+ await expect ( secondPopOver ) . toBeVisible ( ) ;
284
+ } ) ;
285
+
286
+ test ( `GIVEN a pair of manual opened popovers
287
+ WHEN activating the first trigger on the page and then activating the second trigger
288
+ THEN then both popovers should be closed` , async ( { page } ) => {
289
+ const { driver : d } = await setup ( page , 'manual' ) ;
290
+
291
+ const [ firstPopOver , secondPopOver ] = await d . getAllPopovers ( ) ;
292
+ const [ firstPopoverTrigger , secondPopoverTrigger ] = await d . getAllTriggers ( ) ;
293
+
294
+ // Arrange
295
+ await firstPopoverTrigger . press ( 'Enter' ) ;
296
+
297
+ await secondPopoverTrigger . press ( 'Enter' ) ;
298
+
299
+ await expect ( firstPopOver ) . toBeVisible ( ) ;
300
+ await expect ( secondPopOver ) . toBeVisible ( ) ;
301
+
302
+ // Act
303
+ await secondPopoverTrigger . press ( 'Enter' ) ;
304
+ await expect ( secondPopOver ) . toBeHidden ( ) ;
305
+
306
+ // Assert
307
+ await firstPopoverTrigger . press ( 'Enter' ) ;
308
+ await expect ( firstPopOver ) . toBeHidden ( ) ;
309
+ } ) ;
310
+
311
+ test ( `GIVEN a programmatic popover
312
+ WHEN focusing the button on the page and then typing 'o'
313
+ THEN the popover should open` , async ( { page } ) => {
314
+ const { driver : d } = await setup ( page , 'programmatic' ) ;
315
+
316
+ const popover = d . getPopover ( ) ;
317
+ const programmaticButtonTrigger = d . getProgrammaticButtonTrigger ( ) ;
318
+
319
+ await expect ( popover ) . toBeHidden ( ) ;
320
+
321
+ await programmaticButtonTrigger . press ( 'o' ) ;
322
+
323
+ await expect ( popover ) . toBeVisible ( ) ;
324
+ } ) ;
325
+
326
+ test ( `GIVEN an open programmatic popover
327
+ WHEN focusing the button on the page and then typing 'o'
328
+ THEN the popover should close` , async ( { page } ) => {
329
+ const { driver : d } = await setup ( page , 'programmatic' ) ;
330
+
331
+ const popover = d . getPopover ( ) ;
332
+ const programmaticButtonTrigger = d . getProgrammaticButtonTrigger ( ) ;
333
+
334
+ await programmaticButtonTrigger . press ( 'o' ) ;
335
+
336
+ await expect ( popover ) . toBeVisible ( ) ;
337
+
338
+ await programmaticButtonTrigger . press ( 'o' ) ;
339
+
340
+ await expect ( popover ) . toBeHidden ( ) ;
341
+ } ) ;
342
+
343
+ test ( `GIVEN a popover with placement set to top
344
+ WHEN opening the popover using the keyboard
345
+ THEN the popover should appear to the right of the trigger` , async ( { page } ) => {
346
+ const { driver : d } = await setup ( page , 'placement' ) ;
347
+
348
+ const popover = d . getPopover ( ) ;
349
+ const trigger = d . getTrigger ( ) ;
350
+
351
+ await trigger . press ( 'Enter' ) ;
352
+
353
+ await expect ( popover ) . toBeVisible ( ) ;
354
+
355
+ const popoverBoundingBox = await popover . boundingBox ( ) ;
356
+ const triggerBoundingBox = await trigger . boundingBox ( ) ;
357
+
358
+ expect ( popoverBoundingBox ?. x ) . toBeGreaterThan (
359
+ ( triggerBoundingBox ?. x ?? Number . MAX_VALUE ) +
360
+ ( triggerBoundingBox ?. width ?? Number . MAX_VALUE ) ,
361
+ ) ;
362
+ } ) ;
34
363
} ) ;
0 commit comments