@wordpress/e2e-tests 7.6.0 → 7.6.1

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.
@@ -0,0 +1,21 @@
1
+ <?php
2
+ /**
3
+ * Plugin Name: Gutenberg Test Plugin, No-cache Headers
4
+ * Plugin URI: https://github.com/WordPress/gutenberg
5
+ * Author: Gutenberg Team
6
+ *
7
+ * @package gutenberg-test-nocache-headers
8
+ */
9
+
10
+ // Remove 'no-store' from the Cache-Control header set by WordPress when running
11
+ // E2E tests. This is a workaround for an issue where E2E tests time out waiting
12
+ // for 'networkidle'.
13
+ add_filter(
14
+ 'nocache_headers',
15
+ static function( $headers ) {
16
+ $cache_control_parts = explode( ', ', $headers['Cache-Control'] );
17
+ $cache_control_parts = array_diff( $cache_control_parts, array( 'no-store' ) );
18
+ $headers['Cache-Control'] = implode( ', ', $cache_control_parts );
19
+ return $headers;
20
+ }
21
+ );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/e2e-tests",
3
- "version": "7.6.0",
3
+ "version": "7.6.1",
4
4
  "description": "End-To-End (E2E) tests for WordPress.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -23,11 +23,11 @@
23
23
  "node": ">=14"
24
24
  },
25
25
  "dependencies": {
26
- "@wordpress/e2e-test-utils": "^10.6.0",
27
- "@wordpress/jest-console": "^7.6.0",
28
- "@wordpress/jest-puppeteer-axe": "^6.6.0",
29
- "@wordpress/scripts": "^26.6.0",
30
- "@wordpress/url": "^3.36.0",
26
+ "@wordpress/e2e-test-utils": "^10.6.1",
27
+ "@wordpress/jest-console": "^7.6.1",
28
+ "@wordpress/jest-puppeteer-axe": "^6.6.1",
29
+ "@wordpress/scripts": "^26.6.1",
30
+ "@wordpress/url": "^3.36.1",
31
31
  "chalk": "^4.0.0",
32
32
  "expect-puppeteer": "^4.4.0",
33
33
  "filenamify": "^4.2.0",
@@ -45,5 +45,5 @@
45
45
  "publishConfig": {
46
46
  "access": "public"
47
47
  },
48
- "gitHead": "a92f606309b1541b834ff9b0a76ed2a466fc45ed"
48
+ "gitHead": "ce5639111c30763dbdf07f40eeb136ea6030ecf1"
49
49
  }
@@ -1,87 +1,46 @@
1
1
  ( function () {
2
- const { withSelect } = wp.data;
2
+ const { useSelect } = wp.data;
3
3
  const { registerBlockType } = wp.blocks;
4
4
  const { createElement: el } = wp.element;
5
5
  const { InnerBlocks } = wp.blockEditor;
6
- const __ = wp.i18n.__;
7
6
  const divProps = {
8
7
  className: 'product',
9
8
  style: { outline: '1px solid gray', padding: 5 },
10
9
  };
11
- const template = [
12
- [ 'core/image' ],
13
- [ 'core/paragraph', { placeholder: __( 'Add a description' ) } ],
14
- [ 'core/quote' ],
15
- ];
10
+
16
11
  const allowedBlocksWhenSingleEmptyChild = [ 'core/image', 'core/list' ];
17
12
  const allowedBlocksWhenMultipleChildren = [ 'core/gallery', 'core/video' ];
18
13
 
19
- const save = function () {
20
- return el( 'div', divProps, el( InnerBlocks.Content ) );
21
- };
22
- registerBlockType( 'test/allowed-blocks-unset', {
23
- title: 'Allowed Blocks Unset',
24
- icon: 'carrot',
25
- category: 'text',
26
-
27
- edit() {
28
- return el( 'div', divProps, el( InnerBlocks, { template } ) );
29
- },
30
-
31
- save,
32
- } );
33
-
34
- registerBlockType( 'test/allowed-blocks-set', {
35
- title: 'Allowed Blocks Set',
36
- icon: 'carrot',
37
- category: 'text',
38
-
39
- edit() {
40
- return el(
41
- 'div',
42
- divProps,
43
- el( InnerBlocks, {
44
- template,
45
- allowedBlocks: [
46
- 'core/button',
47
- 'core/gallery',
48
- 'core/list',
49
- 'core/media-text',
50
- 'core/quote',
51
- ],
52
- } )
53
- );
54
- },
55
-
56
- save,
57
- } );
58
-
59
14
  registerBlockType( 'test/allowed-blocks-dynamic', {
60
15
  title: 'Allowed Blocks Dynamic',
61
16
  icon: 'carrot',
62
17
  category: 'text',
63
18
 
64
- edit: withSelect( function ( select, ownProps ) {
65
- const getBlockOrder = select( 'core/block-editor' ).getBlockOrder;
66
- return {
67
- numberOfChildren: getBlockOrder( ownProps.clientId ).length,
68
- };
69
- } )( function ( props ) {
19
+ edit: function Edit( props ) {
20
+ const numberOfChildren = useSelect(
21
+ ( select ) => {
22
+ const { getBlockCount } = select( 'core/block-editor' );
23
+ return getBlockCount( props.clientId );
24
+ },
25
+ [ props.clientId ]
26
+ );
27
+
70
28
  return el(
71
29
  'div',
72
30
  {
73
31
  ...divProps,
74
- 'data-number-of-children': props.numberOfChildren,
32
+ 'data-number-of-children': numberOfChildren,
75
33
  },
76
34
  el( InnerBlocks, {
77
35
  allowedBlocks:
78
- props.numberOfChildren < 2
36
+ numberOfChildren < 2
79
37
  ? allowedBlocksWhenSingleEmptyChild
80
38
  : allowedBlocksWhenMultipleChildren,
81
39
  } )
82
40
  );
83
- } ),
84
-
85
- save,
41
+ },
42
+ save() {
43
+ return el( 'div', divProps, el( InnerBlocks.Content ) );
44
+ }
86
45
  } );
87
46
  } )();
@@ -12,7 +12,7 @@
12
12
  */
13
13
  function enqueue_inner_blocks_allowed_blocks_script() {
14
14
  wp_enqueue_script(
15
- 'gutenberg-test-block-icons',
15
+ 'gutenberg-test-inner-blocks-allowed-blocks',
16
16
  plugins_url( 'inner-blocks-allowed-blocks/index.js', __FILE__ ),
17
17
  array(
18
18
  'wp-blocks',
@@ -24,5 +24,4 @@ function enqueue_inner_blocks_allowed_blocks_script() {
24
24
  true
25
25
  );
26
26
  }
27
-
28
- add_action( 'init', 'enqueue_inner_blocks_allowed_blocks_script' );
27
+ add_action( 'enqueue_block_assets', 'enqueue_inner_blocks_allowed_blocks_script' );
@@ -90,7 +90,7 @@ describe( 'block editor keyboard shortcuts', () => {
90
90
  } );
91
91
  it( 'should prevent deleting multiple selected blocks from inputs', async () => {
92
92
  await clickBlockToolbarButton( 'Options' );
93
- await clickMenuItem( 'Create Reusable block' );
93
+ await clickMenuItem( 'Create pattern' );
94
94
  const reusableBlockNameInputSelector =
95
95
  '.reusable-blocks-menu-items__convert-modal .components-text-control__input';
96
96
  const nameInput = await page.waitForSelector(
@@ -585,7 +585,9 @@ describe( 'Links', () => {
585
585
 
586
586
  await editButton.click();
587
587
 
588
- // Tabbing back should land us in the text input.
588
+ // Tabbing forward should land us in the "Text" input.
589
+ await page.keyboard.press( 'Tab' );
590
+
589
591
  const textInputValue = await page.evaluate(
590
592
  () => document.activeElement.value
591
593
  );
@@ -612,7 +614,9 @@ describe( 'Links', () => {
612
614
  );
613
615
  await editButton.click();
614
616
 
615
- // Tabbing should land us in the text input.
617
+ // tab forward to the text input.
618
+ await page.keyboard.press( 'Tab' );
619
+
616
620
  const textInputValue = await page.evaluate(
617
621
  () => document.activeElement.value
618
622
  );
@@ -665,7 +669,9 @@ describe( 'Links', () => {
665
669
  await page.waitForXPath( `//label[text()='Open in new tab']` );
666
670
 
667
671
  // Move focus back to RichText for the underlying link.
668
- await pressKeyTimes( 'Tab', 4 );
672
+ await pressKeyWithModifier( 'shift', 'Tab' );
673
+ await pressKeyWithModifier( 'shift', 'Tab' );
674
+ await pressKeyWithModifier( 'shift', 'Tab' );
669
675
 
670
676
  // Make a selection within the RichText.
671
677
  await pressKeyWithModifier( 'shift', 'ArrowRight' );
@@ -23,6 +23,10 @@ const reusableBlockNameInputSelector =
23
23
  '.reusable-blocks-menu-items__convert-modal .components-text-control__input';
24
24
  const reusableBlockInspectorNameInputSelector =
25
25
  '.block-editor-block-inspector .components-text-control__input';
26
+ const syncToggleSelector =
27
+ '.reusable-blocks-menu-items__convert-modal .components-form-toggle__input';
28
+ const syncToggleSelectorChecked =
29
+ '.reusable-blocks-menu-items__convert-modal .components-form-toggle.is-checked';
26
30
 
27
31
  const saveAll = async () => {
28
32
  const publishButtonSelector =
@@ -193,7 +197,7 @@ describe( 'Reusable blocks', () => {
193
197
 
194
198
  // Convert block to a reusable block.
195
199
  await clickBlockToolbarButton( 'Options' );
196
- await clickMenuItem( 'Create Reusable block' );
200
+ await clickMenuItem( 'Create pattern' );
197
201
 
198
202
  // Set title.
199
203
  const nameInput = await page.waitForSelector(
@@ -201,11 +205,14 @@ describe( 'Reusable blocks', () => {
201
205
  );
202
206
  await nameInput.click();
203
207
  await page.keyboard.type( 'Multi-selection reusable block' );
208
+ const syncToggle = await page.waitForSelector( syncToggleSelector );
209
+ syncToggle.click();
210
+ await page.waitForSelector( syncToggleSelectorChecked );
204
211
  await page.keyboard.press( 'Enter' );
205
212
 
206
213
  // Wait for creation to finish.
207
214
  await page.waitForXPath(
208
- '//*[contains(@class, "components-snackbar")]/*[text()="Reusable block created."]'
215
+ '//*[contains(@class, "components-snackbar")]/*[text()="Synced Pattern created."]'
209
216
  );
210
217
 
211
218
  await clearAllBlocks();
@@ -259,7 +266,7 @@ describe( 'Reusable blocks', () => {
259
266
  // Save the reusable block.
260
267
  await page.click( publishButtonSelector );
261
268
  await page.waitForXPath(
262
- '//*[contains(@class, "components-snackbar")]/*[text()="Reusable block updated."]'
269
+ '//*[contains(@class, "components-snackbar")]/*[text()="Pattern updated."]'
263
270
  );
264
271
 
265
272
  await createNewPost();
@@ -340,12 +347,12 @@ describe( 'Reusable blocks', () => {
340
347
  await canvas().click( 'p[aria-label="Paragraph block"]' );
341
348
  await page.keyboard.type( '2' );
342
349
  const selector =
343
- '//div[@aria-label="Block: Reusable block"]//p[@aria-label="Paragraph block"][.="12"]';
350
+ '//div[@aria-label="Block: Pattern"]//p[@aria-label="Paragraph block"][.="12"]';
344
351
  const reusableBlockWithParagraph = await page.$x( selector );
345
352
  expect( reusableBlockWithParagraph ).toBeTruthy();
346
353
 
347
354
  // Convert back to regular blocks.
348
- await clickBlockToolbarButton( 'Select Reusable block' );
355
+ await clickBlockToolbarButton( 'Select Pattern' );
349
356
  await clickBlockToolbarButton( 'Convert to regular block' );
350
357
  await page.waitForXPath( selector, {
351
358
  hidden: true,
@@ -376,15 +383,18 @@ describe( 'Reusable blocks', () => {
376
383
 
377
384
  // Convert to reusable.
378
385
  await clickBlockToolbarButton( 'Options' );
379
- await clickMenuItem( 'Create Reusable block' );
386
+ await clickMenuItem( 'Create pattern' );
380
387
  const nameInput = await page.waitForSelector(
381
388
  reusableBlockNameInputSelector
382
389
  );
383
390
  await nameInput.click();
384
391
  await page.keyboard.type( 'Block with styles' );
392
+ const syncToggle = await page.waitForSelector( syncToggleSelector );
393
+ syncToggle.click();
394
+ await page.waitForSelector( syncToggleSelectorChecked );
385
395
  await page.keyboard.press( 'Enter' );
386
396
  const reusableBlock = await canvas().waitForSelector(
387
- '.block-editor-block-list__block[aria-label="Block: Reusable block"]'
397
+ '.block-editor-block-list__block[aria-label="Block: Pattern"]'
388
398
  );
389
399
  expect( reusableBlock ).toBeTruthy();
390
400
  } );
@@ -25,8 +25,8 @@ describe( 'RichText', () => {
25
25
  //
26
26
  // See: https://github.com/WordPress/gutenberg/issues/3091
27
27
  await insertBlock( 'Heading' );
28
- await page.waitForSelector( '[aria-label="Change heading level"]' );
29
- await page.click( '[aria-label="Change heading level"]' );
28
+ await page.waitForSelector( '[aria-label="Change level"]' );
29
+ await page.click( '[aria-label="Change level"]' );
30
30
  await page.click( '[aria-label="Heading 3"]' );
31
31
 
32
32
  expect( await getEditedPostContent() ).toMatchSnapshot();
@@ -16,13 +16,12 @@ describe( 'Front End Performance', () => {
16
16
  };
17
17
 
18
18
  beforeAll( async () => {
19
- await activateTheme( 'twentytwentythree' );
19
+ await activateTheme( 'gutenberg-test-themes/twentytwentythree' );
20
20
  await logout();
21
21
  } );
22
22
 
23
23
  afterAll( async () => {
24
24
  saveResultsFile( __filename, results );
25
- await activateTheme( 'twentytwentyone' );
26
25
  } );
27
26
 
28
27
  it( 'Report TTFB, LCP, and LCP-TTFB', async () => {
@@ -16,7 +16,7 @@ describe( 'Front End Performance', () => {
16
16
  };
17
17
 
18
18
  beforeAll( async () => {
19
- await activateTheme( 'twentytwentyone' );
19
+ await activateTheme( 'gutenberg-test-themes/twentytwentyone' );
20
20
  await logout();
21
21
  } );
22
22
 
@@ -7,6 +7,7 @@ import path from 'path';
7
7
  * WordPress dependencies
8
8
  */
9
9
  import {
10
+ activateTheme,
10
11
  createNewPost,
11
12
  saveDraft,
12
13
  insertBlock,
@@ -83,6 +84,11 @@ describe( 'Post Editor Performance', () => {
83
84
 
84
85
  let traceResults;
85
86
 
87
+ beforeAll( async () => {
88
+ // See https://github.com/WordPress/gutenberg/pull/50905/files#r1209014677;
89
+ await activateTheme( 'gutenberg-test-themes/twentytwentyone' );
90
+ } );
91
+
86
92
  afterAll( async () => {
87
93
  saveResultsFile( __filename, results );
88
94
  deleteFile( traceFilePath );
@@ -87,7 +87,6 @@ describe( 'Site Editor Performance', () => {
87
87
  saveResultsFile( __filename, results );
88
88
  await deleteAllTemplates( 'wp_template' );
89
89
  await deleteAllTemplates( 'wp_template_part' );
90
- await activateTheme( 'twentytwentyone' );
91
90
  } );
92
91
 
93
92
  // Number of loading measurements to take.
@@ -142,17 +141,21 @@ describe( 'Site Editor Performance', () => {
142
141
  postType: 'page',
143
142
  } );
144
143
 
145
- // Wait for the first paragraph to be ready.
146
- const firstParagraph = await canvas().waitForXPath(
147
- '//p[contains(text(), "Lorem ipsum dolor sit amet")]'
148
- );
144
+ // Wait for the first block to be ready.
145
+ await canvas().waitForSelector( '.wp-block' );
149
146
 
150
147
  // Get inside the post content.
151
148
  await enterEditMode();
152
149
 
153
- // Insert a new paragraph right under the first one.
154
- await firstParagraph.click(); // Once to select the block overlay.
155
- await firstParagraph.click(); // Once again to select the paragraph.
150
+ // Select the post content block wrapper.
151
+ await canvas().click( '.wp-block-post-content' );
152
+
153
+ // Select the first paragraph in the post content block.
154
+ const firstParagraph = await canvas().waitForXPath(
155
+ '//p[contains(text(), "Lorem ipsum dolor sit amet")]'
156
+ );
157
+ await firstParagraph.click();
158
+
156
159
  await insertBlock( 'Paragraph' );
157
160
 
158
161
  // Start tracing.
@@ -1,97 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import {
5
- activatePlugin,
6
- createNewPost,
7
- deactivatePlugin,
8
- getAllBlockInserterItemTitles,
9
- insertBlock,
10
- openGlobalBlockInserter,
11
- closeGlobalBlockInserter,
12
- clickBlockToolbarButton,
13
- canvas,
14
- } from '@wordpress/e2e-test-utils';
15
-
16
- describe( 'Allowed Blocks Setting on InnerBlocks', () => {
17
- const paragraphSelector =
18
- '.block-editor-rich-text__editable[data-type="core/paragraph"]';
19
- beforeAll( async () => {
20
- await activatePlugin( 'gutenberg-test-innerblocks-allowed-blocks' );
21
- } );
22
-
23
- beforeEach( async () => {
24
- await createNewPost();
25
- } );
26
-
27
- afterAll( async () => {
28
- await deactivatePlugin( 'gutenberg-test-innerblocks-allowed-blocks' );
29
- } );
30
-
31
- it( 'allows all blocks if the allowed blocks setting was not set', async () => {
32
- const parentBlockSelector = '[data-type="test/allowed-blocks-unset"]';
33
- const childParagraphSelector = `${ parentBlockSelector } ${ paragraphSelector }`;
34
- await insertBlock( 'Allowed Blocks Unset' );
35
- await closeGlobalBlockInserter();
36
- await canvas().waitForSelector( childParagraphSelector );
37
- await canvas().click( childParagraphSelector );
38
- await openGlobalBlockInserter();
39
- await expect(
40
- (
41
- await getAllBlockInserterItemTitles()
42
- ).length
43
- ).toBeGreaterThan( 20 );
44
- } );
45
-
46
- it( 'allows the blocks if the allowed blocks setting was set', async () => {
47
- const parentBlockSelector = '[data-type="test/allowed-blocks-set"]';
48
- const childParagraphSelector = `${ parentBlockSelector } ${ paragraphSelector }`;
49
- await insertBlock( 'Allowed Blocks Set' );
50
- await closeGlobalBlockInserter();
51
- await canvas().waitForSelector( childParagraphSelector );
52
- await canvas().click( childParagraphSelector );
53
- await openGlobalBlockInserter();
54
- const allowedBlocks = await getAllBlockInserterItemTitles();
55
- expect( allowedBlocks.sort() ).toEqual( [
56
- 'Button',
57
- 'Gallery',
58
- 'List',
59
- 'Media & Text',
60
- 'Quote',
61
- ] );
62
- } );
63
-
64
- it( 'correctly applies dynamic allowed blocks restrictions', async () => {
65
- await insertBlock( 'Allowed Blocks Dynamic' );
66
- await closeGlobalBlockInserter();
67
- const parentBlockSelector = '[data-type="test/allowed-blocks-dynamic"]';
68
- const blockAppender = '.block-list-appender button';
69
- const appenderSelector = `${ parentBlockSelector } ${ blockAppender }`;
70
- await canvas().waitForSelector( appenderSelector );
71
- await canvas().click( appenderSelector );
72
- expect( await getAllBlockInserterItemTitles() ).toEqual( [
73
- 'Image',
74
- 'List',
75
- ] );
76
- const insertButton = (
77
- await page.$x( `//button//span[contains(text(), 'List')]` )
78
- )[ 0 ];
79
- await insertButton.click();
80
- // Select the list wrapper so the image is insertable.
81
- await page.keyboard.press( 'ArrowUp' );
82
- await insertBlock( 'Image' );
83
- await closeGlobalBlockInserter();
84
- await page.waitForSelector( '.product[data-number-of-children="2"]' );
85
- await clickBlockToolbarButton( 'Select Allowed Blocks Dynamic' );
86
- // This focus shouldn't be neessary but there's a bug in trunk right now
87
- // Where if you open the inserter, don't do anything and click the "appender" on the canvas
88
- // the appender is not opened right away.
89
- // It needs to be investigated on its own.
90
- await page.focus( appenderSelector );
91
- await page.click( appenderSelector );
92
- expect( await getAllBlockInserterItemTitles() ).toEqual( [
93
- 'Gallery',
94
- 'Video',
95
- ] );
96
- } );
97
- } );
@@ -1,63 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`Navigating the block hierarchy should appear and function even without nested blocks 1`] = `
4
- "<!-- wp:paragraph -->
5
- <p>and I say hello</p>
6
- <!-- /wp:paragraph -->
7
-
8
- <!-- wp:image -->
9
- <figure class="wp-block-image"><img alt=""/></figure>
10
- <!-- /wp:image -->"
11
- `;
12
-
13
- exports[`Navigating the block hierarchy should navigate block hierarchy using only the keyboard 1`] = `
14
- "<!-- wp:columns -->
15
- <div class="wp-block-columns"><!-- wp:column -->
16
- <div class="wp-block-column"><!-- wp:paragraph -->
17
- <p>First column</p>
18
- <!-- /wp:paragraph --></div>
19
- <!-- /wp:column -->
20
-
21
- <!-- wp:column -->
22
- <div class="wp-block-column"></div>
23
- <!-- /wp:column -->
24
-
25
- <!-- wp:column -->
26
- <div class="wp-block-column"><!-- wp:paragraph -->
27
- <p>Third column</p>
28
- <!-- /wp:paragraph --></div>
29
- <!-- /wp:column --></div>
30
- <!-- /wp:columns -->"
31
- `;
32
-
33
- exports[`Navigating the block hierarchy should navigate using the list view sidebar 1`] = `
34
- "<!-- wp:columns -->
35
- <div class="wp-block-columns"><!-- wp:column -->
36
- <div class="wp-block-column"><!-- wp:paragraph -->
37
- <p>First column</p>
38
- <!-- /wp:paragraph --></div>
39
- <!-- /wp:column -->
40
-
41
- <!-- wp:column -->
42
- <div class="wp-block-column"></div>
43
- <!-- /wp:column -->
44
-
45
- <!-- wp:column -->
46
- <div class="wp-block-column"><!-- wp:paragraph -->
47
- <p>Third column</p>
48
- <!-- /wp:paragraph --></div>
49
- <!-- /wp:column --></div>
50
- <!-- /wp:columns -->"
51
- `;
52
-
53
- exports[`Navigating the block hierarchy should select the wrapper div for a group 1`] = `
54
- "<!-- wp:group {"layout":{"type":"constrained"}} -->
55
- <div class="wp-block-group"><!-- wp:paragraph -->
56
- <p>just a paragraph</p>
57
- <!-- /wp:paragraph -->
58
-
59
- <!-- wp:separator -->
60
- <hr class="wp-block-separator has-alpha-channel-opacity"/>
61
- <!-- /wp:separator --></div>
62
- <!-- /wp:group -->"
63
- `;
@@ -1,230 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import {
5
- createNewPost,
6
- insertBlock,
7
- getEditedPostContent,
8
- pressKeyTimes,
9
- pressKeyWithModifier,
10
- openDocumentSettingsSidebar,
11
- getListViewBlocks,
12
- switchBlockInspectorTab,
13
- canvas,
14
- } from '@wordpress/e2e-test-utils';
15
-
16
- async function openListViewSidebar() {
17
- await pressKeyWithModifier( 'access', 'o' );
18
- await page.waitForSelector( '.block-editor-list-view-leaf.is-selected' );
19
- }
20
-
21
- async function tabToColumnsControl() {
22
- let isColumnsControl = false;
23
- do {
24
- await page.keyboard.press( 'Tab' );
25
-
26
- const isBlockInspectorTab = await page.evaluate( () => {
27
- const activeElement = document.activeElement;
28
- return (
29
- activeElement.getAttribute( 'role' ) === 'tab' &&
30
- activeElement.attributes.getNamedItem( 'aria-label' ).value ===
31
- 'Styles'
32
- );
33
- } );
34
-
35
- if ( isBlockInspectorTab ) {
36
- await page.keyboard.press( 'ArrowRight' );
37
- }
38
-
39
- isColumnsControl = await page.evaluate( () => {
40
- const activeElement = document.activeElement;
41
- return (
42
- activeElement.tagName === 'INPUT' &&
43
- activeElement.attributes.getNamedItem( 'aria-label' ).value ===
44
- 'Columns'
45
- );
46
- } );
47
- } while ( ! isColumnsControl );
48
- }
49
-
50
- describe( 'Navigating the block hierarchy', () => {
51
- beforeEach( async () => {
52
- await createNewPost();
53
- } );
54
-
55
- it( 'should navigate using the list view sidebar', async () => {
56
- await insertBlock( 'Columns' );
57
- await canvas().click( '[aria-label="Two columns; equal split"]' );
58
-
59
- // Add a paragraph in the first column.
60
- await page.keyboard.press( 'ArrowDown' ); // Navigate to inserter.
61
- await page.keyboard.press( 'Enter' ); // Activate inserter.
62
- // Wait for inserter results to appear and then insert a paragraph.
63
- await page.waitForSelector(
64
- '.block-editor-inserter__quick-inserter-results .editor-block-list-item-paragraph'
65
- );
66
- await page.click( '.editor-block-list-item-paragraph' );
67
- await page.keyboard.type( 'First column' );
68
-
69
- // Navigate to the columns blocks.
70
- await page.click(
71
- '.edit-post-header-toolbar__document-overview-toggle'
72
- );
73
-
74
- const firstColumnsBlockMenuItem = (
75
- await getListViewBlocks( 'Columns' )
76
- )[ 0 ];
77
- await firstColumnsBlockMenuItem.click();
78
-
79
- // Tweak the columns count.
80
- await openDocumentSettingsSidebar();
81
- await switchBlockInspectorTab( 'Settings' );
82
- await page.focus(
83
- '.block-editor-block-inspector [aria-label="Columns"][type="number"]'
84
- );
85
- await page.keyboard.down( 'Shift' );
86
- await page.keyboard.press( 'ArrowLeft' );
87
- await page.keyboard.up( 'Shift' );
88
- await page.keyboard.type( '3' );
89
-
90
- // Wait for the new column block to appear in the list view
91
- // 5 = Columns, Column, Paragraph, Column, *Column*
92
- await page.waitForSelector(
93
- 'tr.block-editor-list-view-leaf:nth-of-type(5)'
94
- );
95
-
96
- // Navigate to the last column block.
97
- const lastColumnBlockMenuItem = (
98
- await getListViewBlocks( 'Column' )
99
- )[ 2 ];
100
- await lastColumnBlockMenuItem.click();
101
-
102
- // Insert text in the last column block.
103
- await page.keyboard.press( 'ArrowDown' ); // Navigate to inserter.
104
- await page.keyboard.press( 'Enter' ); // Activate inserter.
105
- // Wait for inserter results to appear and then insert a paragraph.
106
- await page.waitForSelector(
107
- '.block-editor-inserter__quick-inserter-results .editor-block-list-item-paragraph'
108
- );
109
- await page.click( '.editor-block-list-item-paragraph' );
110
- await page.keyboard.type( 'Third column' );
111
-
112
- expect( await getEditedPostContent() ).toMatchSnapshot();
113
- } );
114
-
115
- it( 'should navigate block hierarchy using only the keyboard', async () => {
116
- await insertBlock( 'Columns' );
117
- await openDocumentSettingsSidebar();
118
- await canvas().click( '[aria-label="Two columns; equal split"]' );
119
-
120
- // Add a paragraph in the first column.
121
- await page.keyboard.press( 'ArrowDown' ); // Navigate to inserter.
122
- await page.keyboard.press( 'Enter' ); // Activate inserter.
123
- // Wait for inserter results to appear and then insert a paragraph.
124
- await page.waitForSelector(
125
- '.block-editor-inserter__quick-inserter-results .editor-block-list-item-paragraph'
126
- );
127
- await page.click( '.editor-block-list-item-paragraph' );
128
- await page.keyboard.type( 'First column' );
129
-
130
- // Navigate to the columns blocks using the keyboard.
131
- await openListViewSidebar();
132
- await pressKeyTimes( 'ArrowUp', 2 );
133
- await page.keyboard.press( 'Enter' );
134
-
135
- // Move focus to the sidebar area.
136
- await pressKeyWithModifier( 'ctrl', '`' );
137
- await tabToColumnsControl();
138
-
139
- // Tweak the columns count by increasing it by one.
140
- await page.keyboard.press( 'ArrowRight' );
141
-
142
- // Navigate to the third column in the columns block.
143
- await pressKeyWithModifier( 'ctrlShift', '`' );
144
- await pressKeyWithModifier( 'ctrlShift', '`' );
145
- await pressKeyTimes( 'Tab', 3 );
146
- await pressKeyTimes( 'ArrowDown', 4 );
147
- await canvas().waitForSelector(
148
- '.is-highlighted[aria-label="Block: Column (3 of 3)"]'
149
- );
150
- await page.keyboard.press( 'Enter' );
151
- await canvas().waitForSelector(
152
- '.is-selected[data-type="core/column"]'
153
- );
154
-
155
- // Insert text in the last column block.
156
- await page.keyboard.press( 'ArrowDown' ); // Navigate to inserter.
157
- await page.keyboard.press( 'Enter' ); // Activate inserter.
158
- // Wait for inserter results to appear and then insert a paragraph.
159
- await page.waitForSelector(
160
- '.block-editor-inserter__quick-inserter-results .editor-block-list-item-paragraph'
161
- );
162
- await page.click( '.editor-block-list-item-paragraph' );
163
- await page.keyboard.type( 'Third column' );
164
-
165
- expect( await getEditedPostContent() ).toMatchSnapshot();
166
- } );
167
-
168
- it( 'should appear and function even without nested blocks', async () => {
169
- const textString = 'You say goodbye';
170
-
171
- await insertBlock( 'Paragraph' );
172
-
173
- // Add content so there is a block in the hierarchy.
174
- await page.keyboard.type( textString );
175
-
176
- // Create an image block too.
177
- await page.keyboard.press( 'Enter' );
178
- await insertBlock( 'Image' );
179
-
180
- // Return to first block.
181
- await openListViewSidebar();
182
- await page.keyboard.press( 'ArrowUp' );
183
- await page.keyboard.press( 'Space' );
184
-
185
- // Replace its content.
186
- await pressKeyWithModifier( 'primary', 'a' );
187
- await page.keyboard.type( 'and I say hello' );
188
-
189
- expect( await getEditedPostContent() ).toMatchSnapshot();
190
- } );
191
-
192
- it( 'should select the wrapper div for a group', async () => {
193
- // Insert a group block.
194
- await insertBlock( 'Group' );
195
- // Select the default, selected Group layout from the variation picker.
196
- await canvas().click(
197
- 'button[aria-label="Group: Gather blocks in a container."]'
198
- );
199
- // Insert some random blocks.
200
- // The last block shouldn't be a textual block.
201
- await canvas().click( '.block-list-appender .block-editor-inserter' );
202
- const paragraphMenuItem = (
203
- await page.$x( `//button//span[contains(text(), 'Paragraph')]` )
204
- )[ 0 ];
205
- await paragraphMenuItem.click();
206
- await page.keyboard.type( 'just a paragraph' );
207
- await insertBlock( 'Separator' );
208
-
209
- // Check the Group block content.
210
- expect( await getEditedPostContent() ).toMatchSnapshot();
211
-
212
- // Unselect the blocks.
213
- await canvas().click( '.editor-post-title' );
214
-
215
- // Try selecting the group block using the Outline.
216
- await page.click(
217
- '.edit-post-header-toolbar__document-overview-toggle'
218
- );
219
- const groupMenuItem = ( await getListViewBlocks( 'Group' ) )[ 0 ];
220
- await groupMenuItem.click();
221
-
222
- // The group block's wrapper should be selected.
223
- const isGroupBlockSelected = await canvas().evaluate(
224
- () =>
225
- document.activeElement.getAttribute( 'data-type' ) ===
226
- 'core/group'
227
- );
228
- expect( isGroupBlockSelected ).toBe( true );
229
- } );
230
- } );
@@ -1,104 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import { createNewPost, pressKeyWithModifier } from '@wordpress/e2e-test-utils';
5
-
6
- async function isInBlockToolbar() {
7
- return await page.evaluate( () => {
8
- return !! document.activeElement.closest(
9
- '.block-editor-block-toolbar'
10
- );
11
- } );
12
- }
13
-
14
- describe( 'Block Toolbar', () => {
15
- beforeEach( async () => {
16
- await createNewPost();
17
- } );
18
-
19
- describe( 'Contextual Toolbar', () => {
20
- it( 'should not scroll page', async () => {
21
- while (
22
- await page.evaluate( () => {
23
- const { activeElement } =
24
- document.activeElement?.contentDocument ?? document;
25
- const scrollable =
26
- wp.dom.getScrollContainer( activeElement );
27
- return ! scrollable || scrollable.scrollTop === 0;
28
- } )
29
- ) {
30
- await page.keyboard.press( 'Enter' );
31
- }
32
-
33
- await page.keyboard.type( 'a' );
34
-
35
- const scrollTopBefore = await page.evaluate( () => {
36
- const { activeElement } =
37
- document.activeElement?.contentDocument ?? document;
38
- window.scrollContainer =
39
- wp.dom.getScrollContainer( activeElement );
40
- return window.scrollContainer.scrollTop;
41
- } );
42
-
43
- await pressKeyWithModifier( 'alt', 'F10' );
44
- expect( await isInBlockToolbar() ).toBe( true );
45
-
46
- const scrollTopAfter = await page.evaluate( () => {
47
- return window.scrollContainer.scrollTop;
48
- } );
49
- expect( scrollTopBefore ).toBe( scrollTopAfter );
50
- } );
51
-
52
- it( 'navigates into the toolbar by keyboard (Alt+F10)', async () => {
53
- // Assumes new post focus starts in title. Create first new
54
- // block by Enter.
55
- await page.keyboard.press( 'Enter' );
56
-
57
- // [TEMPORARY]: A new paragraph is not technically a block yet
58
- // until starting to type within it.
59
- await page.keyboard.type( 'Example' );
60
-
61
- // Upward.
62
- await pressKeyWithModifier( 'alt', 'F10' );
63
-
64
- expect( await isInBlockToolbar() ).toBe( true );
65
- } );
66
- } );
67
-
68
- describe( 'Unified Toolbar', () => {
69
- beforeEach( async () => {
70
- // Enable unified toolbar
71
- await page.evaluate( () => {
72
- const { select, dispatch } = wp.data;
73
- const isCurrentlyUnified =
74
- select( 'core/edit-post' ).isFeatureActive(
75
- 'fixedToolbar'
76
- );
77
- if ( ! isCurrentlyUnified ) {
78
- dispatch( 'core/edit-post' ).toggleFeature(
79
- 'fixedToolbar'
80
- );
81
- }
82
- } );
83
- } );
84
-
85
- it( 'navigates into the toolbar by keyboard (Alt+F10)', async () => {
86
- // Assumes new post focus starts in title. Create first new
87
- // block by Enter.
88
- await page.keyboard.press( 'Enter' );
89
-
90
- // [TEMPORARY]: A new paragraph is not technically a block yet
91
- // until starting to type within it.
92
- await page.keyboard.type( 'Example' );
93
-
94
- // Upward.
95
- await pressKeyWithModifier( 'alt', 'F10' );
96
-
97
- expect(
98
- await page.evaluate( () => {
99
- return document.activeElement.getAttribute( 'aria-label' );
100
- } )
101
- ).toBe( 'Show document tools' );
102
- } );
103
- } );
104
- } );