From b9f2514f9e37099f6481046c4ba20fa46c2d7171 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Tue, 28 Nov 2023 12:40:15 +0400 Subject: [PATCH] Migrate 'align hook' e2e tests to Playwright (#56480) * Migrate 'align hook' e2e tests to Playwright * Remove old test files * Update generated alignment markup assertions --- .../__snapshots__/align-hook.test.js.snap | 43 --- .../specs/editor/plugins/align-hook.test.js | 234 -------------- .../specs/editor/plugins/align-hook.spec.js | 304 ++++++++++++++++++ 3 files changed, 304 insertions(+), 277 deletions(-) delete mode 100644 packages/e2e-tests/specs/editor/plugins/__snapshots__/align-hook.test.js.snap delete mode 100644 packages/e2e-tests/specs/editor/plugins/align-hook.test.js create mode 100644 test/e2e/specs/editor/plugins/align-hook.spec.js diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/align-hook.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/align-hook.test.js.snap deleted file mode 100644 index 6c04d30c41be9d..00000000000000 --- a/packages/e2e-tests/specs/editor/plugins/__snapshots__/align-hook.test.js.snap +++ /dev/null @@ -1,43 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Align Hook Works As Expected Block with align array Correctly applies the selected alignment and correctly removes the alignment 1`] = ` -" -
Test Align Hook
-" -`; - -exports[`Align Hook Works As Expected Block with align array Correctly applies the selected alignment and correctly removes the alignment 2`] = ` -" -
Test Align Hook
-" -`; - -exports[`Align Hook Works As Expected Block with align true Correctly applies the selected alignment and correctly removes the alignment 1`] = ` -" -
Test Align Hook
-" -`; - -exports[`Align Hook Works As Expected Block with align true Correctly applies the selected alignment and correctly removes the alignment 2`] = ` -" -
Test Align Hook
-" -`; - -exports[`Align Hook Works As Expected Block with default align Correctly applies the selected alignment and correctly removes the alignment 1`] = ` -" -
Test Align Hook
-" -`; - -exports[`Align Hook Works As Expected Block with default align Correctly applies the selected alignment and correctly removes the alignment 2`] = ` -" -
Test Align Hook
-" -`; - -exports[`Align Hook Works As Expected Block with no alignment set Does not save any alignment related attribute or class 1`] = ` -" -
Test Align Hook
-" -`; diff --git a/packages/e2e-tests/specs/editor/plugins/align-hook.test.js b/packages/e2e-tests/specs/editor/plugins/align-hook.test.js deleted file mode 100644 index 9246144d810e08..00000000000000 --- a/packages/e2e-tests/specs/editor/plugins/align-hook.test.js +++ /dev/null @@ -1,234 +0,0 @@ -/** - * WordPress dependencies - */ -import { - activatePlugin, - createNewPost, - deactivatePlugin, - getAllBlocks, - getEditedPostContent, - insertBlock, - selectBlockByClientId, - setPostContent, - clickBlockToolbarButton, -} from '@wordpress/e2e-test-utils'; - -const alignLabels = { - none: 'None', - left: 'Align left', - center: 'Align center', - right: 'Align right', - wide: 'Wide width', - full: 'Full width', -}; - -/** - * Helper function to get the `labels` of align control. It actually evaluates the - * basic label of the button without the `info` text node if exists. - * - * @param {Object} options Options for the util function - * @param {boolean} [options.getActiveButtonLabels=false] Flag for returning the active buttons labels only. - * @return {string[]} The matched labels. - */ -const getAlignmentToolbarLabels = async ( { - getActiveButtonLabels = false, -} = {} ) => { - const selector = `.components-dropdown-menu__menu button${ - getActiveButtonLabels ? '.is-active' : '' - } .components-menu-item__item`; - return page.evaluate( ( _selector ) => { - return ( - Array.from( document.querySelectorAll( _selector ) ) - /** - * We neede this for now because conditionally there could be two nodes - * with the same class(). This should be removed when the following - * issue is resolved. - * - * @see https://github.com/WordPress/gutenberg/issues/34838 - */ - .filter( ( contentNode ) => ! contentNode.childElementCount ) - .map( ( contentNode ) => { - return contentNode.innerText; - } ) - ); - }, selector ); -}; - -const expectActiveButtonLabelToBe = async ( expected ) => { - await clickBlockToolbarButton( 'Align' ); - const activeButtonLabels = await getAlignmentToolbarLabels( { - getActiveButtonLabels: true, - } ); - expect( activeButtonLabels ).toHaveLength( 1 ); - expect( activeButtonLabels[ 0 ] ).toEqual( expected ); -}; - -const createShowsTheExpectedButtonsTest = ( blockName, buttonLabels ) => { - it( 'Shows the expected buttons on the alignment toolbar', async () => { - await insertBlock( blockName ); - await clickBlockToolbarButton( 'Align' ); - expect( await getAlignmentToolbarLabels() ).toEqual( - expect.arrayContaining( buttonLabels ) - ); - } ); -}; - -const createAppliesNoneAlignmentByDefaultTest = ( blockName ) => { - it( 'applies none alignment by default', async () => { - await insertBlock( blockName ); - await expectActiveButtonLabelToBe( alignLabels.none ); - } ); -}; - -const verifyMarkupIsValid = async ( htmlMarkup ) => { - await setPostContent( htmlMarkup ); - const blocks = await getAllBlocks(); - expect( blocks ).toHaveLength( 1 ); - expect( blocks[ 0 ].isValid ).toBeTruthy(); -}; - -const createCorrectlyAppliesAndRemovesAlignmentTest = ( - blockName, - alignment -) => { - it( 'Correctly applies the selected alignment and correctly removes the alignment', async () => { - const BUTTON_XPATH = `//button[contains(@class,'components-dropdown-menu__menu-item')]//span[contains(text(), '${ alignLabels[ alignment ] }')]`; - - // Set the specified alignment. - await insertBlock( blockName ); - await clickBlockToolbarButton( 'Align' ); - await ( await page.$x( BUTTON_XPATH ) )[ 0 ].click(); - - // Verify the button of the specified alignment is pressed. - await expectActiveButtonLabelToBe( alignLabels[ alignment ] ); - - let htmlMarkup = await getEditedPostContent(); - - // Verify the markup of the selected alignment was generated. - expect( htmlMarkup ).toMatchSnapshot(); - - // Verify the markup can be correctly parsed. - await verifyMarkupIsValid( htmlMarkup ); - - await selectBlockByClientId( ( await getAllBlocks() )[ 0 ].clientId ); - - // Remove the alignment. - await clickBlockToolbarButton( 'Align' ); - await ( await page.$x( BUTTON_XPATH ) )[ 0 ].click(); - - // Verify 'none' alignment button is in pressed state. - await expectActiveButtonLabelToBe( alignLabels.none ); - - // Verify alignment markup was removed from the block. - htmlMarkup = await getEditedPostContent(); - expect( htmlMarkup ).toMatchSnapshot(); - - // verify the markup when no alignment is set is valid - await verifyMarkupIsValid( htmlMarkup ); - - await selectBlockByClientId( ( await getAllBlocks() )[ 0 ].clientId ); - - // Verify alignment `none` button is in pressed state after parsing the block. - await expectActiveButtonLabelToBe( alignLabels.none ); - } ); -}; - -describe( 'Align Hook Works As Expected', () => { - beforeAll( async () => { - await activatePlugin( 'gutenberg-test-align-hook' ); - } ); - - beforeEach( async () => { - await createNewPost(); - } ); - - afterAll( async () => { - await deactivatePlugin( 'gutenberg-test-align-hook' ); - } ); - - describe( 'Block with no alignment set', () => { - const BLOCK_NAME = 'Test No Alignment Set'; - it( 'Shows no alignment buttons on the alignment toolbar', async () => { - await insertBlock( BLOCK_NAME ); - const CHANGE_ALIGNMENT_BUTTON_SELECTOR = - '.block-editor-block-toolbar .components-dropdown-menu__toggle[aria-label="Align"]'; - const changeAlignmentButton = await page.$( - CHANGE_ALIGNMENT_BUTTON_SELECTOR - ); - expect( changeAlignmentButton ).toBe( null ); - } ); - - it( 'Does not save any alignment related attribute or class', async () => { - await insertBlock( BLOCK_NAME ); - expect( await getEditedPostContent() ).toMatchSnapshot(); - } ); - } ); - - describe( 'Block with align true', () => { - const BLOCK_NAME = 'Test Align True'; - - createShowsTheExpectedButtonsTest( - BLOCK_NAME, - Object.values( alignLabels ) - ); - - createAppliesNoneAlignmentByDefaultTest( BLOCK_NAME ); - - createCorrectlyAppliesAndRemovesAlignmentTest( BLOCK_NAME, 'right' ); - } ); - - describe( 'Block with align array', () => { - const BLOCK_NAME = 'Test Align Array'; - - createShowsTheExpectedButtonsTest( BLOCK_NAME, [ - alignLabels.none, - alignLabels.left, - alignLabels.center, - ] ); - - createAppliesNoneAlignmentByDefaultTest( BLOCK_NAME ); - - createCorrectlyAppliesAndRemovesAlignmentTest( BLOCK_NAME, 'center' ); - } ); - - describe( 'Block with default align', () => { - const BLOCK_NAME = 'Test Default Align'; - const SELECTED_ALIGNMENT_CONTROL_SELECTOR = - '//div[contains(@class, "components-dropdown-menu__menu")]//button[contains(@class, "is-active")]/span[text()="Align right"]'; - createShowsTheExpectedButtonsTest( - BLOCK_NAME, - Object.values( alignLabels ) - ); - - it( 'Applies the selected alignment by default', async () => { - await insertBlock( BLOCK_NAME ); - // Verify the correct alignment button is pressed. - await clickBlockToolbarButton( 'Align' ); - const selectedAlignmentControls = await page.$x( - SELECTED_ALIGNMENT_CONTROL_SELECTOR - ); - expect( selectedAlignmentControls ).toHaveLength( 1 ); - } ); - - it( 'The default markup does not contain the alignment attribute but contains the alignment class', async () => { - await insertBlock( BLOCK_NAME ); - const markup = await getEditedPostContent(); - expect( markup ).not.toContain( '"align":"right"' ); - expect( markup ).toContain( 'alignright' ); - } ); - - it( 'Can remove the default alignment and the align attribute equals none but alignnone class is not applied', async () => { - await insertBlock( BLOCK_NAME ); - // Remove the alignment. - await clickBlockToolbarButton( 'Align' ); - const [ selectedAlignmentControl ] = await page.$x( - SELECTED_ALIGNMENT_CONTROL_SELECTOR - ); - await selectedAlignmentControl.click(); - const markup = await getEditedPostContent(); - expect( markup ).toContain( '"align":""' ); - } ); - - createCorrectlyAppliesAndRemovesAlignmentTest( BLOCK_NAME, 'center' ); - } ); -} ); diff --git a/test/e2e/specs/editor/plugins/align-hook.spec.js b/test/e2e/specs/editor/plugins/align-hook.spec.js new file mode 100644 index 00000000000000..6929022a2c6f87 --- /dev/null +++ b/test/e2e/specs/editor/plugins/align-hook.spec.js @@ -0,0 +1,304 @@ +/** + * WordPress dependencies + */ +const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' ); + +const alignLabels = { + none: 'None', + left: 'Align left', + center: 'Align center', + right: 'Align right', + wide: 'Wide width', + full: 'Full width', +}; + +test.describe( 'Align Hook Works as Expected', () => { + test.beforeAll( async ( { requestUtils } ) => { + await requestUtils.activatePlugin( 'gutenberg-test-align-hook' ); + } ); + + test.beforeEach( async ( { admin } ) => { + await admin.createNewPost(); + } ); + + test.afterAll( async ( { requestUtils } ) => { + await requestUtils.deactivatePlugin( 'gutenberg-test-align-hook' ); + } ); + + test.describe( 'Block with no alignment set', () => { + test( 'shows no alignment buttons on the alignment toolbar', async ( { + editor, + page, + } ) => { + await editor.insertBlock( { name: 'test/test-no-alignment-set' } ); + await editor.showBlockToolbar(); + + await expect( + page + .getByRole( 'toolbar', { name: 'Block tools' } ) + .getByRole( 'button', { name: 'Align', exact: true } ) + ).toBeHidden(); + } ); + + test( 'does not save any alignment related attribute or class', async ( { + editor, + } ) => { + await editor.insertBlock( { name: 'test/test-no-alignment-set' } ); + + await expect + .poll( editor.getEditedPostContent ) + .not.toContain( '"align":' ); + } ); + } ); + + test.describe( 'Block with align true', () => { + test( 'shows the expected buttons on the alignment toolbar', async ( { + editor, + page, + } ) => { + await editor.insertBlock( { name: 'test/test-align-true' } ); + await editor.clickBlockToolbarButton( 'Align' ); + + await expect( + page + .getByRole( 'menu', { name: 'Align' } ) + .getByRole( 'menuitemradio' ) + ).toHaveText( Object.values( alignLabels ) ); + } ); + + test( 'applies none alignment by default', async ( { + editor, + page, + } ) => { + await editor.insertBlock( { name: 'test/test-align-true' } ); + await editor.clickBlockToolbarButton( 'Align' ); + + await expect( + page + .getByRole( 'menu', { name: 'Align' } ) + .getByRole( 'menuitemradio', { name: 'None' } ) + ).toHaveAttribute( 'aria-checked', 'true' ); + } ); + + test( 'correctly applies the selected alignment and correctly removes the alignment', async ( { + editor, + page, + } ) => { + await editor.insertBlock( { name: 'test/test-align-true' } ); + await editor.clickBlockToolbarButton( 'Align' ); + + const dropdown = page.getByRole( 'menu', { + name: 'Align', + } ); + + await dropdown + .getByRole( 'menuitemradio', { name: 'Align right' } ) + .click(); + + // Verify the button of the specified alignment is pressed. + await editor.clickBlockToolbarButton( 'Align' ); + await expect( + dropdown.getByRole( 'menuitemradio', { name: 'Align right' } ) + ).toHaveAttribute( 'aria-checked', 'true' ); + + // Verify the markup of the selected alignment was generated. + await expect + .poll( editor.getEditedPostContent ) + .toContain( 'alignright' ); + + // Remove the alignment. Dropdown should be open. + await dropdown + .getByRole( 'menuitemradio', { name: 'Align right' } ) + .click(); + + // Verify 'none' alignment button is in pressed state. + await editor.clickBlockToolbarButton( 'Align' ); + await expect( + dropdown.getByRole( 'menuitemradio', { name: 'None' } ) + ).toHaveAttribute( 'aria-checked', 'true' ); + + // Verify alignment markup was removed from the block. + await expect + .poll( editor.getEditedPostContent ) + .not.toContain( 'alignright' ); + } ); + } ); + + test.describe( 'Block with align array', () => { + test( 'shows the expected buttons on the alignment toolbar', async ( { + editor, + page, + } ) => { + await editor.insertBlock( { name: 'test/test-align-array' } ); + await editor.clickBlockToolbarButton( 'Align' ); + + await expect( + page + .getByRole( 'menu', { name: 'Align' } ) + .getByRole( 'menuitemradio' ) + ).toHaveText( [ + alignLabels.none, + alignLabels.left, + alignLabels.center, + ] ); + } ); + + test( 'applies none alignment by default', async ( { + editor, + page, + } ) => { + await editor.insertBlock( { name: 'test/test-align-array' } ); + await editor.clickBlockToolbarButton( 'Align' ); + + await expect( + page + .getByRole( 'menu', { name: 'Align' } ) + .getByRole( 'menuitemradio', { name: 'None' } ) + ).toHaveAttribute( 'aria-checked', 'true' ); + } ); + + test( 'correctly applies the selected alignment and correctly removes the alignment', async ( { + editor, + page, + } ) => { + await editor.insertBlock( { name: 'test/test-align-array' } ); + await editor.clickBlockToolbarButton( 'Align' ); + + const dropdown = page.getByRole( 'menu', { + name: 'Align', + } ); + + await dropdown + .getByRole( 'menuitemradio', { name: 'Center' } ) + .click(); + + // Verify the button of the specified alignment is pressed. + await editor.clickBlockToolbarButton( 'Align' ); + await expect( + dropdown.getByRole( 'menuitemradio', { name: 'Center' } ) + ).toHaveAttribute( 'aria-checked', 'true' ); + + // Verify the markup of the selected alignment was generated. + await expect + .poll( editor.getEditedPostContent ) + .toContain( 'aligncenter' ); + + // Remove the alignment. Dropdown should be open. + await dropdown + .getByRole( 'menuitemradio', { name: 'Center' } ) + .click(); + + // Verify 'none' alignment button is in pressed state. + await editor.clickBlockToolbarButton( 'Align' ); + await expect( + dropdown.getByRole( 'menuitemradio', { name: 'None' } ) + ).toHaveAttribute( 'aria-checked', 'true' ); + + // Verify alignment markup was removed from the block. + await expect + .poll( editor.getEditedPostContent ) + .not.toContain( 'aligncenter' ); + } ); + } ); + + test.describe( 'Block with default align', () => { + test( 'shows the expected buttons on the alignment toolbar', async ( { + editor, + page, + } ) => { + await editor.insertBlock( { name: 'test/test-default-align' } ); + await editor.clickBlockToolbarButton( 'Align' ); + + await expect( + page + .getByRole( 'menu', { name: 'Align' } ) + .getByRole( 'menuitemradio' ) + ).toHaveText( Object.values( alignLabels ) ); + } ); + + test( 'applies the selected alignment by default', async ( { + editor, + page, + } ) => { + await editor.insertBlock( { name: 'test/test-default-align' } ); + await editor.clickBlockToolbarButton( 'Align' ); + + await expect( + page + .getByRole( 'menu', { name: 'Align' } ) + .getByRole( 'menuitemradio', { name: 'Align right' } ) + ).toHaveAttribute( 'aria-checked', 'true' ); + } ); + + test( 'the default markup does not contain the alignment attribute but contains the alignment class', async ( { + editor, + } ) => { + await editor.insertBlock( { name: 'test/test-default-align' } ); + + const markup = await editor.getEditedPostContent(); + expect( markup ).toContain( 'alignright' ); + expect( markup ).not.toContain( '"align":"right"' ); + } ); + + test( 'can remove the default alignment and the align attribute equals none but alignnone class is not applied', async ( { + editor, + page, + } ) => { + await editor.insertBlock( { name: 'test/test-default-align' } ); + await editor.clickBlockToolbarButton( 'Align' ); + + // Remove the alignment. + await page + .getByRole( 'menu', { name: 'Align' } ) + .getByRole( 'menuitemradio', { name: 'Align right' } ) + .click(); + + const markup = await editor.getEditedPostContent(); + expect( markup ).not.toContain( 'alignnone' ); + expect( markup ).toContain( '"align":""' ); + } ); + + test( 'correctly applies the selected alignment and correctly removes the alignment', async ( { + editor, + page, + } ) => { + await editor.insertBlock( { name: 'test/test-default-align' } ); + await editor.clickBlockToolbarButton( 'Align' ); + + const dropdown = page.getByRole( 'menu', { + name: 'Align', + } ); + + await dropdown + .getByRole( 'menuitemradio', { name: 'Align center' } ) + .click(); + + // Verify the button of the specified alignment is pressed. + await editor.clickBlockToolbarButton( 'Align' ); + await expect( + dropdown.getByRole( 'menuitemradio', { name: 'Align center' } ) + ).toHaveAttribute( 'aria-checked', 'true' ); + + // Verify the markup of the selected alignment was generated. + await expect + .poll( editor.getEditedPostContent ) + .toContain( 'aligncenter' ); + + // Remove the alignment. Dropdown should be open. + await dropdown + .getByRole( 'menuitemradio', { name: 'Align center' } ) + .click(); + + // Verify 'none' alignment button is in pressed state. + await editor.clickBlockToolbarButton( 'Align' ); + await expect( + dropdown.getByRole( 'menuitemradio', { name: 'None' } ) + ).toHaveAttribute( 'aria-checked', 'true' ); + + // Verify alignment markup was removed from the block. + await expect + .poll( editor.getEditedPostContent ) + .not.toContain( 'aligncenter' ); + } ); + } ); +} );