@wordpress/e2e-tests 2.5.8 → 2.5.12

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 (26) hide show
  1. package/jest.config.js +1 -0
  2. package/package.json +3 -3
  3. package/specs/{experiments → editor}/blocks/__snapshots__/navigation.test.js.snap +0 -0
  4. package/specs/editor/blocks/cover.test.js +3 -0
  5. package/specs/editor/blocks/image.test.js +16 -11
  6. package/specs/{experiments → editor}/blocks/navigation.test.js +0 -0
  7. package/specs/{experiments → editor}/fixtures/menu-items-response-fixture.json +0 -0
  8. package/specs/{experiments → editor/various}/__snapshots__/post-editor-template-mode.test.js.snap +0 -0
  9. package/specs/editor/various/block-grouping.test.js +46 -0
  10. package/specs/{misc/settings.test.js → editor/various/core-settings.test.js} +0 -0
  11. package/specs/editor/various/format-library/__snapshots__/text-color.test.js.snap +13 -0
  12. package/specs/editor/various/format-library/text-color.test.js +46 -0
  13. package/specs/{experiments → editor/various}/post-editor-template-mode.test.js +0 -0
  14. package/specs/editor/various/writing-flow.test.js +21 -1
  15. package/specs/experiments/experimental-features.js +39 -0
  16. package/specs/experiments/navigation-editor.test.js +1 -1
  17. package/specs/performance/site-editor.test.js +1 -1
  18. package/specs/{experiments → site-editor}/document-settings.test.js +6 -6
  19. package/specs/{experiments → site-editor}/multi-entity-editing.test.js +1 -1
  20. package/specs/{experiments → site-editor}/multi-entity-saving.test.js +1 -1
  21. package/specs/{experiments → site-editor}/settings-sidebar.test.js +3 -4
  22. package/specs/{experiments → site-editor}/site-editor-export.test.js +1 -1
  23. package/specs/{experiments → site-editor}/site-editor-inserter.test.js +1 -1
  24. package/specs/{experiments → site-editor}/template-part.test.js +1 -1
  25. package/specs/{experiments → site-editor}/template-revert.test.js +1 -1
  26. package/{experimental-features.js → specs/site-editor/utils.js} +0 -34
package/jest.config.js CHANGED
@@ -5,6 +5,7 @@ const baseConfig = require( '@wordpress/scripts/config/jest-e2e.config' );
5
5
 
6
6
  module.exports = {
7
7
  ...baseConfig,
8
+ testMatch: [ '<rootDir>/specs/**/*.test.js' ],
8
9
  setupFiles: [ '<rootDir>/config/gutenberg-phase.js' ],
9
10
  setupFilesAfterEnv: [
10
11
  '<rootDir>/config/setup-test-framework.js',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/e2e-tests",
3
- "version": "2.5.8",
3
+ "version": "2.5.12",
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,7 +23,7 @@
23
23
  "node": ">=12"
24
24
  },
25
25
  "dependencies": {
26
- "@wordpress/e2e-test-utils": "^5.4.8",
26
+ "@wordpress/e2e-test-utils": "^5.4.10",
27
27
  "@wordpress/jest-console": "^4.1.1",
28
28
  "@wordpress/jest-puppeteer-axe": "^3.1.1",
29
29
  "@wordpress/scripts": "^19.2.2",
@@ -43,5 +43,5 @@
43
43
  "publishConfig": {
44
44
  "access": "public"
45
45
  },
46
- "gitHead": "6d3bd917064b4b194677233ee426f5988fa441b9"
46
+ "gitHead": "3665e3e1b121046300d8b2fa35074d748f16dbc2"
47
47
  }
@@ -197,6 +197,9 @@ describe( 'Cover', () => {
197
197
  await insertBlock( 'Image' );
198
198
  // Upload image and transform to the Cover block
199
199
  await upload( '.wp-block-image' );
200
+ // Click the block wrapper before trying to convert to make sure figcaption toolbar is not obscuring
201
+ // the block toolbar.
202
+ await page.click( '.wp-block-image' );
200
203
  await transformBlockTo( 'Cover' );
201
204
 
202
205
  // Get the block's background dim color and its opacity
@@ -74,7 +74,7 @@ describe( 'Image', () => {
74
74
  expect( await getEditedPostContent() ).toMatch( regex );
75
75
  } );
76
76
 
77
- it.skip( 'should replace, reset size, and keep selection', async () => {
77
+ it( 'should replace, reset size, and keep selection', async () => {
78
78
  await insertBlock( 'Image' );
79
79
  const filename1 = await upload( '.wp-block-image input[type="file"]' );
80
80
  await waitForImage( filename1 );
@@ -103,8 +103,9 @@ describe( 'Image', () => {
103
103
  `<!-- wp:image {"id":\\d+,"sizeSlug":"full","linkDestination":"none"} -->\\s*<figure class="wp-block-image size-full"><img src="[^"]+\\/${ filename2 }\\.png" alt="" class="wp-image-\\d+"/></figure>\\s*<!-- \\/wp:image -->`
104
104
  );
105
105
  expect( await getEditedPostContent() ).toMatch( regex3 );
106
-
107
- await page.click( '.wp-block-image img' );
106
+ // For some reason just clicking the block wrapper causes figcaption to get focus
107
+ // in puppeteer but not in live browser, so clicking on the image wrapper div here instead.
108
+ await page.click( '.wp-block-image > div' );
108
109
  await page.keyboard.press( 'Backspace' );
109
110
 
110
111
  expect( await getEditedPostContent() ).toBe( '' );
@@ -314,9 +315,13 @@ describe( 'Image', () => {
314
315
 
315
316
  // Upload an initial image.
316
317
  const filename = await upload( '.wp-block-image input[type="file"]' );
317
-
318
+ await waitForImage( filename );
318
319
  // Resize the Uploaded Image.
319
320
  await openDocumentSettingsSidebar();
321
+ await page.waitForSelector(
322
+ '[aria-label="Image size presets"] button:first-child',
323
+ { visible: true }
324
+ );
320
325
  await page.click(
321
326
  '[aria-label="Image size presets"] button:first-child'
322
327
  );
@@ -337,15 +342,15 @@ describe( 'Image', () => {
337
342
  await editButton.click();
338
343
 
339
344
  await page.waitForSelector( '.block-editor-url-input__input' );
340
- await page.evaluate(
341
- () =>
342
- ( document.querySelector(
343
- '.block-editor-url-input__input'
344
- ).value = '' )
345
- );
346
345
 
346
+ // Clear the input field. Delay added to account for typing delays.
347
+ const inputField = await page.$( '.block-editor-url-input__input' );
348
+ await inputField.click( { clickCount: 3, delay: 100 } );
349
+ await page.keyboard.press( 'Backspace', { delay: 100 } );
350
+
351
+ // Replace the url. Delay added to account for typing delays.
347
352
  await page.focus( '.block-editor-url-input__input' );
348
- await page.keyboard.type( imageUrl );
353
+ await page.keyboard.type( imageUrl, { delay: 100 } );
349
354
  await page.click( '.block-editor-link-control__search-submit' );
350
355
 
351
356
  const regexAfter = new RegExp(
@@ -110,6 +110,52 @@ describe( 'Block Grouping', () => {
110
110
  );
111
111
  expect( ungroupButtons ).toHaveLength( 0 );
112
112
  } );
113
+ it( 'should group and ungroup a controlled block properly', async () => {
114
+ const getParagraphText = async () => {
115
+ const paragraphInReusableSelector =
116
+ '.block-editor-block-list__block[data-type="core/block"] p';
117
+ await page.waitForSelector( paragraphInReusableSelector );
118
+ return page.$eval(
119
+ paragraphInReusableSelector,
120
+ ( element ) => element.innerText
121
+ );
122
+ };
123
+
124
+ const paragraphText = 'hi';
125
+ const reusableBlockNameInputSelector =
126
+ '.reusable-blocks-menu-items__convert-modal .components-text-control__input';
127
+ await insertBlock( 'Paragraph' );
128
+ await page.keyboard.type( paragraphText );
129
+
130
+ await clickBlockToolbarButton( 'Options' );
131
+ await clickMenuItem( 'Add to Reusable blocks' );
132
+ const nameInput = await page.waitForSelector(
133
+ reusableBlockNameInputSelector
134
+ );
135
+ await nameInput.click();
136
+ await page.keyboard.type( 'Block' );
137
+ await page.keyboard.press( 'Enter' );
138
+
139
+ // Wait for creation to finish
140
+ await page.waitForXPath(
141
+ '//*[contains(@class, "components-snackbar")]/*[text()="Reusable block created."]'
142
+ );
143
+ // Group
144
+ await clickBlockToolbarButton( 'Options' );
145
+ await clickMenuItem( 'Group' );
146
+
147
+ let group = await page.$$( '[data-type="core/group"]' );
148
+ expect( group ).toHaveLength( 1 );
149
+ // Make sure the paragraph in reusable block exists.
150
+ expect( await getParagraphText() ).toMatch( paragraphText );
151
+
152
+ await clickBlockToolbarButton( 'Options' );
153
+ await clickMenuItem( 'Ungroup' );
154
+ group = await page.$$( '[data-type="core/group"]' );
155
+ expect( group ).toHaveLength( 0 );
156
+ // Make sure the paragraph in reusable block exists.
157
+ expect( await getParagraphText() ).toEqual( paragraphText );
158
+ } );
113
159
  } );
114
160
 
115
161
  describe( 'Grouping Block availability', () => {
@@ -0,0 +1,13 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`RichText should remove highlighting element 1`] = `
4
+ "<!-- wp:paragraph -->
5
+ <p><mark style=\\"background-color:rgba(0, 0, 0, 0)\\" class=\\"has-inline-color has-cyan-bluish-gray-color\\">1</mark></p>
6
+ <!-- /wp:paragraph -->"
7
+ `;
8
+
9
+ exports[`RichText should remove highlighting element 2`] = `
10
+ "<!-- wp:paragraph -->
11
+ <p>1</p>
12
+ <!-- /wp:paragraph -->"
13
+ `;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import {
5
+ createNewPost,
6
+ getEditedPostContent,
7
+ clickBlockAppender,
8
+ pressKeyWithModifier,
9
+ clickBlockToolbarButton,
10
+ } from '@wordpress/e2e-test-utils';
11
+
12
+ describe( 'RichText', () => {
13
+ beforeEach( async () => {
14
+ await createNewPost();
15
+ } );
16
+
17
+ it( 'should remove highlighting element', async () => {
18
+ await clickBlockAppender();
19
+
20
+ // Add text and select to color.
21
+ await page.keyboard.type( '1' );
22
+ await pressKeyWithModifier( 'primary', 'a' );
23
+ await clickBlockToolbarButton( 'More' );
24
+
25
+ const button = await page.waitForXPath(
26
+ `//button[text()='Highlight']`
27
+ );
28
+ // Clicks may fail if the button is out of view. Assure it is before click.
29
+ await button.evaluate( ( element ) => element.scrollIntoView() );
30
+ await button.click();
31
+
32
+ // Use a color name with multiple words to ensure that it becomes
33
+ // active. Previously we had a broken regular expression.
34
+ const option = await page.waitForSelector(
35
+ '[aria-label="Color: Cyan bluish gray"]'
36
+ );
37
+
38
+ await option.click();
39
+
40
+ expect( await getEditedPostContent() ).toMatchSnapshot();
41
+
42
+ await option.click();
43
+
44
+ expect( await getEditedPostContent() ).toMatchSnapshot();
45
+ } );
46
+ } );
@@ -13,7 +13,7 @@ import {
13
13
 
14
14
  const getActiveBlockName = async () =>
15
15
  page.evaluate(
16
- () => wp.data.select( 'core/block-editor' ).getSelectedBlock().name
16
+ () => wp.data.select( 'core/block-editor' ).getSelectedBlock()?.name
17
17
  );
18
18
 
19
19
  const addParagraphsAndColumnsDemo = async () => {
@@ -626,4 +626,24 @@ describe( 'Writing Flow', () => {
626
626
  )
627
627
  ).toBe( 'Table' );
628
628
  } );
629
+
630
+ it( 'Should unselect all blocks when hitting double escape', async () => {
631
+ // Add demo content.
632
+ await page.keyboard.press( 'Enter' );
633
+ await page.keyboard.type( 'Random Paragraph' );
634
+
635
+ // Select a block.
636
+ let activeBlockName = await getActiveBlockName();
637
+ expect( activeBlockName ).toBe( 'core/paragraph' );
638
+
639
+ // First escape enters navigaiton mode.
640
+ await page.keyboard.press( 'Escape' );
641
+ activeBlockName = await getActiveBlockName();
642
+ expect( activeBlockName ).toBe( 'core/paragraph' );
643
+
644
+ // Second escape unselects the blocks.
645
+ await page.keyboard.press( 'Escape' );
646
+ activeBlockName = await getActiveBlockName();
647
+ expect( activeBlockName ).toBe( undefined );
648
+ } );
629
649
  } );
@@ -0,0 +1,39 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { addQueryArgs } from '@wordpress/url';
5
+ import { visitAdminPage } from '@wordpress/e2e-test-utils';
6
+
7
+ async function setExperimentalFeaturesState( features, enable ) {
8
+ const query = addQueryArgs( '', {
9
+ page: 'gutenberg-experiments',
10
+ } );
11
+ await visitAdminPage( '/admin.php', query );
12
+
13
+ await Promise.all(
14
+ features.map( async ( feature ) => {
15
+ await page.waitForSelector( feature );
16
+ const checkedSelector = `${ feature }[checked=checked]`;
17
+ const isChecked = !! ( await page.$( checkedSelector ) );
18
+ if ( ( ! isChecked && enable ) || ( isChecked && ! enable ) ) {
19
+ await page.click( feature );
20
+ }
21
+ } )
22
+ );
23
+ await Promise.all( [
24
+ page.waitForNavigation( { waitUntil: 'networkidle0' } ),
25
+ page.click( '#submit' ),
26
+ ] );
27
+ }
28
+
29
+ /**
30
+ * Establishes test lifecycle to enable experimental feature for the duration of
31
+ * the grouped test block.
32
+ *
33
+ * @param {Array} features Array of {string} selectors of settings to enable.
34
+ * Assumes they can be enabled with one click.
35
+ */
36
+ export function useExperimentalFeatures( features ) {
37
+ beforeAll( () => setExperimentalFeaturesState( features, true ) );
38
+ afterAll( () => setExperimentalFeaturesState( features, false ) );
39
+ }
@@ -22,7 +22,7 @@ import { addQueryArgs } from '@wordpress/url';
22
22
  /**
23
23
  * Internal dependencies
24
24
  */
25
- import { useExperimentalFeatures } from '../../experimental-features';
25
+ import { useExperimentalFeatures } from './experimental-features';
26
26
  import menuItemsFixture from './fixtures/menu-items-request-fixture.json';
27
27
 
28
28
  const TYPE_NAMES = {
@@ -19,7 +19,7 @@ import {
19
19
  /**
20
20
  * Internal dependencies
21
21
  */
22
- import { siteEditor } from '../../experimental-features';
22
+ import { siteEditor } from '../site-editor/utils';
23
23
  import {
24
24
  readFile,
25
25
  deleteFile,
@@ -6,14 +6,14 @@ import { trashAllPosts, activateTheme } from '@wordpress/e2e-test-utils';
6
6
  /**
7
7
  * Internal dependencies
8
8
  */
9
- import { siteEditor } from '../../experimental-features';
9
+ import { siteEditor } from './utils';
10
10
 
11
11
  async function getDocumentSettingsTitle() {
12
12
  const titleElement = await page.waitForSelector(
13
13
  '.edit-site-document-actions__title'
14
14
  );
15
15
 
16
- return titleElement.evaluate( ( el ) => el.innerText );
16
+ return titleElement.evaluate( ( el ) => el.textContent );
17
17
  }
18
18
 
19
19
  async function getDocumentSettingsSecondaryTitle() {
@@ -21,7 +21,7 @@ async function getDocumentSettingsSecondaryTitle() {
21
21
  '.edit-site-document-actions__secondary-item'
22
22
  );
23
23
 
24
- return secondaryTitleElement.evaluate( ( el ) => el.innerText );
24
+ return secondaryTitleElement.evaluate( ( el ) => el.textContent );
25
25
  }
26
26
 
27
27
  describe( 'Document Settings', () => {
@@ -50,7 +50,7 @@ describe( 'Document Settings', () => {
50
50
  // Evaluate the document settings title
51
51
  const actual = await getDocumentSettingsTitle();
52
52
 
53
- expect( actual ).toEqual( 'Index' );
53
+ expect( actual ).toEqual( 'Editing template: Index' );
54
54
  } );
55
55
 
56
56
  describe( 'and a template part is clicked in the template', () => {
@@ -70,7 +70,7 @@ describe( 'Document Settings', () => {
70
70
  // Evaluate the document settings secondary title
71
71
  const actual = await getDocumentSettingsSecondaryTitle();
72
72
 
73
- expect( actual ).toEqual( 'Header' );
73
+ expect( actual ).toEqual( 'Editing template part: header' );
74
74
  } );
75
75
  } );
76
76
  } );
@@ -86,7 +86,7 @@ describe( 'Document Settings', () => {
86
86
  // Evaluate the document settings title
87
87
  const actual = await getDocumentSettingsTitle();
88
88
 
89
- expect( actual ).toEqual( 'header' );
89
+ expect( actual ).toEqual( 'Editing template part: header' );
90
90
  } );
91
91
  } );
92
92
  } );
@@ -16,7 +16,7 @@ import {
16
16
  /**
17
17
  * Internal dependencies
18
18
  */
19
- import { navigationPanel, siteEditor } from '../../experimental-features';
19
+ import { navigationPanel, siteEditor } from './utils';
20
20
 
21
21
  const clickTemplateItem = async ( menus, itemName ) => {
22
22
  await navigationPanel.open();
@@ -14,7 +14,7 @@ import {
14
14
  /**
15
15
  * Internal dependencies
16
16
  */
17
- import { siteEditor } from '../../experimental-features';
17
+ import { siteEditor } from './utils';
18
18
 
19
19
  describe( 'Multi-entity save flow', () => {
20
20
  // Selectors - usable between Post/Site editors.
@@ -12,7 +12,7 @@ import {
12
12
  /**
13
13
  * Internal dependencies
14
14
  */
15
- import { siteEditor } from '../../experimental-features';
15
+ import { siteEditor } from './utils';
16
16
 
17
17
  async function toggleSidebar() {
18
18
  await page.click(
@@ -77,12 +77,11 @@ describe( 'Settings sidebar', () => {
77
77
 
78
78
  expect( templateCardBeforeNavigation ).toMatchObject( {
79
79
  title: 'Index',
80
- description:
81
- 'The default template used when no other template is available. This is a required template in WordPress.',
80
+ description: 'Displays posts.',
82
81
  } );
83
82
  expect( templateCardAfterNavigation ).toMatchObject( {
84
83
  title: '404',
85
- description: 'Template shown when no content is found.',
84
+ description: 'Displays when no content is found.',
86
85
  } );
87
86
  } );
88
87
  } );
@@ -13,7 +13,7 @@ import { trashAllPosts, activateTheme } from '@wordpress/e2e-test-utils';
13
13
  /**
14
14
  * Internal dependencies
15
15
  */
16
- import { siteEditor } from '../../experimental-features';
16
+ import { siteEditor } from './utils';
17
17
 
18
18
  async function waitForFileExists( filePath, timeout = 10000 ) {
19
19
  const start = Date.now();
@@ -6,7 +6,7 @@ import { trashAllPosts, activateTheme } from '@wordpress/e2e-test-utils';
6
6
  /**
7
7
  * Internal dependencies
8
8
  */
9
- import { siteEditor } from '../../experimental-features';
9
+ import { siteEditor } from './utils';
10
10
 
11
11
  describe( 'Site Editor Inserter', () => {
12
12
  beforeAll( async () => {
@@ -16,7 +16,7 @@ import {
16
16
  /**
17
17
  * Internal dependencies
18
18
  */
19
- import { siteEditor } from '../../experimental-features';
19
+ import { siteEditor } from './utils';
20
20
 
21
21
  const templatePartNameInput =
22
22
  '.edit-site-create-template-part-modal .components-text-control__input';
@@ -14,7 +14,7 @@ import { addQueryArgs } from '@wordpress/url';
14
14
  /**
15
15
  * Internal dependencies
16
16
  */
17
- import { siteEditor } from '../../experimental-features';
17
+ import { siteEditor } from './utils';
18
18
 
19
19
  const {
20
20
  visit: visitSiteEditor,
@@ -4,40 +4,6 @@
4
4
  import { addQueryArgs } from '@wordpress/url';
5
5
  import { visitAdminPage } from '@wordpress/e2e-test-utils';
6
6
 
7
- async function setExperimentalFeaturesState( features, enable ) {
8
- const query = addQueryArgs( '', {
9
- page: 'gutenberg-experiments',
10
- } );
11
- await visitAdminPage( '/admin.php', query );
12
-
13
- await Promise.all(
14
- features.map( async ( feature ) => {
15
- await page.waitForSelector( feature );
16
- const checkedSelector = `${ feature }[checked=checked]`;
17
- const isChecked = !! ( await page.$( checkedSelector ) );
18
- if ( ( ! isChecked && enable ) || ( isChecked && ! enable ) ) {
19
- await page.click( feature );
20
- }
21
- } )
22
- );
23
- await Promise.all( [
24
- page.waitForNavigation( { waitUntil: 'networkidle0' } ),
25
- page.click( '#submit' ),
26
- ] );
27
- }
28
-
29
- /**
30
- * Establishes test lifecycle to enable experimental feature for the duration of
31
- * the grouped test block.
32
- *
33
- * @param {Array} features Array of {string} selectors of settings to enable.
34
- * Assumes they can be enabled with one click.
35
- */
36
- export function useExperimentalFeatures( features ) {
37
- beforeAll( () => setExperimentalFeaturesState( features, true ) );
38
- afterAll( () => setExperimentalFeaturesState( features, false ) );
39
- }
40
-
41
7
  export const navigationPanel = {
42
8
  async open() {
43
9
  const isOpen = !! ( await page.$(