@wordpress/e2e-tests 3.1.1 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +2 -0
  3. package/config/flaky-tests-reporter.js +1 -0
  4. package/package.json +8 -6
  5. package/specs/editor/blocks/__snapshots__/buttons.test.js.snap +8 -0
  6. package/specs/editor/blocks/__snapshots__/navigation.test.js.snap +2 -2
  7. package/specs/editor/blocks/__snapshots__/separator.test.js.snap +1 -1
  8. package/specs/editor/blocks/buttons.test.js +10 -0
  9. package/specs/editor/blocks/columns.test.js +3 -3
  10. package/specs/editor/blocks/gallery.test.js +36 -6
  11. package/specs/editor/blocks/heading.test.js +1 -1
  12. package/specs/editor/blocks/navigation.test.js +370 -72
  13. package/specs/editor/plugins/annotations.test.js +63 -67
  14. package/specs/editor/various/__snapshots__/block-deletion.test.js.snap +20 -12
  15. package/specs/editor/various/__snapshots__/block-editor-keyboard-shortcuts.test.js.snap +26 -0
  16. package/specs/editor/various/__snapshots__/block-hierarchy-navigation.test.js.snap +1 -1
  17. package/specs/editor/various/__snapshots__/multi-block-selection.test.js.snap +122 -6
  18. package/specs/editor/various/__snapshots__/writing-flow.test.js.snap +6 -6
  19. package/specs/editor/various/autosave.test.js +3 -3
  20. package/specs/editor/various/block-deletion.test.js +1 -0
  21. package/specs/editor/various/block-editor-keyboard-shortcuts.test.js +3 -5
  22. package/specs/editor/various/block-hierarchy-navigation.test.js +10 -16
  23. package/specs/editor/various/block-locking.test.js +120 -0
  24. package/specs/editor/various/keyboard-navigable-blocks.test.js +23 -0
  25. package/specs/editor/various/list-view.test.js +139 -7
  26. package/specs/editor/various/multi-block-selection.test.js +153 -9
  27. package/specs/editor/various/post-editor-template-mode.test.js +1 -1
  28. package/specs/editor/various/toolbar-roving-tabindex.test.js +10 -4
  29. package/specs/editor/various/writing-flow.test.js +10 -5
  30. package/specs/experiments/blocks/comments-query.test.js +131 -0
  31. package/specs/experiments/navigation-editor.test.js +126 -121
  32. package/specs/performance/post-editor.test.js +4 -6
  33. package/specs/site-editor/iframe-rendering-mode.test.js +31 -0
  34. package/specs/site-editor/site-editor-export.test.js +2 -2
  35. package/specs/site-editor/style-variations.test.js +9 -7
  36. package/specs/site-editor/template-part.test.js +3 -1
  37. package/specs/editor/various/__snapshots__/copy-cut-paste-whole-blocks.test.js.snap +0 -125
  38. package/specs/editor/various/copy-cut-paste-whole-blocks.test.js +0 -187
  39. package/specs/editor/various/new-post.test.js +0 -99
  40. package/specs/widgets/customizing-widgets.test.js +0 -913
@@ -0,0 +1,120 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import {
5
+ createNewPost,
6
+ clickButton,
7
+ clickMenuItem,
8
+ clickBlockToolbarButton,
9
+ getEditedPostContent,
10
+ insertBlock,
11
+ } from '@wordpress/e2e-test-utils';
12
+
13
+ describe( 'Block Grouping', () => {
14
+ beforeEach( async () => {
15
+ await createNewPost();
16
+ } );
17
+
18
+ describe( 'General', () => {
19
+ it( 'can prevent removal', async () => {
20
+ await insertBlock( 'Paragraph' );
21
+ await page.keyboard.type( 'Some paragraph' );
22
+
23
+ await clickBlockToolbarButton( 'Options' );
24
+ await clickMenuItem( 'Lock' );
25
+
26
+ const [ checkbox ] = await page.$x(
27
+ '//label[contains(text(), "Prevent removal")]'
28
+ );
29
+ await checkbox.click();
30
+
31
+ await clickButton( 'Apply' );
32
+
33
+ const [ removeBlock ] = await page.$x(
34
+ '//*[@role="menu"]//*[text()="Remove Paragraph"]'
35
+ );
36
+
37
+ expect( removeBlock ).toBeFalsy();
38
+ } );
39
+
40
+ it( 'can disable movement', async () => {
41
+ await insertBlock( 'Paragraph' );
42
+ await page.keyboard.type( 'First paragraph' );
43
+
44
+ await insertBlock( 'Paragraph' );
45
+ await page.keyboard.type( 'Second paragraph' );
46
+
47
+ await clickBlockToolbarButton( 'Options' );
48
+ await clickMenuItem( 'Lock' );
49
+
50
+ const [ checkbox ] = await page.$x(
51
+ '//label[contains(text(), "Disable movement")]'
52
+ );
53
+ await checkbox.click();
54
+
55
+ await clickButton( 'Apply' );
56
+
57
+ // Hide options.
58
+ await clickBlockToolbarButton( 'Options' );
59
+
60
+ const blockMover = await page.$( '.block-editor-block-mover' );
61
+ expect( blockMover ).toBeNull();
62
+
63
+ const [ lockButton ] = await page.$x(
64
+ '//button[@aria-label="Unlock Paragraph"]'
65
+ );
66
+ expect( lockButton ).toBeTruthy();
67
+ } );
68
+
69
+ it( 'can lock everything', async () => {
70
+ await insertBlock( 'Paragraph' );
71
+ await page.keyboard.type( 'Some paragraph' );
72
+
73
+ await clickBlockToolbarButton( 'Options' );
74
+ await clickMenuItem( 'Lock' );
75
+
76
+ const [ checkbox ] = await page.$x(
77
+ '//label//*[contains(text(), "Lock all")]'
78
+ );
79
+ await checkbox.click();
80
+
81
+ await clickButton( 'Apply' );
82
+
83
+ expect( await getEditedPostContent() ).toMatchInlineSnapshot( `
84
+ "<!-- wp:paragraph {\\"lock\\":{\\"move\\":true,\\"remove\\":true}} -->
85
+ <p>Some paragraph</p>
86
+ <!-- /wp:paragraph -->"
87
+ ` );
88
+ } );
89
+
90
+ it( 'can unlock from toolbar', async () => {
91
+ await insertBlock( 'Paragraph' );
92
+ await page.keyboard.type( 'Some paragraph' );
93
+
94
+ await clickBlockToolbarButton( 'Options' );
95
+ await clickMenuItem( 'Lock' );
96
+
97
+ const [ lockCheckbox ] = await page.$x(
98
+ '//label//*[contains(text(), "Lock all")]'
99
+ );
100
+ await lockCheckbox.click();
101
+
102
+ await clickButton( 'Apply' );
103
+
104
+ await clickBlockToolbarButton( 'Unlock Paragraph' );
105
+
106
+ const [ unlockCheckbox ] = await page.$x(
107
+ '//label//*[contains(text(), "Lock all")]'
108
+ );
109
+ await unlockCheckbox.click();
110
+
111
+ await clickButton( 'Apply' );
112
+
113
+ expect( await getEditedPostContent() ).toMatchInlineSnapshot( `
114
+ "<!-- wp:paragraph {\\"lock\\":{\\"move\\":false,\\"remove\\":false}} -->
115
+ <p>Some paragraph</p>
116
+ <!-- /wp:paragraph -->"
117
+ ` );
118
+ } );
119
+ } );
120
+ } );
@@ -207,4 +207,27 @@ describe( 'Order of block keyboard navigation', () => {
207
207
  await page.keyboard.press( 'ArrowRight' );
208
208
  await expect( await getActiveLabel() ).toBe( 'Move up' );
209
209
  } );
210
+
211
+ it( 'allows the first element within a block to receive focus', async () => {
212
+ // Insert a image block.
213
+ await insertBlock( 'Image' );
214
+
215
+ // Make sure the upload button has focus.
216
+ const uploadButton = await page.waitForXPath(
217
+ '//button[contains( text(), "Upload" ) ]'
218
+ );
219
+ await expect( uploadButton ).toHaveFocus();
220
+
221
+ // Try to focus the image block wrapper.
222
+ await page.keyboard.press( 'ArrowUp' );
223
+ await expect( await getActiveLabel() ).toBe( 'Block: Image' );
224
+ } );
225
+
226
+ it( 'allows the block wrapper to gain focus for a group block instead of the first element', async () => {
227
+ // Insert a group block.
228
+ await insertBlock( 'Group' );
229
+
230
+ // If active label matches, that means focus did not change from group block wrapper.
231
+ await expect( await getActiveLabel() ).toBe( 'Block: Group' );
232
+ } );
210
233
  } );
@@ -72,8 +72,8 @@ describe( 'List view', () => {
72
72
  await pressKeyWithModifier( 'access', 'o' );
73
73
 
74
74
  // The last inserted paragraph block should be selected in List View.
75
- await page.waitForXPath(
76
- '//a[contains(., "Paragraph(selected block)")]'
75
+ await page.waitForSelector(
76
+ '.block-editor-list-view-block__contents-cell[aria-selected="true"][aria-label^="Paragraph"]'
77
77
  );
78
78
 
79
79
  // Go to the image block in list view.
@@ -81,17 +81,18 @@ describe( 'List view', () => {
81
81
  const listViewImageBlock = await page.waitForXPath(
82
82
  '//a[contains(., "Image")]'
83
83
  );
84
- expect( listViewImageBlock ).toHaveFocus();
84
+ await expect( listViewImageBlock ).toHaveFocus();
85
85
 
86
86
  // Select the image block in the canvas.
87
87
  await page.keyboard.press( 'Enter' );
88
88
 
89
- const canvasImageBlock = await page.waitForSelector(
90
- 'figure[aria-label="Block: Image"]'
89
+ const uploadButton = await page.waitForXPath(
90
+ '//button[contains( text(), "Upload" ) ]'
91
91
  );
92
- expect( canvasImageBlock ).toHaveFocus();
92
+ await expect( uploadButton ).toHaveFocus();
93
93
 
94
94
  // Delete the image block in the canvas.
95
+ await page.keyboard.press( 'ArrowUp' );
95
96
  await page.keyboard.press( 'Backspace' );
96
97
 
97
98
  // List view should have two rows.
@@ -103,6 +104,135 @@ describe( 'List view', () => {
103
104
  expect( console ).not.toHaveErrored();
104
105
  } );
105
106
 
107
+ // Check for regression of https://github.com/WordPress/gutenberg/issues/39026
108
+ it( 'should select previous block after removing selected one', async () => {
109
+ // Insert some blocks of different types.
110
+ await insertBlock( 'Image' );
111
+ await insertBlock( 'Heading' );
112
+ await insertBlock( 'Paragraph' );
113
+
114
+ // Open list view.
115
+ await openListView();
116
+
117
+ // The last inserted paragraph block should be selected in List View.
118
+ await page.waitForSelector(
119
+ '.block-editor-list-view-block__contents-cell[aria-selected="true"][aria-label^="Paragraph"]'
120
+ );
121
+
122
+ // Paragraph options button.
123
+ const paragraphOptionsButton = await page.waitForSelector(
124
+ 'tr.block-editor-list-view-leaf:last-child button[aria-label="Options for Paragraph block"]'
125
+ );
126
+
127
+ await paragraphOptionsButton.click();
128
+
129
+ const paragraphRemoveButton = await page.waitForXPath(
130
+ '//button[contains(., "Remove Paragraph")]'
131
+ );
132
+
133
+ // Remove paragraph.
134
+ await paragraphRemoveButton.click();
135
+
136
+ // Heading block should be selected as previous block.
137
+ await page.waitForSelector(
138
+ '.block-editor-list-view-block__contents-cell[aria-selected="true"][aria-label^="Heading"]'
139
+ );
140
+ } );
141
+
142
+ // Check for regression of https://github.com/WordPress/gutenberg/issues/39026
143
+ it( 'should select next block after removing the very first block', async () => {
144
+ // Insert some blocks of different types.
145
+ await insertBlock( 'Image' );
146
+ await insertBlock( 'Heading' );
147
+ await insertBlock( 'Paragraph' );
148
+
149
+ // Open list view.
150
+ await openListView();
151
+
152
+ // The last inserted paragraph block should be selected in List View.
153
+ await page.waitForSelector(
154
+ '.block-editor-list-view-block__contents-cell[aria-selected="true"][aria-label^="Paragraph"]'
155
+ );
156
+
157
+ // Go to the image block in list view.
158
+ await pressKeyTimes( 'ArrowUp', 2 );
159
+ await pressKeyTimes( 'Enter', 1 );
160
+
161
+ // Image block should have selected.
162
+ await page.waitForSelector(
163
+ '.block-editor-list-view-block__contents-cell[aria-selected="true"][aria-label^="Image"]'
164
+ );
165
+
166
+ // Image options dropdown.
167
+ const imageOptionsButton = await page.waitForSelector(
168
+ 'tr.block-editor-list-view-leaf:first-child button[aria-label="Options for Image block"]'
169
+ );
170
+
171
+ await imageOptionsButton.click();
172
+
173
+ const imageRemoveButton = await page.waitForXPath(
174
+ '//button[contains(., "Remove Image")]'
175
+ );
176
+
177
+ // Remove Image block.
178
+ await imageRemoveButton.click();
179
+
180
+ // Heading block should be selected as next block.
181
+ await page.waitForSelector(
182
+ '.block-editor-list-view-block__contents-cell[aria-selected="true"][aria-label^="Heading"]'
183
+ );
184
+ } );
185
+
186
+ /**
187
+ * When all the blocks gets removed from the editor, it inserts a default paragraph block;
188
+ * make sure that paragraph block gets selected after removing blocks from ListView.
189
+ */
190
+ it( 'should select default paragraph block after removing all blocks', async () => {
191
+ // Insert some blocks of different types.
192
+ await insertBlock( 'Image' );
193
+ await insertBlock( 'Heading' );
194
+
195
+ // Open list view.
196
+ await openListView();
197
+
198
+ // The last inserted heading block should be selected in List View.
199
+ const headingBlock = await page.waitForSelector(
200
+ '.block-editor-list-view-block__contents-cell[aria-selected="true"][aria-label^="Heading"]'
201
+ );
202
+
203
+ await headingBlock.click();
204
+
205
+ // Select all two blocks.
206
+ await pressKeyWithModifier( 'shift', 'ArrowUp' );
207
+
208
+ // Both Image and Heading blocks should have selected.
209
+ await page.waitForSelector(
210
+ '.block-editor-list-view-block__contents-cell[aria-selected="true"][aria-label^="Heading"]'
211
+ );
212
+ await page.waitForSelector(
213
+ '.block-editor-list-view-block__contents-cell[aria-selected="true"][aria-label^="Image"]'
214
+ );
215
+
216
+ const imageOptionsButton = await page.waitForSelector(
217
+ 'tr.block-editor-list-view-leaf:first-child button[aria-label="Options for Image block"]'
218
+ );
219
+
220
+ // Blocks options dropdown.
221
+ await imageOptionsButton.click();
222
+
223
+ const blocksRemoveButton = await page.waitForXPath(
224
+ '//button[contains(., "Remove blocks")]'
225
+ );
226
+
227
+ // Remove all blocks.
228
+ await blocksRemoveButton.click();
229
+
230
+ // Newly created default paragraph block should be selected.
231
+ await page.waitForSelector(
232
+ '.block-editor-list-view-block__contents-cell[aria-selected="true"][aria-label^="Paragraph"]'
233
+ );
234
+ } );
235
+
106
236
  it( 'should expand nested list items', async () => {
107
237
  // Insert some blocks of different types.
108
238
  await insertBlock( 'Cover' );
@@ -163,7 +293,9 @@ describe( 'List view', () => {
163
293
  await pressKeyWithModifier( 'access', 'o' );
164
294
 
165
295
  // The last inserted group block should be selected in list view.
166
- await page.waitForXPath( '//a[contains(., "Group(selected block)")]' );
296
+ await page.waitForSelector(
297
+ '.block-editor-list-view-block__contents-cell[aria-selected="true"][aria-label^="Group"]'
298
+ );
167
299
 
168
300
  // Press Home to go to the first inserted block (image).
169
301
  await page.keyboard.press( 'Home' );
@@ -79,14 +79,13 @@ async function testNativeSelection() {
79
79
 
80
80
  const firstElement = elements[ 0 ];
81
81
  const lastElement = elements[ elements.length - 1 ];
82
- const { startContainer, endContainer } = selection.getRangeAt( 0 );
83
82
 
84
- if ( ! firstElement.contains( startContainer ) ) {
85
- throw 'expected selection to start in the first selected block';
83
+ if ( ! selection.containsNode( firstElement, true ) ) {
84
+ throw 'expected selection to include in the first selected block';
86
85
  }
87
86
 
88
- if ( ! lastElement.contains( endContainer ) ) {
89
- throw 'expected selection to end in the last selected block';
87
+ if ( ! selection.containsNode( lastElement, true ) ) {
88
+ throw 'expected selection to include in the last selected block';
90
89
  }
91
90
  } );
92
91
  }
@@ -172,10 +171,10 @@ describe( 'Multi-block selection', () => {
172
171
  await page.keyboard.press( 'Enter' );
173
172
  await page.keyboard.type( '12' );
174
173
  await page.keyboard.press( 'ArrowLeft' );
175
- await pressKeyWithModifier( 'shift', 'ArrowRight' );
174
+ await pressKeyWithModifier( 'shift', 'ArrowLeft' );
176
175
  await pressKeyWithModifier( 'shift', 'ArrowUp' );
177
176
  await testNativeSelection();
178
- // This delete all blocks.
177
+ // This deletes all blocks.
179
178
  await page.keyboard.press( 'Backspace' );
180
179
 
181
180
  expect( await getEditedPostContent() ).toMatchSnapshot();
@@ -331,7 +330,6 @@ describe( 'Multi-block selection', () => {
331
330
  await page.keyboard.press( 'ArrowUp' );
332
331
  await page.keyboard.up( 'Shift' );
333
332
  await transformBlockTo( 'Group' );
334
- await page.keyboard.press( 'ArrowDown' );
335
333
 
336
334
  // Click the first paragraph in the first Group block while pressing `shift` key.
337
335
  const firstParagraph = await page.waitForXPath( "//p[text()='first']" );
@@ -355,6 +353,7 @@ describe( 'Multi-block selection', () => {
355
353
  await page.mouse.move( x + 20, y );
356
354
  await page.mouse.down();
357
355
  await page.keyboard.up( 'Shift' );
356
+ await page.mouse.up();
358
357
  await page.keyboard.type( 'hi' );
359
358
  expect( await getEditedPostContent() ).toMatchInlineSnapshot( `
360
359
  "<!-- wp:group -->
@@ -655,7 +654,6 @@ describe( 'Multi-block selection', () => {
655
654
  await page.keyboard.press( 'Enter' );
656
655
  // Select two columns.
657
656
  await page.keyboard.press( 'ArrowRight' );
658
- await page.keyboard.press( 'ArrowRight' );
659
657
  await page.keyboard.press( 'Enter' );
660
658
  // Navigate to appender.
661
659
  await page.keyboard.press( 'ArrowRight' );
@@ -831,4 +829,150 @@ describe( 'Multi-block selection', () => {
831
829
  await page.keyboard.up( 'Shift' );
832
830
  expect( await getSelectedFlatIndices() ).toEqual( [ 3, 4 ] );
833
831
  } );
832
+
833
+ it( 'should forward delete across blocks', async () => {
834
+ await clickBlockAppender();
835
+ await page.keyboard.type( '1[' );
836
+ await page.keyboard.press( 'Enter' );
837
+ await page.keyboard.type( '.' );
838
+ await page.keyboard.press( 'Enter' );
839
+ // "## " creates h2.
840
+ await page.keyboard.type( '## ]2' );
841
+ await page.keyboard.press( 'ArrowLeft' );
842
+ // Select everything between [].
843
+ await pressKeyWithModifier( 'shift', 'ArrowLeft' );
844
+ await pressKeyWithModifier( 'shift', 'ArrowLeft' );
845
+ await pressKeyWithModifier( 'shift', 'ArrowLeft' );
846
+ await pressKeyWithModifier( 'shift', 'ArrowLeft' );
847
+ await pressKeyWithModifier( 'shift', 'ArrowLeft' );
848
+
849
+ // Test setup.
850
+ expect( await getEditedPostContent() ).toMatchSnapshot();
851
+
852
+ await page.keyboard.press( 'Delete' );
853
+
854
+ // Ensure selection is in the correct place.
855
+ await page.keyboard.type( '&' );
856
+
857
+ // Expect a heading with "1&2" as its content.
858
+ expect( await getEditedPostContent() ).toMatchSnapshot();
859
+ } );
860
+
861
+ it( 'should write over selection', async () => {
862
+ await clickBlockAppender();
863
+ await page.keyboard.type( '1[' );
864
+ await page.keyboard.press( 'Enter' );
865
+ await page.keyboard.type( ']2' );
866
+ await page.keyboard.press( 'ArrowLeft' );
867
+ // Select everything between [].
868
+ await pressKeyWithModifier( 'shift', 'ArrowLeft' );
869
+ await pressKeyWithModifier( 'shift', 'ArrowLeft' );
870
+ await pressKeyWithModifier( 'shift', 'ArrowLeft' );
871
+
872
+ // Test setup.
873
+ expect( await getEditedPostContent() ).toMatchSnapshot();
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 handle Enter across blocks', async () => {
883
+ await clickBlockAppender();
884
+ await page.keyboard.type( '1[' );
885
+ await page.keyboard.press( 'Enter' );
886
+ await page.keyboard.type( '.' );
887
+ await page.keyboard.press( 'Enter' );
888
+ // "## " creates h2.
889
+ await page.keyboard.type( '## ]2' );
890
+ await page.keyboard.press( 'ArrowLeft' );
891
+ // Select everything between [].
892
+ await pressKeyWithModifier( 'shift', 'ArrowLeft' );
893
+ await pressKeyWithModifier( 'shift', 'ArrowLeft' );
894
+ await pressKeyWithModifier( 'shift', 'ArrowLeft' );
895
+ await pressKeyWithModifier( 'shift', 'ArrowLeft' );
896
+ await pressKeyWithModifier( 'shift', 'ArrowLeft' );
897
+
898
+ // Test setup.
899
+ expect( await getEditedPostContent() ).toMatchSnapshot();
900
+
901
+ await page.keyboard.press( 'Enter' );
902
+
903
+ // Ensure selection is in the correct place.
904
+ await page.keyboard.type( '&' );
905
+
906
+ // Expect two blocks with "&" in between.
907
+ expect( await getEditedPostContent() ).toMatchSnapshot();
908
+ } );
909
+
910
+ it( 'should merge into quote with correct selection', async () => {
911
+ await clickBlockAppender();
912
+ await page.keyboard.type( '> 1[' );
913
+ await page.keyboard.press( 'Enter' );
914
+ await page.keyboard.press( 'Enter' );
915
+ await page.keyboard.type( ']2' );
916
+ await page.keyboard.press( 'ArrowLeft' );
917
+ // Select everything between [].
918
+ await pressKeyWithModifier( 'shift', 'ArrowLeft' );
919
+ await pressKeyWithModifier( 'shift', 'ArrowLeft' );
920
+ await pressKeyWithModifier( 'shift', 'ArrowLeft' );
921
+
922
+ // Test setup.
923
+ expect( await getEditedPostContent() ).toMatchSnapshot();
924
+
925
+ await page.keyboard.press( 'Backspace' );
926
+
927
+ // Ensure selection is in the correct place.
928
+ await page.keyboard.type( '&' );
929
+
930
+ // Expect two blocks with "&" in between.
931
+ expect( await getEditedPostContent() ).toMatchSnapshot();
932
+ } );
933
+
934
+ it( 'should select separator (single element block)', async () => {
935
+ await clickBlockAppender();
936
+ await page.keyboard.type( '/hr' );
937
+ await page.keyboard.press( 'Enter' );
938
+ await page.keyboard.press( 'Enter' );
939
+ await page.keyboard.type( 'a' );
940
+ await pressKeyWithModifier( 'shift', 'ArrowUp' );
941
+
942
+ // Test setup.
943
+ expect( await getEditedPostContent() ).toMatchSnapshot();
944
+
945
+ await page.keyboard.press( 'Backspace' );
946
+
947
+ // Ensure selection is in the correct place.
948
+ await page.keyboard.type( '&' );
949
+
950
+ // Expect two blocks with "&" in between.
951
+ expect( await getEditedPostContent() ).toMatchSnapshot();
952
+ } );
953
+
954
+ it( 'should partially select with shift + click', async () => {
955
+ await clickBlockAppender();
956
+ await pressKeyWithModifier( 'primary', 'b' );
957
+ await page.keyboard.type( '1' );
958
+ await pressKeyWithModifier( 'primary', 'b' );
959
+ await page.keyboard.type( '[' );
960
+ await page.keyboard.press( 'Enter' );
961
+ await page.keyboard.type( ']2' );
962
+ await page.keyboard.press( 'ArrowLeft' );
963
+ await page.keyboard.down( 'Shift' );
964
+ await page.click( 'strong' );
965
+ await page.keyboard.up( 'Shift' );
966
+
967
+ // Test setup.
968
+ expect( await getEditedPostContent() ).toMatchSnapshot();
969
+
970
+ await page.keyboard.press( 'Backspace' );
971
+
972
+ // Ensure selection is in the correct place.
973
+ await page.keyboard.type( '&' );
974
+
975
+ // Expect two blocks with "&" in between.
976
+ expect( await getEditedPostContent() ).toMatchSnapshot();
977
+ } );
834
978
  } );
@@ -239,7 +239,7 @@ describe( 'Delete Post Template Confirmation Dialog', () => {
239
239
  if ( isWelcomeGuideActive === true ) {
240
240
  await page.evaluate( () =>
241
241
  wp.data
242
- .dispatch( 'core/edit-post' )
242
+ .dispatch( 'core/preferences' )
243
243
  .toggle( 'core/edit-post', 'welcomeGuide' )
244
244
  );
245
245
  await page.reload();
@@ -13,11 +13,17 @@ async function focusBlockToolbar() {
13
13
  }
14
14
 
15
15
  async function expectLabelToHaveFocus( label ) {
16
- await expect(
17
- await page.evaluate( () =>
16
+ let ariaLabel = await page.evaluate( () =>
17
+ document.activeElement.getAttribute( 'aria-label' )
18
+ );
19
+ // If the labels don't match, try pressing Up Arrow to focus the block wrapper in non-content editable block.
20
+ if ( ariaLabel !== label ) {
21
+ await page.keyboard.press( 'ArrowUp' );
22
+ ariaLabel = await page.evaluate( () =>
18
23
  document.activeElement.getAttribute( 'aria-label' )
19
- )
20
- ).toBe( label );
24
+ );
25
+ }
26
+ await expect( ariaLabel ).toBe( label );
21
27
  }
22
28
 
23
29
  async function testBlockToolbarKeyboardNavigation(
@@ -26,8 +26,8 @@ const addParagraphsAndColumnsDemo = async () => {
26
26
  `//*[contains(@class, "components-autocomplete__result") and contains(@class, "is-selected") and contains(text(), 'Columns')]`
27
27
  );
28
28
  await page.keyboard.press( 'Enter' );
29
- await page.click( ':focus [aria-label="Two columns; equal split"]' );
30
- await page.click( ':focus .block-editor-button-block-appender' );
29
+ await page.click( 'button[aria-label="Two columns; equal split"]' );
30
+ await page.click( '.block-editor-button-block-appender' );
31
31
  await page.waitForSelector( '.block-editor-inserter__search input:focus' );
32
32
  await page.keyboard.type( 'Paragraph' );
33
33
  await pressKeyTimes( 'Tab', 2 ); // Tab to paragraph result.
@@ -628,9 +628,12 @@ describe( 'Writing Flow', () => {
628
628
  `//button[contains(@class,'components-dropdown-menu__menu-item')]//span[contains(text(), 'Wide width')]`
629
629
  );
630
630
  await wideButton.click();
631
+ // Focus the block content
632
+ await page.keyboard.press( 'Tab' );
631
633
 
632
634
  // Select the previous block.
633
635
  await page.keyboard.press( 'ArrowUp' );
636
+ await page.keyboard.press( 'ArrowUp' );
634
637
 
635
638
  // Confirm correct setup.
636
639
  expect( await getEditedPostContent() ).toMatchSnapshot();
@@ -650,13 +653,17 @@ describe( 'Writing Flow', () => {
650
653
  const inserter = await page.$(
651
654
  '.block-editor-block-list__insertion-point'
652
655
  );
656
+ // Find the space between the inserter and the image block.
653
657
  const inserterRect = await inserter.boundingBox();
654
658
  const lowerInserterY = inserterRect.y + ( 2 * inserterRect.height ) / 3;
655
659
 
660
+ // Clicking that in-between space should select the image block.
656
661
  await page.mouse.click( x, lowerInserterY );
657
662
 
658
663
  const type = await page.evaluate( () =>
659
- document.activeElement.getAttribute( 'data-type' )
664
+ document.activeElement
665
+ .closest( '[data-block]' )
666
+ .getAttribute( 'data-type' )
660
667
  );
661
668
 
662
669
  expect( type ).toBe( 'core/image' );
@@ -666,8 +673,6 @@ describe( 'Writing Flow', () => {
666
673
  await page.keyboard.press( 'Enter' );
667
674
  await page.keyboard.type( '/table' );
668
675
  await page.keyboard.press( 'Enter' );
669
- // Move into the placeholder UI.
670
- await page.keyboard.press( 'ArrowDown' );
671
676
  // Tab to the "Create table" button.
672
677
  await page.keyboard.press( 'Tab' );
673
678
  await page.keyboard.press( 'Tab' );