From 389a4b77f616b7ce7c20ae0aebbf7bf51229b510 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Wed, 15 Dec 2021 15:44:06 +0800 Subject: [PATCH 1/6] Re-enable single entity test --- packages/e2e-tests/specs/editor/blocks/navigation.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/e2e-tests/specs/editor/blocks/navigation.test.js b/packages/e2e-tests/specs/editor/blocks/navigation.test.js index 12d8cb841e8748..07e525fadd19ab 100644 --- a/packages/e2e-tests/specs/editor/blocks/navigation.test.js +++ b/packages/e2e-tests/specs/editor/blocks/navigation.test.js @@ -682,7 +682,7 @@ describe( 'Navigation', () => { expect( await page.$x( NAV_ENTITY_SELECTOR ) ).toHaveLength( 1 ); } ); - it( 'only update a single entity currently linked with the block', async () => { + it( 'only updates a single entity currently linked with the block', async () => { await createNewPost(); await insertBlock( 'Navigation' ); From 7e88ad210b7fedb8c3529f59ce74aedfdb22dc96 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Thu, 16 Dec 2021 10:34:34 +0800 Subject: [PATCH 2/6] Fix and enable page creation test --- .../__snapshots__/navigation.test.js.snap | 2 + .../specs/editor/blocks/navigation.test.js | 37 +++++++++---------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/packages/e2e-tests/specs/editor/blocks/__snapshots__/navigation.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/navigation.test.js.snap index 7b910d141d8ed4..b45293d6464de2 100644 --- a/packages/e2e-tests/specs/editor/blocks/__snapshots__/navigation.test.js.snap +++ b/packages/e2e-tests/specs/editor/blocks/__snapshots__/navigation.test.js.snap @@ -6,6 +6,8 @@ exports[`Navigation allows an empty navigation block to be created and manually " `; +exports[`Navigation allows pages to be created from the navigation block and their links added to menu 1`] = `""`; + exports[`Navigation encodes URL when create block if needed 1`] = ` " diff --git a/packages/e2e-tests/specs/editor/blocks/navigation.test.js b/packages/e2e-tests/specs/editor/blocks/navigation.test.js index 07e525fadd19ab..90f35b0e75297f 100644 --- a/packages/e2e-tests/specs/editor/blocks/navigation.test.js +++ b/packages/e2e-tests/specs/editor/blocks/navigation.test.js @@ -464,43 +464,28 @@ describe( 'Navigation', () => { expect( await getNavigationMenuRawContent() ).toMatchSnapshot(); } ); - // URL details endpoint is throwing a 404, which causes this test to fail. - it.skip( 'allows pages to be created from the navigation block and their links added to menu', async () => { + it( 'allows pages to be created from the navigation block and their links added to menu', async () => { await createNewPost(); await insertBlock( 'Navigation' ); const startEmptyButton = await page.waitForXPath( START_EMPTY_XPATH ); await startEmptyButton.click(); - const appender = await page.waitForSelector( '.wp-block-navigation .block-list-appender' ); await appender.click(); // Wait for URL input to be focused - await page.waitForSelector( - 'input.block-editor-url-input__input:focus' - ); - // Insert name for the new page. - await page.type( - 'input[placeholder="Search or type url"]', - 'A really long page name that will not exist' - ); - - // Wait for URL input to be focused - await page.waitForSelector( + const pageTitle = 'A really long page name that will not exist'; + const input = await page.waitForSelector( 'input.block-editor-url-input__input:focus' ); + await input.type( pageTitle ); // Wait for the create button to appear and click it. - await page.waitForSelector( - '.block-editor-link-control__search-create' - ); - - const createPageButton = await page.$( + const createPageButton = await page.waitForSelector( '.block-editor-link-control__search-create' ); - await createPageButton.click(); const draftLink = await page.waitForSelector( @@ -508,6 +493,18 @@ describe( 'Navigation', () => { ); await draftLink.click(); + // Creating a draft is async, so wait for a sign of completion. In this + // case the link that shows in the URL popover once a link is added. + await page.waitForXPath( + `//a[contains(@class, "block-editor-link-control__search-item-title") and contains(., "${ pageTitle }")]` + ); + + // The URL Details endpoint 404s for the created page, since it will + // be a draft that is inaccessible publicly. Wait for the HTTP request + // to finish, since this seems to make the test more stable. + await page.waitForNetworkIdle(); + expect( console ).toHaveErrored(); + // Expect a Navigation Block with a link for "A really long page name that will not exist". expect( await getNavigationMenuRawContent() ).toMatchSnapshot(); } ); From fee3fb925767d340f6ce523c218f066e498eeef5 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Thu, 16 Dec 2021 11:56:45 +0800 Subject: [PATCH 3/6] Split up and enable script loading tests --- .../specs/editor/blocks/navigation.test.js | 161 ++---------------- 1 file changed, 10 insertions(+), 151 deletions(-) diff --git a/packages/e2e-tests/specs/editor/blocks/navigation.test.js b/packages/e2e-tests/specs/editor/blocks/navigation.test.js index 90f35b0e75297f..fec0a9c7c015b0 100644 --- a/packages/e2e-tests/specs/editor/blocks/navigation.test.js +++ b/packages/e2e-tests/specs/editor/blocks/navigation.test.js @@ -14,8 +14,6 @@ import { saveDraft, showBlockToolbar, openPreviewPage, - selectBlockByClientId, - getAllBlocks, ensureSidebarOpened, __experimentalRest as rest, publishPost, @@ -121,21 +119,6 @@ const START_EMPTY_XPATH = `${ PLACEHOLDER_ACTIONS_XPATH }//button[text()='Start const ADD_ALL_PAGES_XPATH = `${ PLACEHOLDER_ACTIONS_XPATH }//button[text()='Add all pages']`; const SELECT_MENU_XPATH = `${ PLACEHOLDER_ACTIONS_XPATH }//button[text()='Select menu']`; -async function turnResponsivenessOn() { - const blocks = await getAllBlocks(); - - await selectBlockByClientId( blocks[ 0 ].clientId ); - await ensureSidebarOpened(); - - const [ responsivenessToggleButton ] = await page.$x( - '//label[text()[contains(.,"Enable responsive menu")]]' - ); - - await responsivenessToggleButton.click(); - - await saveDraft(); -} - /** * Delete all items for the given REST resources using the REST API. * @@ -732,29 +715,11 @@ describe( 'Navigation', () => { } ); } ); - // The following tests are unstable, roughly around when https://github.com/WordPress/wordpress-develop/pull/1412 - // landed. The block manually tests well, so let's skip to unblock other PRs and immediately follow up. cc @vcanales - it.skip( 'loads frontend code only if the block is present', async () => { - // Mock the response from the Pages endpoint. This is done so that the pages returned are always - // consistent and to test the feature more rigorously than the single default sample page. - // await mockPagesResponse( [ - // { - // title: 'Home', - // slug: 'home', - // }, - // { - // title: 'About', - // slug: 'about', - // }, - // { - // title: 'Contact Us', - // slug: 'contact', - // }, - // ] ); - - // Create first block at the start in order to enable preview. - await insertBlock( 'Navigation' ); - await saveDraft(); + it( 'does not load the frontend script if no navigation blocks are present', async () => { + await createNewPost(); + await insertBlock( 'Paragraph' ); + await page.waitForSelector( 'p[data-title="Paragraph"]:focus' ); + await page.keyboard.type( 'Hello' ); const previewPage = await openPreviewPage(); const isScriptLoaded = await previewPage.evaluate( @@ -766,22 +731,14 @@ describe( 'Navigation', () => { ); expect( isScriptLoaded ).toBe( false ); + } ); - const allPagesButton = await page.waitForXPath( ADD_ALL_PAGES_XPATH ); - await allPagesButton.click(); + it( 'loads the frontend script only once even when multiple navigation blocks are present', async () => { + await createNewPost(); await insertBlock( 'Navigation' ); - const allPagesButton2 = await page.waitForXPath( ADD_ALL_PAGES_XPATH ); - await allPagesButton2.click(); - await turnResponsivenessOn(); - - await previewPage.reload( { - waitFor: [ 'networkidle0', 'domcontentloaded' ], - } ); + await insertBlock( 'Navigation' ); + const previewPage = await openPreviewPage(); - /* - Count instances of the tag to make sure that it's been loaded only once, - regardless of the number of navigation blocks present. - */ const tagCount = await previewPage.evaluate( () => Array.from( @@ -793,102 +750,4 @@ describe( 'Navigation', () => { expect( tagCount ).toBe( 1 ); } ); - - it.skip( 'loads frontend code only if responsiveness is turned on', async () => { - // await mockPagesResponse( [ - // { - // title: 'Home', - // slug: 'home', - // }, - // { - // title: 'About', - // slug: 'about', - // }, - // { - // title: 'Contact Us', - // slug: 'contact', - // }, - // ] ); - - await insertBlock( 'Navigation' ); - await saveDraft(); - - const previewPage = await openPreviewPage(); - let isScriptLoaded = await previewPage.evaluate( - () => - null !== - document.querySelector( - 'script[src*="navigation/view.min.js"]' - ) - ); - - expect( isScriptLoaded ).toBe( false ); - - const allPagesButton = await page.waitForXPath( ADD_ALL_PAGES_XPATH ); - await allPagesButton.click(); - - await turnResponsivenessOn(); - - await previewPage.reload( { - waitFor: [ 'networkidle0', 'domcontentloaded' ], - } ); - - isScriptLoaded = await previewPage.evaluate( - () => - null !== - document.querySelector( - 'script[src*="navigation/view.min.js"]' - ) - ); - - expect( isScriptLoaded ).toBe( true ); - } ); - - describe( 'Permission based restrictions', () => { - it( 'shows a warning if user does not have permission to edit or update navigation menus', async () => { - await createNewPost(); - await insertBlock( 'Navigation' ); - - const startEmptyButton = await page.waitForXPath( - START_EMPTY_XPATH - ); - - // This creates an empty Navigation post type entity. - await startEmptyButton.click(); - - // Publishing the Post ensures the Navigation entity is saved. - // The Post itself is irrelevant. - await publishPost(); - - // Switch to a Contributor role user - they should not have - // permission to update Navigations. - await loginUser( username, contribUserPassword ); - - await createNewPost(); - - await insertBlock( 'Navigation' ); - - // Select the Navigation post created by the Admin early - // in the test. - const navigationPostCreatedByAdminName = 'Navigation'; - const dropdown = await page.waitForXPath( SELECT_MENU_XPATH ); - await dropdown.click(); - const theOption = await page.waitForXPath( - `//*[contains(@class, 'components-menu-item__item')][ text()="${ navigationPostCreatedByAdminName }" ]` - ); - await theOption.click(); - - // Make sure the snackbar error shows up - await page.waitForXPath( - `//*[contains(@class, 'components-snackbar__content')][ text()="You do not have permission to edit this Menu. Any changes made will not be saved." ]` - ); - - // Expect a console 403 for request to Navigation Areas for lower permisison users. - // This is because reading requires the `edit_theme_options` capability - // which the Contributor level user does not have. - // See: https://github.com/WordPress/gutenberg/blob/4cedaf0c4abb0aeac4bfd4289d63e9889efe9733/lib/class-wp-rest-block-navigation-areas-controller.php#L81-L91. - // Todo: removed once Nav Areas are removed from the Gutenberg Plugin. - expect( console ).toHaveErrored(); - } ); - } ); } ); From 1bc857f13920ee3e50084b72e6f2ac99ca21b4ff Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Fri, 17 Dec 2021 16:42:07 +0800 Subject: [PATCH 4/6] Fix page adding test --- .../specs/editor/blocks/__snapshots__/navigation.test.js.snap | 2 +- packages/e2e-tests/specs/editor/blocks/navigation.test.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/e2e-tests/specs/editor/blocks/__snapshots__/navigation.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/navigation.test.js.snap index b45293d6464de2..310dc8a1611219 100644 --- a/packages/e2e-tests/specs/editor/blocks/__snapshots__/navigation.test.js.snap +++ b/packages/e2e-tests/specs/editor/blocks/__snapshots__/navigation.test.js.snap @@ -6,7 +6,7 @@ exports[`Navigation allows an empty navigation block to be created and manually " `; -exports[`Navigation allows pages to be created from the navigation block and their links added to menu 1`] = `""`; +exports[`Navigation allows pages to be created from the navigation block and their links added to menu 1`] = `""`; exports[`Navigation encodes URL when create block if needed 1`] = ` " diff --git a/packages/e2e-tests/specs/editor/blocks/navigation.test.js b/packages/e2e-tests/specs/editor/blocks/navigation.test.js index fec0a9c7c015b0..a20c5e26c8fb56 100644 --- a/packages/e2e-tests/specs/editor/blocks/navigation.test.js +++ b/packages/e2e-tests/specs/editor/blocks/navigation.test.js @@ -488,6 +488,8 @@ describe( 'Navigation', () => { await page.waitForNetworkIdle(); expect( console ).toHaveErrored(); + await publishPost(); + // Expect a Navigation Block with a link for "A really long page name that will not exist". expect( await getNavigationMenuRawContent() ).toMatchSnapshot(); } ); From 9167091a9d105b205e06a2880f5bec3dd1116138 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Fri, 17 Dec 2021 16:42:20 +0800 Subject: [PATCH 5/6] Add permissions test back again --- .../specs/editor/blocks/navigation.test.js | 74 +++++++++++++++---- 1 file changed, 61 insertions(+), 13 deletions(-) diff --git a/packages/e2e-tests/specs/editor/blocks/navigation.test.js b/packages/e2e-tests/specs/editor/blocks/navigation.test.js index a20c5e26c8fb56..633edc53ba8587 100644 --- a/packages/e2e-tests/specs/editor/blocks/navigation.test.js +++ b/packages/e2e-tests/specs/editor/blocks/navigation.test.js @@ -199,17 +199,6 @@ async function getNavigationMenuRawContent() { // Disable reason - these tests are to be re-written. // eslint-disable-next-line jest/no-disabled-tests describe( 'Navigation', () => { - let username; - let contribUserPassword; - - beforeAll( async () => { - username = 'contributoruser'; - - contribUserPassword = await createUser( username, { - role: 'contributor', - } ); - } ); - beforeEach( async () => { await deleteAll( [ POSTS_ENDPOINT, @@ -230,8 +219,6 @@ describe( 'Navigation', () => { NAVIGATION_MENUS_ENDPOINT, ] ); await deleteAllClassicMenus(); - - await deleteUser( username ); } ); describe( 'placeholder', () => { @@ -752,4 +739,65 @@ describe( 'Navigation', () => { expect( tagCount ).toBe( 1 ); } ); + + describe( 'Permission based restrictions', () => { + const contributorUsername = 'contributoruser'; + let contributorPassword; + + beforeAll( async () => { + contributorPassword = await createUser( contributorUsername, { + role: 'contributor', + } ); + } ); + + afterAll( async () => { + await deleteUser( contributorUsername ); + } ); + + it( 'shows a warning if user does not have permission to edit or update navigation menus', async () => { + await createNewPost(); + await insertBlock( 'Navigation' ); + + const startEmptyButton = await page.waitForXPath( + START_EMPTY_XPATH + ); + + // This creates an empty Navigation post type entity. + await startEmptyButton.click(); + + // Publishing the Post ensures the Navigation entity is saved. + // The Post itself is irrelevant. + await publishPost(); + + // Switch to a Contributor role user - they should not have + // permission to update Navigation menus. + await loginUser( contributorUsername, contributorPassword ); + + await createNewPost(); + + await insertBlock( 'Navigation' ); + + // Select the Navigation post created by the Admin early + // in the test. + const navigationPostCreatedByAdminName = 'Navigation'; + const dropdown = await page.waitForXPath( SELECT_MENU_XPATH ); + await dropdown.click(); + const theOption = await page.waitForXPath( + `//*[contains(@class, 'components-menu-item__item')][ text()="${ navigationPostCreatedByAdminName }" ]` + ); + await theOption.click(); + + // Make sure the snackbar error shows up + await page.waitForXPath( + `//*[contains(@class, 'components-snackbar__content')][ text()="You do not have permission to edit this Menu. Any changes made will not be saved." ]` + ); + + // Expect a console 403 for request to Navigation Areas for lower permission users. + // This is because reading requires the `edit_theme_options` capability + // which the Contributor level user does not have. + // See: https://github.com/WordPress/gutenberg/blob/4cedaf0c4abb0aeac4bfd4289d63e9889efe9733/lib/class-wp-rest-block-navigation-areas-controller.php#L81-L91. + // Todo: removed once Nav Areas are removed from the Gutenberg Plugin. + expect( console ).toHaveErrored(); + } ); + } ); } ); From d76e62a213512bb50bdc0957de540d3dca98fe90 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Fri, 17 Dec 2021 17:16:28 +0800 Subject: [PATCH 6/6] Fix script tests --- .../specs/editor/blocks/navigation.test.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/e2e-tests/specs/editor/blocks/navigation.test.js b/packages/e2e-tests/specs/editor/blocks/navigation.test.js index 633edc53ba8587..6f99aca0509993 100644 --- a/packages/e2e-tests/specs/editor/blocks/navigation.test.js +++ b/packages/e2e-tests/specs/editor/blocks/navigation.test.js @@ -248,7 +248,7 @@ describe( 'Navigation', () => { await allPagesButton.click(); // Wait for the page list block to be present - await page.waitForSelector( 'div[aria-label="Block: Page List"]' ); + await page.waitForSelector( 'ul[aria-label="Block: Page List"]' ); expect( await getNavigationMenuRawContent() ).toMatchSnapshot(); } ); @@ -711,6 +711,9 @@ describe( 'Navigation', () => { await page.keyboard.type( 'Hello' ); const previewPage = await openPreviewPage(); + await previewPage.bringToFront(); + await previewPage.waitForNetworkIdle(); + const isScriptLoaded = await previewPage.evaluate( () => null !== @@ -726,14 +729,15 @@ describe( 'Navigation', () => { await createNewPost(); await insertBlock( 'Navigation' ); await insertBlock( 'Navigation' ); + const previewPage = await openPreviewPage(); + await previewPage.bringToFront(); + await previewPage.waitForNetworkIdle(); const tagCount = await previewPage.evaluate( () => - Array.from( - document.querySelectorAll( - 'script[src*="navigation/view.min.js"]' - ) + document.querySelectorAll( + 'script[src*="navigation/view.min.js"]' ).length );