@wordpress/e2e-tests 3.0.7 → 3.0.10-next.a55ed9455a.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/config/setup-performance-test.js +1 -1
- package/config/setup-test-framework.js +1 -1
- package/package.json +7 -7
- package/specs/editor/blocks/__snapshots__/heading.test.js.snap +8 -8
- package/specs/editor/blocks/__snapshots__/navigation.test.js.snap +16 -16
- package/specs/editor/blocks/__snapshots__/quote.test.js.snap +10 -10
- package/specs/editor/blocks/classic.test.js +2 -2
- package/specs/editor/blocks/cover.test.js +17 -17
- package/specs/editor/blocks/image.test.js +4 -3
- package/specs/editor/blocks/list.test.js +1 -1
- package/specs/editor/blocks/navigation.test.js +392 -65
- package/specs/editor/blocks/table.test.js +1 -1
- package/specs/editor/plugins/align-hook.test.js +10 -10
- package/specs/editor/plugins/block-context.test.js +1 -1
- package/specs/editor/plugins/block-directory-add.test.js +14 -14
- package/specs/editor/plugins/custom-post-types.test.js +1 -1
- package/specs/editor/plugins/custom-taxonomies.test.js +3 -3
- package/specs/editor/plugins/meta-attribute-block.test.js +1 -1
- package/specs/editor/plugins/meta-boxes.test.js +3 -3
- package/specs/editor/plugins/templates.test.js +1 -1
- package/specs/editor/plugins/wp-editor-meta-box.test.js +1 -1
- package/specs/editor/various/__snapshots__/block-grouping.test.js.snap +4 -4
- package/specs/editor/various/__snapshots__/inserting-blocks.test.js.snap +2 -2
- package/specs/editor/various/__snapshots__/keep-styles-on-block-transforms.test.js.snap +3 -3
- package/specs/editor/various/autosave.test.js +19 -19
- package/specs/editor/various/block-deletion.test.js +5 -5
- package/specs/editor/various/block-grouping.test.js +29 -12
- package/specs/editor/various/block-hierarchy-navigation.test.js +5 -5
- package/specs/editor/various/change-detection.test.js +3 -3
- package/specs/editor/various/compatibility-classic-editor.test.js +1 -1
- package/specs/editor/various/copy-cut-paste-whole-blocks.test.js +7 -7
- package/specs/editor/various/datepicker.test.js +1 -1
- package/specs/editor/various/duplicating-blocks.test.js +3 -3
- package/specs/editor/various/editor-modes.test.js +5 -5
- package/specs/editor/various/inserting-blocks.test.js +6 -6
- package/specs/editor/various/invalid-block.test.js +4 -4
- package/specs/editor/various/is-typing.test.js +8 -8
- package/specs/editor/various/keyboard-navigable-blocks.test.js +2 -2
- package/specs/editor/various/links.test.js +90 -90
- package/specs/editor/various/list-view.test.js +142 -1
- package/specs/editor/various/manage-reusable-blocks.test.js +5 -5
- package/specs/editor/various/multi-block-selection.test.js +86 -2
- package/specs/editor/various/navigable-toolbar.test.js +1 -1
- package/specs/editor/various/new-post-default-content.test.js +2 -2
- package/specs/editor/various/new-post.test.js +1 -1
- package/specs/editor/various/nux.test.js +11 -11
- package/specs/editor/various/popovers.test.js +3 -3
- package/specs/editor/various/post-editor-template-mode.test.js +189 -11
- package/specs/editor/various/post-visibility.test.js +1 -1
- package/specs/editor/various/preferences.test.js +1 -1
- package/specs/editor/various/preview.test.js +8 -4
- package/specs/editor/various/publish-button.test.js +2 -2
- package/specs/editor/various/publishing.test.js +50 -1
- package/specs/editor/various/reusable-blocks.test.js +31 -31
- package/specs/editor/various/rich-text.test.js +1 -1
- package/specs/editor/various/splitting-merging.test.js +6 -6
- package/specs/editor/various/style-variation.test.js +2 -2
- package/specs/editor/various/switch-to-draft.test.js +256 -0
- package/specs/editor/various/taxonomies.test.js +1 -1
- package/specs/editor/various/toolbar-roving-tabindex.test.js +1 -1
- package/specs/editor/various/writing-flow.test.js +85 -20
- package/specs/experiments/navigation-editor.test.js +168 -3
- package/specs/performance/post-editor.test.js +7 -7
- package/specs/performance/site-editor.test.js +6 -7
- package/specs/site-editor/document-settings.test.js +8 -8
- package/specs/site-editor/multi-entity-editing.test.js +6 -6
- package/specs/site-editor/multi-entity-saving.test.js +5 -4
- package/specs/site-editor/settings-sidebar.test.js +5 -5
- package/specs/site-editor/site-editor-export.test.js +3 -3
- package/specs/site-editor/site-editor-inserter.test.js +3 -3
- package/specs/site-editor/template-part.test.js +27 -26
- package/specs/site-editor/template-revert.test.js +12 -22
- package/specs/widgets/customizing-widgets.test.js +14 -9
- package/specs/widgets/editing-widgets.test.js +8 -7
@@ -26,6 +26,7 @@ import {
|
|
26
26
|
loginUser,
|
27
27
|
deleteUser,
|
28
28
|
switchUserToAdmin,
|
29
|
+
clickBlockToolbarButton,
|
29
30
|
} from '@wordpress/e2e-test-utils';
|
30
31
|
import { addQueryArgs } from '@wordpress/url';
|
31
32
|
|
@@ -83,15 +84,15 @@ async function updateActiveNavigationLink( { url, label, type } ) {
|
|
83
84
|
|
84
85
|
// Wait for the autocomplete suggestion item to appear.
|
85
86
|
await page.waitForXPath( suggestionPath );
|
86
|
-
// Set the suggestion
|
87
|
+
// Set the suggestion.
|
87
88
|
const suggestion = await page.waitForXPath( suggestionPath );
|
88
89
|
|
89
|
-
// Select it (so we're clicking the right one, even if it's further down the list)
|
90
|
+
// Select it (so we're clicking the right one, even if it's further down the list).
|
90
91
|
await suggestion.click();
|
91
92
|
}
|
92
93
|
|
93
94
|
if ( label ) {
|
94
|
-
// Wait for rich text editor input to be focused before we start typing the label
|
95
|
+
// Wait for rich text editor input to be focused before we start typing the label.
|
95
96
|
await page.waitForSelector( ':focus.rich-text' );
|
96
97
|
|
97
98
|
// With https://github.com/WordPress/gutenberg/pull/19686, we're auto-selecting the label if the label is URL-ish.
|
@@ -119,12 +120,31 @@ async function selectClassicMenu( optionText ) {
|
|
119
120
|
`//*[contains(@class, 'components-menu-item__item')][ text()="${ optionText }" ]`
|
120
121
|
);
|
121
122
|
await theOption.click();
|
123
|
+
|
124
|
+
await page.waitForResponse(
|
125
|
+
( response ) =>
|
126
|
+
response.url().includes( 'menu-items' ) && response.status() === 200
|
127
|
+
);
|
128
|
+
}
|
129
|
+
|
130
|
+
async function populateNavWithOneItem() {
|
131
|
+
// Add a Link block first.
|
132
|
+
const appender = await page.waitForSelector(
|
133
|
+
'.wp-block-navigation .block-list-appender'
|
134
|
+
);
|
135
|
+
await appender.click();
|
136
|
+
// Add a link to the Link block.
|
137
|
+
await updateActiveNavigationLink( {
|
138
|
+
url: 'https://wordpress.org',
|
139
|
+
label: 'WP',
|
140
|
+
type: 'url',
|
141
|
+
} );
|
122
142
|
}
|
123
143
|
|
124
144
|
const PLACEHOLDER_ACTIONS_CLASS = 'wp-block-navigation-placeholder__actions';
|
125
145
|
const PLACEHOLDER_ACTIONS_XPATH = `//*[contains(@class, '${ PLACEHOLDER_ACTIONS_CLASS }')]`;
|
126
146
|
const START_EMPTY_XPATH = `${ PLACEHOLDER_ACTIONS_XPATH }//button[text()='Start empty']`;
|
127
|
-
const SELECT_MENU_XPATH = `${ PLACEHOLDER_ACTIONS_XPATH }//button[text()='Select
|
147
|
+
const SELECT_MENU_XPATH = `${ PLACEHOLDER_ACTIONS_XPATH }//button[text()='Select Menu']`;
|
128
148
|
|
129
149
|
/**
|
130
150
|
* Delete all items for the given REST resources using the REST API.
|
@@ -194,6 +214,13 @@ async function getNavigationMenuRawContent() {
|
|
194
214
|
return stripPageIds( response.content.raw );
|
195
215
|
}
|
196
216
|
|
217
|
+
async function waitForBlock( blockName ) {
|
218
|
+
const blockSelector = `[aria-label="Editor content"][role="region"] [aria-label="Block: ${ blockName }"]`;
|
219
|
+
|
220
|
+
// Wait for a Submenu block before making assertion.
|
221
|
+
return page.waitForSelector( blockSelector );
|
222
|
+
}
|
223
|
+
|
197
224
|
// Disable reason - these tests are to be re-written.
|
198
225
|
// eslint-disable-next-line jest/no-disabled-tests
|
199
226
|
describe( 'Navigation', () => {
|
@@ -237,49 +264,246 @@ describe( 'Navigation', () => {
|
|
237
264
|
await deleteUser( contributorUsername );
|
238
265
|
} );
|
239
266
|
|
240
|
-
describe( '
|
241
|
-
it( '
|
242
|
-
await
|
243
|
-
await
|
244
|
-
|
245
|
-
|
267
|
+
describe( 'loading states', () => {
|
268
|
+
it( 'does not show a loading indicator if there is no ref to a Navigation post', async () => {
|
269
|
+
await createNewPost();
|
270
|
+
await clickOnMoreMenuItem( 'Code editor' );
|
271
|
+
const codeEditorInput = await page.waitForSelector(
|
272
|
+
'.editor-post-text-editor'
|
273
|
+
);
|
274
|
+
|
275
|
+
// Simulate block behaviour when loading a page containing an unconfigured Nav block
|
276
|
+
// that is not selected.
|
277
|
+
await codeEditorInput.click();
|
278
|
+
const markup = '<!-- wp:navigation /-->';
|
279
|
+
await page.keyboard.type( markup );
|
280
|
+
await clickButton( 'Exit code editor' );
|
281
|
+
|
282
|
+
// Wait for block to render...
|
283
|
+
const navBlock = await waitForBlock( 'Navigation' );
|
284
|
+
|
285
|
+
// Test specifically for the primary loading indicator because a spinner also exists
|
286
|
+
// in the hidden Placeholder component when it is loading.
|
287
|
+
const loadingSpinner = await navBlock.$(
|
288
|
+
'.wp-block-navigation__loading-indicator.components-spinner'
|
246
289
|
);
|
247
290
|
|
291
|
+
// We should not see the loading state if the block has not been configured and is empty.
|
292
|
+
expect( loadingSpinner ).toBeNull();
|
293
|
+
} );
|
294
|
+
|
295
|
+
it( 'shows a loading indicator whilst ref resolves to Navigation post items', async () => {
|
296
|
+
const testNavId = 1;
|
297
|
+
|
298
|
+
let resolveNavigationRequest;
|
299
|
+
|
300
|
+
// Mock the request for the single Navigation post in order to fully
|
301
|
+
// control the resolution of the request. This will enable the ability
|
302
|
+
// to assert on how the UI responds during the API resolution without
|
303
|
+
// relying on variable factors such as network conditions.
|
304
|
+
await setUpResponseMocking( [
|
305
|
+
{
|
306
|
+
match: ( request ) =>
|
307
|
+
request.url().includes( `rest_route` ) &&
|
308
|
+
request.url().includes( `navigation` ) &&
|
309
|
+
request.url().includes( testNavId ),
|
310
|
+
onRequestMatch: () => {
|
311
|
+
// The Promise simulates a REST API request whose resolultion
|
312
|
+
// the test has full control over.
|
313
|
+
return new Promise( ( resolve ) => {
|
314
|
+
// Assign the resolution function to the var in the
|
315
|
+
// upper scope to afford control over resolution.
|
316
|
+
resolveNavigationRequest = resolve;
|
317
|
+
} );
|
318
|
+
},
|
319
|
+
},
|
320
|
+
] );
|
321
|
+
|
248
322
|
await createNewPost();
|
249
|
-
await
|
250
|
-
|
323
|
+
await clickOnMoreMenuItem( 'Code editor' );
|
324
|
+
const codeEditorInput = await page.waitForSelector(
|
325
|
+
'.editor-post-text-editor'
|
326
|
+
);
|
327
|
+
await codeEditorInput.click();
|
328
|
+
|
329
|
+
// The ID used in this `ref` is that which we mock in the request
|
330
|
+
// above to ensure we can control the resolution of the Navigation post.
|
331
|
+
const markup = `<!-- wp:navigation {"ref":${ testNavId }} /-->`;
|
332
|
+
await page.keyboard.type( markup );
|
333
|
+
await clickButton( 'Exit code editor' );
|
251
334
|
|
252
|
-
|
253
|
-
|
254
|
-
|
335
|
+
const navBlock = await waitForBlock( 'Navigation' );
|
336
|
+
|
337
|
+
// Check for the spinner to be present whilst loading.
|
338
|
+
await navBlock.waitForSelector( '.components-spinner' );
|
339
|
+
|
340
|
+
// Resolve the controlled mocked API request.
|
341
|
+
resolveNavigationRequest();
|
255
342
|
} );
|
256
343
|
|
257
|
-
it( '
|
258
|
-
|
344
|
+
it( 'shows a loading indicator whilst empty Navigation menu is being created', async () => {
|
345
|
+
const testNavId = 1;
|
346
|
+
|
347
|
+
let resolveNavigationRequest;
|
348
|
+
|
349
|
+
// Mock the request for the single Navigation post in order to fully
|
350
|
+
// control the resolution of the request. This will enable the ability
|
351
|
+
// to assert on how the UI responds during the API resolution without
|
352
|
+
// relying on variable factors such as network conditions.
|
353
|
+
await setUpResponseMocking( [
|
354
|
+
{
|
355
|
+
match: ( request ) =>
|
356
|
+
request.url().includes( `rest_route` ) &&
|
357
|
+
request.url().includes( `navigation` ) &&
|
358
|
+
request.url().includes( testNavId ),
|
359
|
+
onRequestMatch: () => {
|
360
|
+
// The Promise simulates a REST API request whose resolultion
|
361
|
+
// the test has full control over.
|
362
|
+
return new Promise( ( resolve ) => {
|
363
|
+
// Assign the resolution function to the var in the
|
364
|
+
// upper scope to afford control over resolution.
|
365
|
+
resolveNavigationRequest = resolve;
|
366
|
+
} );
|
367
|
+
},
|
368
|
+
},
|
369
|
+
] );
|
370
|
+
|
259
371
|
await createNewPost();
|
260
372
|
await insertBlock( 'Navigation' );
|
261
|
-
await selectClassicMenu( 'Test Menu 1' );
|
262
373
|
|
263
|
-
|
264
|
-
|
265
|
-
|
374
|
+
let navBlock = await waitForBlock( 'Navigation' );
|
375
|
+
|
376
|
+
// Create empty Navigation block with no items
|
377
|
+
const startEmptyButton = await page.waitForXPath(
|
378
|
+
START_EMPTY_XPATH
|
266
379
|
);
|
267
|
-
|
380
|
+
await startEmptyButton.click();
|
381
|
+
|
382
|
+
navBlock = await waitForBlock( 'Navigation' );
|
383
|
+
|
384
|
+
// Check for the spinner to be present whilst loading.
|
385
|
+
await navBlock.waitForSelector( '.components-spinner' );
|
386
|
+
|
387
|
+
// Resolve the controlled mocked API request.
|
388
|
+
resolveNavigationRequest();
|
268
389
|
} );
|
390
|
+
} );
|
269
391
|
|
270
|
-
|
271
|
-
|
392
|
+
describe( 'Placeholder', () => {
|
393
|
+
describe( 'placeholder states', () => {
|
394
|
+
it( 'shows placeholder on insertion of block', async () => {
|
395
|
+
await createNewPost();
|
396
|
+
await insertBlock( 'Navigation' );
|
397
|
+
await page.waitForXPath( START_EMPTY_XPATH );
|
398
|
+
} );
|
272
399
|
|
273
|
-
|
274
|
-
|
400
|
+
it( 'shows placeholder preview when unconfigured block is not selected', async () => {
|
401
|
+
await createNewPost();
|
402
|
+
await insertBlock( 'Navigation' );
|
275
403
|
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
404
|
+
// Check for unconfigured Placeholder state to display
|
405
|
+
await page.waitForXPath( START_EMPTY_XPATH );
|
406
|
+
|
407
|
+
// Deselect the Nav block by inserting a new block at the root level
|
408
|
+
// outside of the Nav block.
|
409
|
+
await insertBlock( 'Paragraph' );
|
410
|
+
|
411
|
+
const navBlock = await waitForBlock( 'Navigation' );
|
412
|
+
|
413
|
+
// Check Placeholder Preview is visible.
|
414
|
+
await navBlock.waitForSelector(
|
415
|
+
'.wp-block-navigation-placeholder__preview',
|
416
|
+
{ visible: true }
|
417
|
+
);
|
418
|
+
|
419
|
+
// Check Placeholder Component itself is not visible.
|
420
|
+
await navBlock.waitForSelector(
|
421
|
+
'.wp-block-navigation-placeholder__controls',
|
422
|
+
{ visible: false }
|
423
|
+
);
|
424
|
+
} );
|
425
|
+
|
426
|
+
it( 'shows placeholder preview when block with no menu items is not selected', async () => {
|
427
|
+
await createNewPost();
|
428
|
+
await insertBlock( 'Navigation' );
|
429
|
+
|
430
|
+
// Create empty Navigation block with no items
|
431
|
+
const startEmptyButton = await page.waitForXPath(
|
432
|
+
START_EMPTY_XPATH
|
433
|
+
);
|
434
|
+
await startEmptyButton.click();
|
435
|
+
|
436
|
+
// Wait for block to resolve
|
437
|
+
let navBlock = await waitForBlock( 'Navigation' );
|
438
|
+
|
439
|
+
// Deselect the Nav block by inserting a new block at the root level
|
440
|
+
// outside of the Nav block.
|
441
|
+
await insertBlock( 'Paragraph' );
|
442
|
+
|
443
|
+
// Aquire fresh reference to block
|
444
|
+
navBlock = await waitForBlock( 'Navigation' );
|
445
|
+
|
446
|
+
// Check Placeholder Preview is visible.
|
447
|
+
await navBlock.waitForSelector(
|
448
|
+
'.wp-block-navigation-placeholder__preview',
|
449
|
+
{ visible: true }
|
450
|
+
);
|
451
|
+
|
452
|
+
// Check the block's appender is not visible.
|
453
|
+
const blockAppender = await navBlock.$(
|
454
|
+
'.block-list-appender'
|
455
|
+
);
|
456
|
+
|
457
|
+
expect( blockAppender ).toBeNull();
|
458
|
+
} );
|
459
|
+
} );
|
460
|
+
|
461
|
+
describe( 'placeholder actions', () => {
|
462
|
+
it( 'allows a navigation block to be created from existing menus', async () => {
|
463
|
+
await createClassicMenu( { name: 'Test Menu 1' } );
|
464
|
+
await createClassicMenu(
|
465
|
+
{ name: 'Test Menu 2' },
|
466
|
+
menuItemsFixture
|
467
|
+
);
|
468
|
+
|
469
|
+
await createNewPost();
|
470
|
+
await insertBlock( 'Navigation' );
|
471
|
+
await selectClassicMenu( 'Test Menu 2' );
|
472
|
+
|
473
|
+
// Wait for a navigation link block before making assertion.
|
474
|
+
await page.waitForSelector(
|
475
|
+
'*[aria-label="Block: Custom Link"]'
|
476
|
+
);
|
477
|
+
expect( await getNavigationMenuRawContent() ).toMatchSnapshot();
|
478
|
+
} );
|
479
|
+
|
480
|
+
it( 'creates an empty navigation block when the selected existing menu is also empty', async () => {
|
481
|
+
await createClassicMenu( { name: 'Test Menu 1' } );
|
482
|
+
await createNewPost();
|
483
|
+
await insertBlock( 'Navigation' );
|
484
|
+
await selectClassicMenu( 'Test Menu 1' );
|
485
|
+
|
486
|
+
// Wait for the appender so that we know the navigation menu was created.
|
487
|
+
await page.waitForSelector(
|
488
|
+
'nav[aria-label="Block: Navigation"] button[aria-label="Add block"]'
|
489
|
+
);
|
490
|
+
expect( await getNavigationMenuRawContent() ).toMatchSnapshot();
|
491
|
+
} );
|
492
|
+
|
493
|
+
it( 'does not display the options to create from existing menus if there are no existing menus', async () => {
|
494
|
+
await createNewPost();
|
495
|
+
|
496
|
+
await insertBlock( 'Navigation' );
|
497
|
+
await page.waitForXPath( START_EMPTY_XPATH );
|
498
|
+
|
499
|
+
const placeholderActionsLength = await page.$$eval(
|
500
|
+
`.${ PLACEHOLDER_ACTIONS_CLASS } button`,
|
501
|
+
( els ) => els.length
|
502
|
+
);
|
280
503
|
|
281
|
-
|
282
|
-
|
504
|
+
// Should only be showing "Start empty".
|
505
|
+
expect( placeholderActionsLength ).toEqual( 1 );
|
506
|
+
} );
|
283
507
|
} );
|
284
508
|
} );
|
285
509
|
|
@@ -289,6 +513,11 @@ describe( 'Navigation', () => {
|
|
289
513
|
const startEmptyButton = await page.waitForXPath( START_EMPTY_XPATH );
|
290
514
|
await startEmptyButton.click();
|
291
515
|
|
516
|
+
// Await "success" notice.
|
517
|
+
await page.waitForXPath(
|
518
|
+
'//div[@class="components-snackbar__content"][contains(text(), "Navigation Menu successfully created.")]'
|
519
|
+
);
|
520
|
+
|
292
521
|
const appender = await page.waitForSelector(
|
293
522
|
'.wp-block-navigation .block-list-appender'
|
294
523
|
);
|
@@ -313,7 +542,7 @@ describe( 'Navigation', () => {
|
|
313
542
|
// After adding a new block, search input should be shown immediately.
|
314
543
|
// Verify that Escape would close the popover.
|
315
544
|
// Regression: https://github.com/WordPress/gutenberg/pull/19885
|
316
|
-
// Wait for URL input to be focused
|
545
|
+
// Wait for URL input to be focused.
|
317
546
|
await page.waitForSelector(
|
318
547
|
'input.block-editor-url-input__input:focus'
|
319
548
|
);
|
@@ -378,7 +607,7 @@ describe( 'Navigation', () => {
|
|
378
607
|
);
|
379
608
|
await appenderAgain.click();
|
380
609
|
|
381
|
-
// Wait for URL input to be focused
|
610
|
+
// Wait for URL input to be focused.
|
382
611
|
await page.waitForSelector(
|
383
612
|
'input.block-editor-url-input__input:focus'
|
384
613
|
);
|
@@ -393,7 +622,7 @@ describe( 'Navigation', () => {
|
|
393
622
|
expect( isInURLInput ).toBe( true );
|
394
623
|
await page.keyboard.press( 'Escape' );
|
395
624
|
|
396
|
-
// Click the link placeholder
|
625
|
+
// Click the link placeholder.
|
397
626
|
const placeholder = await page.waitForSelector(
|
398
627
|
'.wp-block-navigation-link__placeholder'
|
399
628
|
);
|
@@ -557,14 +786,17 @@ describe( 'Navigation', () => {
|
|
557
786
|
const markup =
|
558
787
|
'<!-- wp:navigation --><!-- wp:page-list /--><!-- /wp:navigation -->';
|
559
788
|
await page.keyboard.type( markup );
|
789
|
+
|
560
790
|
await clickButton( 'Exit code editor' );
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
// Select the block to convert to a wp_navigation
|
565
|
-
// The select menu button shows up when saving is complete.
|
791
|
+
|
792
|
+
const navBlock = await waitForBlock( 'Navigation' );
|
793
|
+
|
794
|
+
// Select the block to convert to a wp_navigation.
|
566
795
|
await navBlock.click();
|
567
|
-
|
796
|
+
|
797
|
+
// The Page List block is rendered within Navigation InnerBlocks when saving is complete.
|
798
|
+
await waitForBlock( 'Page List' );
|
799
|
+
|
568
800
|
await publishPost();
|
569
801
|
|
570
802
|
// Check that the wp_navigation post has the page list block.
|
@@ -575,20 +807,6 @@ describe( 'Navigation', () => {
|
|
575
807
|
const NAV_ENTITY_SELECTOR =
|
576
808
|
'//div[@class="entities-saved-states__panel"]//label//strong[contains(text(), "Navigation")]';
|
577
809
|
|
578
|
-
async function populateNavWithOneItem() {
|
579
|
-
// Add a Link block first.
|
580
|
-
const appender = await page.waitForSelector(
|
581
|
-
'.wp-block-navigation .block-list-appender'
|
582
|
-
);
|
583
|
-
await appender.click();
|
584
|
-
// Add a link to the Link block.
|
585
|
-
await updateActiveNavigationLink( {
|
586
|
-
url: 'https://wordpress.org',
|
587
|
-
label: 'WP',
|
588
|
-
type: 'url',
|
589
|
-
} );
|
590
|
-
}
|
591
|
-
|
592
810
|
async function resetNavBlockToInitialState() {
|
593
811
|
const selectMenuDropdown = await page.waitForSelector(
|
594
812
|
'[aria-label="Select Menu"]'
|
@@ -611,17 +829,18 @@ describe( 'Navigation', () => {
|
|
611
829
|
'<!-- wp:navigation --><!-- wp:page-list /--><!-- /wp:navigation -->';
|
612
830
|
await page.keyboard.type( markup );
|
613
831
|
await clickButton( 'Exit code editor' );
|
614
|
-
const navBlock = await page.waitForSelector(
|
615
|
-
'nav[aria-label="Block: Navigation"]'
|
616
|
-
);
|
617
832
|
|
618
|
-
|
619
|
-
|
833
|
+
const navBlock = await waitForBlock( 'Navigation' );
|
834
|
+
|
835
|
+
// Select the block to convert to a wp_navigation.
|
620
836
|
await navBlock.click();
|
621
|
-
|
837
|
+
|
838
|
+
// The Page List block is rendered within Navigation InnerBlocks when saving is complete.
|
839
|
+
await waitForBlock( 'Page List' );
|
622
840
|
|
623
841
|
// Reset the nav block to create a new entity.
|
624
842
|
await resetNavBlockToInitialState();
|
843
|
+
|
625
844
|
const startEmptyButton = await page.waitForXPath(
|
626
845
|
START_EMPTY_XPATH
|
627
846
|
);
|
@@ -657,7 +876,7 @@ describe( 'Navigation', () => {
|
|
657
876
|
await page.waitForXPath( NAV_ENTITY_SELECTOR );
|
658
877
|
expect( await page.$x( NAV_ENTITY_SELECTOR ) ).toHaveLength( 1 );
|
659
878
|
|
660
|
-
// Publish the post
|
879
|
+
// Publish the post.
|
661
880
|
const entitySaveButton = await page.waitForSelector(
|
662
881
|
'.editor-entities-saved-states__save-button'
|
663
882
|
);
|
@@ -731,6 +950,113 @@ describe( 'Navigation', () => {
|
|
731
950
|
expect( tagCount ).toBe( 1 );
|
732
951
|
} );
|
733
952
|
|
953
|
+
describe( 'Submenus', () => {
|
954
|
+
it( 'shows button which converts submenu to link when submenu is not-populated (empty)', async () => {
|
955
|
+
const navSubmenuSelector = `[aria-label="Editor content"][role="region"] [aria-label="Block: Submenu"]`;
|
956
|
+
|
957
|
+
await createNewPost();
|
958
|
+
await insertBlock( 'Navigation' );
|
959
|
+
|
960
|
+
const startEmptyButton = await page.waitForXPath(
|
961
|
+
START_EMPTY_XPATH
|
962
|
+
);
|
963
|
+
|
964
|
+
await startEmptyButton.click();
|
965
|
+
|
966
|
+
await populateNavWithOneItem();
|
967
|
+
|
968
|
+
await clickBlockToolbarButton( 'Add submenu' );
|
969
|
+
|
970
|
+
await waitForBlock( 'Submenu' );
|
971
|
+
|
972
|
+
// Revert the Submenu back to a Navigation Link block.
|
973
|
+
await clickBlockToolbarButton( 'Convert to Link' );
|
974
|
+
|
975
|
+
// Check the Submenu block is no longer present.
|
976
|
+
const submenuBlock = await page.$( navSubmenuSelector );
|
977
|
+
|
978
|
+
expect( submenuBlock ).toBeFalsy();
|
979
|
+
} );
|
980
|
+
|
981
|
+
it( 'shows button to convert submenu to link in disabled state when submenu is populated', async () => {
|
982
|
+
await createNewPost();
|
983
|
+
await insertBlock( 'Navigation' );
|
984
|
+
|
985
|
+
const startEmptyButton = await page.waitForXPath(
|
986
|
+
START_EMPTY_XPATH
|
987
|
+
);
|
988
|
+
|
989
|
+
await startEmptyButton.click();
|
990
|
+
|
991
|
+
await populateNavWithOneItem();
|
992
|
+
|
993
|
+
await clickBlockToolbarButton( 'Add submenu' );
|
994
|
+
|
995
|
+
await waitForBlock( 'Submenu' );
|
996
|
+
|
997
|
+
// Add a Link block first.
|
998
|
+
const appender = await page.waitForSelector(
|
999
|
+
'[aria-label="Block: Submenu"] [aria-label="Add block"]'
|
1000
|
+
);
|
1001
|
+
|
1002
|
+
await appender.click();
|
1003
|
+
|
1004
|
+
await updateActiveNavigationLink( {
|
1005
|
+
url: 'https://make.wordpress.org/core/',
|
1006
|
+
label: 'Submenu item #1',
|
1007
|
+
type: 'url',
|
1008
|
+
} );
|
1009
|
+
|
1010
|
+
await clickBlockToolbarButton( 'Select Submenu' );
|
1011
|
+
|
1012
|
+
// Check button exists but is in disabled state.
|
1013
|
+
const disabledConvertToLinkButton = await page.$(
|
1014
|
+
'[aria-label="Block tools"] [aria-label="Convert to Link"][disabled]'
|
1015
|
+
);
|
1016
|
+
|
1017
|
+
expect( disabledConvertToLinkButton ).toBeTruthy();
|
1018
|
+
} );
|
1019
|
+
|
1020
|
+
it( 'shows button to convert submenu to link when submenu is populated with a single incomplete link item', async () => {
|
1021
|
+
// For context on why this test is required please see:
|
1022
|
+
// https://github.com/WordPress/gutenberg/pull/38203#issuecomment-1027672948.
|
1023
|
+
|
1024
|
+
await createNewPost();
|
1025
|
+
await insertBlock( 'Navigation' );
|
1026
|
+
|
1027
|
+
const startEmptyButton = await page.waitForXPath(
|
1028
|
+
START_EMPTY_XPATH
|
1029
|
+
);
|
1030
|
+
|
1031
|
+
await startEmptyButton.click();
|
1032
|
+
|
1033
|
+
await populateNavWithOneItem();
|
1034
|
+
|
1035
|
+
await clickBlockToolbarButton( 'Add submenu' );
|
1036
|
+
|
1037
|
+
await waitForBlock( 'Submenu' );
|
1038
|
+
|
1039
|
+
// Add a Link block first.
|
1040
|
+
const appender = await page.waitForSelector(
|
1041
|
+
'[aria-label="Block: Submenu"] [aria-label="Add block"]'
|
1042
|
+
);
|
1043
|
+
|
1044
|
+
await appender.click();
|
1045
|
+
|
1046
|
+
// Here we intentionally do not populate the inserted Navigation Link block.
|
1047
|
+
// Rather we immediaely click away leaving the link in a state where it has
|
1048
|
+
// no URL of label and can be considered unpopulated.
|
1049
|
+
await clickBlockToolbarButton( 'Select Submenu' );
|
1050
|
+
|
1051
|
+
// Check for non-disabled Convert to Link button.
|
1052
|
+
const convertToLinkButton = await page.$(
|
1053
|
+
'[aria-label="Block tools"] [aria-label="Convert to Link"]:not([disabled])'
|
1054
|
+
);
|
1055
|
+
|
1056
|
+
expect( convertToLinkButton ).toBeTruthy();
|
1057
|
+
} );
|
1058
|
+
} );
|
1059
|
+
|
734
1060
|
describe( 'Permission based restrictions', () => {
|
735
1061
|
afterEach( async () => {
|
736
1062
|
await switchUserToAdmin();
|
@@ -759,9 +1085,10 @@ describe( 'Navigation', () => {
|
|
759
1085
|
|
760
1086
|
await insertBlock( 'Navigation' );
|
761
1087
|
|
762
|
-
// Select the Navigation post created by the Admin
|
1088
|
+
// Select the Navigation post created by the Admin earlier
|
763
1089
|
// in the test.
|
764
1090
|
const navigationPostCreatedByAdminName = 'Navigation';
|
1091
|
+
|
765
1092
|
const dropdown = await page.waitForXPath( SELECT_MENU_XPATH );
|
766
1093
|
await dropdown.click();
|
767
1094
|
const theOption = await page.waitForXPath(
|
@@ -769,7 +1096,7 @@ describe( 'Navigation', () => {
|
|
769
1096
|
);
|
770
1097
|
await theOption.click();
|
771
1098
|
|
772
|
-
// Make sure the snackbar error shows up
|
1099
|
+
// Make sure the snackbar error shows up.
|
773
1100
|
await page.waitForXPath(
|
774
1101
|
`//*[contains(@class, 'components-snackbar__content')][ text()="You do not have permission to edit this Menu. Any changes made will not be saved." ]`
|
775
1102
|
);
|
@@ -792,7 +1119,7 @@ describe( 'Navigation', () => {
|
|
792
1119
|
await createNewPost();
|
793
1120
|
await insertBlock( 'Navigation' );
|
794
1121
|
|
795
|
-
// Make sure the snackbar error shows up
|
1122
|
+
// Make sure the snackbar error shows up.
|
796
1123
|
await page.waitForXPath(
|
797
1124
|
`//*[contains(@class, 'components-snackbar__content')][ text()="${ noticeText }" ]`
|
798
1125
|
);
|
@@ -131,7 +131,7 @@ describe( 'Table', () => {
|
|
131
131
|
// Expect the table to have a header, body and footer with written content.
|
132
132
|
expect( await getEditedPostContent() ).toMatchSnapshot();
|
133
133
|
|
134
|
-
// Toggle off the switches
|
134
|
+
// Toggle off the switches.
|
135
135
|
await headerSwitch[ 0 ].click();
|
136
136
|
await footerSwitch[ 0 ].click();
|
137
137
|
|
@@ -94,32 +94,32 @@ const createCorrectlyAppliesAndRemovesAlignmentTest = (
|
|
94
94
|
it( 'Correctly applies the selected alignment and correctly removes the alignment', async () => {
|
95
95
|
const BUTTON_XPATH = `//button[contains(@class,'components-dropdown-menu__menu-item')]//span[contains(text(), '${ alignLabels[ alignment ] }')]`;
|
96
96
|
|
97
|
-
//
|
97
|
+
// Set the specified alignment.
|
98
98
|
await insertBlock( blockName );
|
99
99
|
await clickBlockToolbarButton( 'Align' );
|
100
100
|
await ( await page.$x( BUTTON_XPATH ) )[ 0 ].click();
|
101
101
|
|
102
|
-
//
|
102
|
+
// Verify the button of the specified alignment is pressed.
|
103
103
|
await expectActiveButtonLabelToBe( alignLabels[ alignment ] );
|
104
104
|
|
105
105
|
let htmlMarkup = await getEditedPostContent();
|
106
106
|
|
107
|
-
//
|
107
|
+
// Verify the markup of the selected alignment was generated.
|
108
108
|
expect( htmlMarkup ).toMatchSnapshot();
|
109
109
|
|
110
|
-
//
|
110
|
+
// Verify the markup can be correctly parsed.
|
111
111
|
await verifyMarkupIsValid( htmlMarkup );
|
112
112
|
|
113
113
|
await selectBlockByClientId( ( await getAllBlocks() )[ 0 ].clientId );
|
114
114
|
|
115
|
-
//
|
115
|
+
// Remove the alignment.
|
116
116
|
await clickBlockToolbarButton( 'Align' );
|
117
117
|
await ( await page.$x( BUTTON_XPATH ) )[ 0 ].click();
|
118
118
|
|
119
|
-
//
|
119
|
+
// Verify 'none' alignment button is in pressed state.
|
120
120
|
await expectActiveButtonLabelToBe( alignLabels.none );
|
121
121
|
|
122
|
-
//
|
122
|
+
// Verify alignment markup was removed from the block.
|
123
123
|
htmlMarkup = await getEditedPostContent();
|
124
124
|
expect( htmlMarkup ).toMatchSnapshot();
|
125
125
|
|
@@ -128,7 +128,7 @@ const createCorrectlyAppliesAndRemovesAlignmentTest = (
|
|
128
128
|
|
129
129
|
await selectBlockByClientId( ( await getAllBlocks() )[ 0 ].clientId );
|
130
130
|
|
131
|
-
//
|
131
|
+
// Verify alignment `none` button is in pressed state after parsing the block.
|
132
132
|
await expectActiveButtonLabelToBe( alignLabels.none );
|
133
133
|
} );
|
134
134
|
};
|
@@ -202,7 +202,7 @@ describe( 'Align Hook Works As Expected', () => {
|
|
202
202
|
|
203
203
|
it( 'Applies the selected alignment by default', async () => {
|
204
204
|
await insertBlock( BLOCK_NAME );
|
205
|
-
//
|
205
|
+
// Verify the correct alignment button is pressed.
|
206
206
|
await clickBlockToolbarButton( 'Align' );
|
207
207
|
const selectedAlignmentControls = await page.$x(
|
208
208
|
SELECTED_ALIGNMENT_CONTROL_SELECTOR
|
@@ -219,7 +219,7 @@ describe( 'Align Hook Works As Expected', () => {
|
|
219
219
|
|
220
220
|
it( 'Can remove the default alignment and the align attribute equals none but alignnone class is not applied', async () => {
|
221
221
|
await insertBlock( BLOCK_NAME );
|
222
|
-
//
|
222
|
+
// Remove the alignment.
|
223
223
|
await clickBlockToolbarButton( 'Align' );
|
224
224
|
const [ selectedAlignmentControl ] = await page.$x(
|
225
225
|
SELECTED_ALIGNMENT_CONTROL_SELECTOR
|