@wordpress/e2e-tests 3.0.1-next.33ec3857e2.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -1
- package/LICENSE.md +1 -1
- package/package.json +9 -9
- package/plugins/query-block.php +2 -2
- package/specs/editor/blocks/__snapshots__/navigation.test.js.snap +4 -0
- package/specs/editor/blocks/__snapshots__/spacer.test.js.snap +1 -1
- package/specs/editor/blocks/classic.test.js +5 -2
- package/specs/editor/blocks/navigation.test.js +280 -191
- package/specs/editor/plugins/block-variations.test.js +1 -1
- package/specs/editor/plugins/iframed-inline-styles.test.js +0 -6
- package/specs/editor/plugins/iframed-multiple-block-stylesheets.test.js +0 -4
- package/specs/editor/various/__snapshots__/block-editor-keyboard-shortcuts.test.js.snap +38 -24
- package/specs/editor/various/block-editor-keyboard-shortcuts.test.js +43 -3
- package/specs/editor/various/font-size-picker.test.js +57 -11
- package/specs/editor/various/post-editor-template-mode.test.js +1 -1
- package/specs/editor/various/preview.test.js +66 -1
- package/specs/editor/various/reusable-blocks.test.js +52 -5
- package/specs/editor/various/undo.test.js +21 -0
- package/specs/performance/site-editor.test.js +1 -1
- package/specs/site-editor/document-settings.test.js +4 -4
- package/specs/site-editor/multi-entity-editing.test.js +2 -2
- package/specs/site-editor/multi-entity-saving.test.js +15 -18
- package/specs/site-editor/settings-sidebar.test.js +4 -4
- package/specs/site-editor/site-editor-export.test.js +1 -1
- package/specs/site-editor/site-editor-inserter.test.js +1 -1
- package/specs/site-editor/template-part.test.js +9 -12
- package/specs/site-editor/template-revert.test.js +13 -9
- package/specs/widgets/customizing-widgets.test.js +3 -23
- package/specs/widgets/editing-widgets.test.js +36 -12
@@ -1,7 +1,14 @@
|
|
1
|
+
/**
|
2
|
+
* External dependencies
|
3
|
+
*/
|
4
|
+
import { uniqueId } from 'lodash';
|
5
|
+
|
1
6
|
/**
|
2
7
|
* WordPress dependencies
|
3
8
|
*/
|
4
9
|
import {
|
10
|
+
clickButton,
|
11
|
+
clickOnMoreMenuItem,
|
5
12
|
createJSONResponse,
|
6
13
|
createNewPost,
|
7
14
|
createMenu as createClassicMenu,
|
@@ -12,12 +19,15 @@ import {
|
|
12
19
|
saveDraft,
|
13
20
|
showBlockToolbar,
|
14
21
|
openPreviewPage,
|
15
|
-
selectBlockByClientId,
|
16
|
-
getAllBlocks,
|
17
22
|
ensureSidebarOpened,
|
18
23
|
__experimentalRest as rest,
|
19
24
|
publishPost,
|
25
|
+
createUser,
|
26
|
+
loginUser,
|
27
|
+
deleteUser,
|
28
|
+
switchUserToAdmin,
|
20
29
|
} from '@wordpress/e2e-test-utils';
|
30
|
+
import { addQueryArgs } from '@wordpress/url';
|
21
31
|
|
22
32
|
/**
|
23
33
|
* Internal dependencies
|
@@ -26,6 +36,7 @@ import menuItemsFixture from '../fixtures/menu-items-request-fixture.json';
|
|
26
36
|
|
27
37
|
const POSTS_ENDPOINT = '/wp/v2/posts';
|
28
38
|
const PAGES_ENDPOINT = '/wp/v2/pages';
|
39
|
+
const DRAFT_PAGES_ENDPOINT = [ PAGES_ENDPOINT, { status: 'draft' } ];
|
29
40
|
const NAVIGATION_MENUS_ENDPOINT = '/wp/v2/navigation';
|
30
41
|
|
31
42
|
async function mockSearchResponse( items ) {
|
@@ -63,7 +74,10 @@ async function updateActiveNavigationLink( { url, label, type } ) {
|
|
63
74
|
};
|
64
75
|
|
65
76
|
if ( url ) {
|
66
|
-
await page.
|
77
|
+
const input = await page.waitForSelector(
|
78
|
+
'input[placeholder="Search or type url"]'
|
79
|
+
);
|
80
|
+
await input.type( url );
|
67
81
|
|
68
82
|
const suggestionPath = `//button[contains(@class, 'block-editor-link-control__search-item') and contains(@class, '${ typeClasses[ type ] }')]/span/span[@class='block-editor-link-control__search-item-title']/mark[text()="${ url }"]`;
|
69
83
|
|
@@ -111,21 +125,7 @@ const PLACEHOLDER_ACTIONS_CLASS = 'wp-block-navigation-placeholder__actions';
|
|
111
125
|
const PLACEHOLDER_ACTIONS_XPATH = `//*[contains(@class, '${ PLACEHOLDER_ACTIONS_CLASS }')]`;
|
112
126
|
const START_EMPTY_XPATH = `${ PLACEHOLDER_ACTIONS_XPATH }//button[text()='Start empty']`;
|
113
127
|
const ADD_ALL_PAGES_XPATH = `${ PLACEHOLDER_ACTIONS_XPATH }//button[text()='Add all pages']`;
|
114
|
-
|
115
|
-
async function turnResponsivenessOn() {
|
116
|
-
const blocks = await getAllBlocks();
|
117
|
-
|
118
|
-
await selectBlockByClientId( blocks[ 0 ].clientId );
|
119
|
-
await ensureSidebarOpened();
|
120
|
-
|
121
|
-
const [ responsivenessToggleButton ] = await page.$x(
|
122
|
-
'//label[text()[contains(.,"Enable responsive menu")]]'
|
123
|
-
);
|
124
|
-
|
125
|
-
await responsivenessToggleButton.click();
|
126
|
-
|
127
|
-
await saveDraft();
|
128
|
-
}
|
128
|
+
const SELECT_MENU_XPATH = `${ PLACEHOLDER_ACTIONS_XPATH }//button[text()='Select menu']`;
|
129
129
|
|
130
130
|
/**
|
131
131
|
* Delete all items for the given REST resources using the REST API.
|
@@ -133,8 +133,17 @@ async function turnResponsivenessOn() {
|
|
133
133
|
* @param {*} endpoints The endpoints of the resources to delete.
|
134
134
|
*/
|
135
135
|
async function deleteAll( endpoints ) {
|
136
|
-
for ( const
|
137
|
-
const
|
136
|
+
for ( const endpoint of endpoints ) {
|
137
|
+
const defaultArgs = { per_page: -1 };
|
138
|
+
const isArrayEndpoint = Array.isArray( endpoint );
|
139
|
+
const path = isArrayEndpoint ? endpoint[ 0 ] : endpoint;
|
140
|
+
const args = isArrayEndpoint
|
141
|
+
? { ...defaultArgs, ...endpoint[ 1 ] }
|
142
|
+
: defaultArgs;
|
143
|
+
|
144
|
+
const items = await rest( {
|
145
|
+
path: addQueryArgs( path, args ),
|
146
|
+
} );
|
138
147
|
|
139
148
|
for ( const item of items ) {
|
140
149
|
await rest( {
|
@@ -192,6 +201,10 @@ async function getNavigationMenuRawContent() {
|
|
192
201
|
return navigationBlock.attributes.ref;
|
193
202
|
} );
|
194
203
|
|
204
|
+
if ( ! menuRef ) {
|
205
|
+
throw 'getNavigationMenuRawContent was unable to find a ref attribute on the first navigation block';
|
206
|
+
}
|
207
|
+
|
195
208
|
const response = await rest( {
|
196
209
|
method: 'GET',
|
197
210
|
path: `/wp/v2/navigation/${ menuRef }?context=edit`,
|
@@ -203,10 +216,23 @@ async function getNavigationMenuRawContent() {
|
|
203
216
|
// Disable reason - these tests are to be re-written.
|
204
217
|
// eslint-disable-next-line jest/no-disabled-tests
|
205
218
|
describe( 'Navigation', () => {
|
219
|
+
const contributorUsername = uniqueId( 'contributoruser_' );
|
220
|
+
let contributorPassword;
|
221
|
+
|
222
|
+
beforeAll( async () => {
|
223
|
+
// Creation of the contributor user **MUST** be at the top level describe block
|
224
|
+
// otherwise this test will become unstable. This action only happens once
|
225
|
+
// so there is no huge performance hit.
|
226
|
+
contributorPassword = await createUser( contributorUsername, {
|
227
|
+
role: 'contributor',
|
228
|
+
} );
|
229
|
+
} );
|
230
|
+
|
206
231
|
beforeEach( async () => {
|
207
232
|
await deleteAll( [
|
208
233
|
POSTS_ENDPOINT,
|
209
234
|
PAGES_ENDPOINT,
|
235
|
+
DRAFT_PAGES_ENDPOINT,
|
210
236
|
NAVIGATION_MENUS_ENDPOINT,
|
211
237
|
] );
|
212
238
|
await deleteAllClassicMenus();
|
@@ -220,9 +246,14 @@ describe( 'Navigation', () => {
|
|
220
246
|
await deleteAll( [
|
221
247
|
POSTS_ENDPOINT,
|
222
248
|
PAGES_ENDPOINT,
|
249
|
+
DRAFT_PAGES_ENDPOINT,
|
223
250
|
NAVIGATION_MENUS_ENDPOINT,
|
224
251
|
] );
|
225
252
|
await deleteAllClassicMenus();
|
253
|
+
|
254
|
+
// As per the creation in the beforeAll() above, this
|
255
|
+
// action must be done at the root level describe() block.
|
256
|
+
await deleteUser( contributorUsername );
|
226
257
|
} );
|
227
258
|
|
228
259
|
describe( 'placeholder', () => {
|
@@ -252,7 +283,7 @@ describe( 'Navigation', () => {
|
|
252
283
|
await allPagesButton.click();
|
253
284
|
|
254
285
|
// Wait for the page list block to be present
|
255
|
-
await page.waitForSelector( '
|
286
|
+
await page.waitForSelector( 'ul[aria-label="Block: Page List"]' );
|
256
287
|
|
257
288
|
expect( await getNavigationMenuRawContent() ).toMatchSnapshot();
|
258
289
|
} );
|
@@ -438,52 +469,53 @@ describe( 'Navigation', () => {
|
|
438
469
|
expect( await getNavigationMenuRawContent() ).toMatchSnapshot();
|
439
470
|
} );
|
440
471
|
|
441
|
-
|
442
|
-
it.skip( 'allows pages to be created from the navigation block and their links added to menu', async () => {
|
472
|
+
it( 'allows pages to be created from the navigation block and their links added to menu', async () => {
|
443
473
|
await createNewPost();
|
444
474
|
await insertBlock( 'Navigation' );
|
445
475
|
const startEmptyButton = await page.waitForXPath( START_EMPTY_XPATH );
|
446
476
|
await startEmptyButton.click();
|
447
|
-
|
448
477
|
const appender = await page.waitForSelector(
|
449
478
|
'.wp-block-navigation .block-list-appender'
|
450
479
|
);
|
451
480
|
await appender.click();
|
452
481
|
|
453
482
|
// Wait for URL input to be focused
|
454
|
-
await page.waitForSelector(
|
455
|
-
'input.block-editor-url-input__input:focus'
|
456
|
-
);
|
457
|
-
|
458
483
|
// Insert name for the new page.
|
459
|
-
|
460
|
-
|
461
|
-
'A really long page name that will not exist'
|
462
|
-
);
|
463
|
-
|
464
|
-
// Wait for URL input to be focused
|
465
|
-
await page.waitForSelector(
|
484
|
+
const pageTitle = 'A really long page name that will not exist';
|
485
|
+
const input = await page.waitForSelector(
|
466
486
|
'input.block-editor-url-input__input:focus'
|
467
487
|
);
|
468
|
-
|
469
|
-
|
470
|
-
|
488
|
+
await input.type( pageTitle );
|
489
|
+
|
490
|
+
// When creating a page, the URLControl makes a request to the
|
491
|
+
// url-details endpoint to fetch information about the page.
|
492
|
+
// Because the draft is inaccessible publicly, this request
|
493
|
+
// returns a 404 response. Wait for the response and expect
|
494
|
+
// the error to have occurred.
|
495
|
+
const createPageButton = await page.waitForSelector(
|
471
496
|
'.block-editor-link-control__search-create'
|
472
497
|
);
|
473
|
-
|
474
|
-
|
475
|
-
|
498
|
+
const responsePromise = page.waitForResponse(
|
499
|
+
( response ) =>
|
500
|
+
response.url().includes( 'url-details' ) &&
|
501
|
+
response.status() === 404
|
476
502
|
);
|
503
|
+
const createPagePromise = createPageButton.click();
|
504
|
+
await Promise.all( [ responsePromise, createPagePromise ] );
|
477
505
|
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
506
|
+
// Creating a draft is async, so wait for a sign of completion. In this
|
507
|
+
// case the link that shows in the URL popover once a link is added.
|
508
|
+
await page.waitForXPath(
|
509
|
+
`//a[contains(@class, "block-editor-link-control__search-item-title") and contains(., "${ pageTitle }")]`
|
482
510
|
);
|
483
|
-
|
511
|
+
|
512
|
+
await publishPost();
|
484
513
|
|
485
514
|
// Expect a Navigation Block with a link for "A really long page name that will not exist".
|
486
515
|
expect( await getNavigationMenuRawContent() ).toMatchSnapshot();
|
516
|
+
expect( console ).toHaveErroredWith(
|
517
|
+
'Failed to load resource: the server responded with a status of 404 (Not Found)'
|
518
|
+
);
|
487
519
|
} );
|
488
520
|
|
489
521
|
it( 'renders buttons for the submenu opener elements when the block is set to open on click instead of hover', async () => {
|
@@ -564,125 +596,41 @@ describe( 'Navigation', () => {
|
|
564
596
|
expect( quickInserter ).toBeTruthy();
|
565
597
|
} );
|
566
598
|
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
// {
|
574
|
-
// title: 'Home',
|
575
|
-
// slug: 'home',
|
576
|
-
// },
|
577
|
-
// {
|
578
|
-
// title: 'About',
|
579
|
-
// slug: 'about',
|
580
|
-
// },
|
581
|
-
// {
|
582
|
-
// title: 'Contact Us',
|
583
|
-
// slug: 'contact',
|
584
|
-
// },
|
585
|
-
// ] );
|
586
|
-
|
587
|
-
// Create first block at the start in order to enable preview.
|
588
|
-
await insertBlock( 'Navigation' );
|
589
|
-
await saveDraft();
|
590
|
-
|
591
|
-
const previewPage = await openPreviewPage();
|
592
|
-
const isScriptLoaded = await previewPage.evaluate(
|
593
|
-
() =>
|
594
|
-
null !==
|
595
|
-
document.querySelector(
|
596
|
-
'script[src*="navigation/view.min.js"]'
|
597
|
-
)
|
599
|
+
it( 'supports navigation blocks that have inner blocks within their markup and converts them to wp_navigation posts', async () => {
|
600
|
+
// Insert 'old-school' inner blocks via the code editor.
|
601
|
+
await createNewPost();
|
602
|
+
await clickOnMoreMenuItem( 'Code editor' );
|
603
|
+
const codeEditorInput = await page.waitForSelector(
|
604
|
+
'.editor-post-text-editor'
|
598
605
|
);
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
await
|
604
|
-
await
|
605
|
-
|
606
|
-
await allPagesButton2.click();
|
607
|
-
await turnResponsivenessOn();
|
608
|
-
|
609
|
-
await previewPage.reload( {
|
610
|
-
waitFor: [ 'networkidle0', 'domcontentloaded' ],
|
611
|
-
} );
|
612
|
-
|
613
|
-
/*
|
614
|
-
Count instances of the tag to make sure that it's been loaded only once,
|
615
|
-
regardless of the number of navigation blocks present.
|
616
|
-
*/
|
617
|
-
const tagCount = await previewPage.evaluate(
|
618
|
-
() =>
|
619
|
-
Array.from(
|
620
|
-
document.querySelectorAll(
|
621
|
-
'script[src*="navigation/view.min.js"]'
|
622
|
-
)
|
623
|
-
).length
|
606
|
+
await codeEditorInput.click();
|
607
|
+
const markup =
|
608
|
+
'<!-- wp:navigation --><!-- wp:page-list /--><!-- /wp:navigation -->';
|
609
|
+
await page.keyboard.type( markup );
|
610
|
+
await clickButton( 'Exit code editor' );
|
611
|
+
const navBlock = await page.waitForSelector(
|
612
|
+
'nav[aria-label="Block: Navigation"]'
|
624
613
|
);
|
614
|
+
// Select the block to convert to a wp_navigation and publish.
|
615
|
+
// The select menu button shows up when saving is complete.
|
616
|
+
await navBlock.click();
|
617
|
+
await page.waitForSelector( 'button[aria-label="Select Menu"]' );
|
618
|
+
await publishPost();
|
625
619
|
|
626
|
-
|
620
|
+
// Check that the wp_navigation post has the page list block.
|
621
|
+
expect( await getNavigationMenuRawContent() ).toMatchSnapshot();
|
627
622
|
} );
|
628
623
|
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
// title: 'Home',
|
633
|
-
// slug: 'home',
|
634
|
-
// },
|
635
|
-
// {
|
636
|
-
// title: 'About',
|
637
|
-
// slug: 'about',
|
638
|
-
// },
|
639
|
-
// {
|
640
|
-
// title: 'Contact Us',
|
641
|
-
// slug: 'contact',
|
642
|
-
// },
|
643
|
-
// ] );
|
624
|
+
describe( 'Creating and restarting', () => {
|
625
|
+
const NAV_ENTITY_SELECTOR =
|
626
|
+
'//div[@class="entities-saved-states__panel"]//label//strong[contains(text(), "Navigation")]';
|
644
627
|
|
645
|
-
await insertBlock( 'Navigation' );
|
646
|
-
await saveDraft();
|
647
|
-
|
648
|
-
const previewPage = await openPreviewPage();
|
649
|
-
let isScriptLoaded = await previewPage.evaluate(
|
650
|
-
() =>
|
651
|
-
null !==
|
652
|
-
document.querySelector(
|
653
|
-
'script[src*="navigation/view.min.js"]'
|
654
|
-
)
|
655
|
-
);
|
656
|
-
|
657
|
-
expect( isScriptLoaded ).toBe( false );
|
658
|
-
|
659
|
-
const allPagesButton = await page.waitForXPath( ADD_ALL_PAGES_XPATH );
|
660
|
-
await allPagesButton.click();
|
661
|
-
|
662
|
-
await turnResponsivenessOn();
|
663
|
-
|
664
|
-
await previewPage.reload( {
|
665
|
-
waitFor: [ 'networkidle0', 'domcontentloaded' ],
|
666
|
-
} );
|
667
|
-
|
668
|
-
isScriptLoaded = await previewPage.evaluate(
|
669
|
-
() =>
|
670
|
-
null !==
|
671
|
-
document.querySelector(
|
672
|
-
'script[src*="navigation/view.min.js"]'
|
673
|
-
)
|
674
|
-
);
|
675
|
-
|
676
|
-
expect( isScriptLoaded ).toBe( true );
|
677
|
-
} );
|
678
|
-
|
679
|
-
describe.skip( 'Creating and restarting', () => {
|
680
628
|
async function populateNavWithOneItem() {
|
681
629
|
// Add a Link block first.
|
682
|
-
await page.waitForSelector(
|
630
|
+
const appender = await page.waitForSelector(
|
683
631
|
'.wp-block-navigation .block-list-appender'
|
684
632
|
);
|
685
|
-
await
|
633
|
+
await appender.click();
|
686
634
|
// Add a link to the Link block.
|
687
635
|
await updateActiveNavigationLink( {
|
688
636
|
url: 'https://wordpress.org',
|
@@ -692,62 +640,88 @@ describe( 'Navigation', () => {
|
|
692
640
|
}
|
693
641
|
|
694
642
|
async function resetNavBlockToInitialState() {
|
695
|
-
await page.waitForSelector(
|
696
|
-
|
697
|
-
|
698
|
-
await
|
699
|
-
const newMenuButton = await page
|
643
|
+
const selectMenuDropdown = await page.waitForSelector(
|
644
|
+
'[aria-label="Select Menu"]'
|
645
|
+
);
|
646
|
+
await selectMenuDropdown.click();
|
647
|
+
const newMenuButton = await page.waitForXPath(
|
700
648
|
'//span[text()="Create new menu"]'
|
701
649
|
);
|
702
|
-
newMenuButton
|
650
|
+
newMenuButton.click();
|
703
651
|
}
|
704
652
|
|
705
|
-
it( '
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
//
|
721
|
-
//
|
653
|
+
it( 'does not retain uncontrolled inner blocks when creating a new entity', async () => {
|
654
|
+
await createNewPost();
|
655
|
+
await clickOnMoreMenuItem( 'Code editor' );
|
656
|
+
const codeEditorInput = await page.waitForSelector(
|
657
|
+
'.editor-post-text-editor'
|
658
|
+
);
|
659
|
+
await codeEditorInput.click();
|
660
|
+
const markup =
|
661
|
+
'<!-- wp:navigation --><!-- wp:page-list /--><!-- /wp:navigation -->';
|
662
|
+
await page.keyboard.type( markup );
|
663
|
+
await clickButton( 'Exit code editor' );
|
664
|
+
const navBlock = await page.waitForSelector(
|
665
|
+
'nav[aria-label="Block: Navigation"]'
|
666
|
+
);
|
667
|
+
|
668
|
+
// Select the block to convert to a wp_navigation and publish.
|
669
|
+
// The select menu button shows up when saving is complete.
|
670
|
+
await navBlock.click();
|
671
|
+
await page.waitForSelector( 'button[aria-label="Select Menu"]' );
|
672
|
+
|
673
|
+
// Reset the nav block to create a new entity.
|
674
|
+
await resetNavBlockToInitialState();
|
675
|
+
const startEmptyButton = await page.waitForXPath(
|
676
|
+
START_EMPTY_XPATH
|
677
|
+
);
|
678
|
+
await startEmptyButton.click();
|
679
|
+
await populateNavWithOneItem();
|
680
|
+
|
681
|
+
// Confirm that only the last menu entity was updated.
|
682
|
+
const publishPanelButton2 = await page.waitForSelector(
|
683
|
+
'.editor-post-publish-button__button:not([aria-disabled="true"])'
|
684
|
+
);
|
685
|
+
await publishPanelButton2.click();
|
722
686
|
|
687
|
+
await page.waitForXPath( NAV_ENTITY_SELECTOR );
|
688
|
+
expect( await page.$x( NAV_ENTITY_SELECTOR ) ).toHaveLength( 1 );
|
689
|
+
} );
|
690
|
+
|
691
|
+
it( 'only updates a single entity currently linked with the block', async () => {
|
692
|
+
await createNewPost();
|
723
693
|
await insertBlock( 'Navigation' );
|
694
|
+
|
724
695
|
const startEmptyButton = await page.waitForXPath(
|
725
696
|
START_EMPTY_XPATH
|
726
697
|
);
|
727
698
|
await startEmptyButton.click();
|
728
699
|
await populateNavWithOneItem();
|
729
700
|
|
730
|
-
//
|
731
|
-
await page.waitForSelector(
|
701
|
+
// Confirm that the menu entity was updated.
|
702
|
+
const publishPanelButton = await page.waitForSelector(
|
732
703
|
'.editor-post-publish-panel__toggle:not([aria-disabled="true"])'
|
733
704
|
);
|
734
|
-
await
|
705
|
+
await publishPanelButton.click();
|
735
706
|
|
736
|
-
const NAV_ENTITY_SELECTOR =
|
737
|
-
'//div[@class="entities-saved-states__panel"]//label//strong[contains(text(), "Navigation")]';
|
738
707
|
await page.waitForXPath( NAV_ENTITY_SELECTOR );
|
739
708
|
expect( await page.$x( NAV_ENTITY_SELECTOR ) ).toHaveLength( 1 );
|
740
709
|
|
741
710
|
// Publish the post
|
742
|
-
await page.
|
743
|
-
|
744
|
-
|
711
|
+
const entitySaveButton = await page.waitForSelector(
|
712
|
+
'.editor-entities-saved-states__save-button'
|
713
|
+
);
|
714
|
+
await entitySaveButton.click();
|
715
|
+
const publishButton = await page.waitForSelector(
|
716
|
+
'.editor-post-publish-button:not([aria-disabled="true"])'
|
717
|
+
);
|
718
|
+
await publishButton.click();
|
745
719
|
|
746
|
-
// A success notice should show up
|
720
|
+
// A success notice should show up.
|
747
721
|
await page.waitForSelector( '.components-snackbar' );
|
748
722
|
|
749
723
|
// Now try inserting another Link block via the quick inserter.
|
750
|
-
await page.
|
724
|
+
await page.click( 'nav[aria-label="Block: Navigation"]' );
|
751
725
|
|
752
726
|
await resetNavBlockToInitialState();
|
753
727
|
const startEmptyButton2 = await page.waitForXPath(
|
@@ -756,14 +730,129 @@ describe( 'Navigation', () => {
|
|
756
730
|
await startEmptyButton2.click();
|
757
731
|
await populateNavWithOneItem();
|
758
732
|
|
759
|
-
//
|
760
|
-
await page.waitForSelector(
|
733
|
+
// Confirm that only the last menu entity was updated.
|
734
|
+
const publishPanelButton2 = await page.waitForSelector(
|
761
735
|
'.editor-post-publish-button__button:not([aria-disabled="true"])'
|
762
736
|
);
|
763
|
-
await
|
737
|
+
await publishPanelButton2.click();
|
764
738
|
|
765
739
|
await page.waitForXPath( NAV_ENTITY_SELECTOR );
|
766
740
|
expect( await page.$x( NAV_ENTITY_SELECTOR ) ).toHaveLength( 1 );
|
767
741
|
} );
|
768
742
|
} );
|
743
|
+
|
744
|
+
it( 'does not load the frontend script if no navigation blocks are present', async () => {
|
745
|
+
await createNewPost();
|
746
|
+
await insertBlock( 'Paragraph' );
|
747
|
+
await page.waitForSelector( 'p[data-title="Paragraph"]:focus' );
|
748
|
+
await page.keyboard.type( 'Hello' );
|
749
|
+
|
750
|
+
const previewPage = await openPreviewPage();
|
751
|
+
await previewPage.bringToFront();
|
752
|
+
await previewPage.waitForNetworkIdle();
|
753
|
+
|
754
|
+
const isScriptLoaded = await previewPage.evaluate(
|
755
|
+
() =>
|
756
|
+
null !==
|
757
|
+
document.querySelector(
|
758
|
+
'script[src*="navigation/view.min.js"]'
|
759
|
+
)
|
760
|
+
);
|
761
|
+
|
762
|
+
expect( isScriptLoaded ).toBe( false );
|
763
|
+
} );
|
764
|
+
|
765
|
+
it( 'loads the frontend script only once even when multiple navigation blocks are present', async () => {
|
766
|
+
await createNewPost();
|
767
|
+
await insertBlock( 'Navigation' );
|
768
|
+
await insertBlock( 'Navigation' );
|
769
|
+
|
770
|
+
const previewPage = await openPreviewPage();
|
771
|
+
await previewPage.bringToFront();
|
772
|
+
await previewPage.waitForNetworkIdle();
|
773
|
+
|
774
|
+
const tagCount = await previewPage.evaluate(
|
775
|
+
() =>
|
776
|
+
document.querySelectorAll(
|
777
|
+
'script[src*="navigation/view.min.js"]'
|
778
|
+
).length
|
779
|
+
);
|
780
|
+
|
781
|
+
expect( tagCount ).toBe( 1 );
|
782
|
+
} );
|
783
|
+
|
784
|
+
describe( 'Permission based restrictions', () => {
|
785
|
+
afterEach( async () => {
|
786
|
+
await switchUserToAdmin();
|
787
|
+
} );
|
788
|
+
|
789
|
+
it( 'shows a warning if user does not have permission to edit or update navigation menus', async () => {
|
790
|
+
await createNewPost();
|
791
|
+
await insertBlock( 'Navigation' );
|
792
|
+
|
793
|
+
const startEmptyButton = await page.waitForXPath(
|
794
|
+
START_EMPTY_XPATH
|
795
|
+
);
|
796
|
+
|
797
|
+
// This creates an empty Navigation post type entity.
|
798
|
+
await startEmptyButton.click();
|
799
|
+
|
800
|
+
// Publishing the Post ensures the Navigation entity is saved.
|
801
|
+
// The Post itself is irrelevant.
|
802
|
+
await publishPost();
|
803
|
+
|
804
|
+
// Switch to a Contributor role user - they should not have
|
805
|
+
// permission to update Navigation menus.
|
806
|
+
await loginUser( contributorUsername, contributorPassword );
|
807
|
+
|
808
|
+
await createNewPost();
|
809
|
+
|
810
|
+
await insertBlock( 'Navigation' );
|
811
|
+
|
812
|
+
// Select the Navigation post created by the Admin early
|
813
|
+
// in the test.
|
814
|
+
const navigationPostCreatedByAdminName = 'Navigation';
|
815
|
+
const dropdown = await page.waitForXPath( SELECT_MENU_XPATH );
|
816
|
+
await dropdown.click();
|
817
|
+
const theOption = await page.waitForXPath(
|
818
|
+
`//*[contains(@class, 'components-menu-item__item')][ text()="${ navigationPostCreatedByAdminName }" ]`
|
819
|
+
);
|
820
|
+
await theOption.click();
|
821
|
+
|
822
|
+
// Make sure the snackbar error shows up
|
823
|
+
await page.waitForXPath(
|
824
|
+
`//*[contains(@class, 'components-snackbar__content')][ text()="You do not have permission to edit this Menu. Any changes made will not be saved." ]`
|
825
|
+
);
|
826
|
+
|
827
|
+
// Expect a console 403 for request to Navigation Areas for lower permission users.
|
828
|
+
// This is because reading requires the `edit_theme_options` capability
|
829
|
+
// which the Contributor level user does not have.
|
830
|
+
// See: https://github.com/WordPress/gutenberg/blob/4cedaf0c4abb0aeac4bfd4289d63e9889efe9733/lib/class-wp-rest-block-navigation-areas-controller.php#L81-L91.
|
831
|
+
// Todo: removed once Nav Areas are removed from the Gutenberg Plugin.
|
832
|
+
expect( console ).toHaveErrored();
|
833
|
+
} );
|
834
|
+
|
835
|
+
it( 'shows a warning if user does not have permission to create navigation menus', async () => {
|
836
|
+
const noticeText =
|
837
|
+
'You do not have permission to create Navigation Menus.';
|
838
|
+
// Switch to a Contributor role user - they should not have
|
839
|
+
// permission to update Navigations.
|
840
|
+
await loginUser( contributorUsername, contributorPassword );
|
841
|
+
|
842
|
+
await createNewPost();
|
843
|
+
await insertBlock( 'Navigation' );
|
844
|
+
|
845
|
+
// Make sure the snackbar error shows up
|
846
|
+
await page.waitForXPath(
|
847
|
+
`//*[contains(@class, 'components-snackbar__content')][ text()="${ noticeText }" ]`
|
848
|
+
);
|
849
|
+
|
850
|
+
// Expect a console 403 for request to Navigation Areas for lower permission users.
|
851
|
+
// This is because reading requires the `edit_theme_options` capability
|
852
|
+
// which the Contributor level user does not have.
|
853
|
+
// See: https://github.com/WordPress/gutenberg/blob/4cedaf0c4abb0aeac4bfd4289d63e9889efe9733/lib/class-wp-rest-block-navigation-areas-controller.php#L81-L91.
|
854
|
+
// Todo: removed once Nav Areas are removed from the Gutenberg Plugin.
|
855
|
+
expect( console ).toHaveErrored();
|
856
|
+
} );
|
857
|
+
} );
|
769
858
|
} );
|
@@ -181,7 +181,7 @@ describe( 'Block variations', () => {
|
|
181
181
|
).toBeTruthy();
|
182
182
|
const description = await getBlockCardDescription();
|
183
183
|
expect( description ).toEqual(
|
184
|
-
'Start with the building block of all narrative.'
|
184
|
+
'Start with the basic building block of all narrative.'
|
185
185
|
);
|
186
186
|
} );
|
187
187
|
} );
|
@@ -57,11 +57,5 @@ describe( 'iframed inline styles', () => {
|
|
57
57
|
expect( await getComputedStyle( canvas(), 'border-width' ) ).toBe(
|
58
58
|
'2px'
|
59
59
|
);
|
60
|
-
|
61
|
-
expect( console ).toHaveWarned(
|
62
|
-
`Stylesheet iframed-inline-styles-compat-style-css was not properly added.
|
63
|
-
For blocks, use the block API's style (https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#style) or editorStyle (https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#editor-style).
|
64
|
-
For themes, use add_editor_style (https://developer.wordpress.org/block-editor/how-to-guides/themes/theme-support/#editor-styles). <link rel="stylesheet" id="iframed-inline-styles-compat-style-css" href="http://localhost:8889/wp-content/plugins/gutenberg-test-plugins/iframed-inline-styles/compat-style.css?ver=1626189899" media="all">`
|
65
|
-
);
|
66
60
|
} );
|
67
61
|
} );
|
@@ -63,9 +63,5 @@ describe( 'iframed multiple block stylesheets', () => {
|
|
63
63
|
expect( await getComputedStyle( canvas(), 'background-color' ) ).toBe(
|
64
64
|
'rgb(0, 0, 0)'
|
65
65
|
);
|
66
|
-
|
67
|
-
// Skip warnings related to block-styles enqueing and the use of add_editor_style.
|
68
|
-
// The issue is tracked on https://github.com/WordPress/gutenberg/issues/33212.
|
69
|
-
expect( console ).toHaveWarned();
|
70
66
|
} );
|
71
67
|
} );
|