diff --git a/packages/e2e-tests/specs/editor/various/invalid-block.test.js b/packages/e2e-tests/specs/editor/various/invalid-block.test.js deleted file mode 100644 index 354c370434be92..00000000000000 --- a/packages/e2e-tests/specs/editor/various/invalid-block.test.js +++ /dev/null @@ -1,100 +0,0 @@ -/** - * WordPress dependencies - */ -import { - clickMenuItem, - createNewPost, - clickBlockAppender, - clickBlockToolbarButton, - setPostContent, - canvas, -} from '@wordpress/e2e-test-utils'; - -describe( 'invalid blocks', () => { - beforeEach( async () => { - await createNewPost(); - } ); - - it( 'Should show an invalid block message with clickable options', async () => { - // Create an empty paragraph with the focus in the block. - await clickBlockAppender(); - await page.keyboard.type( 'hello' ); - - await clickBlockToolbarButton( 'Options' ); - - // Change to HTML mode and close the options. - await clickMenuItem( 'Edit as HTML' ); - - // Focus on the textarea and enter an invalid paragraph - await canvas().click( - '.block-editor-block-list__layout .block-editor-block-list__block .block-editor-block-list__block-html-textarea' - ); - await page.keyboard.type( '

invalid paragraph' ); - - // Takes the focus away from the block so the invalid warning is triggered - await page.click( '.editor-post-save-draft' ); - - // Click on the 'three-dots' menu toggle. - await canvas().click( - '.block-editor-warning__actions button[aria-label="More options"]' - ); - - await clickMenuItem( 'Resolve' ); - - // Check we get the resolve modal with the appropriate contents. - const htmlBlockContent = await page.$eval( - '.block-editor-block-compare__html', - ( node ) => node.textContent - ); - expect( htmlBlockContent ).toEqual( - '

hello

invalid paragraph' - ); - } ); - - it( 'should strip potentially malicious on* attributes', async () => { - let hasAlert = false; - - page.on( 'dialog', () => { - hasAlert = true; - } ); - - // The paragraph block contains invalid HTML, which causes it to be an - // invalid block. - await setPostContent( - ` - -

aaaa 1 - - ` - ); - - // Give the browser time to show the alert. - await page.evaluate( () => new Promise( window.requestIdleCallback ) ); - - expect( console ).toHaveWarned(); - expect( console ).toHaveErrored(); - expect( hasAlert ).toBe( false ); - } ); - - it( 'should not trigger malicious script tags when using a shortcode block', async () => { - let hasAlert = false; - - page.on( 'dialog', () => { - hasAlert = true; - } ); - - // The shortcode block contains invalid HTML, which causes it to be an - // invalid block. - await setPostContent( - ` - - - - ` - ); - - // Give the browser time to show the alert. - await page.evaluate( () => new Promise( window.requestIdleCallback ) ); - expect( hasAlert ).toBe( false ); - } ); -} ); diff --git a/test/e2e/specs/editor/various/invalid-block.spec.js b/test/e2e/specs/editor/various/invalid-block.spec.js new file mode 100644 index 00000000000000..07c04a5a55457e --- /dev/null +++ b/test/e2e/specs/editor/various/invalid-block.spec.js @@ -0,0 +1,119 @@ +/** + * WordPress dependencies + */ +const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' ); + +test.describe( 'Invalid blocks', () => { + test.beforeEach( async ( { admin } ) => { + await admin.createNewPost(); + } ); + + test( 'should show an invalid block message with clickable options', async ( { + editor, + page, + } ) => { + // Create an empty paragraph with the focus in the block. + await editor.canvas + .getByRole( 'button', { name: 'Add default block' } ) + .click(); + await page.keyboard.type( 'hello' ); + + // Change to HTML mode and close the options. + await editor.clickBlockOptionsMenuItem( 'Edit as HTML' ); + + // Focus on the textarea and enter an invalid paragraph. + await editor.canvas + .getByRole( 'document', { name: 'Block: Paragraph' } ) + .getByRole( 'textbox' ) + .fill( '

invalid paragraph' ); + + // Takes the focus away from the block so the invalid warning is triggered. + await editor.saveDraft(); + + // Click on the 'three-dots' menu toggle. + await editor.canvas + .getByRole( 'document', { name: 'Block: Paragraph' } ) + .getByRole( 'button', { name: 'More options' } ) + .click(); + + await page + .getByRole( 'menu', { name: 'More options' } ) + .getByRole( 'menuitem', { name: 'Resolve' } ) + .click(); + + // Check we get the resolve modal with the appropriate contents. + await expect( + page + .getByRole( 'dialog', { name: 'Resolve Block' } ) + .locator( '.block-editor-block-compare__html' ) + ).toHaveText( [ '

invalid paragraph', '

invalid paragraph

' ] ); + } ); + + test( 'should strip potentially malicious on* attributes', async ( { + editor, + page, + } ) => { + let hasAlert = false; + let error = ''; + let warning = ''; + + page.on( 'dialog', () => { + hasAlert = true; + } ); + + page.on( 'console', ( msg ) => { + if ( msg.type() === 'error' ) { + error = msg.text(); + } + + if ( msg.type() === 'warning' ) { + warning = msg.text(); + } + } ); + + await editor.setContent( ` + +

aaaa 1 + + ` ); + + // Give the browser time to show the alert. + await expect( + editor.canvas + .getByRole( 'document', { name: 'Block: Paragraph' } ) + .getByRole( 'button', { name: 'Attempt Block Recovery' } ) + ).toBeVisible(); + + expect( hasAlert ).toBe( false ); + expect( error ).toContain( + 'Block validation: Block validation failed' + ); + expect( warning ).toContain( + 'Block validation: Malformed HTML detected' + ); + } ); + + test( 'should not trigger malicious script tags when using a shortcode block', async ( { + editor, + page, + } ) => { + let hasAlert = false; + + page.on( 'dialog', () => { + hasAlert = true; + } ); + + await editor.setContent( ` + + + + ` ); + + // Give the browser time to show the alert. + await expect( + editor.canvas.getByRole( 'document', { name: 'Block: Shortcode' } ) + ).toBeVisible(); + + expect( hasAlert ).toBe( false ); + } ); +} );