@wordpress/e2e-tests 7.18.1 → 7.19.1-next.79a6196f.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/LICENSE.md +1 -1
  3. package/jest.config.js +0 -1
  4. package/package.json +8 -9
  5. package/plugins/iframed-block/block.json +1 -0
  6. package/plugins/iframed-inline-styles/block.json +1 -0
  7. package/plugins/iframed-masonry-block/block.json +1 -0
  8. package/plugins/iframed-multiple-stylesheets/block.json +1 -0
  9. package/plugins/interactive-blocks/directive-bind/block.json +1 -0
  10. package/plugins/interactive-blocks/directive-body/block.json +1 -0
  11. package/plugins/interactive-blocks/directive-class/block.json +1 -0
  12. package/plugins/interactive-blocks/directive-context/block.json +1 -0
  13. package/plugins/interactive-blocks/directive-init/block.json +1 -0
  14. package/plugins/interactive-blocks/directive-key/block.json +1 -0
  15. package/plugins/interactive-blocks/directive-on/block.json +1 -0
  16. package/plugins/interactive-blocks/directive-priorities/block.json +1 -0
  17. package/plugins/interactive-blocks/directive-slots/block.json +1 -0
  18. package/plugins/interactive-blocks/directive-style/block.json +1 -0
  19. package/plugins/interactive-blocks/directive-text/block.json +1 -0
  20. package/plugins/interactive-blocks/directive-watch/block.json +1 -0
  21. package/plugins/interactive-blocks/negation-operator/block.json +1 -0
  22. package/plugins/interactive-blocks/router-navigate/block.json +1 -0
  23. package/plugins/interactive-blocks/router-navigate/render.php +1 -0
  24. package/plugins/interactive-blocks/router-regions/block.json +1 -0
  25. package/plugins/interactive-blocks/router-regions/render.php +1 -0
  26. package/plugins/interactive-blocks/store-tag/block.json +1 -0
  27. package/plugins/interactive-blocks/store-tag/render.php +1 -0
  28. package/plugins/interactive-blocks/tovdom/block.json +1 -0
  29. package/plugins/interactive-blocks/tovdom-islands/block.json +1 -0
  30. package/plugins/interactive-blocks/tovdom-islands/render.php +12 -0
  31. package/plugins/pattern-recursion.php +22 -0
  32. package/specs/editor/various/change-detection.test.js +5 -1
  33. package/specs/editor/various/inserting-blocks.test.js +3 -5
  34. package/specs/editor/plugins/innerblocks-locking-all-embed.js +0 -56
  35. package/specs/editor/various/__snapshots__/block-editor-keyboard-shortcuts.test.js.snap +0 -153
  36. package/specs/editor/various/allowed-patterns.test.js +0 -74
  37. package/specs/editor/various/block-editor-keyboard-shortcuts.test.js +0 -110
  38. package/specs/editor/various/block-switcher.test.js +0 -130
  39. package/specs/editor/various/core-settings.test.js +0 -42
  40. package/specs/editor/various/datepicker.test.js +0 -148
  41. package/specs/editor/various/dropdown-menu.test.js +0 -143
  42. package/specs/editor/various/editor-modes.test.js +0 -160
  43. package/specs/editor/various/invalid-block.test.js +0 -100
  44. package/specs/editor/various/nux.test.js +0 -158
  45. package/specs/editor/various/preferences.test.js +0 -58
  46. package/specs/editor/various/publish-panel.test.js +0 -82
  47. package/specs/editor/various/publishing.test.js +0 -176
  48. package/specs/editor/various/scheduling.test.js +0 -65
  49. package/specs/editor/various/sidebar.test.js +0 -168
  50. package/specs/editor/various/taxonomies.test.js +0 -251
  51. package/specs/experiments/blocks/post-comments-form.test.js +0 -53
  52. package/specs/experiments/experimental-features.js +0 -39
  53. package/specs/experiments/fixtures/menu-items-request-fixture.json +0 -84
  54. package/specs/site-editor/multi-entity-saving.test.js +0 -239
  55. package/specs/site-editor/settings-sidebar.test.js +0 -122
  56. package/specs/site-editor/site-editor-export.test.js +0 -63
  57. package/specs/widgets/editing-widgets.test.js +0 -962
@@ -1,39 +0,0 @@
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
- }
@@ -1,84 +0,0 @@
1
- [
2
- {
3
- "title": "Home",
4
- "url": "http://localhost:8889/",
5
- "menu_order": 1
6
- },
7
- {
8
- "title": "About",
9
- "type": "post_type",
10
- "object": "page",
11
- "menu_order": 2
12
- },
13
- {
14
- "title": "Our team",
15
- "type": "post_type",
16
- "object": "page",
17
- "menu_order": 3,
18
- "parent": 1
19
- },
20
- {
21
- "title": "Shop",
22
- "type": "post_type",
23
- "object": "page",
24
- "menu_order": 4
25
- },
26
- {
27
- "title": "Winter apparel",
28
- "type": "post_type",
29
- "object": "page",
30
- "menu_order": 5,
31
- "parent": 3
32
- },
33
- {
34
- "title": "Chunky socks",
35
- "type": "post_type",
36
- "object": "page",
37
- "menu_order": 6,
38
- "parent": 4
39
- },
40
- {
41
- "title": "Hideous hats",
42
- "type": "post_type",
43
- "object": "page",
44
- "menu_order": 7,
45
- "parent": 4
46
- },
47
- {
48
- "title": "Glorious gloves",
49
- "type": "post_type",
50
- "object": "page",
51
- "menu_order": 8,
52
- "parent": 4
53
- },
54
- {
55
- "title": "Jazzy Jumpers",
56
- "type": "post_type",
57
- "object": "page",
58
- "menu_order": 9,
59
- "parent": 4
60
- },
61
- {
62
- "title": "Shipping",
63
- "type": "post_type",
64
- "object": "page",
65
- "menu_order": 10
66
- },
67
- {
68
- "title": "Contact Us",
69
- "type": "post_type",
70
- "object": "page",
71
- "menu_order": 11
72
- },
73
- {
74
- "title": "WordPress.org",
75
- "url": "https://wordpress.org",
76
- "menu_order": 12
77
- },
78
- {
79
- "title": "Google",
80
- "url": "https://google.com",
81
- "menu_order": 13,
82
- "parent": 11
83
- }
84
- ]
@@ -1,239 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import {
5
- createNewPost,
6
- disablePrePublishChecks,
7
- getOption,
8
- insertBlock,
9
- publishPost,
10
- setOption,
11
- trashAllPosts,
12
- activateTheme,
13
- clickButton,
14
- createReusableBlock,
15
- deleteAllTemplates,
16
- canvas,
17
- } from '@wordpress/e2e-test-utils';
18
-
19
- describe( 'Multi-entity save flow', () => {
20
- // Selectors - usable between Post/Site editors.
21
- const checkedBoxSelector = '.components-checkbox-control__checked';
22
- const checkboxInputSelector = '.components-checkbox-control__input';
23
- const entitiesSaveSelector = '.editor-entities-saved-states__save-button';
24
- const savePanelSelector = '.entities-saved-states__panel';
25
- const closePanelButtonSelector =
26
- '.editor-post-publish-panel__header-cancel-button button:not(:disabled)';
27
-
28
- // Reusable assertions across Post/Site editors.
29
- const assertAllBoxesChecked = async () => {
30
- const checkedBoxes = await page.$$( checkedBoxSelector );
31
- const checkboxInputs = await page.$$( checkboxInputSelector );
32
- expect( checkedBoxes.length - checkboxInputs.length ).toBe( 0 );
33
- };
34
- const assertExistence = async ( selector, shouldBePresent ) => {
35
- const element = await page.$( selector );
36
- if ( shouldBePresent ) {
37
- expect( element ).not.toBeNull();
38
- } else {
39
- expect( element ).toBeNull();
40
- }
41
- };
42
-
43
- let originalSiteTitle, originalBlogDescription;
44
-
45
- beforeAll( async () => {
46
- await activateTheme( 'emptytheme' );
47
- await deleteAllTemplates( 'wp_template' );
48
- await deleteAllTemplates( 'wp_template_part' );
49
- await trashAllPosts( 'wp_block' );
50
-
51
- // Get the current Site Title and Site Tagline, so that we can reset
52
- // them back to the original values once the test suite has finished.
53
- originalSiteTitle = await getOption( 'blogname' );
54
- originalBlogDescription = await getOption( 'blogdescription' );
55
- } );
56
-
57
- afterAll( async () => {
58
- await activateTheme( 'twentytwentyone' );
59
-
60
- // Reset the Site Title and Site Tagline back to their original values.
61
- await setOption( 'blogname', originalSiteTitle );
62
- await setOption( 'blogdescription', originalBlogDescription );
63
- } );
64
-
65
- describe( 'Post Editor', () => {
66
- // Selectors - Post editor specific.
67
- const draftSavedSelector = '.editor-post-saved-state.is-saved';
68
- const multiSaveSelector =
69
- '.editor-post-publish-button__button.has-changes-dot';
70
- const savePostSelector = '.editor-post-publish-button__button';
71
- const enabledSavePostSelector = `${ savePostSelector }[aria-disabled=false]`;
72
- const publishA11ySelector =
73
- '.edit-post-layout__toggle-publish-panel-button';
74
- const saveA11ySelector =
75
- '.edit-post-layout__toggle-entities-saved-states-panel-button';
76
- const publishPanelSelector = '.editor-post-publish-panel';
77
-
78
- // Reusable assertions inside Post editor.
79
- const assertMultiSaveEnabled = async () => {
80
- const multiSaveButton =
81
- await page.waitForSelector( multiSaveSelector );
82
- expect( multiSaveButton ).not.toBeNull();
83
- };
84
- const assertMultiSaveDisabled = async () => {
85
- const multiSaveButton = await page.waitForSelector(
86
- multiSaveSelector,
87
- { hidden: true }
88
- );
89
- expect( multiSaveButton ).toBeNull();
90
- };
91
-
92
- it( 'Save flow should work as expected.', async () => {
93
- await createNewPost();
94
- // Edit the page some.
95
- await canvas().waitForSelector( '.editor-post-title' );
96
- await canvas().click( '.editor-post-title' );
97
- await page.keyboard.type( 'Test Post...' );
98
- await page.keyboard.press( 'Enter' );
99
-
100
- // Should not trigger multi-entity save button with only post edited.
101
- await assertMultiSaveDisabled();
102
-
103
- // Should only have publish panel a11y button active with only post edited.
104
- await assertExistence( publishA11ySelector, true );
105
- await assertExistence( saveA11ySelector, false );
106
- await assertExistence( publishPanelSelector, false );
107
- await assertExistence( savePanelSelector, false );
108
-
109
- // Add a reusable block and edit it.
110
- await createReusableBlock( 'Hi!', 'Test' );
111
- await canvas().waitForSelector( 'p[data-type="core/paragraph"]' );
112
- await canvas().click( 'p[data-type="core/paragraph"]' );
113
- await page.keyboard.type( 'Oh!' );
114
-
115
- // Should trigger multi-entity save button once template part edited.
116
- await assertMultiSaveEnabled();
117
-
118
- // Should only have save panel a11y button active after child entities edited.
119
- await assertExistence( publishA11ySelector, false );
120
- await assertExistence( saveA11ySelector, true );
121
- await assertExistence( publishPanelSelector, false );
122
- await assertExistence( savePanelSelector, false );
123
-
124
- // Opening panel has boxes checked by default.
125
- await page.click( savePostSelector );
126
- await page.waitForSelector( savePanelSelector );
127
- await assertAllBoxesChecked();
128
-
129
- // Should not show other panels (or their a11y buttons) while save panel opened.
130
- await assertExistence( publishA11ySelector, false );
131
- await assertExistence( saveA11ySelector, false );
132
- await assertExistence( publishPanelSelector, false );
133
-
134
- // Publish panel should open after saving.
135
- await page.click( entitiesSaveSelector );
136
- await page.waitForSelector( publishPanelSelector );
137
-
138
- // No other panels (or their a11y buttons) should be present with publish panel open.
139
- await assertExistence( publishA11ySelector, false );
140
- await assertExistence( saveA11ySelector, false );
141
- await assertExistence( savePanelSelector, false );
142
-
143
- // Close publish panel.
144
- const closePanelButton = await page.waitForSelector(
145
- closePanelButtonSelector
146
- );
147
- await closePanelButton.click();
148
-
149
- // Verify saving is disabled.
150
- const draftSaved = await page.waitForSelector( draftSavedSelector );
151
- expect( draftSaved ).not.toBeNull();
152
- await assertMultiSaveDisabled();
153
- await assertExistence( saveA11ySelector, false );
154
-
155
- await publishPost();
156
- // Wait for the success notice specifically for the published post.
157
- // `publishPost()` has a similar check but it only checks for the
158
- // existence of any snackbars. In this case, there's another "Site updated"
159
- // notice which will be sufficient for that and thus creating a false-positive.
160
- await page.waitForXPath(
161
- '//*[@id="a11y-speak-polite"][contains(text(), "Post published")]'
162
- );
163
-
164
- // Unselect the blocks to avoid clicking the block toolbar.
165
- await page.evaluate( () => {
166
- wp.data.dispatch( 'core/block-editor' ).clearSelectedBlock();
167
- } );
168
-
169
- // Update the post.
170
- await canvas().click( '.editor-post-title' );
171
- await page.keyboard.type( '...more title!' );
172
-
173
- // Verify update button is enabled.
174
- const enabledSaveButton = await page.waitForSelector(
175
- enabledSavePostSelector
176
- );
177
- expect( enabledSaveButton ).not.toBeNull();
178
- // Verify multi-entity saving not enabled.
179
- await assertMultiSaveDisabled();
180
- await assertExistence( saveA11ySelector, false );
181
-
182
- // Update reusable block again.
183
- await canvas().click( 'p[data-type="core/paragraph"]' );
184
- // We need to click again due to the clickthrough overlays in reusable blocks.
185
- await canvas().click( 'p[data-type="core/paragraph"]' );
186
- await page.keyboard.type( 'R!' );
187
-
188
- // Multi-entity saving should be enabled.
189
- await assertMultiSaveEnabled();
190
- await assertExistence( saveA11ySelector, true );
191
- } );
192
-
193
- it( 'Site blocks should save individually', async () => {
194
- await createNewPost();
195
- await disablePrePublishChecks();
196
-
197
- await insertBlock( 'Site Title' );
198
- // Ensure title is retrieved before typing.
199
- await page.waitForXPath(
200
- `//a[contains(text(), "${ originalSiteTitle }")]`
201
- );
202
- const editableSiteTitleSelector =
203
- '.wp-block-site-title a[contenteditable="true"]';
204
- await canvas().waitForSelector( editableSiteTitleSelector );
205
- await canvas().focus( editableSiteTitleSelector );
206
- await page.keyboard.type( '...' );
207
-
208
- await insertBlock( 'Site Tagline' );
209
- // Wait for the placeholder.
210
- await canvas().waitForXPath(
211
- '//span[@data-rich-text-placeholder="Write site tagline…"]'
212
- );
213
- const editableSiteTagLineSelector =
214
- '.wp-block-site-tagline[contenteditable="true"]';
215
- await canvas().waitForSelector( editableSiteTagLineSelector );
216
- await canvas().focus( editableSiteTagLineSelector );
217
- await page.keyboard.type( 'Just another WordPress site' );
218
-
219
- await clickButton( 'Publish' );
220
- await page.waitForSelector( savePanelSelector );
221
- let checkboxInputs = await page.$$( checkboxInputSelector );
222
- expect( checkboxInputs ).toHaveLength( 3 );
223
-
224
- await checkboxInputs[ 1 ].click();
225
- await page.click( entitiesSaveSelector );
226
-
227
- // Wait for the snackbar notice that the post has been published.
228
- await page.waitForSelector( '.components-snackbar' );
229
-
230
- await clickButton( 'Update…' );
231
- await page.waitForSelector( savePanelSelector );
232
-
233
- await page.waitForSelector( checkboxInputSelector );
234
- checkboxInputs = await page.$$( checkboxInputSelector );
235
-
236
- expect( checkboxInputs ).toHaveLength( 1 );
237
- } );
238
- } );
239
- } );
@@ -1,122 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import {
5
- deleteAllTemplates,
6
- activateTheme,
7
- getAllBlocks,
8
- selectBlockByClientId,
9
- insertBlock,
10
- visitSiteEditor,
11
- enterEditMode,
12
- } from '@wordpress/e2e-test-utils';
13
-
14
- async function toggleSidebar() {
15
- await page.click(
16
- '.edit-site-header-edit-mode__actions button[aria-label="Settings"]'
17
- );
18
- }
19
-
20
- async function getActiveTabLabel() {
21
- return await page.$eval(
22
- '.edit-site-sidebar-edit-mode__panel-tab.is-active',
23
- ( element ) => element.getAttribute( 'aria-label' )
24
- );
25
- }
26
-
27
- async function getTemplateCard() {
28
- return {
29
- title: await page.$eval(
30
- '.edit-site-sidebar-card__title',
31
- ( element ) => element.innerText
32
- ),
33
- description: await page.$eval(
34
- '.edit-site-sidebar-card__description',
35
- ( element ) => element.innerText
36
- ),
37
- };
38
- }
39
-
40
- describe( 'Settings sidebar', () => {
41
- beforeAll( async () => {
42
- await activateTheme( 'emptytheme' );
43
- await deleteAllTemplates( 'wp_template' );
44
- await deleteAllTemplates( 'wp_template_part' );
45
- } );
46
- afterAll( async () => {
47
- await deleteAllTemplates( 'wp_template' );
48
- await deleteAllTemplates( 'wp_template_part' );
49
- await activateTheme( 'twentytwentyone' );
50
- } );
51
- beforeEach( async () => {
52
- await visitSiteEditor();
53
- await enterEditMode();
54
- } );
55
-
56
- describe( 'Template tab', () => {
57
- it( 'should open template tab by default if no block is selected', async () => {
58
- await toggleSidebar();
59
-
60
- expect( await getActiveTabLabel() ).toEqual(
61
- 'Template (selected)'
62
- );
63
- } );
64
-
65
- it( "should show the currently selected template's title and description", async () => {
66
- await toggleSidebar();
67
-
68
- const templateCardBeforeNavigation = await getTemplateCard();
69
- await visitSiteEditor( {
70
- postId: 'emptytheme//singular',
71
- postType: 'wp_template',
72
- } );
73
- await enterEditMode();
74
- const templateCardAfterNavigation = await getTemplateCard();
75
-
76
- expect( templateCardBeforeNavigation ).toMatchObject( {
77
- title: 'Index',
78
- description:
79
- 'Used as a fallback template for all pages when a more specific template is not defined.',
80
- } );
81
- expect( templateCardAfterNavigation ).toMatchObject( {
82
- title: 'Single Entries',
83
- description:
84
- 'Displays any single entry, such as a post or a page. This template will serve as a fallback when a more specific template (e.g. Single Post, Page, or Attachment) cannot be found.',
85
- } );
86
- } );
87
- } );
88
-
89
- describe( 'Block tab', () => {
90
- it( 'should open block tab by default if a block is selected', async () => {
91
- const allBlocks = await getAllBlocks();
92
- await selectBlockByClientId( allBlocks[ 0 ].clientId );
93
-
94
- await toggleSidebar();
95
-
96
- expect( await getActiveTabLabel() ).toEqual( 'Block (selected)' );
97
- } );
98
- } );
99
-
100
- describe( 'Tab switch based on selection', () => {
101
- it( 'should switch to block tab if we select a block, when Template is selected', async () => {
102
- await toggleSidebar();
103
- expect( await getActiveTabLabel() ).toEqual(
104
- 'Template (selected)'
105
- );
106
- // By inserting the block is also selected.
107
- await insertBlock( 'Heading' );
108
- expect( await getActiveTabLabel() ).toEqual( 'Block (selected)' );
109
- } );
110
- it( 'should switch to Template tab when a block was selected and we select the Template', async () => {
111
- await insertBlock( 'Heading' );
112
- await toggleSidebar();
113
- expect( await getActiveTabLabel() ).toEqual( 'Block (selected)' );
114
- await page.evaluate( () => {
115
- wp.data.dispatch( 'core/block-editor' ).clearSelectedBlock();
116
- } );
117
- expect( await getActiveTabLabel() ).toEqual(
118
- 'Template (selected)'
119
- );
120
- } );
121
- } );
122
- } );
@@ -1,63 +0,0 @@
1
- /**
2
- * External dependencies
3
- */
4
- import fs from 'fs';
5
- import path from 'path';
6
- import os from 'os';
7
-
8
- /**
9
- * WordPress dependencies
10
- */
11
- import {
12
- deleteAllTemplates,
13
- activateTheme,
14
- visitSiteEditor,
15
- enterEditMode,
16
- clickOnMoreMenuItem,
17
- } from '@wordpress/e2e-test-utils';
18
-
19
- async function waitForFileExists( filePath, timeout = 10000 ) {
20
- const start = Date.now();
21
- while ( ! fs.existsSync( filePath ) ) {
22
- // Puppeteer doesn't have an API for managing file downloads.
23
- // We are using `waitForTimeout` to add delays between check of file existence.
24
- // eslint-disable-next-line no-restricted-syntax
25
- await page.waitForTimeout( 1000 );
26
- if ( Date.now() - start > timeout ) {
27
- throw Error( 'waitForFileExists timeout' );
28
- }
29
- }
30
- }
31
-
32
- describe( 'Site Editor Templates Export', () => {
33
- beforeAll( async () => {
34
- await activateTheme( 'emptytheme' );
35
- await deleteAllTemplates( 'wp_template' );
36
- await deleteAllTemplates( 'wp_template_part' );
37
- } );
38
-
39
- afterAll( async () => {
40
- await activateTheme( 'twentytwentyone' );
41
- } );
42
-
43
- beforeEach( async () => {
44
- await visitSiteEditor();
45
- await enterEditMode();
46
- } );
47
-
48
- it( 'clicking export should download emptytheme.zip file', async () => {
49
- const directory = fs.mkdtempSync(
50
- path.join( os.tmpdir(), 'test-edit-site-export-' )
51
- );
52
- await page._client.send( 'Page.setDownloadBehavior', {
53
- behavior: 'allow',
54
- downloadPath: directory,
55
- } );
56
-
57
- await clickOnMoreMenuItem( 'Export', 'site-editor' );
58
- const filePath = path.join( directory, 'emptytheme.zip' );
59
- await waitForFileExists( filePath );
60
- expect( fs.existsSync( filePath ) ).toBe( true );
61
- fs.unlinkSync( filePath );
62
- } );
63
- } );