@wordpress/e2e-tests 6.5.1 → 7.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.
@@ -1,1048 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import {
5
- clickBlockAppender,
6
- createNewPost,
7
- pressKeyWithModifier,
8
- pressKeyTimes,
9
- getEditedPostContent,
10
- clickBlockToolbarButton,
11
- clickButton,
12
- clickMenuItem,
13
- insertBlock,
14
- openListView,
15
- saveDraft,
16
- transformBlockTo,
17
- } from '@wordpress/e2e-test-utils';
18
-
19
- async function getSelectedFlatIndices() {
20
- return await page.evaluate( () => {
21
- const indices = [];
22
- let single;
23
-
24
- Array.from(
25
- document.querySelectorAll( '.wp-block:not(.editor-post-title)' )
26
- ).forEach( ( node, index ) => {
27
- if ( node.classList.contains( 'is-selected' ) ) {
28
- single = index + 1;
29
- }
30
-
31
- if ( node.classList.contains( 'is-multi-selected' ) ) {
32
- indices.push( index + 1 );
33
- }
34
- } );
35
-
36
- return single !== undefined ? single : indices;
37
- } );
38
- }
39
-
40
- /**
41
- * Tests if the native selection matches the block selection.
42
- */
43
- async function testNativeSelection() {
44
- // Wait for the selection to update and async mode to update classes of
45
- // deselected blocks.
46
- await page.evaluate( () => new Promise( window.requestIdleCallback ) );
47
- await page.evaluate( () => {
48
- const selection = window.getSelection();
49
- const elements = Array.from(
50
- document.querySelectorAll( '.is-multi-selected' )
51
- );
52
-
53
- if ( ! elements.length ) {
54
- const element = document.querySelector( '.is-selected' );
55
-
56
- if ( ! element || ! selection.rangeCount ) {
57
- return;
58
- }
59
-
60
- const { startContainer, endContainer } = selection.getRangeAt( 0 );
61
-
62
- if ( ! element.contains( startContainer ) ) {
63
- throw 'expected selection to start in the selected block';
64
- }
65
-
66
- if ( ! element.contains( endContainer ) ) {
67
- throw 'expected selection to start in the selected block';
68
- }
69
-
70
- return;
71
- }
72
-
73
- if ( selection.rangeCount !== 1 ) {
74
- throw 'expected one range';
75
- }
76
-
77
- if ( selection.isCollapsed ) {
78
- throw 'expected an uncollapsed selection';
79
- }
80
-
81
- const firstElement = elements[ 0 ];
82
- const lastElement = elements[ elements.length - 1 ];
83
-
84
- if ( ! selection.containsNode( firstElement, true ) ) {
85
- throw 'expected selection to include in the first selected block';
86
- }
87
-
88
- if ( ! selection.containsNode( lastElement, true ) ) {
89
- throw 'expected selection to include in the last selected block';
90
- }
91
- } );
92
- }
93
-
94
- describe( 'Multi-block selection', () => {
95
- beforeEach( async () => {
96
- await createNewPost();
97
- } );
98
-
99
- it( 'should select with double ctrl+a and speak', async () => {
100
- await clickBlockAppender();
101
- await page.keyboard.type( '1' );
102
- await page.keyboard.press( 'Enter' );
103
- await page.keyboard.type( '2' );
104
- await page.keyboard.press( 'Enter' );
105
- await page.keyboard.type( '3' );
106
-
107
- // Multiselect via keyboard.
108
- await pressKeyWithModifier( 'primary', 'a' );
109
- await pressKeyWithModifier( 'primary', 'a' );
110
-
111
- expect( await getSelectedFlatIndices() ).toEqual( [ 1, 2, 3 ] );
112
-
113
- // TODO: It would be great to do this test by spying on `wp.a11y.speak`,
114
- // but it's very difficult to do that because `wp.a11y` has
115
- // DOM-dependant side-effect setup code and doesn't seem straightforward
116
- // to mock. Instead, we check for the DOM node that `wp.a11y.speak()`
117
- // inserts text into.
118
- const speakTextContent = await page.$eval(
119
- '#a11y-speak-assertive',
120
- ( element ) => element.textContent
121
- );
122
- expect( speakTextContent.trim() ).toEqual( '3 blocks selected.' );
123
- } );
124
-
125
- // See #14448: an incorrect buffer may trigger multi-selection too soon.
126
- it( 'should only trigger multi-selection when at the end', async () => {
127
- // Create a paragraph with four lines.
128
- await clickBlockAppender();
129
- await page.keyboard.type( '1.' );
130
- await pressKeyWithModifier( 'shift', 'Enter' );
131
- await page.keyboard.type( '2.' );
132
- await pressKeyWithModifier( 'shift', 'Enter' );
133
- await page.keyboard.type( '3.' );
134
- await pressKeyWithModifier( 'shift', 'Enter' );
135
- await page.keyboard.type( '4.' );
136
- // Create a second block.
137
- await page.keyboard.press( 'Enter' );
138
- // Move to the middle of the first line.
139
- await pressKeyTimes( 'ArrowUp', 4 );
140
- await page.keyboard.press( 'ArrowRight' );
141
- // Select mid line one to mid line four.
142
- await pressKeyWithModifier( 'shift', 'ArrowDown' );
143
- await pressKeyWithModifier( 'shift', 'ArrowDown' );
144
- await pressKeyWithModifier( 'shift', 'ArrowDown' );
145
- // Delete the text to see if the selection was correct.
146
- await page.keyboard.press( 'Backspace' );
147
-
148
- expect( await getEditedPostContent() ).toMatchSnapshot();
149
- } );
150
-
151
- it( 'should use selection direction to determine vertical edge', async () => {
152
- await clickBlockAppender();
153
- await page.keyboard.type( '1' );
154
- await pressKeyWithModifier( 'shift', 'Enter' );
155
- await page.keyboard.press( 'Enter' );
156
- await page.keyboard.type( '3' );
157
- await page.keyboard.press( 'ArrowUp' );
158
- await page.keyboard.type( '2' );
159
-
160
- await pressKeyWithModifier( 'shift', 'ArrowUp' );
161
- await pressKeyWithModifier( 'shift', 'ArrowDown' );
162
-
163
- // Should type at the end of the paragraph.
164
- await page.keyboard.type( '.' );
165
-
166
- expect( await getEditedPostContent() ).toMatchSnapshot();
167
- } );
168
-
169
- it( 'should always expand single line selection', async () => {
170
- await clickBlockAppender();
171
- await page.keyboard.press( 'Enter' );
172
- await page.keyboard.type( '12' );
173
- await page.keyboard.press( 'ArrowLeft' );
174
- await pressKeyWithModifier( 'shift', 'ArrowLeft' );
175
- await pressKeyWithModifier( 'shift', 'ArrowUp' );
176
- await testNativeSelection();
177
- // This deletes all blocks.
178
- await page.keyboard.press( 'Backspace' );
179
-
180
- expect( await getEditedPostContent() ).toMatchSnapshot();
181
- } );
182
-
183
- it( 'should allow selecting outer edge if there is no sibling block', async () => {
184
- await clickBlockAppender();
185
- await page.keyboard.type( '1' );
186
- await pressKeyWithModifier( 'shift', 'ArrowUp' );
187
- // This should replace the content.
188
- await page.keyboard.type( '2' );
189
-
190
- expect( await getEditedPostContent() ).toMatchSnapshot();
191
- } );
192
-
193
- it( 'should select and deselect with shift and arrow keys', async () => {
194
- await clickBlockAppender();
195
- await page.keyboard.type( '1' );
196
- await page.keyboard.press( 'Enter' );
197
- await page.keyboard.type( '2' );
198
- await page.keyboard.press( 'Enter' );
199
- await page.keyboard.type( '3' );
200
- await page.keyboard.press( 'Enter' );
201
- await page.keyboard.type( '4' );
202
- await page.keyboard.press( 'Enter' );
203
- await page.keyboard.type( '5' );
204
- await page.keyboard.press( 'ArrowUp' );
205
- await page.keyboard.press( 'ArrowUp' );
206
- await pressKeyWithModifier( 'shift', 'ArrowDown' );
207
-
208
- await testNativeSelection();
209
- expect( await getSelectedFlatIndices() ).toEqual( [ 3, 4 ] );
210
-
211
- await pressKeyWithModifier( 'shift', 'ArrowDown' );
212
-
213
- await testNativeSelection();
214
- expect( await getSelectedFlatIndices() ).toEqual( [ 3, 4, 5 ] );
215
-
216
- await pressKeyWithModifier( 'shift', 'ArrowUp' );
217
-
218
- await testNativeSelection();
219
- expect( await getSelectedFlatIndices() ).toEqual( [ 3, 4 ] );
220
-
221
- await pressKeyWithModifier( 'shift', 'ArrowUp' );
222
-
223
- await testNativeSelection();
224
- expect( await getSelectedFlatIndices() ).toBe( 3 );
225
-
226
- await pressKeyWithModifier( 'shift', 'ArrowUp' );
227
-
228
- await testNativeSelection();
229
- expect( await getSelectedFlatIndices() ).toEqual( [ 2, 3 ] );
230
-
231
- await pressKeyWithModifier( 'shift', 'ArrowUp' );
232
-
233
- await testNativeSelection();
234
- expect( await getSelectedFlatIndices() ).toEqual( [ 1, 2, 3 ] );
235
-
236
- await pressKeyWithModifier( 'shift', 'ArrowDown' );
237
-
238
- await testNativeSelection();
239
- expect( await getSelectedFlatIndices() ).toEqual( [ 2, 3 ] );
240
-
241
- await pressKeyWithModifier( 'shift', 'ArrowDown' );
242
-
243
- await testNativeSelection();
244
- expect( await getSelectedFlatIndices() ).toBe( 3 );
245
- } );
246
-
247
- // Flaky test.
248
- it.skip( 'should deselect with Escape', async () => {
249
- await clickBlockAppender();
250
- await page.keyboard.type( '1' );
251
- await page.keyboard.press( 'Enter' );
252
- await page.keyboard.type( '2' );
253
-
254
- await pressKeyWithModifier( 'primary', 'a' );
255
- await pressKeyWithModifier( 'primary', 'a' );
256
-
257
- await testNativeSelection();
258
- expect( await getSelectedFlatIndices() ).toEqual( [ 1, 2 ] );
259
-
260
- await page.keyboard.press( 'Escape' );
261
-
262
- // Wait for blocks to have updated asynchronously.
263
- await page.evaluate( () => new Promise( window.requestIdleCallback ) );
264
- expect( await getSelectedFlatIndices() ).toEqual( [] );
265
- } );
266
-
267
- it( 'should select with shift + click', async () => {
268
- await clickBlockAppender();
269
- await page.keyboard.type( '1' );
270
- await page.keyboard.press( 'Enter' );
271
- await page.keyboard.type( '2' );
272
- await page.keyboard.down( 'Shift' );
273
- await page.click( '[data-type="core/paragraph"]' );
274
- await page.keyboard.up( 'Shift' );
275
-
276
- await testNativeSelection();
277
- expect( await getSelectedFlatIndices() ).toEqual( [ 1, 2 ] );
278
-
279
- // Group the blocks and test that multiselection also works for nested
280
- // blocks. Checks for regressions of
281
- // https://github.com/WordPress/gutenberg/issues/32056
282
-
283
- await clickBlockToolbarButton( 'Options' );
284
- await clickMenuItem( 'Group' );
285
- await page.click( '[data-type="core/paragraph"]' );
286
- await page.keyboard.down( 'Shift' );
287
- await page.click( '[data-type="core/paragraph"]:nth-child(2)' );
288
- await page.keyboard.up( 'Shift' );
289
- await testNativeSelection();
290
- expect( await getSelectedFlatIndices() ).toEqual( [ 2, 3 ] );
291
- } );
292
-
293
- // @see https://github.com/WordPress/gutenberg/issues/34118
294
- it( 'should properly select a single block even if `shift` was held for the selection', async () => {
295
- await clickBlockAppender();
296
- await page.keyboard.type( 'test' );
297
-
298
- await saveDraft();
299
- await page.reload();
300
- await page.waitForSelector( '.edit-post-layout' );
301
-
302
- await page.keyboard.down( 'Shift' );
303
- await page.click( '[data-type="core/paragraph"]', { visible: true } );
304
- await page.keyboard.up( 'Shift' );
305
-
306
- await pressKeyWithModifier( 'primary', 'a' );
307
- await page.keyboard.type( 'new content' );
308
- expect( await getEditedPostContent() ).toMatchInlineSnapshot( `
309
- "<!-- wp:paragraph -->
310
- <p>new content</p>
311
- <!-- /wp:paragraph -->"
312
- ` );
313
- } );
314
-
315
- it( 'should properly select multiple blocks if selected nested blocks belong to different parent', async () => {
316
- await clickBlockAppender();
317
- await page.keyboard.type( 'first' );
318
- await page.keyboard.press( 'Enter' );
319
- await page.keyboard.type( 'group' );
320
- // Multiselect via keyboard.
321
- await page.keyboard.down( 'Shift' );
322
- await page.keyboard.press( 'ArrowUp' );
323
- await page.keyboard.up( 'Shift' );
324
- await transformBlockTo( 'Group' );
325
- await page.keyboard.press( 'Enter' );
326
- await page.keyboard.type( 'second' );
327
- await page.keyboard.press( 'Enter' );
328
- await page.keyboard.type( 'group' );
329
- await page.keyboard.down( 'Shift' );
330
- await page.keyboard.press( 'ArrowUp' );
331
- await page.keyboard.up( 'Shift' );
332
- await transformBlockTo( 'Group' );
333
-
334
- // Confirm setup.
335
- expect( await getEditedPostContent() ).toMatchSnapshot();
336
-
337
- // Click the first paragraph in the first Group block while pressing `shift` key.
338
- const firstParagraph = await page.waitForXPath( "//p[text()='first']" );
339
- await page.keyboard.down( 'Shift' );
340
- await firstParagraph.click();
341
- await page.keyboard.up( 'Shift' );
342
-
343
- await page.waitForSelector( '.is-multi-selected' );
344
- const selectedBlocks = await page.$$( '.is-multi-selected' );
345
- expect( selectedBlocks ).toHaveLength( 2 );
346
- } );
347
- it( 'should properly select part of nested rich text block while holding shift', async () => {
348
- await clickBlockAppender();
349
- await page.keyboard.type( 'rich text in group' );
350
- await transformBlockTo( 'Group' );
351
- await page.keyboard.press( 'ArrowDown' );
352
-
353
- await page.keyboard.down( 'Shift' );
354
- const paragraph = await page.$( '[data-type="core/paragraph"]' );
355
- const { x, y } = await paragraph.boundingBox();
356
- await page.mouse.move( x + 20, y );
357
- await page.mouse.down();
358
- await page.keyboard.up( 'Shift' );
359
- await page.mouse.up();
360
- await page.keyboard.type( 'hi' );
361
- expect( await getEditedPostContent() ).toMatchInlineSnapshot( `
362
- "<!-- wp:group {"layout":{"type":"constrained"}} -->
363
- <div class="wp-block-group"><!-- wp:paragraph -->
364
- <p>hih text in group</p>
365
- <!-- /wp:paragraph --></div>
366
- <!-- /wp:group -->"
367
- ` );
368
- } );
369
-
370
- it( 'should select by dragging', async () => {
371
- await clickBlockAppender();
372
- await page.keyboard.type( '1' );
373
- await page.keyboard.press( 'Enter' );
374
- await page.keyboard.type( '2' );
375
- await page.keyboard.press( 'ArrowUp' );
376
-
377
- const [ paragraph1, paragraph2 ] = await page.$$(
378
- '[data-type="core/paragraph"]'
379
- );
380
- const coord1 = await paragraph1.clickablePoint();
381
- const coord2 = await paragraph2.clickablePoint();
382
-
383
- await page.mouse.move( coord1.x, coord1.y );
384
- await page.mouse.down();
385
- await page.mouse.move( coord2.x, coord2.y, { steps: 10 } );
386
- await page.mouse.up();
387
-
388
- await testNativeSelection();
389
- expect( await getSelectedFlatIndices() ).toEqual( [ 1, 2 ] );
390
- } );
391
-
392
- it( 'should select by dragging into nested block', async () => {
393
- await clickBlockAppender();
394
- await page.keyboard.type( '1' );
395
- await page.keyboard.press( 'Enter' );
396
- await page.keyboard.type( '/group' );
397
- await page.waitForXPath(
398
- '//button[@aria-selected="true"][text()="Group"]'
399
- );
400
- await page.keyboard.press( 'Enter' );
401
-
402
- // Select the default, selected Group layout from the variation picker.
403
- await page.click(
404
- 'button[aria-label="Group: Gather blocks in a container."]'
405
- );
406
-
407
- const groupAppender = await page.waitForSelector(
408
- '.block-editor-button-block-appender'
409
- );
410
- await groupAppender.click();
411
-
412
- const paragraphBlockButton = await page.waitForSelector(
413
- '.editor-block-list-item-paragraph'
414
- );
415
- await paragraphBlockButton.click();
416
-
417
- await page.keyboard.type( '2' );
418
-
419
- const [ paragraph1, paragraph2 ] = await page.$$(
420
- '[data-type="core/paragraph"]'
421
- );
422
- const coord1 = await paragraph1.clickablePoint();
423
- const coord2 = await paragraph2.clickablePoint();
424
-
425
- await page.mouse.move( coord1.x, coord1.y );
426
- await page.mouse.down();
427
- await page.mouse.move( coord2.x, coord2.y, { steps: 10 } );
428
- await page.mouse.up();
429
-
430
- expect( await getSelectedFlatIndices() ).toEqual( [ 1, 2 ] );
431
- } );
432
-
433
- it( 'should cut and paste', async () => {
434
- await clickBlockAppender();
435
- await page.keyboard.type( '1' );
436
- await page.keyboard.press( 'Enter' );
437
- await page.keyboard.type( '2' );
438
- await pressKeyWithModifier( 'primary', 'a' );
439
- await pressKeyWithModifier( 'primary', 'a' );
440
- await pressKeyWithModifier( 'primary', 'x' );
441
-
442
- expect( await getEditedPostContent() ).toMatchSnapshot();
443
-
444
- await pressKeyWithModifier( 'primary', 'v' );
445
-
446
- expect( await getEditedPostContent() ).toMatchSnapshot();
447
- } );
448
-
449
- it( 'should copy and paste', async () => {
450
- await clickBlockAppender();
451
- await page.keyboard.type( '1' );
452
- await page.keyboard.press( 'Enter' );
453
- await page.keyboard.type( '2' );
454
- await pressKeyWithModifier( 'primary', 'a' );
455
- await pressKeyWithModifier( 'primary', 'a' );
456
- await pressKeyWithModifier( 'primary', 'c' );
457
-
458
- expect( await getEditedPostContent() ).toMatchSnapshot();
459
-
460
- await page.keyboard.press( 'Backspace' );
461
-
462
- expect( await getEditedPostContent() ).toMatchSnapshot();
463
-
464
- await pressKeyWithModifier( 'primary', 'v' );
465
-
466
- expect( await getEditedPostContent() ).toMatchSnapshot();
467
- } );
468
-
469
- it( 'should return original focus after failed multi selection attempt', async () => {
470
- await clickBlockAppender();
471
- await page.keyboard.type( '1' );
472
- await page.keyboard.type( '2' );
473
- await page.keyboard.press( 'ArrowLeft' );
474
-
475
- const [ coord1, coord2 ] = await page.evaluate( () => {
476
- const selection = window.getSelection();
477
-
478
- if ( ! selection.rangeCount ) {
479
- return;
480
- }
481
-
482
- const range = selection.getRangeAt( 0 );
483
- const rect1 = range.getClientRects()[ 0 ];
484
- const element = document.querySelector(
485
- '[data-type="core/paragraph"]'
486
- );
487
- const rect2 = element.getBoundingClientRect();
488
-
489
- return [
490
- {
491
- x: rect1.x,
492
- y: rect1.y + rect1.height / 2,
493
- },
494
- {
495
- // Move a bit outside the paragraph.
496
- x: rect2.x - 5,
497
- y: rect2.y + rect2.height / 2,
498
- },
499
- ];
500
- } );
501
-
502
- await page.mouse.move( coord1.x, coord1.y );
503
- await page.mouse.down();
504
- await page.mouse.move( coord2.x, coord2.y, { steps: 10 } );
505
- await page.mouse.up();
506
-
507
- // Wait for the selection to update.
508
- await page.evaluate(
509
- () => new Promise( window.requestAnimationFrame )
510
- );
511
-
512
- // Only "1" should be deleted.
513
- await page.keyboard.press( 'Backspace' );
514
-
515
- expect( await getEditedPostContent() ).toMatchSnapshot();
516
- } );
517
-
518
- it( 'should preserve dragged selection on move', async () => {
519
- await clickBlockAppender();
520
- await page.keyboard.type( '1' );
521
- await page.keyboard.press( 'Enter' );
522
- await page.keyboard.type( '2' );
523
- await page.keyboard.press( 'Enter' );
524
- await page.keyboard.type( '3' );
525
-
526
- const paragraphs = await page.$$( '[data-type="core/paragraph"]' );
527
- const coord1 = await paragraphs[ 2 ].clickablePoint();
528
- const coord2 = await paragraphs[ 1 ].clickablePoint();
529
-
530
- await page.mouse.move( coord1.x, coord1.y );
531
- await page.mouse.down();
532
- await page.mouse.move( coord2.x, coord2.y );
533
- await page.mouse.up();
534
-
535
- await testNativeSelection();
536
- expect( await getSelectedFlatIndices() ).toEqual( [ 2, 3 ] );
537
-
538
- await clickBlockToolbarButton( 'Move up' );
539
-
540
- await testNativeSelection();
541
- expect( await getSelectedFlatIndices() ).toEqual( [ 1, 2 ] );
542
-
543
- expect( await getEditedPostContent() ).toMatchSnapshot();
544
- } );
545
-
546
- it( 'should clear selection when clicking next to blocks', async () => {
547
- await clickBlockAppender();
548
- await page.keyboard.type( '1' );
549
- await page.keyboard.press( 'Enter' );
550
- await page.keyboard.type( '2' );
551
- await pressKeyWithModifier( 'shift', 'ArrowUp' );
552
- await testNativeSelection();
553
- expect( await getSelectedFlatIndices() ).toEqual( [ 1, 2 ] );
554
- const paragraph = await page.$( '[data-type="core/paragraph"]' );
555
- const rect = await paragraph.boundingBox();
556
- const coord = {
557
- x: rect.x - 1,
558
- y: rect.y + rect.height / 2,
559
- };
560
-
561
- await page.mouse.click( coord.x, coord.y );
562
-
563
- // Wait for blocks to have updated asynchronously.
564
- await page.evaluate( () => new Promise( window.requestIdleCallback ) );
565
- await testNativeSelection();
566
- expect( await getSelectedFlatIndices() ).toEqual( [] );
567
-
568
- expect( await getEditedPostContent() ).toMatchSnapshot();
569
- } );
570
-
571
- it( 'should place the caret at the end of last pasted paragraph (paste to empty editor)', async () => {
572
- await clickBlockAppender();
573
- await page.keyboard.type( 'first paragraph' );
574
- await page.keyboard.press( 'Enter' );
575
- await page.keyboard.type( 'second paragraph' );
576
- await pressKeyWithModifier( 'primary', 'a' );
577
- await pressKeyWithModifier( 'primary', 'a' );
578
- await pressKeyWithModifier( 'primary', 'c' );
579
- await page.keyboard.press( 'Backspace' );
580
- await pressKeyWithModifier( 'primary', 'v' );
581
- await page.keyboard.press( 'Backspace' );
582
-
583
- expect( await getEditedPostContent() ).toMatchSnapshot();
584
- } );
585
-
586
- it( 'should place the caret at the end of last pasted paragraph (paste mid-block)', async () => {
587
- await clickBlockAppender();
588
- await page.keyboard.type( 'first paragraph' );
589
- await page.keyboard.press( 'Enter' );
590
- await page.keyboard.type( 'second paragraph' );
591
- await pressKeyWithModifier( 'primary', 'a' );
592
- await pressKeyWithModifier( 'primary', 'a' );
593
- await pressKeyWithModifier( 'primary', 'c' );
594
-
595
- await page.keyboard.press( 'ArrowRight' );
596
- await page.keyboard.press( 'ArrowLeft' );
597
- await page.keyboard.press( 'ArrowLeft' );
598
- await page.keyboard.press( 'ArrowLeft' );
599
-
600
- await pressKeyWithModifier( 'primary', 'v' );
601
- await page.keyboard.press( 'Backspace' );
602
-
603
- expect( await getEditedPostContent() ).toMatchSnapshot();
604
- } );
605
-
606
- it( 'should place the caret at the end of last pasted paragraph (replace)', async () => {
607
- await clickBlockAppender();
608
- await page.keyboard.type( 'first paragraph' );
609
- await page.keyboard.press( 'Enter' );
610
- await page.keyboard.type( 'second paragraph' );
611
- await pressKeyWithModifier( 'primary', 'a' );
612
- await pressKeyWithModifier( 'primary', 'a' );
613
- await pressKeyWithModifier( 'primary', 'c' );
614
- await pressKeyWithModifier( 'primary', 'v' );
615
- await page.keyboard.press( 'Backspace' );
616
-
617
- expect( await getEditedPostContent() ).toMatchSnapshot();
618
- } );
619
-
620
- it( 'should set attributes for multiple paragraphs', async () => {
621
- await clickBlockAppender();
622
- await page.keyboard.type( '1' );
623
- await page.keyboard.press( 'Enter' );
624
- await page.keyboard.type( '2' );
625
- await pressKeyWithModifier( 'primary', 'a' );
626
- await pressKeyWithModifier( 'primary', 'a' );
627
- await clickBlockToolbarButton( 'Align text' );
628
- await clickButton( 'Align text center' );
629
-
630
- expect( await getEditedPostContent() ).toMatchSnapshot();
631
- } );
632
-
633
- it( 'should copy multiple blocks', async () => {
634
- await clickBlockAppender();
635
- await page.keyboard.type( '1' );
636
- await page.keyboard.press( 'Enter' );
637
- await page.keyboard.type( '2' );
638
- await pressKeyWithModifier( 'primary', 'a' );
639
- await pressKeyWithModifier( 'primary', 'a' );
640
- await pressKeyWithModifier( 'primary', 'c' );
641
- await page.keyboard.press( 'ArrowUp' );
642
- await pressKeyWithModifier( 'primary', 'v' );
643
-
644
- expect( await getEditedPostContent() ).toMatchSnapshot();
645
- } );
646
-
647
- // Previously we would unexpectedly duplicate the block on Enter.
648
- it( 'should not multi select single block', async () => {
649
- await clickBlockAppender();
650
- await page.keyboard.type( '1' );
651
- await pressKeyWithModifier( 'primary', 'a' );
652
- await pressKeyWithModifier( 'primary', 'a' );
653
- await page.keyboard.press( 'Enter' );
654
-
655
- expect( await getEditedPostContent() ).toMatchSnapshot();
656
- } );
657
-
658
- it( 'should gradually multi-select', async () => {
659
- await clickBlockAppender();
660
- await page.keyboard.type( '/columns' );
661
- await page.waitForXPath(
662
- '//button[@aria-selected="true"][text()="Columns"]'
663
- );
664
- await page.keyboard.press( 'Enter' );
665
- // Select two columns.
666
- await page.keyboard.press( 'ArrowRight' );
667
- await page.keyboard.press( 'Enter' );
668
- // Navigate to appender.
669
- await page.keyboard.press( 'ArrowRight' );
670
- await page.keyboard.press( 'Enter' );
671
- // Wait for inserter results to appear and then select a paragraph.
672
- await page.waitForSelector(
673
- '.block-editor-inserter__quick-inserter-results .block-editor-block-types-list__item'
674
- );
675
- await page.keyboard.press( 'Tab' );
676
- await page.keyboard.press( 'Enter' );
677
- // Type two paragraphs
678
- await page.keyboard.type( '1' );
679
- await page.keyboard.press( 'Enter' );
680
- await page.keyboard.type( '2' );
681
-
682
- // Confirm correct setup: two columns with two paragraphs in the first.
683
- expect( await getEditedPostContent() ).toMatchSnapshot();
684
-
685
- await pressKeyWithModifier( 'primary', 'a' );
686
- await pressKeyWithModifier( 'primary', 'a' );
687
-
688
- await page.waitForSelector(
689
- '[data-type="core/paragraph"].is-multi-selected'
690
- );
691
-
692
- await pressKeyWithModifier( 'primary', 'a' );
693
-
694
- await page.waitForSelector( '[data-type="core/column"].is-selected' );
695
-
696
- await pressKeyWithModifier( 'primary', 'a' );
697
-
698
- await page.waitForSelector(
699
- '[data-type="core/column"].is-multi-selected'
700
- );
701
-
702
- await page.keyboard.press( 'Backspace' );
703
-
704
- // Expect both columns to be deleted.
705
- expect( await getEditedPostContent() ).toMatchSnapshot();
706
- } );
707
-
708
- it( 'should multi-select from within the list block', async () => {
709
- await clickBlockAppender();
710
- // Select a paragraph.
711
- await page.keyboard.type( '1' );
712
- await page.keyboard.press( 'Enter' );
713
- // Add a list.
714
- await page.keyboard.type( '/list' );
715
- await page.waitForXPath(
716
- '//button[@aria-selected="true"][text()="List"]'
717
- );
718
- await page.keyboard.press( 'Enter' );
719
- await page.keyboard.type( '1' );
720
-
721
- // Confirm correct setup: a paragraph and a list.
722
- expect( await getEditedPostContent() ).toMatchSnapshot();
723
-
724
- await pressKeyWithModifier( 'primary', 'a' );
725
- await pressKeyWithModifier( 'primary', 'a' );
726
- await pressKeyWithModifier( 'primary', 'a' );
727
-
728
- await page.waitForSelector(
729
- '[data-type="core/paragraph"].is-multi-selected'
730
- );
731
- } );
732
-
733
- it( 'should select all from empty selection', async () => {
734
- await clickBlockAppender();
735
-
736
- await page.keyboard.type( '1' );
737
- await page.keyboard.press( 'Enter' );
738
- await page.keyboard.type( '2' );
739
-
740
- // Confirm setup.
741
- expect( await getEditedPostContent() ).toMatchSnapshot();
742
-
743
- // Clear the selected block.
744
- await page.keyboard.press( 'Escape' );
745
- await page.keyboard.press( 'Escape' );
746
-
747
- await pressKeyWithModifier( 'primary', 'a' );
748
-
749
- await page.keyboard.press( 'Backspace' );
750
-
751
- // Expect both paragraphs to be deleted.
752
- expect( await getEditedPostContent() ).toMatchSnapshot();
753
- } );
754
-
755
- it( 'should select title if the cursor is on title', async () => {
756
- await clickBlockAppender();
757
-
758
- await page.keyboard.type( '1' );
759
- await page.keyboard.press( 'Enter' );
760
- await page.keyboard.type( '2' );
761
-
762
- await page.type( '.editor-post-title__input', 'Post title' );
763
-
764
- await pressKeyWithModifier( 'primary', 'a' );
765
- const selectedText = await page.evaluate( () => {
766
- return window.getSelection().toString();
767
- } );
768
- expect( selectedText ).toEqual( 'Post title' );
769
- } );
770
-
771
- it( 'should multi-select in the ListView component with shift + click', async () => {
772
- // Create four blocks.
773
- await clickBlockAppender();
774
- await page.keyboard.type( '1' );
775
- await page.keyboard.press( 'Enter' );
776
- await page.keyboard.type( '2' );
777
- await page.keyboard.press( 'Enter' );
778
- await page.keyboard.type( '3' );
779
- await page.keyboard.press( 'Enter' );
780
- await page.keyboard.type( '4' );
781
-
782
- // Open up the list view, and get a reference to each of the list items.
783
- await openListView();
784
- const navButtons = await page.$$(
785
- '.block-editor-list-view-block-select-button'
786
- );
787
-
788
- // Clicking on the second list item should result in the second block being selected.
789
- await navButtons[ 1 ].click();
790
- expect( await getSelectedFlatIndices() ).toEqual( 2 );
791
-
792
- // Shift clicking the fourth list item should result in blocks 2 through 4 being selected.
793
- await page.keyboard.down( 'Shift' );
794
- await navButtons[ 3 ].click();
795
- expect( await getSelectedFlatIndices() ).toEqual( [ 2, 3, 4 ] );
796
-
797
- // With the shift key still held down, clicking the first block should result in
798
- // the first two blocks being selected.
799
- await navButtons[ 0 ].click();
800
- expect( await getSelectedFlatIndices() ).toEqual( [ 1, 2 ] );
801
-
802
- // With the shift key up, clicking the fourth block should result in only that block
803
- // being selected.
804
- await page.keyboard.up( 'Shift' );
805
- await navButtons[ 3 ].click();
806
- expect( await getSelectedFlatIndices() ).toEqual( 4 );
807
- } );
808
-
809
- it( 'should multi-select in the ListView component with shift + up and down keys', async () => {
810
- // Create four blocks.
811
- await clickBlockAppender();
812
- await page.keyboard.type( '1' );
813
- await page.keyboard.press( 'Enter' );
814
- await page.keyboard.type( '2' );
815
- await page.keyboard.press( 'Enter' );
816
- await page.keyboard.type( '3' );
817
- await page.keyboard.press( 'Enter' );
818
- await page.keyboard.type( '4' );
819
-
820
- // Open up the list view. The fourth block button will be focused.
821
- await openListView();
822
-
823
- // Press Up twice to focus over the second block.
824
- await pressKeyTimes( 'ArrowUp', 2 );
825
-
826
- // Shift + press Down to select the 2nd and 3rd blocks.
827
- await page.keyboard.down( 'Shift' );
828
- await page.keyboard.press( 'ArrowDown' );
829
- expect( await getSelectedFlatIndices() ).toEqual( [ 2, 3 ] );
830
-
831
- // Press Down once more to also select the 4th block.
832
- await page.keyboard.press( 'ArrowDown' );
833
- expect( await getSelectedFlatIndices() ).toEqual( [ 2, 3, 4 ] );
834
-
835
- // Press Up three times to adjust the selection to only include the first two blocks.
836
- await pressKeyTimes( 'ArrowUp', 3 );
837
- expect( await getSelectedFlatIndices() ).toEqual( [ 1, 2 ] );
838
-
839
- // Raise the shift key
840
- await page.keyboard.up( 'Shift' );
841
-
842
- // Navigate to the bottom of the list of blocks.
843
- await pressKeyTimes( 'ArrowDown', 3 );
844
-
845
- // Shift + press UP to select the 3rd and 4th blocks.
846
- // This tests that shift selecting blocks by keyboard that are not adjacent
847
- // to an existing selection resets the selection.
848
- await page.keyboard.down( 'Shift' );
849
- await page.keyboard.press( 'ArrowUp' );
850
- await page.keyboard.up( 'Shift' );
851
- expect( await getSelectedFlatIndices() ).toEqual( [ 3, 4 ] );
852
- } );
853
-
854
- it( 'should forward delete across blocks', async () => {
855
- await clickBlockAppender();
856
- await page.keyboard.type( '1[' );
857
- await page.keyboard.press( 'Enter' );
858
- await page.keyboard.type( '.' );
859
- await page.keyboard.press( 'Enter' );
860
- // "## " creates h2.
861
- await page.keyboard.type( '## ]2' );
862
- await page.keyboard.press( 'ArrowLeft' );
863
- // Select everything between [].
864
- await pressKeyWithModifier( 'shift', 'ArrowLeft' );
865
- await pressKeyWithModifier( 'shift', 'ArrowLeft' );
866
- await pressKeyWithModifier( 'shift', 'ArrowLeft' );
867
- await pressKeyWithModifier( 'shift', 'ArrowLeft' );
868
- await pressKeyWithModifier( 'shift', 'ArrowLeft' );
869
-
870
- // Test setup.
871
- expect( await getEditedPostContent() ).toMatchSnapshot();
872
-
873
- await page.keyboard.press( 'Delete' );
874
-
875
- // Ensure selection is in the correct place.
876
- await page.keyboard.type( '&' );
877
-
878
- // Expect a heading with "1&2" as its content.
879
- expect( await getEditedPostContent() ).toMatchSnapshot();
880
- } );
881
-
882
- it( 'should write over selection', async () => {
883
- await clickBlockAppender();
884
- await page.keyboard.type( '1[' );
885
- await page.keyboard.press( 'Enter' );
886
- await page.keyboard.type( ']2' );
887
- await page.keyboard.press( 'ArrowLeft' );
888
- // Select everything between [].
889
- await pressKeyWithModifier( 'shift', 'ArrowLeft' );
890
- await pressKeyWithModifier( 'shift', 'ArrowLeft' );
891
- await pressKeyWithModifier( 'shift', 'ArrowLeft' );
892
-
893
- // Test setup.
894
- expect( await getEditedPostContent() ).toMatchSnapshot();
895
-
896
- // Ensure selection is in the correct place.
897
- await page.keyboard.type( '...' );
898
-
899
- // Expect a heading with "1&2" as its content.
900
- expect( await getEditedPostContent() ).toMatchSnapshot();
901
- } );
902
-
903
- it( 'should handle Enter across blocks', async () => {
904
- await clickBlockAppender();
905
- await page.keyboard.type( '1[' );
906
- await page.keyboard.press( 'Enter' );
907
- await page.keyboard.type( '.' );
908
- await page.keyboard.press( 'Enter' );
909
- // "## " creates h2.
910
- await page.keyboard.type( '## ]2' );
911
- await page.keyboard.press( 'ArrowLeft' );
912
- // Select everything between [].
913
- await pressKeyWithModifier( 'shift', 'ArrowLeft' );
914
- await pressKeyWithModifier( 'shift', 'ArrowLeft' );
915
- await pressKeyWithModifier( 'shift', 'ArrowLeft' );
916
- await pressKeyWithModifier( 'shift', 'ArrowLeft' );
917
- await pressKeyWithModifier( 'shift', 'ArrowLeft' );
918
-
919
- // Test setup.
920
- expect( await getEditedPostContent() ).toMatchSnapshot();
921
-
922
- await page.keyboard.press( 'Enter' );
923
-
924
- // Ensure selection is in the correct place.
925
- await page.keyboard.type( '&' );
926
-
927
- // Expect two blocks with "&" in between.
928
- expect( await getEditedPostContent() ).toMatchSnapshot();
929
- } );
930
-
931
- it( 'should select separator (single element block)', async () => {
932
- await clickBlockAppender();
933
- await page.keyboard.type( 'a' );
934
- await page.keyboard.press( 'Enter' );
935
- await page.keyboard.press( 'Enter' );
936
- await page.keyboard.type( '/hr' );
937
- await page.waitForXPath(
938
- '//button[@aria-selected="true"][text()="Separator"]'
939
- );
940
- await page.keyboard.press( 'Enter' );
941
- await page.keyboard.press( 'ArrowUp' );
942
- await page.keyboard.press( 'ArrowUp' );
943
- await page.keyboard.press( 'ArrowRight' );
944
- await pressKeyWithModifier( 'shift', 'ArrowDown' );
945
- await pressKeyWithModifier( 'shift', 'ArrowDown' );
946
-
947
- // Test setup.
948
- expect( await getEditedPostContent() ).toMatchSnapshot();
949
-
950
- await page.keyboard.press( 'Backspace' );
951
-
952
- // Ensure selection is in the correct place.
953
- await page.keyboard.type( '&' );
954
-
955
- // Expect a paragraph with "&".
956
- expect( await getEditedPostContent() ).toMatchSnapshot();
957
- } );
958
-
959
- it( 'should partially select with shift + click', async () => {
960
- await clickBlockAppender();
961
- await pressKeyWithModifier( 'primary', 'b' );
962
- await page.keyboard.type( '1' );
963
- await pressKeyWithModifier( 'primary', 'b' );
964
- await page.keyboard.type( '[' );
965
- await page.keyboard.press( 'Enter' );
966
- await page.keyboard.type( ']2' );
967
- await page.keyboard.press( 'ArrowLeft' );
968
- await page.keyboard.down( 'Shift' );
969
- await page.click( 'strong' );
970
- await page.keyboard.up( 'Shift' );
971
-
972
- // Test setup.
973
- expect( await getEditedPostContent() ).toMatchSnapshot();
974
-
975
- await page.keyboard.press( 'Backspace' );
976
-
977
- // Ensure selection is in the correct place.
978
- await page.keyboard.type( '&' );
979
-
980
- // Expect two blocks with "&" in between.
981
- expect( await getEditedPostContent() ).toMatchSnapshot();
982
- } );
983
- describe( 'shift+click multi-selection', () => {
984
- it( 'should multi-select block with text selection and a block without text selection', async () => {
985
- await page.keyboard.press( 'Enter' );
986
- await page.keyboard.type( 'hi' );
987
- await page.keyboard.press( 'Enter' );
988
- await insertBlock( 'Spacer' );
989
- await page.keyboard.press( 'ArrowUp' );
990
-
991
- const spacerBlock = await page.waitForSelector(
992
- '.wp-block.wp-block-spacer'
993
- );
994
- const boundingBox = await spacerBlock.boundingBox();
995
- const mousePosition = {
996
- x: boundingBox.x + boundingBox.width / 2,
997
- y: boundingBox.y + boundingBox.height / 2,
998
- };
999
- await page.keyboard.down( 'Shift' );
1000
- await page.mouse.click( mousePosition.x, mousePosition.y );
1001
- await page.keyboard.up( 'Shift' );
1002
-
1003
- const selectedBlocks = await page.$$(
1004
- '.wp-block.is-multi-selected'
1005
- );
1006
- expect( selectedBlocks.length ).toBe( 2 );
1007
- } );
1008
- it( 'should multi-select blocks without text selection', async () => {
1009
- await insertBlock( 'Spacer' );
1010
- // Get the first spacer block element.
1011
- const spacerBlock = await page.waitForSelector(
1012
- '.wp-block.wp-block-spacer'
1013
- );
1014
- const boundingBox = await spacerBlock.boundingBox();
1015
- await page.keyboard.press( 'Enter' );
1016
- await insertBlock( 'Spacer' );
1017
- const mousePosition = {
1018
- x: boundingBox.x + boundingBox.width / 2,
1019
- y: boundingBox.y + boundingBox.height / 2,
1020
- };
1021
- await page.keyboard.down( 'Shift' );
1022
- await page.mouse.click( mousePosition.x, mousePosition.y );
1023
- await page.keyboard.up( 'Shift' );
1024
- const selectedBlocks = await page.$$(
1025
- '.wp-block.is-multi-selected'
1026
- );
1027
- expect( selectedBlocks.length ).toBe( 2 );
1028
- } );
1029
- } );
1030
-
1031
- it( 'should select by dragging into separator', async () => {
1032
- await clickBlockAppender();
1033
- await page.keyboard.type( '1' );
1034
- await insertBlock( 'Separator' );
1035
- await page.keyboard.press( 'ArrowUp' );
1036
-
1037
- const [ paragraph, hr ] = await page.$$( '[data-type]' );
1038
- const coord1 = await paragraph.clickablePoint();
1039
- const coord2 = await hr.clickablePoint();
1040
-
1041
- await page.mouse.move( coord1.x, coord1.y );
1042
- await page.mouse.down();
1043
- await page.mouse.move( coord2.x, coord2.y, { steps: 10 } );
1044
- await page.mouse.up();
1045
-
1046
- expect( await getSelectedFlatIndices() ).toEqual( [ 1, 2 ] );
1047
- } );
1048
- } );