@wordpress/e2e-tests 7.3.0 → 7.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 7.5.0 (2023-05-24)
6
+
7
+ ## 7.4.0 (2023-05-10)
8
+
5
9
  ## 7.3.0 (2023-04-26)
6
10
 
7
11
  ## 7.2.0 (2023-04-12)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/e2e-tests",
3
- "version": "7.3.0",
3
+ "version": "7.5.0",
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.3.0",
27
- "@wordpress/jest-console": "^7.3.0",
28
- "@wordpress/jest-puppeteer-axe": "^6.3.0",
29
- "@wordpress/scripts": "^26.3.0",
30
- "@wordpress/url": "^3.33.0",
26
+ "@wordpress/e2e-test-utils": "^10.5.0",
27
+ "@wordpress/jest-console": "^7.5.0",
28
+ "@wordpress/jest-puppeteer-axe": "^6.5.0",
29
+ "@wordpress/scripts": "^26.5.0",
30
+ "@wordpress/url": "^3.35.0",
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": "6df0c62d43b8901414ccd22ffbe56eaa99d012a6"
48
+ "gitHead": "c7c79cb11b677adcbf06cf5f8cfb6c5ec1699f19"
49
49
  }
@@ -0,0 +1,82 @@
1
+ ( function () {
2
+ const { registerBlockType } = wp.blocks;
3
+ const { createElement: el } = wp.element;
4
+ const { InnerBlocks } = wp.blockEditor;
5
+
6
+ const divProps = {
7
+ className: 'product',
8
+ style: { outline: '1px solid gray', padding: 5 },
9
+ };
10
+
11
+ // without a placeholder within the inner blocks it can be difficult to select the block using e2e tests
12
+ // especially using Puppeteer, so we use an image block which has a placeholder.
13
+ const template = [
14
+ [ 'core/image' ],
15
+ ];
16
+
17
+ const save = function () {
18
+ return el( 'div', divProps, el( InnerBlocks.Content ) );
19
+ };
20
+ registerBlockType( 'test/prioritized-inserter-blocks-unset', {
21
+ title: 'Prioritized Inserter Blocks Unset',
22
+ icon: 'carrot',
23
+ category: 'text',
24
+
25
+ edit() {
26
+ return el( 'div', divProps, el( InnerBlocks, { template } ) );
27
+ },
28
+
29
+ save,
30
+ } );
31
+
32
+ registerBlockType( 'test/prioritized-inserter-blocks-set', {
33
+ title: 'Prioritized Inserter Blocks Set',
34
+ icon: 'carrot',
35
+ category: 'text',
36
+ edit() {
37
+ return el(
38
+ 'div',
39
+ divProps,
40
+ el( InnerBlocks, {
41
+ template,
42
+ prioritizedInserterBlocks: [
43
+ 'core/audio',
44
+ 'core/spacer',
45
+ 'core/code',
46
+ ],
47
+ } )
48
+ );
49
+ },
50
+
51
+ save,
52
+ } );
53
+
54
+ registerBlockType( 'test/prioritized-inserter-blocks-set-with-conflicting-allowed-blocks', {
55
+ title: 'Prioritized Inserter Blocks Set With Conflicting Allowed Blocks',
56
+ icon: 'carrot',
57
+ category: 'text',
58
+ edit() {
59
+ return el(
60
+ 'div',
61
+ divProps,
62
+ el( InnerBlocks, {
63
+ template,
64
+ allowedBlocks: [
65
+ 'core/spacer',
66
+ 'core/code',
67
+ 'core/paragraph',
68
+ 'core/heading'
69
+ ],
70
+ prioritizedInserterBlocks: [
71
+ 'core/audio', // this is **not** in the allowedBlocks list
72
+ 'core/spacer',
73
+ 'core/code',
74
+ ],
75
+ } )
76
+ );
77
+ },
78
+
79
+ save,
80
+ } );
81
+
82
+ } )();
@@ -0,0 +1,28 @@
1
+ <?php
2
+ /**
3
+ * Plugin Name: Gutenberg Test InnerBlocks Prioritized Inserter Blocks
4
+ * Plugin URI: https://github.com/WordPress/gutenberg
5
+ * Author: Gutenberg Team
6
+ *
7
+ * @package gutenberg-test-inner-blocks-prioritized-inserter-blocks
8
+ */
9
+
10
+ /**
11
+ * Registers a custom script for the plugin.
12
+ */
13
+ function enqueue_inner_blocks_prioritized_inserter_blocks_script() {
14
+ wp_enqueue_script(
15
+ 'gutenberg-test-inner-blocks-prioritized-inserter-blocks',
16
+ plugins_url( 'inner-blocks-prioritized-inserter-blocks/index.js', __FILE__ ),
17
+ array(
18
+ 'wp-blocks',
19
+ 'wp-block-editor',
20
+ 'wp-element',
21
+ 'wp-i18n',
22
+ ),
23
+ filemtime( plugin_dir_path( __FILE__ ) . 'inner-blocks-prioritized-inserter-blocks/index.js' ),
24
+ true
25
+ );
26
+ }
27
+
28
+ add_action( 'init', 'enqueue_inner_blocks_prioritized_inserter_blocks_script' );
@@ -94,7 +94,7 @@
94
94
  PluginSidebar,
95
95
  {
96
96
  name: 'annotations-sidebar',
97
- title: __( 'Annotations Sidebar' ),
97
+ title: __( 'Annotations' ),
98
98
  },
99
99
  el( SidebarContents, {} )
100
100
  ),
@@ -103,7 +103,7 @@
103
103
  {
104
104
  target: 'annotations-sidebar',
105
105
  },
106
- __( 'Annotations Sidebar' )
106
+ __( 'Annotations' )
107
107
  )
108
108
  );
109
109
  }
@@ -70,7 +70,7 @@
70
70
  PluginSidebar,
71
71
  {
72
72
  name: 'title-sidebar',
73
- title: __( 'Plugin sidebar title' ),
73
+ title: __( 'Plugin title' ),
74
74
  },
75
75
  el( SidebarContents, {} )
76
76
  ),
@@ -79,7 +79,7 @@
79
79
  {
80
80
  target: 'title-sidebar',
81
81
  },
82
- __( 'Plugin sidebar more menu title' )
82
+ __( 'Plugin more menu title' )
83
83
  )
84
84
  );
85
85
  }
@@ -2,6 +2,6 @@
2
2
 
3
3
  exports[`Using Plugins API Document Setting Custom Panel Should render a custom panel inside Document Setting sidebar 1`] = `"My Custom Panel"`;
4
4
 
5
- exports[`Using Plugins API Sidebar Medium screen Should open plugins sidebar using More Menu item and render content 1`] = `"<div class="components-panel__header interface-complementary-area-header__small"><span class="interface-complementary-area-header__small-title">(no title)</span><button type="button" class="components-button has-icon" aria-label="Close plugin"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><path d="M12 13.06l3.712 3.713 1.061-1.06L13.061 12l3.712-3.712-1.06-1.06L12 10.938 8.288 7.227l-1.061 1.06L10.939 12l-3.712 3.712 1.06 1.061L12 13.061z"></path></svg></button></div><div class="components-panel__header interface-complementary-area-header" tabindex="-1"><strong>Plugin sidebar title</strong><button type="button" aria-pressed="true" aria-expanded="true" class="components-button interface-complementary-area__pin-unpin-item is-pressed has-icon" aria-label="Unpin from toolbar"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><path d="M11.776 4.454a.25.25 0 01.448 0l2.069 4.192a.25.25 0 00.188.137l4.626.672a.25.25 0 01.139.426l-3.348 3.263a.25.25 0 00-.072.222l.79 4.607a.25.25 0 01-.362.263l-4.138-2.175a.25.25 0 00-.232 0l-4.138 2.175a.25.25 0 01-.363-.263l.79-4.607a.25.25 0 00-.071-.222L4.754 9.881a.25.25 0 01.139-.426l4.626-.672a.25.25 0 00.188-.137l2.069-4.192z"></path></svg></button><button type="button" class="components-button has-icon" aria-label="Close plugin"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><path d="M12 13.06l3.712 3.713 1.061-1.06L13.061 12l3.712-3.712-1.06-1.06L12 10.938 8.288 7.227l-1.061 1.06L10.939 12l-3.712 3.712 1.06 1.061L12 13.061z"></path></svg></button></div><div class="components-panel"><div class="components-panel__body sidebar-title-plugin-panel is-opened"><div class="components-panel__row"><label for="title-plain-text">Title:</label><textarea class="block-editor-plain-text" id="title-plain-text" placeholder="(no title)" rows="1" style="overflow: hidden; overflow-wrap: break-word; resize: none; height: 18px;"></textarea></div><div class="components-panel__row"><button type="button" class="components-button is-primary">Reset</button></div></div></div>"`;
5
+ exports[`Using Plugins API Sidebar Medium screen Should open plugins sidebar using More Menu item and render content 1`] = `"<div class="components-panel__header interface-complementary-area-header__small"><span class="interface-complementary-area-header__small-title">(no title)</span><button type="button" class="components-button has-icon" aria-label="Close plugin"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><path d="M12 13.06l3.712 3.713 1.061-1.06L13.061 12l3.712-3.712-1.06-1.06L12 10.938 8.288 7.227l-1.061 1.06L10.939 12l-3.712 3.712 1.06 1.061L12 13.061z"></path></svg></button></div><div class="components-panel__header interface-complementary-area-header" tabindex="-1"><strong>Plugin title</strong><button type="button" aria-pressed="true" aria-expanded="true" class="components-button interface-complementary-area__pin-unpin-item is-pressed has-icon" aria-label="Unpin from toolbar"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><path d="M11.776 4.454a.25.25 0 01.448 0l2.069 4.192a.25.25 0 00.188.137l4.626.672a.25.25 0 01.139.426l-3.348 3.263a.25.25 0 00-.072.222l.79 4.607a.25.25 0 01-.362.263l-4.138-2.175a.25.25 0 00-.232 0l-4.138 2.175a.25.25 0 01-.363-.263l.79-4.607a.25.25 0 00-.071-.222L4.754 9.881a.25.25 0 01.139-.426l4.626-.672a.25.25 0 00.188-.137l2.069-4.192z"></path></svg></button><button type="button" class="components-button has-icon" aria-label="Close plugin"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><path d="M12 13.06l3.712 3.713 1.061-1.06L13.061 12l3.712-3.712-1.06-1.06L12 10.938 8.288 7.227l-1.061 1.06L10.939 12l-3.712 3.712 1.06 1.061L12 13.061z"></path></svg></button></div><div class="components-panel"><div class="components-panel__body sidebar-title-plugin-panel is-opened"><div class="components-panel__row"><label for="title-plain-text">Title:</label><textarea class="block-editor-plain-text" id="title-plain-text" placeholder="(no title)" rows="1" style="overflow: hidden; overflow-wrap: break-word; resize: none; height: 18px;"></textarea></div><div class="components-panel__row"><button type="button" class="components-button is-primary">Reset</button></div></div></div>"`;
6
6
 
7
- exports[`Using Plugins API Sidebar Should open plugins sidebar using More Menu item and render content 1`] = `"<div class="components-panel__header interface-complementary-area-header__small"><span class="interface-complementary-area-header__small-title">(no title)</span><button type="button" class="components-button has-icon" aria-label="Close plugin"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><path d="M12 13.06l3.712 3.713 1.061-1.06L13.061 12l3.712-3.712-1.06-1.06L12 10.938 8.288 7.227l-1.061 1.06L10.939 12l-3.712 3.712 1.06 1.061L12 13.061z"></path></svg></button></div><div class="components-panel__header interface-complementary-area-header" tabindex="-1"><strong>Plugin sidebar title</strong><button type="button" aria-pressed="true" aria-expanded="true" class="components-button interface-complementary-area__pin-unpin-item is-pressed has-icon" aria-label="Unpin from toolbar"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><path d="M11.776 4.454a.25.25 0 01.448 0l2.069 4.192a.25.25 0 00.188.137l4.626.672a.25.25 0 01.139.426l-3.348 3.263a.25.25 0 00-.072.222l.79 4.607a.25.25 0 01-.362.263l-4.138-2.175a.25.25 0 00-.232 0l-4.138 2.175a.25.25 0 01-.363-.263l.79-4.607a.25.25 0 00-.071-.222L4.754 9.881a.25.25 0 01.139-.426l4.626-.672a.25.25 0 00.188-.137l2.069-4.192z"></path></svg></button><button type="button" class="components-button has-icon" aria-label="Close plugin"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><path d="M12 13.06l3.712 3.713 1.061-1.06L13.061 12l3.712-3.712-1.06-1.06L12 10.938 8.288 7.227l-1.061 1.06L10.939 12l-3.712 3.712 1.06 1.061L12 13.061z"></path></svg></button></div><div class="components-panel"><div class="components-panel__body sidebar-title-plugin-panel is-opened"><div class="components-panel__row"><label for="title-plain-text">Title:</label><textarea class="block-editor-plain-text" id="title-plain-text" placeholder="(no title)" rows="1" style="overflow: hidden; overflow-wrap: break-word; resize: none; height: 18px;"></textarea></div><div class="components-panel__row"><button type="button" class="components-button is-primary">Reset</button></div></div></div>"`;
7
+ exports[`Using Plugins API Sidebar Should open plugins sidebar using More Menu item and render content 1`] = `"<div class="components-panel__header interface-complementary-area-header__small"><span class="interface-complementary-area-header__small-title">(no title)</span><button type="button" class="components-button has-icon" aria-label="Close plugin"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><path d="M12 13.06l3.712 3.713 1.061-1.06L13.061 12l3.712-3.712-1.06-1.06L12 10.938 8.288 7.227l-1.061 1.06L10.939 12l-3.712 3.712 1.06 1.061L12 13.061z"></path></svg></button></div><div class="components-panel__header interface-complementary-area-header" tabindex="-1"><strong>Plugin title</strong><button type="button" aria-pressed="true" aria-expanded="true" class="components-button interface-complementary-area__pin-unpin-item is-pressed has-icon" aria-label="Unpin from toolbar"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><path d="M11.776 4.454a.25.25 0 01.448 0l2.069 4.192a.25.25 0 00.188.137l4.626.672a.25.25 0 01.139.426l-3.348 3.263a.25.25 0 00-.072.222l.79 4.607a.25.25 0 01-.362.263l-4.138-2.175a.25.25 0 00-.232 0l-4.138 2.175a.25.25 0 01-.363-.263l.79-4.607a.25.25 0 00-.071-.222L4.754 9.881a.25.25 0 01.139-.426l4.626-.672a.25.25 0 00.188-.137l2.069-4.192z"></path></svg></button><button type="button" class="components-button has-icon" aria-label="Close plugin"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><path d="M12 13.06l3.712 3.713 1.061-1.06L13.061 12l3.712-3.712-1.06-1.06L12 10.938 8.288 7.227l-1.061 1.06L10.939 12l-3.712 3.712 1.06 1.061L12 13.061z"></path></svg></button></div><div class="components-panel"><div class="components-panel__body sidebar-title-plugin-panel is-opened"><div class="components-panel__row"><label for="title-plain-text">Title:</label><textarea class="block-editor-plain-text" id="title-plain-text" placeholder="(no title)" rows="1" style="overflow: hidden; overflow-wrap: break-word; resize: none; height: 18px;"></textarea></div><div class="components-panel__row"><button type="button" class="components-button is-primary">Reset</button></div></div></div>"`;
@@ -100,7 +100,7 @@ describe( 'Annotations', () => {
100
100
  it( 'allows a block to be annotated', async () => {
101
101
  await page.keyboard.type( 'Title' + '\n' + 'Paragraph to annotate' );
102
102
 
103
- await clickOnMoreMenuItem( 'Annotations Sidebar' );
103
+ await clickOnMoreMenuItem( 'Annotations' );
104
104
 
105
105
  let annotations = await page.$$( ANNOTATIONS_SELECTOR );
106
106
  expect( annotations ).toHaveLength( 0 );
@@ -128,7 +128,7 @@ describe( 'Annotations', () => {
128
128
 
129
129
  it( 'keeps the cursor in the same location when applying annotation', async () => {
130
130
  await page.keyboard.type( 'Title' + '\n' + 'ABC' );
131
- await clickOnMoreMenuItem( 'Annotations Sidebar' );
131
+ await clickOnMoreMenuItem( 'Annotations' );
132
132
 
133
133
  await annotateFirstBlock( 1, 2 );
134
134
 
@@ -146,7 +146,7 @@ describe( 'Annotations', () => {
146
146
 
147
147
  it( 'moves when typing before it', async () => {
148
148
  await page.keyboard.type( 'Title' + '\n' + 'ABC' );
149
- await clickOnMoreMenuItem( 'Annotations Sidebar' );
149
+ await clickOnMoreMenuItem( 'Annotations' );
150
150
 
151
151
  await annotateFirstBlock( 1, 2 );
152
152
 
@@ -168,7 +168,7 @@ describe( 'Annotations', () => {
168
168
 
169
169
  it( 'grows when typing inside it', async () => {
170
170
  await page.keyboard.type( 'Title' + '\n' + 'ABC' );
171
- await clickOnMoreMenuItem( 'Annotations Sidebar' );
171
+ await clickOnMoreMenuItem( 'Annotations' );
172
172
 
173
173
  await annotateFirstBlock( 1, 2 );
174
174
 
@@ -56,7 +56,8 @@ describe( 'Child Blocks', () => {
56
56
  '[data-type="test/child-blocks-restricted-parent"] .block-editor-default-block-appender'
57
57
  );
58
58
  await openGlobalBlockInserter();
59
- expect( await getAllBlockInserterItemTitles() ).toEqual( [
59
+ const allowedBlocks = await getAllBlockInserterItemTitles();
60
+ expect( allowedBlocks.sort() ).toEqual( [
60
61
  'Child Blocks Child',
61
62
  'Image',
62
63
  'Paragraph',
@@ -31,7 +31,6 @@ describe( 'iframed inline styles', () => {
31
31
  await deactivatePlugin( 'gutenberg-test-iframed-inline-styles' );
32
32
  } );
33
33
 
34
- // Skip flaky test. See https://github.com/WordPress/gutenberg/issues/35172
35
34
  it( 'should load inline styles in iframe', async () => {
36
35
  await insertBlock( 'Iframed Inline Styles' );
37
36
 
@@ -50,7 +50,8 @@ describe( 'Allowed Blocks Setting on InnerBlocks', () => {
50
50
  await page.waitForSelector( childParagraphSelector );
51
51
  await page.click( childParagraphSelector );
52
52
  await openGlobalBlockInserter();
53
- expect( await getAllBlockInserterItemTitles() ).toEqual( [
53
+ const allowedBlocks = await getAllBlockInserterItemTitles();
54
+ expect( allowedBlocks.sort() ).toEqual( [
54
55
  'Button',
55
56
  'Gallery',
56
57
  'List',
@@ -75,7 +76,7 @@ describe( 'Allowed Blocks Setting on InnerBlocks', () => {
75
76
  await page.$x( `//button//span[contains(text(), 'List')]` )
76
77
  )[ 0 ];
77
78
  await insertButton.click();
78
- // Select the list wrapper so the image is inserable.
79
+ // Select the list wrapper so the image is insertable.
79
80
  await page.keyboard.press( 'ArrowUp' );
80
81
  await insertBlock( 'Image' );
81
82
  await closeGlobalBlockInserter();
@@ -0,0 +1,131 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import {
5
+ activatePlugin,
6
+ createNewPost,
7
+ deactivatePlugin,
8
+ getAllBlockInserterItemTitles,
9
+ insertBlock,
10
+ closeGlobalBlockInserter,
11
+ } from '@wordpress/e2e-test-utils';
12
+
13
+ const QUICK_INSERTER_RESULTS_SELECTOR =
14
+ '.block-editor-inserter__quick-inserter-results';
15
+
16
+ describe( 'Prioritized Inserter Blocks Setting on InnerBlocks', () => {
17
+ beforeAll( async () => {
18
+ await activatePlugin(
19
+ 'gutenberg-test-innerblocks-prioritized-inserter-blocks'
20
+ );
21
+ } );
22
+
23
+ beforeEach( async () => {
24
+ await createNewPost();
25
+ } );
26
+
27
+ afterAll( async () => {
28
+ await deactivatePlugin(
29
+ 'gutenberg-test-innerblocks-prioritized-inserter-blocks'
30
+ );
31
+ } );
32
+
33
+ describe( 'Quick inserter', () => {
34
+ it( 'uses defaulting ordering if prioritzed blocks setting was not set', async () => {
35
+ const parentBlockSelector =
36
+ '[data-type="test/prioritized-inserter-blocks-unset"]';
37
+ await insertBlock( 'Prioritized Inserter Blocks Unset' );
38
+ await closeGlobalBlockInserter();
39
+
40
+ await page.waitForSelector( parentBlockSelector );
41
+
42
+ await page.click(
43
+ `${ parentBlockSelector } .block-list-appender .block-editor-inserter__toggle`
44
+ );
45
+
46
+ await page.waitForSelector( QUICK_INSERTER_RESULTS_SELECTOR );
47
+
48
+ await expect( await getAllBlockInserterItemTitles() ).toHaveLength(
49
+ 6
50
+ );
51
+ } );
52
+
53
+ it( 'uses the priority ordering if prioritzed blocks setting is set', async () => {
54
+ const parentBlockSelector =
55
+ '[data-type="test/prioritized-inserter-blocks-set"]';
56
+ await insertBlock( 'Prioritized Inserter Blocks Set' );
57
+ await closeGlobalBlockInserter();
58
+
59
+ await page.waitForSelector( parentBlockSelector );
60
+
61
+ await page.click(
62
+ `${ parentBlockSelector } .block-list-appender .block-editor-inserter__toggle`
63
+ );
64
+
65
+ await page.waitForSelector( QUICK_INSERTER_RESULTS_SELECTOR );
66
+
67
+ // Should still be only 6 results regardless of the priority ordering.
68
+ const inserterItems = await getAllBlockInserterItemTitles();
69
+
70
+ // Should still be only 6 results regardless of the priority ordering.
71
+ expect( inserterItems ).toHaveLength( 6 );
72
+
73
+ expect( inserterItems.slice( 0, 3 ) ).toEqual( [
74
+ 'Audio',
75
+ 'Spacer',
76
+ 'Code',
77
+ ] );
78
+ } );
79
+
80
+ it( 'obeys allowed blocks over prioritzed blocks setting if conflicted', async () => {
81
+ const parentBlockSelector =
82
+ '[data-type="test/prioritized-inserter-blocks-set-with-conflicting-allowed-blocks"]';
83
+ await insertBlock(
84
+ 'Prioritized Inserter Blocks Set With Conflicting Allowed Blocks'
85
+ );
86
+ await closeGlobalBlockInserter();
87
+
88
+ await page.waitForSelector( parentBlockSelector );
89
+
90
+ await page.click(
91
+ `${ parentBlockSelector } .block-list-appender .block-editor-inserter__toggle`
92
+ );
93
+
94
+ await page.waitForSelector( QUICK_INSERTER_RESULTS_SELECTOR );
95
+
96
+ const inserterItems = await getAllBlockInserterItemTitles();
97
+
98
+ expect( inserterItems.slice( 0, 3 ) ).toEqual( [
99
+ 'Spacer',
100
+ 'Code',
101
+ 'Paragraph',
102
+ ] );
103
+ expect( inserterItems ).toEqual(
104
+ expect.not.arrayContaining( [ 'Audio' ] )
105
+ );
106
+ } );
107
+ } );
108
+ describe( 'Slash inserter', () => {
109
+ it( 'uses the priority ordering if prioritzed blocks setting is set', async () => {
110
+ await insertBlock( 'Prioritized Inserter Blocks Set' );
111
+ await page.click( '[data-type="core/image"]' );
112
+ await page.keyboard.press( 'Enter' );
113
+ await page.keyboard.type( '/' );
114
+ // Wait for the results to display.
115
+ await page.waitForSelector( '.components-autocomplete__result' );
116
+ const inserterItemTitles = await page.evaluate( () => {
117
+ return Array.from(
118
+ document.querySelectorAll(
119
+ '.components-autocomplete__result'
120
+ )
121
+ ).map( ( { innerText } ) => innerText );
122
+ } );
123
+ expect( inserterItemTitles ).toHaveLength( 9 ); // Default suggested blocks number.
124
+ expect( inserterItemTitles.slice( 0, 3 ) ).toEqual( [
125
+ 'Audio',
126
+ 'Spacer',
127
+ 'Code',
128
+ ] );
129
+ } );
130
+ } );
131
+ } );
@@ -69,10 +69,10 @@ describe( 'Using Plugins API', () => {
69
69
 
70
70
  describe( 'Sidebar', () => {
71
71
  const SIDEBAR_PINNED_ITEM_BUTTON =
72
- '.interface-pinned-items button[aria-label="Plugin sidebar title"]';
72
+ '.interface-pinned-items button[aria-label="Plugin title"]';
73
73
  const SIDEBAR_PANEL_SELECTOR = '.sidebar-title-plugin-panel';
74
74
  it( 'Should open plugins sidebar using More Menu item and render content', async () => {
75
- await clickOnMoreMenuItem( 'Plugin sidebar more menu title' );
75
+ await clickOnMoreMenuItem( 'Plugin more menu title' );
76
76
 
77
77
  const pluginSidebarContent = await page.$eval(
78
78
  '.edit-post-sidebar',
@@ -105,7 +105,7 @@ describe( 'Using Plugins API', () => {
105
105
  await page.reload();
106
106
  await page.waitForSelector( '.edit-post-layout' );
107
107
  expect( await page.$( SIDEBAR_PINNED_ITEM_BUTTON ) ).toBeNull();
108
- await clickOnMoreMenuItem( 'Plugin sidebar more menu title' );
108
+ await clickOnMoreMenuItem( 'Plugin more menu title' );
109
109
  await page.click( 'button[aria-label="Pin to toolbar"]' );
110
110
  expect( await page.$( SIDEBAR_PINNED_ITEM_BUTTON ) ).not.toBeNull();
111
111
  await page.reload();
@@ -114,12 +114,12 @@ describe( 'Using Plugins API', () => {
114
114
  } );
115
115
 
116
116
  it( 'Should close plugins sidebar using More Menu item', async () => {
117
- await clickOnMoreMenuItem( 'Plugin sidebar more menu title' );
117
+ await clickOnMoreMenuItem( 'Plugin more menu title' );
118
118
 
119
119
  const pluginSidebarOpened = await page.$( '.edit-post-sidebar' );
120
120
  expect( pluginSidebarOpened ).not.toBeNull();
121
121
 
122
- await clickOnMoreMenuItem( 'Plugin sidebar more menu title' );
122
+ await clickOnMoreMenuItem( 'Plugin more menu title' );
123
123
 
124
124
  const pluginSidebarClosed = await page.$( '.edit-post-sidebar' );
125
125
  expect( pluginSidebarClosed ).toBeNull();
@@ -135,7 +135,7 @@ describe( 'Using Plugins API', () => {
135
135
  } );
136
136
 
137
137
  it( 'Should open plugins sidebar using More Menu item and render content', async () => {
138
- await clickOnMoreMenuItem( 'Plugin sidebar more menu title' );
138
+ await clickOnMoreMenuItem( 'Plugin more menu title' );
139
139
 
140
140
  const pluginSidebarContent = await page.$eval(
141
141
  '.edit-post-sidebar',
@@ -46,7 +46,7 @@ describe( 'preferences', () => {
46
46
 
47
47
  // Dismiss.
48
48
  await page.click(
49
- '.edit-post-sidebar__panel-tabs [aria-label="Close settings"]'
49
+ '.edit-post-sidebar__panel-tabs [aria-label="Close Settings"]'
50
50
  );
51
51
  expect( await getActiveSidebarTabText() ).toBe( null );
52
52
 
@@ -275,7 +275,7 @@ describe( 'Multi-entity save flow', () => {
275
275
  '//a[contains(@class, "block-editor-list-view-block-select-button")][contains(., "header")]'
276
276
  );
277
277
  headerTemplatePartListViewButton.click();
278
- await page.click( 'button[aria-label="Close List View Sidebar"]' );
278
+ await page.click( 'button[aria-label="Close"]' );
279
279
 
280
280
  // Insert something to dirty the editor.
281
281
  await insertBlock( 'Paragraph' );
@@ -1,177 +0,0 @@
1
- /**
2
- * External dependencies
3
- */
4
- import path from 'path';
5
- import fs from 'fs';
6
- import os from 'os';
7
- import { v4 as uuid } from 'uuid';
8
-
9
- /**
10
- * WordPress dependencies
11
- */
12
- import {
13
- insertBlock,
14
- createNewPost,
15
- openDocumentSettingsSidebar,
16
- switchBlockInspectorTab,
17
- transformBlockTo,
18
- } from '@wordpress/e2e-test-utils';
19
-
20
- async function upload( selector ) {
21
- const inputElement = await page.waitForSelector(
22
- `${ selector } input[type="file"]`
23
- );
24
- const testImagePath = path.join(
25
- __dirname,
26
- '..',
27
- '..',
28
- '..',
29
- 'assets',
30
- '10x10_e2e_test_image_z9T8jK.png'
31
- );
32
- const filename = uuid();
33
- const tmpFileName = path.join( os.tmpdir(), filename + '.png' );
34
- fs.copyFileSync( testImagePath, tmpFileName );
35
- await inputElement.uploadFile( tmpFileName );
36
- await page.waitForSelector( `${ selector } img[src$="${ filename }.png"]` );
37
- return filename;
38
- }
39
-
40
- describe( 'Cover', () => {
41
- beforeEach( async () => {
42
- await createNewPost();
43
- } );
44
-
45
- it( 'can set background image using image upload on block placeholder', async () => {
46
- await insertBlock( 'Cover' );
47
- // Create the block using uploaded image.
48
- const sourceImageFilename = await upload( '.wp-block-cover' );
49
- // Get the block's background image URL.
50
- const blockImage = await page.waitForSelector( '.wp-block-cover img' );
51
- const blockImageUrl = await blockImage.evaluate( ( el ) => el.src );
52
-
53
- expect( blockImageUrl ).toContain( sourceImageFilename );
54
- } );
55
-
56
- it( 'dims background image down by 50% by default', async () => {
57
- await insertBlock( 'Cover' );
58
- // Create the block using uploaded image.
59
- await upload( '.wp-block-cover' );
60
- // Get the block's background dim color and its opacity.
61
- const backgroundDim = await page.waitForSelector(
62
- '.wp-block-cover .has-background-dim'
63
- );
64
- const [ backgroundDimColor, backgroundDimOpacity ] =
65
- await page.evaluate( ( el ) => {
66
- const computedStyle = window.getComputedStyle( el );
67
- return [ computedStyle.backgroundColor, computedStyle.opacity ];
68
- }, backgroundDim );
69
-
70
- expect( backgroundDimColor ).toBe( 'rgb(0, 0, 0)' );
71
- expect( backgroundDimOpacity ).toBe( '0.5' );
72
- } );
73
-
74
- it( 'can be resized using drag & drop', async () => {
75
- await insertBlock( 'Cover' );
76
- // Close the inserter.
77
- await page.click( '.edit-post-header-toolbar__inserter-toggle' );
78
- // Open the sidebar.
79
- await openDocumentSettingsSidebar();
80
- // Choose the first solid color as the background of the cover.
81
- await page.click(
82
- '.components-circular-option-picker__option-wrapper:first-child button'
83
- );
84
-
85
- // Select the cover block. By default the child paragraph gets selected.
86
- await page.click(
87
- '.edit-post-header-toolbar__document-overview-toggle'
88
- );
89
- await page.click(
90
- '.block-editor-list-view-block__contents-container a'
91
- );
92
-
93
- switchBlockInspectorTab( 'Styles' );
94
- const heightInputHandle = await page.waitForSelector(
95
- 'input[id*="block-cover-height-input"]'
96
- );
97
-
98
- // Verify the height of the cover is not defined.
99
- expect(
100
- await page.evaluate( ( { value } ) => value, heightInputHandle )
101
- ).toBe( '' );
102
-
103
- const resizeButton = await page.$(
104
- '.components-resizable-box__handle-bottom'
105
- );
106
- const boundingBoxResizeButton = await resizeButton.boundingBox();
107
- const coordinatesResizeButton = {
108
- x: boundingBoxResizeButton.x + boundingBoxResizeButton.width / 2,
109
- y: boundingBoxResizeButton.y + boundingBoxResizeButton.height / 2,
110
- };
111
-
112
- // Move the mouse to the position of the resize button.
113
- await page.mouse.move(
114
- coordinatesResizeButton.x,
115
- coordinatesResizeButton.y
116
- );
117
-
118
- // Trigger a mousedown event against the resize button.
119
- // Using page.mouse.down does not works because it triggers a global event,
120
- // not an event for that element.
121
- page.evaluate( ( { x, y } ) => {
122
- const element = document.querySelector(
123
- '.components-resizable-box__handle-bottom'
124
- );
125
- event = document.createEvent( 'CustomEvent' );
126
- event.initCustomEvent( 'mousedown', true, true, null );
127
- event.clientX = x;
128
- event.clientY = y;
129
- element.dispatchEvent( event );
130
- }, coordinatesResizeButton );
131
-
132
- // Move the mouse to resize the cover.
133
- await page.mouse.move(
134
- coordinatesResizeButton.x,
135
- coordinatesResizeButton.y + 100,
136
- { steps: 10 }
137
- );
138
-
139
- // Release the mouse.
140
- await page.mouse.up();
141
-
142
- // Verify the height of the cover has changed.
143
- expect(
144
- await page.evaluate(
145
- ( { value } ) => Number.parseInt( value ),
146
- heightInputHandle
147
- )
148
- ).toBeGreaterThan( 100 );
149
- } );
150
-
151
- it( 'dims the background image down by 50% when transformed from the Image block', async () => {
152
- await insertBlock( 'Image' );
153
- // Upload image and transform to the Cover block.
154
- const filename = await upload( '.wp-block-image' );
155
- await page.waitForSelector(
156
- `.wp-block-image img[src$="${ filename }.png"]`
157
- );
158
-
159
- // Focus the block wrapper before trying to convert to make sure figcaption toolbar is not obscuring
160
- // the block toolbar.
161
- await page.focus( '.wp-block-image' );
162
- await transformBlockTo( 'Cover' );
163
-
164
- // Get the block's background dim color and its opacity.
165
- const backgroundDim = await page.waitForSelector(
166
- '.wp-block-cover .has-background-dim'
167
- );
168
- const [ backgroundDimColor, backgroundDimOpacity ] =
169
- await page.evaluate( ( el ) => {
170
- const computedStyle = window.getComputedStyle( el );
171
- return [ computedStyle.backgroundColor, computedStyle.opacity ];
172
- }, backgroundDim );
173
-
174
- expect( backgroundDimColor ).toBe( 'rgb(0, 0, 0)' );
175
- expect( backgroundDimOpacity ).toBe( '0.5' );
176
- } );
177
- } );
@@ -1,47 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import {
5
- clickBlockAppender,
6
- getEditedPostContent,
7
- createNewPost,
8
- transformBlockTo,
9
- } from '@wordpress/e2e-test-utils';
10
-
11
- describe( 'Quote', () => {
12
- beforeEach( async () => {
13
- await createNewPost();
14
- } );
15
-
16
- it( 'can be created by converting a quote and converted back to quote', async () => {
17
- await clickBlockAppender();
18
- await page.keyboard.type( 'test' );
19
- await transformBlockTo( 'Quote' );
20
-
21
- expect( await getEditedPostContent() ).toMatchInlineSnapshot( `
22
- "<!-- wp:quote -->
23
- <blockquote class="wp-block-quote"><!-- wp:paragraph -->
24
- <p>test</p>
25
- <!-- /wp:paragraph --></blockquote>
26
- <!-- /wp:quote -->"
27
- ` );
28
-
29
- await transformBlockTo( 'Pullquote' );
30
-
31
- expect( await getEditedPostContent() ).toMatchInlineSnapshot( `
32
- "<!-- wp:pullquote -->
33
- <figure class="wp-block-pullquote"><blockquote><p>test</p></blockquote></figure>
34
- <!-- /wp:pullquote -->"
35
- ` );
36
-
37
- await transformBlockTo( 'Quote' );
38
-
39
- expect( await getEditedPostContent() ).toMatchInlineSnapshot( `
40
- "<!-- wp:quote -->
41
- <blockquote class="wp-block-quote"><!-- wp:paragraph -->
42
- <p>test</p>
43
- <!-- /wp:paragraph --></blockquote>
44
- <!-- /wp:quote -->"
45
- ` );
46
- } );
47
- } );
@@ -1,11 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`adding patterns should insert a block pattern 1`] = `
4
- "<!-- wp:social-links {"customIconColor":"#ffffff","iconColorValue":"#ffffff","customIconBackgroundColor":"#3962e3","iconBackgroundColorValue":"#3962e3","className":"has-icon-color"} -->
5
- <ul class="wp-block-social-links has-icon-color has-icon-background-color"><!-- wp:social-link {"url":"https://wordpress.org","service":"wordpress"} /-->
6
-
7
- <!-- wp:social-link {"url":"#","service":"chain"} /-->
8
-
9
- <!-- wp:social-link {"url":"#","service":"mail"} /--></ul>
10
- <!-- /wp:social-links -->"
11
- `;
@@ -1,29 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`Keep styles on block transforms Should keep colors during a transform 1`] = `
4
- "<!-- wp:paragraph {"textColor":"luminous-vivid-orange"} -->
5
- <p class="has-luminous-vivid-orange-color has-text-color">Heading</p>
6
- <!-- /wp:paragraph -->"
7
- `;
8
-
9
- exports[`Keep styles on block transforms Should keep the font size during a transform from multiple blocks into multiple blocks 1`] = `
10
- "<!-- wp:heading {"fontSize":"large"} -->
11
- <h2 class="wp-block-heading has-large-font-size">Line 1 to be made large</h2>
12
- <!-- /wp:heading -->
13
-
14
- <!-- wp:heading {"fontSize":"large"} -->
15
- <h2 class="wp-block-heading has-large-font-size">Line 2 to be made large</h2>
16
- <!-- /wp:heading -->
17
-
18
- <!-- wp:heading {"fontSize":"large"} -->
19
- <h2 class="wp-block-heading has-large-font-size">Line 3 to be made large</h2>
20
- <!-- /wp:heading -->"
21
- `;
22
-
23
- exports[`Keep styles on block transforms Should not include styles in the group block when grouping a block 1`] = `
24
- "<!-- wp:group {"layout":{"type":"constrained"}} -->
25
- <div class="wp-block-group"><!-- wp:paragraph {"fontSize":"large"} -->
26
- <p class="has-large-font-size">Line 1 to be made large</p>
27
- <!-- /wp:paragraph --></div>
28
- <!-- /wp:group -->"
29
- `;
@@ -1,31 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`undo should immediately create an undo level on typing 1`] = `
4
- "<!-- wp:paragraph -->
5
- <p>1</p>
6
- <!-- /wp:paragraph -->"
7
- `;
8
-
9
- exports[`undo should undo typing after a pause 1`] = `
10
- "<!-- wp:paragraph -->
11
- <p>before pause after pause</p>
12
- <!-- /wp:paragraph -->"
13
- `;
14
-
15
- exports[`undo should undo typing after a pause 2`] = `
16
- "<!-- wp:paragraph -->
17
- <p>before pause</p>
18
- <!-- /wp:paragraph -->"
19
- `;
20
-
21
- exports[`undo should undo typing after non input change 1`] = `
22
- "<!-- wp:paragraph -->
23
- <p>before keyboard <strong>after keyboard</strong></p>
24
- <!-- /wp:paragraph -->"
25
- `;
26
-
27
- exports[`undo should undo typing after non input change 2`] = `
28
- "<!-- wp:paragraph -->
29
- <p>before keyboard </p>
30
- <!-- /wp:paragraph -->"
31
- `;
@@ -1,22 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import {
5
- createNewPost,
6
- insertPattern,
7
- getEditedPostContent,
8
- } from '@wordpress/e2e-test-utils';
9
-
10
- /** @typedef {import('puppeteer-core').ElementHandle} ElementHandle */
11
-
12
- describe( 'adding patterns', () => {
13
- beforeEach( async () => {
14
- await createNewPost();
15
- } );
16
-
17
- it( 'should insert a block pattern', async () => {
18
- await insertPattern( 'Social links with a shared background color' );
19
-
20
- expect( await getEditedPostContent() ).toMatchSnapshot();
21
- } );
22
- } );
@@ -1,64 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import {
5
- clickBlockAppender,
6
- createNewPost,
7
- getEditedPostContent,
8
- pressKeyWithModifier,
9
- transformBlockTo,
10
- } from '@wordpress/e2e-test-utils';
11
-
12
- describe( 'Keep styles on block transforms', () => {
13
- beforeEach( async () => {
14
- await createNewPost();
15
- } );
16
-
17
- it( 'Should keep colors during a transform', async () => {
18
- await clickBlockAppender();
19
- await page.keyboard.type( '## Heading' );
20
-
21
- const textColorButton = await page.waitForSelector(
22
- '.block-editor-panel-color-gradient-settings__dropdown'
23
- );
24
- await textColorButton.click();
25
-
26
- const colorButtonSelector = `//button[@aria-label='Color: Luminous vivid orange']`;
27
- const [ colorButton ] = await page.$x( colorButtonSelector );
28
- await colorButton.click();
29
- await page.waitForXPath(
30
- `${ colorButtonSelector }[@aria-pressed='true']`
31
- );
32
- await page.click( 'h2[data-type="core/heading"]' );
33
- await transformBlockTo( 'Paragraph' );
34
- expect( await getEditedPostContent() ).toMatchSnapshot();
35
- } );
36
-
37
- it( 'Should keep the font size during a transform from multiple blocks into multiple blocks', async () => {
38
- // Create a paragraph block with some content.
39
- await clickBlockAppender();
40
- await page.keyboard.type( 'Line 1 to be made large' );
41
- await page.keyboard.press( 'Enter' );
42
- await page.keyboard.type( 'Line 2 to be made large' );
43
- await page.keyboard.press( 'Enter' );
44
- await page.keyboard.type( 'Line 3 to be made large' );
45
- await pressKeyWithModifier( 'shift', 'ArrowUp' );
46
- await pressKeyWithModifier( 'shift', 'ArrowUp' );
47
- await page.click(
48
- '[role="radiogroup"][aria-label="Font size"] [aria-label="Large"]'
49
- );
50
- await transformBlockTo( 'Heading' );
51
- expect( await getEditedPostContent() ).toMatchSnapshot();
52
- } );
53
-
54
- it( 'Should not include styles in the group block when grouping a block', async () => {
55
- // Create a paragraph block with some content.
56
- await clickBlockAppender();
57
- await page.keyboard.type( 'Line 1 to be made large' );
58
- await page.click(
59
- '[role="radiogroup"][aria-label="Font size"] [aria-label="Large"]'
60
- );
61
- await transformBlockTo( 'Group' );
62
- expect( await getEditedPostContent() ).toMatchSnapshot();
63
- } );
64
- } );
@@ -1,444 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import {
5
- clickBlockAppender,
6
- getEditedPostContent,
7
- createNewPost,
8
- pressKeyWithModifier,
9
- selectBlockByClientId,
10
- getAllBlocks,
11
- saveDraft,
12
- publishPost,
13
- } from '@wordpress/e2e-test-utils';
14
-
15
- const getSelection = async () => {
16
- return await page.evaluate( () => {
17
- const selectedBlock = document.activeElement.closest( '.wp-block' );
18
- const blocks = Array.from( document.querySelectorAll( '.wp-block' ) );
19
- const blockIndex = blocks.indexOf( selectedBlock );
20
-
21
- if ( blockIndex === -1 ) {
22
- return {};
23
- }
24
-
25
- let editables;
26
-
27
- if ( selectedBlock.getAttribute( 'contenteditable' ) ) {
28
- editables = [ selectedBlock ];
29
- } else {
30
- editables = Array.from(
31
- selectedBlock.querySelectorAll( '[contenteditable]' )
32
- );
33
- }
34
-
35
- const editableIndex = editables.indexOf( document.activeElement );
36
- const selection = window.getSelection();
37
-
38
- if ( editableIndex === -1 || ! selection.rangeCount ) {
39
- return { blockIndex };
40
- }
41
-
42
- const range = selection.getRangeAt( 0 );
43
- const cloneStart = range.cloneRange();
44
- const cloneEnd = range.cloneRange();
45
-
46
- cloneStart.setStart( document.activeElement, 0 );
47
- cloneEnd.setStart( document.activeElement, 0 );
48
-
49
- /**
50
- * Zero width non-breaking space, used as padding in the editable DOM
51
- * tree when it is empty otherwise.
52
- */
53
- const ZWNBSP = '\ufeff';
54
-
55
- return {
56
- blockIndex,
57
- editableIndex,
58
- startOffset: cloneStart.toString().replace( ZWNBSP, '' ).length,
59
- endOffset: cloneEnd.toString().replace( ZWNBSP, '' ).length,
60
- };
61
- } );
62
- };
63
-
64
- describe( 'undo', () => {
65
- beforeEach( async () => {
66
- await createNewPost();
67
- } );
68
-
69
- it( 'should undo typing after a pause', async () => {
70
- await clickBlockAppender();
71
-
72
- await page.keyboard.type( 'before pause' );
73
- await new Promise( ( resolve ) => setTimeout( resolve, 1000 ) );
74
- await page.keyboard.type( ' after pause' );
75
-
76
- const after = await getEditedPostContent();
77
-
78
- expect( after ).toMatchSnapshot();
79
-
80
- await pressKeyWithModifier( 'primary', 'z' );
81
-
82
- const before = await getEditedPostContent();
83
-
84
- expect( before ).toMatchSnapshot();
85
- expect( await getSelection() ).toEqual( {
86
- blockIndex: 1,
87
- editableIndex: 0,
88
- startOffset: 'before pause'.length,
89
- endOffset: 'before pause'.length,
90
- } );
91
-
92
- await pressKeyWithModifier( 'primary', 'z' );
93
-
94
- expect( await getEditedPostContent() ).toBe( '' );
95
- expect( await getSelection() ).toEqual( {
96
- blockIndex: 1,
97
- editableIndex: 0,
98
- startOffset: 0,
99
- endOffset: 0,
100
- } );
101
-
102
- await pressKeyWithModifier( 'primaryShift', 'z' );
103
-
104
- expect( await getEditedPostContent() ).toBe( before );
105
- expect( await getSelection() ).toEqual( {
106
- blockIndex: 1,
107
- editableIndex: 0,
108
- startOffset: 'before pause'.length,
109
- endOffset: 'before pause'.length,
110
- } );
111
-
112
- await pressKeyWithModifier( 'primaryShift', 'z' );
113
-
114
- expect( await getEditedPostContent() ).toBe( after );
115
- expect( await getSelection() ).toEqual( {
116
- blockIndex: 1,
117
- editableIndex: 0,
118
- startOffset: 'before pause after pause'.length,
119
- endOffset: 'before pause after pause'.length,
120
- } );
121
- } );
122
-
123
- it( 'should undo typing after non input change', async () => {
124
- await clickBlockAppender();
125
-
126
- await page.keyboard.type( 'before keyboard ' );
127
- await pressKeyWithModifier( 'primary', 'b' );
128
- await page.keyboard.type( 'after keyboard' );
129
-
130
- const after = await getEditedPostContent();
131
-
132
- expect( after ).toMatchSnapshot();
133
-
134
- await pressKeyWithModifier( 'primary', 'z' );
135
-
136
- const before = await getEditedPostContent();
137
-
138
- expect( before ).toMatchSnapshot();
139
- expect( await getSelection() ).toEqual( {
140
- blockIndex: 1,
141
- editableIndex: 0,
142
- startOffset: 'before keyboard '.length,
143
- endOffset: 'before keyboard '.length,
144
- } );
145
-
146
- await pressKeyWithModifier( 'primary', 'z' );
147
-
148
- expect( await getEditedPostContent() ).toBe( '' );
149
- expect( await getSelection() ).toEqual( {
150
- blockIndex: 1,
151
- editableIndex: 0,
152
- startOffset: 0,
153
- endOffset: 0,
154
- } );
155
-
156
- await pressKeyWithModifier( 'primaryShift', 'z' );
157
-
158
- expect( await getEditedPostContent() ).toBe( before );
159
- expect( await getSelection() ).toEqual( {
160
- blockIndex: 1,
161
- editableIndex: 0,
162
- startOffset: 'before keyboard '.length,
163
- endOffset: 'before keyboard '.length,
164
- } );
165
-
166
- await pressKeyWithModifier( 'primaryShift', 'z' );
167
-
168
- expect( await getEditedPostContent() ).toBe( after );
169
- expect( await getSelection() ).toEqual( {
170
- blockIndex: 1,
171
- editableIndex: 0,
172
- startOffset: 'before keyboard after keyboard'.length,
173
- endOffset: 'before keyboard after keyboard'.length,
174
- } );
175
- } );
176
-
177
- it( 'should undo bold', async () => {
178
- await clickBlockAppender();
179
- await page.keyboard.type( 'test' );
180
- await saveDraft();
181
- await page.reload();
182
- await page.waitForSelector( '.edit-post-layout' );
183
- await page.click( '[data-type="core/paragraph"]' );
184
- await pressKeyWithModifier( 'primary', 'a' );
185
- await pressKeyWithModifier( 'primary', 'b' );
186
- await pressKeyWithModifier( 'primary', 'z' );
187
-
188
- const visibleResult = await page.evaluate(
189
- () => document.activeElement.innerHTML
190
- );
191
- expect( visibleResult ).toBe( 'test' );
192
- } );
193
-
194
- it( 'Should undo/redo to expected level intervals', async () => {
195
- await clickBlockAppender();
196
-
197
- const firstBlock = await getEditedPostContent();
198
-
199
- await page.keyboard.type( 'This' );
200
-
201
- const firstText = await getEditedPostContent();
202
-
203
- await page.keyboard.press( 'Enter' );
204
-
205
- const secondBlock = await getEditedPostContent();
206
-
207
- await page.keyboard.type( 'is' );
208
-
209
- const secondText = await getEditedPostContent();
210
-
211
- await page.keyboard.press( 'Enter' );
212
-
213
- const thirdBlock = await getEditedPostContent();
214
-
215
- await page.keyboard.type( 'test' );
216
-
217
- const thirdText = await getEditedPostContent();
218
-
219
- await pressKeyWithModifier( 'primary', 'z' ); // Undo 3rd paragraph text.
220
-
221
- expect( await getEditedPostContent() ).toBe( thirdBlock );
222
- expect( await getSelection() ).toEqual( {
223
- blockIndex: 3,
224
- editableIndex: 0,
225
- startOffset: 0,
226
- endOffset: 0,
227
- } );
228
-
229
- await pressKeyWithModifier( 'primary', 'z' ); // Undo 3rd block.
230
-
231
- expect( await getEditedPostContent() ).toBe( secondText );
232
- expect( await getSelection() ).toEqual( {
233
- blockIndex: 2,
234
- editableIndex: 0,
235
- startOffset: 'is'.length,
236
- endOffset: 'is'.length,
237
- } );
238
-
239
- await pressKeyWithModifier( 'primary', 'z' ); // Undo 2nd paragraph text.
240
-
241
- expect( await getEditedPostContent() ).toBe( secondBlock );
242
- expect( await getSelection() ).toEqual( {
243
- blockIndex: 2,
244
- editableIndex: 0,
245
- startOffset: 0,
246
- endOffset: 0,
247
- } );
248
-
249
- await pressKeyWithModifier( 'primary', 'z' ); // Undo 2nd block.
250
-
251
- expect( await getEditedPostContent() ).toBe( firstText );
252
- expect( await getSelection() ).toEqual( {
253
- blockIndex: 1,
254
- editableIndex: 0,
255
- startOffset: 'This'.length,
256
- endOffset: 'This'.length,
257
- } );
258
-
259
- await pressKeyWithModifier( 'primary', 'z' ); // Undo 1st paragraph text.
260
-
261
- expect( await getEditedPostContent() ).toBe( firstBlock );
262
- expect( await getSelection() ).toEqual( {
263
- blockIndex: 1,
264
- editableIndex: 0,
265
- startOffset: 0,
266
- endOffset: 0,
267
- } );
268
-
269
- await pressKeyWithModifier( 'primary', 'z' ); // Undo 1st block.
270
-
271
- expect( await getEditedPostContent() ).toBe( '' );
272
- expect( await getSelection() ).toEqual( {} );
273
- // After undoing every action, there should be no more undo history.
274
- expect(
275
- await page.$( '.editor-history__undo[aria-disabled="true"]' )
276
- ).not.toBeNull();
277
-
278
- await pressKeyWithModifier( 'primaryShift', 'z' ); // Redo 1st block.
279
-
280
- expect( await getEditedPostContent() ).toBe( firstBlock );
281
- expect( await getSelection() ).toEqual( {
282
- blockIndex: 1,
283
- editableIndex: 0,
284
- startOffset: 0,
285
- endOffset: 0,
286
- } );
287
- // After redoing one change, the undo button should be enabled again.
288
- expect(
289
- await page.$( '.editor-history__undo[aria-disabled="true"]' )
290
- ).toBeNull();
291
-
292
- await pressKeyWithModifier( 'primaryShift', 'z' ); // Redo 1st paragraph text.
293
-
294
- expect( await getEditedPostContent() ).toBe( firstText );
295
- expect( await getSelection() ).toEqual( {
296
- blockIndex: 1,
297
- editableIndex: 0,
298
- startOffset: 'This'.length,
299
- endOffset: 'This'.length,
300
- } );
301
-
302
- await pressKeyWithModifier( 'primaryShift', 'z' ); // Redo 2nd block.
303
-
304
- expect( await getEditedPostContent() ).toBe( secondBlock );
305
- expect( await getSelection() ).toEqual( {
306
- blockIndex: 2,
307
- editableIndex: 0,
308
- startOffset: 0,
309
- endOffset: 0,
310
- } );
311
-
312
- await pressKeyWithModifier( 'primaryShift', 'z' ); // Redo 2nd paragraph text.
313
-
314
- expect( await getEditedPostContent() ).toBe( secondText );
315
- expect( await getSelection() ).toEqual( {
316
- blockIndex: 2,
317
- editableIndex: 0,
318
- startOffset: 'is'.length,
319
- endOffset: 'is'.length,
320
- } );
321
-
322
- await pressKeyWithModifier( 'primaryShift', 'z' ); // Redo 3rd block.
323
-
324
- expect( await getEditedPostContent() ).toBe( thirdBlock );
325
- expect( await getSelection() ).toEqual( {
326
- blockIndex: 3,
327
- editableIndex: 0,
328
- startOffset: 0,
329
- endOffset: 0,
330
- } );
331
-
332
- await pressKeyWithModifier( 'primaryShift', 'z' ); // Redo 3rd paragraph text.
333
-
334
- expect( await getEditedPostContent() ).toBe( thirdText );
335
- expect( await getSelection() ).toEqual( {
336
- blockIndex: 3,
337
- editableIndex: 0,
338
- startOffset: 'test'.length,
339
- endOffset: 'test'.length,
340
- } );
341
- } );
342
-
343
- it( 'should undo for explicit persistence editing post', async () => {
344
- // Regression test: An issue had occurred where the creation of an
345
- // explicit undo level would interfere with blocks values being synced
346
- // correctly to the block editor.
347
- //
348
- // See: https://github.com/WordPress/gutenberg/issues/14950
349
-
350
- // Issue is demonstrated from an edited post: create, save, and reload.
351
- await clickBlockAppender();
352
- await page.keyboard.type( 'original' );
353
- await saveDraft();
354
- await page.reload();
355
- await page.waitForSelector( '.edit-post-layout' );
356
-
357
- // Issue is demonstrated by forcing state merges (multiple inputs) on
358
- // an existing text after a fresh reload.
359
- await selectBlockByClientId( ( await getAllBlocks() )[ 0 ].clientId );
360
- await page.keyboard.type( 'modified' );
361
-
362
- // The issue is demonstrated after the one second delay to trigger the
363
- // creation of an explicit undo persistence level.
364
- await new Promise( ( resolve ) => setTimeout( resolve, 1000 ) );
365
-
366
- await pressKeyWithModifier( 'primary', 'z' );
367
-
368
- // Assert against the _visible_ content. Since editor state with the
369
- // regression present was accurate, it would produce the correct
370
- // content. The issue had manifested in the form of what was shown to
371
- // the user since the blocks state failed to sync to block editor.
372
- const visibleContent = await page.evaluate(
373
- () => document.activeElement.textContent
374
- );
375
- expect( visibleContent ).toBe( 'original' );
376
- } );
377
-
378
- it( 'should not create undo levels when saving', async () => {
379
- await clickBlockAppender();
380
- await page.keyboard.type( '1' );
381
- await saveDraft();
382
- await pressKeyWithModifier( 'primary', 'z' );
383
-
384
- expect( await getEditedPostContent() ).toBe( '' );
385
- } );
386
-
387
- it( 'should not create undo levels when publishing', async () => {
388
- await clickBlockAppender();
389
- await page.keyboard.type( '1' );
390
- await publishPost();
391
- await pressKeyWithModifier( 'primary', 'z' );
392
-
393
- expect( await getEditedPostContent() ).toBe( '' );
394
- } );
395
-
396
- it( 'should immediately create an undo level on typing', async () => {
397
- await clickBlockAppender();
398
-
399
- await page.keyboard.type( '1' );
400
- await saveDraft();
401
- await page.reload();
402
- await page.waitForSelector( '.edit-post-layout' );
403
-
404
- // Expect undo button to be disabled.
405
- expect(
406
- await page.$( '.editor-history__undo[aria-disabled="true"]' )
407
- ).not.toBeNull();
408
-
409
- await page.click( '[data-type="core/paragraph"]' );
410
-
411
- await page.keyboard.type( '2' );
412
-
413
- // Expect undo button to be enabled.
414
- expect(
415
- await page.$( '.editor-history__undo[aria-disabled="true"]' )
416
- ).toBeNull();
417
-
418
- await pressKeyWithModifier( 'primary', 'z' );
419
-
420
- // Expect "1".
421
- expect( await getEditedPostContent() ).toMatchSnapshot();
422
- } );
423
-
424
- it( 'should be able to undo and redo when transient changes have been made and we update/publish', async () => {
425
- // Typing consecutive characters in a `Paragraph` block updates the same
426
- // block attribute as in the previous action and results in transient edits
427
- // and skipping `undo` history steps.
428
- const text = 'tonis';
429
- await clickBlockAppender();
430
- await page.keyboard.type( text );
431
- await publishPost();
432
- await pressKeyWithModifier( 'primary', 'z' );
433
- expect( await getEditedPostContent() ).toBe( '' );
434
- await page.waitForSelector(
435
- '.editor-history__redo[aria-disabled="false"]'
436
- );
437
- await page.click( '.editor-history__redo[aria-disabled="false"]' );
438
- expect( await getEditedPostContent() ).toMatchInlineSnapshot( `
439
- "<!-- wp:paragraph -->
440
- <p>tonis</p>
441
- <!-- /wp:paragraph -->"
442
- ` );
443
- } );
444
- } );