From 9679746a147005d1c43b8c3ab2454e5a950d243e Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Tue, 13 Jun 2023 16:25:39 +0400 Subject: [PATCH 1/4] Migrate block hierarchy navigation tests to Playwright --- .../block-hierarchy-navigation.spec.js | 245 ++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 test/e2e/specs/editor/various/block-hierarchy-navigation.spec.js diff --git a/test/e2e/specs/editor/various/block-hierarchy-navigation.spec.js b/test/e2e/specs/editor/various/block-hierarchy-navigation.spec.js new file mode 100644 index 00000000000000..93bedc1efcbbde --- /dev/null +++ b/test/e2e/specs/editor/various/block-hierarchy-navigation.spec.js @@ -0,0 +1,245 @@ +/** + * WordPress dependencies + */ +const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' ); + +const COLUMNS_BLOCK = [ + { + name: 'core/columns', + innerBlocks: [ + { + name: 'core/column', + innerBlocks: [ + { + name: 'core/paragraph', + attributes: { content: 'First column' }, + }, + ], + }, + { + name: 'core/column', + }, + { + name: 'core/column', + innerBlocks: [ + { + name: 'core/paragraph', + attributes: { content: 'Third column' }, + }, + ], + }, + ], + }, +]; + +test.describe( 'Navigating the block hierarchy', () => { + test.beforeEach( async ( { admin } ) => { + await admin.createNewPost(); + } ); + + test( 'should navigate using the list view sidebar', async ( { + editor, + page, + pageUtils, + } ) => { + await editor.openDocumentSettingsSidebar(); + await editor.insertBlock( { name: 'core/columns' } ); + await editor.canvas.click( + 'role=button[name="Two columns; equal split"i]' + ); + + // Open the block inserter. + await page.keyboard.press( 'ArrowDown' ); + await page.keyboard.press( 'Enter' ); + + // Add a paragraph in the first column. + const paragraph = page.getByRole( 'option', { name: 'Paragraph' } ); + await expect( paragraph ).toBeVisible(); + await paragraph.click(); + await page.keyboard.type( 'First column' ); + + await pageUtils.pressKeys( 'access+o' ); + + const listView = page.getByRole( 'treegrid', { + name: 'Block navigation structure', + } ); + + await expect( listView ).toBeVisible(); + await listView + .getByRole( 'gridcell', { name: 'Columns', exact: true } ) + .click(); + + // Tweak the columns count. + await page.getByRole( 'spinbutton', { name: 'Columns' } ).click(); + await pageUtils.pressKeys( 'primary+a' ); + await page.keyboard.type( '3' ); + + // Wait for the new column block to appear in the list view + const column = listView.getByRole( 'gridcell', { + name: 'Column', + exact: true, + } ); + await expect( column ).toHaveCount( 3 ); + + await column.last().click(); + + // Open the block inserter. + await page.keyboard.press( 'ArrowDown' ); + await page.keyboard.press( 'Enter' ); + + await expect( paragraph ).toBeVisible(); + await paragraph.click(); + await page.keyboard.type( 'Third column' ); + + await expect.poll( editor.getBlocks ).toMatchObject( COLUMNS_BLOCK ); + } ); + + test( 'should navigate block hierarchy using only the keyboard', async ( { + editor, + page, + pageUtils, + } ) => { + await editor.openDocumentSettingsSidebar(); + await editor.insertBlock( { name: 'core/columns' } ); + await editor.canvas.click( + 'role=button[name="Two columns; equal split"i]' + ); + + // Open the block inserter. + await page.keyboard.press( 'ArrowDown' ); + await page.keyboard.press( 'Enter' ); + + // Add a paragraph in the first column. + const paragraph = page.getByRole( 'option', { name: 'Paragraph' } ); + await expect( paragraph ).toBeVisible(); + await paragraph.click(); + await page.keyboard.type( 'First column' ); + + await pageUtils.pressKeys( 'access+o' ); + const listView = page.getByRole( 'treegrid', { + name: 'Block navigation structure', + } ); + await expect( listView ).toBeVisible(); + + // Navigate to the columns blocks using the keyboard. + await pageUtils.pressKeys( 'ArrowUp', { times: 2 } ); + await page.keyboard.press( 'Enter' ); + + // Move focus to the sidebar area. + await pageUtils.pressKeys( 'ctrl+`' ); + + // Navigate to the block settings sidebar and tweak the column count. + await pageUtils.pressKeys( 'Tab', { times: 5 } ); + await expect( + page.getByRole( 'slider', { name: 'Columns' } ) + ).toBeFocused(); + await page.keyboard.press( 'ArrowRight' ); + + // Navigate to the third column in the columns block via List View. + await pageUtils.pressKeys( 'ctrlShift+`', { times: 2 } ); + await pageUtils.pressKeys( 'Tab', { times: 3 } ); + await pageUtils.pressKeys( 'ArrowDown', { times: 4 } ); + + // Insert text in the last column block. + await page.keyboard.press( 'Enter' ); + await page.keyboard.press( 'ArrowDown' ); + await page.keyboard.press( 'Enter' ); + + await expect( paragraph ).toBeVisible(); + await paragraph.click(); + await page.keyboard.type( 'Third column' ); + + await expect.poll( editor.getBlocks ).toMatchObject( COLUMNS_BLOCK ); + } ); + + test( 'should appear and function even without nested blocks', async ( { + editor, + page, + pageUtils, + } ) => { + await editor.canvas.click( 'role=button[name="Add default block"i]' ); + await page.keyboard.type( 'You say goodbye' ); + await page.keyboard.press( 'Enter' ); + await page.keyboard.type( '## Hello, hello' ); + + // Open list view and return to the first block. + await pageUtils.pressKeys( 'access+o' ); + await expect( + page.getByRole( 'treegrid', { + name: 'Block navigation structure', + } ) + ).toBeVisible(); + await page.keyboard.press( 'ArrowUp' ); + await page.keyboard.press( 'Space' ); + + // Replace its contents. + await pageUtils.pressKeys( 'primary+a' ); + await page.keyboard.type( 'and I say hello' ); + + await expect.poll( editor.getBlocks ).toMatchObject( [ + { + name: 'core/paragraph', + attributes: { content: 'and I say hello' }, + }, + { + name: 'core/heading', + }, + ] ); + } ); + + test( 'should select the wrapper div for a group', async ( { + editor, + page, + pageUtils, + } ) => { + await editor.insertBlock( { name: 'core/group' } ); + await editor.canvas.click( + 'role=button[name="Group: Gather blocks in a container."i]' + ); + + // Open the block inserter. + await page.keyboard.press( 'ArrowDown' ); + await page.keyboard.press( 'Enter' ); + + // Add some random blocks. + const paragraph = page.getByRole( 'option', { name: 'Paragraph' } ); + await expect( paragraph ).toBeVisible(); + await paragraph.click(); + await page.keyboard.type( 'just a paragraph' ); + await page.keyboard.press( 'Enter' ); + await page.keyboard.type( '/spacer' ); + await page.keyboard.press( 'Enter' ); + + // Verify group block contents. + await expect.poll( editor.getBlocks ).toMatchObject( [ + { + name: 'core/group', + innerBlocks: [ + { + name: 'core/paragraph', + attributes: { content: 'just a paragraph' }, + }, + { + name: 'core/spacer', + }, + ], + }, + ] ); + + // Deselect the blocks. + await editor.canvas.click( 'role=textbox[name="Add title"i]' ); + + // Open list view and return to the first block. + await pageUtils.pressKeys( 'access+o' ); + await expect( + page.getByRole( 'treegrid', { + name: 'Block navigation structure', + } ) + ).toBeVisible(); + await page.keyboard.press( 'Enter' ); + + await expect( + editor.canvas.getByRole( 'document', { name: 'Block: Group' } ) + ).toBeFocused(); + } ); +} ); From bf38cbf57b2adfc61797bbe0f30fc1b3a9c1e902 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Thu, 15 Jun 2023 08:06:28 +0400 Subject: [PATCH 2/4] Remove old test file --- .../block-hierarchy-navigation.test.js | 230 ------------------ 1 file changed, 230 deletions(-) delete mode 100644 packages/e2e-tests/specs/editor/various/block-hierarchy-navigation.test.js diff --git a/packages/e2e-tests/specs/editor/various/block-hierarchy-navigation.test.js b/packages/e2e-tests/specs/editor/various/block-hierarchy-navigation.test.js deleted file mode 100644 index 9737007ce656e4..00000000000000 --- a/packages/e2e-tests/specs/editor/various/block-hierarchy-navigation.test.js +++ /dev/null @@ -1,230 +0,0 @@ -/** - * WordPress dependencies - */ -import { - createNewPost, - insertBlock, - getEditedPostContent, - pressKeyTimes, - pressKeyWithModifier, - openDocumentSettingsSidebar, - getListViewBlocks, - switchBlockInspectorTab, - canvas, -} from '@wordpress/e2e-test-utils'; - -async function openListViewSidebar() { - await pressKeyWithModifier( 'access', 'o' ); - await page.waitForSelector( '.block-editor-list-view-leaf.is-selected' ); -} - -async function tabToColumnsControl() { - let isColumnsControl = false; - do { - await page.keyboard.press( 'Tab' ); - - const isBlockInspectorTab = await page.evaluate( () => { - const activeElement = document.activeElement; - return ( - activeElement.getAttribute( 'role' ) === 'tab' && - activeElement.attributes.getNamedItem( 'aria-label' ).value === - 'Styles' - ); - } ); - - if ( isBlockInspectorTab ) { - await page.keyboard.press( 'ArrowRight' ); - } - - isColumnsControl = await page.evaluate( () => { - const activeElement = document.activeElement; - return ( - activeElement.tagName === 'INPUT' && - activeElement.attributes.getNamedItem( 'aria-label' ).value === - 'Columns' - ); - } ); - } while ( ! isColumnsControl ); -} - -describe( 'Navigating the block hierarchy', () => { - beforeEach( async () => { - await createNewPost(); - } ); - - it( 'should navigate using the list view sidebar', async () => { - await insertBlock( 'Columns' ); - await canvas().click( '[aria-label="Two columns; equal split"]' ); - - // Add a paragraph in the first column. - await page.keyboard.press( 'ArrowDown' ); // Navigate to inserter. - await page.keyboard.press( 'Enter' ); // Activate inserter. - // Wait for inserter results to appear and then insert a paragraph. - await page.waitForSelector( - '.block-editor-inserter__quick-inserter-results .editor-block-list-item-paragraph' - ); - await page.click( '.editor-block-list-item-paragraph' ); - await page.keyboard.type( 'First column' ); - - // Navigate to the columns blocks. - await page.click( - '.edit-post-header-toolbar__document-overview-toggle' - ); - - const firstColumnsBlockMenuItem = ( - await getListViewBlocks( 'Columns' ) - )[ 0 ]; - await firstColumnsBlockMenuItem.click(); - - // Tweak the columns count. - await openDocumentSettingsSidebar(); - await switchBlockInspectorTab( 'Settings' ); - await page.focus( - '.block-editor-block-inspector [aria-label="Columns"][type="number"]' - ); - await page.keyboard.down( 'Shift' ); - await page.keyboard.press( 'ArrowLeft' ); - await page.keyboard.up( 'Shift' ); - await page.keyboard.type( '3' ); - - // Wait for the new column block to appear in the list view - // 5 = Columns, Column, Paragraph, Column, *Column* - await page.waitForSelector( - 'tr.block-editor-list-view-leaf:nth-of-type(5)' - ); - - // Navigate to the last column block. - const lastColumnBlockMenuItem = ( - await getListViewBlocks( 'Column' ) - )[ 2 ]; - await lastColumnBlockMenuItem.click(); - - // Insert text in the last column block. - await page.keyboard.press( 'ArrowDown' ); // Navigate to inserter. - await page.keyboard.press( 'Enter' ); // Activate inserter. - // Wait for inserter results to appear and then insert a paragraph. - await page.waitForSelector( - '.block-editor-inserter__quick-inserter-results .editor-block-list-item-paragraph' - ); - await page.click( '.editor-block-list-item-paragraph' ); - await page.keyboard.type( 'Third column' ); - - expect( await getEditedPostContent() ).toMatchSnapshot(); - } ); - - it( 'should navigate block hierarchy using only the keyboard', async () => { - await insertBlock( 'Columns' ); - await openDocumentSettingsSidebar(); - await canvas().click( '[aria-label="Two columns; equal split"]' ); - - // Add a paragraph in the first column. - await page.keyboard.press( 'ArrowDown' ); // Navigate to inserter. - await page.keyboard.press( 'Enter' ); // Activate inserter. - // Wait for inserter results to appear and then insert a paragraph. - await page.waitForSelector( - '.block-editor-inserter__quick-inserter-results .editor-block-list-item-paragraph' - ); - await page.click( '.editor-block-list-item-paragraph' ); - await page.keyboard.type( 'First column' ); - - // Navigate to the columns blocks using the keyboard. - await openListViewSidebar(); - await pressKeyTimes( 'ArrowUp', 2 ); - await page.keyboard.press( 'Enter' ); - - // Move focus to the sidebar area. - await pressKeyWithModifier( 'ctrl', '`' ); - await tabToColumnsControl(); - - // Tweak the columns count by increasing it by one. - await page.keyboard.press( 'ArrowRight' ); - - // Navigate to the third column in the columns block. - await pressKeyWithModifier( 'ctrlShift', '`' ); - await pressKeyWithModifier( 'ctrlShift', '`' ); - await pressKeyTimes( 'Tab', 3 ); - await pressKeyTimes( 'ArrowDown', 4 ); - await canvas().waitForSelector( - '.is-highlighted[aria-label="Block: Column (3 of 3)"]' - ); - await page.keyboard.press( 'Enter' ); - await canvas().waitForSelector( - '.is-selected[data-type="core/column"]' - ); - - // Insert text in the last column block. - await page.keyboard.press( 'ArrowDown' ); // Navigate to inserter. - await page.keyboard.press( 'Enter' ); // Activate inserter. - // Wait for inserter results to appear and then insert a paragraph. - await page.waitForSelector( - '.block-editor-inserter__quick-inserter-results .editor-block-list-item-paragraph' - ); - await page.click( '.editor-block-list-item-paragraph' ); - await page.keyboard.type( 'Third column' ); - - expect( await getEditedPostContent() ).toMatchSnapshot(); - } ); - - it( 'should appear and function even without nested blocks', async () => { - const textString = 'You say goodbye'; - - await insertBlock( 'Paragraph' ); - - // Add content so there is a block in the hierarchy. - await page.keyboard.type( textString ); - - // Create an image block too. - await page.keyboard.press( 'Enter' ); - await insertBlock( 'Image' ); - - // Return to first block. - await openListViewSidebar(); - await page.keyboard.press( 'ArrowUp' ); - await page.keyboard.press( 'Space' ); - - // Replace its content. - await pressKeyWithModifier( 'primary', 'a' ); - await page.keyboard.type( 'and I say hello' ); - - expect( await getEditedPostContent() ).toMatchSnapshot(); - } ); - - it( 'should select the wrapper div for a group', async () => { - // Insert a group block. - await insertBlock( 'Group' ); - // Select the default, selected Group layout from the variation picker. - await canvas().click( - 'button[aria-label="Group: Gather blocks in a container."]' - ); - // Insert some random blocks. - // The last block shouldn't be a textual block. - await canvas().click( '.block-list-appender .block-editor-inserter' ); - const paragraphMenuItem = ( - await page.$x( `//button//span[contains(text(), 'Paragraph')]` ) - )[ 0 ]; - await paragraphMenuItem.click(); - await page.keyboard.type( 'just a paragraph' ); - await insertBlock( 'Separator' ); - - // Check the Group block content. - expect( await getEditedPostContent() ).toMatchSnapshot(); - - // Unselect the blocks. - await canvas().click( '.editor-post-title' ); - - // Try selecting the group block using the Outline. - await page.click( - '.edit-post-header-toolbar__document-overview-toggle' - ); - const groupMenuItem = ( await getListViewBlocks( 'Group' ) )[ 0 ]; - await groupMenuItem.click(); - - // The group block's wrapper should be selected. - const isGroupBlockSelected = await canvas().evaluate( - () => - document.activeElement.getAttribute( 'data-type' ) === - 'core/group' - ); - expect( isGroupBlockSelected ).toBe( true ); - } ); -} ); From a7b86161e6f4ff01b9c4d05aa8a9dbd233d4f032 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Thu, 15 Jun 2023 08:44:01 +0400 Subject: [PATCH 3/4] Remove snapshot --- .../block-hierarchy-navigation.test.js.snap | 63 ------------------- 1 file changed, 63 deletions(-) delete mode 100644 packages/e2e-tests/specs/editor/various/__snapshots__/block-hierarchy-navigation.test.js.snap diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/block-hierarchy-navigation.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/block-hierarchy-navigation.test.js.snap deleted file mode 100644 index b4d171f170d918..00000000000000 --- a/packages/e2e-tests/specs/editor/various/__snapshots__/block-hierarchy-navigation.test.js.snap +++ /dev/null @@ -1,63 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Navigating the block hierarchy should appear and function even without nested blocks 1`] = ` -" -

and I say hello

- - - -
-" -`; - -exports[`Navigating the block hierarchy should navigate block hierarchy using only the keyboard 1`] = ` -" -
-
-

First column

-
- - - -
- - - -
-

Third column

-
-
-" -`; - -exports[`Navigating the block hierarchy should navigate using the list view sidebar 1`] = ` -" -
-
-

First column

-
- - - -
- - - -
-

Third column

-
-
-" -`; - -exports[`Navigating the block hierarchy should select the wrapper div for a group 1`] = ` -" -
-

just a paragraph

- - - -
-
-" -`; From a61ab7b42abad0115346e00c5853ae57e99b9b6a Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Thu, 15 Jun 2023 09:32:09 +0400 Subject: [PATCH 4/4] Use locator fill --- .../specs/editor/various/block-hierarchy-navigation.spec.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/e2e/specs/editor/various/block-hierarchy-navigation.spec.js b/test/e2e/specs/editor/various/block-hierarchy-navigation.spec.js index 93bedc1efcbbde..4dc49bc0f7510a 100644 --- a/test/e2e/specs/editor/various/block-hierarchy-navigation.spec.js +++ b/test/e2e/specs/editor/various/block-hierarchy-navigation.spec.js @@ -70,9 +70,7 @@ test.describe( 'Navigating the block hierarchy', () => { .click(); // Tweak the columns count. - await page.getByRole( 'spinbutton', { name: 'Columns' } ).click(); - await pageUtils.pressKeys( 'primary+a' ); - await page.keyboard.type( '3' ); + await page.getByRole( 'spinbutton', { name: 'Columns' } ).fill( '3' ); // Wait for the new column block to appear in the list view const column = listView.getByRole( 'gridcell', {