From 980a8fa35400e2367e838a454755bb929eef2148 Mon Sep 17 00:00:00 2001 From: Andrei Draganescu Date: Thu, 17 Nov 2022 11:40:45 +0200 Subject: [PATCH 1/5] mark applying templates as a not persistent change --- .../components/inner-blocks/use-inner-block-template-sync.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/inner-blocks/use-inner-block-template-sync.js b/packages/block-editor/src/components/inner-blocks/use-inner-block-template-sync.js index 1b81069c44f3dc..c9ccfe7faaf0e4 100644 --- a/packages/block-editor/src/components/inner-blocks/use-inner-block-template-sync.js +++ b/packages/block-editor/src/components/inner-blocks/use-inner-block-template-sync.js @@ -42,7 +42,8 @@ export default function useInnerBlockTemplateSync( ) { const { getSelectedBlocksInitialCaretPosition, isBlockSelected } = useSelect( blockEditorStore ); - const { replaceInnerBlocks } = useDispatch( blockEditorStore ); + const { replaceInnerBlocks, __unstableMarkNextChangeAsNotPersistent } = + useDispatch( blockEditorStore ); const innerBlocks = useSelect( ( select ) => select( blockEditorStore ).getBlocks( clientId ), [ clientId ] @@ -81,6 +82,7 @@ export default function useInnerBlockTemplateSync( ); if ( ! isEqual( nextBlocks, currentInnerBlocks ) ) { + __unstableMarkNextChangeAsNotPersistent(); replaceInnerBlocks( clientId, nextBlocks, From 87efa23dc7ff9a29e63704c38dedba3766860841 Mon Sep 17 00:00:00 2001 From: Ben Dwyer Date: Thu, 24 Nov 2022 17:30:48 +0000 Subject: [PATCH 2/5] Add a test --- .../editor/various/block-locking.spec.js | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/test/e2e/specs/editor/various/block-locking.spec.js b/test/e2e/specs/editor/various/block-locking.spec.js index 7398cc6be7b185..bd549a0b7d4986 100644 --- a/test/e2e/specs/editor/various/block-locking.spec.js +++ b/test/e2e/specs/editor/various/block-locking.spec.js @@ -82,5 +82,75 @@ test.describe( 'Block Locking', () => {

Some paragraph

` ); } ); + + test( 'Applying block templates does not create a persistent change in the editor', async ( { editor, page, pageUtils } ) => { + // Create a new block template for the test. + // Should this live in a different file? + await page.evaluate( () => { + const el = window.wp.element.createElement; + const useState = window.wp.element.useState; + const InnerBlocks = window.wp.blockEditor.InnerBlocks; + const TEMPLATE_TWO_PARAGRAPHS = [ + [ + 'core/paragraph', + { + fontSize: 'large', + content: 'One', + }, + ], + [ + 'core/paragraph', + { + fontSize: 'large', + content: 'Two', + }, + ], + ]; + + window.wp.blocks.registerBlockType( 'test/test-inner-blocks-async-template', { + title: 'Test Inner Blocks no locking', + icon: 'cart', + category: 'text', + + edit() { + + const [ template, setTemplate ] = useState([]); + + setInterval( () => { + setTemplate( TEMPLATE_TWO_PARAGRAPHS ); + }, 1000 ); + + return el( InnerBlocks, { + template: template, + } ); + }, + + save() { + return el( InnerBlocks.Content ); + }, + } ); + + } ); + await editor.insertBlock( { name: 'test/test-inner-blocks-async-template' } ); + + await expect( await editor.getEditedPostContent() ) + .toBe( `` ); + + const undoButton = await page.locator( '.editor-history__undo' ); + + // Check is that the undo button is enabled. + // Unfortunately the button does not have a disabled attribute. + await expect( undoButton ).toHaveAttribute( 'aria-disabled', 'false' ); + + // Undo the change. + await pageUtils.pressKeyWithModifier( 'primary', 'z' ); + + await expect( await editor.getEditedPostContent() ) + .toBe( `` ); + + // There should be no more undo history. + // Unfortunately the button does not have a disabled attribute. + await expect( undoButton ).toHaveAttribute( 'aria-disabled', 'true' ); + } ); } ); } ); From b28c09cd8d00f2e84a8f941f4b306655991168fd Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Fri, 25 Nov 2022 11:46:31 +0800 Subject: [PATCH 3/5] Update e2e test - Move block code to test plugin file - Move from block locking test file to a new inner blocks template file - Update test logic to test post is not dirty on a fresh load - Rename post type templates file to distinguish from inner blocks templates file --- .../plugins/inner-blocks-templates/index.js | 30 ++++++++ ...with-a-predefined-template-1-chromium.txt} | 0 ...es.spec.js => post-type-templates.spec.js} | 2 +- .../editor/various/block-locking.spec.js | 70 ------------------- .../various/inner-blocks-templates.spec.js | 53 ++++++++++++++ 5 files changed, 84 insertions(+), 71 deletions(-) rename test/e2e/specs/editor/plugins/__snapshots__/{templates-Using-a-CPT-with-a-predefined-templa-7538a--custom-post-types-with-a-predefined-template-1-chromium.txt => Post-type-templates-Using-a-CPT-with-a-predefi-fffe1--custom-post-types-with-a-predefined-template-1-chromium.txt} (100%) rename test/e2e/specs/editor/plugins/{templates.spec.js => post-type-templates.spec.js} (98%) create mode 100644 test/e2e/specs/editor/various/inner-blocks-templates.spec.js diff --git a/packages/e2e-tests/plugins/inner-blocks-templates/index.js b/packages/e2e-tests/plugins/inner-blocks-templates/index.js index 3d8630103f16a1..ff5158627767f7 100644 --- a/packages/e2e-tests/plugins/inner-blocks-templates/index.js +++ b/packages/e2e-tests/plugins/inner-blocks-templates/index.js @@ -3,6 +3,8 @@ const createBlock = wp.blocks.createBlock; const el = wp.element.createElement; const InnerBlocks = wp.blockEditor.InnerBlocks; + const useState = window.wp.element.useState; + const TEMPLATE = [ [ 'core/paragraph', @@ -171,4 +173,32 @@ save, } ); + + + function InnerBlocksAsyncTemplateEdit() { + const [ template, setTemplate ] = useState( [] ); + + setInterval( () => { + setTemplate( TEMPLATE_TWO_PARAGRAPHS ); + }, 1000 ); + + return el( InnerBlocks, { + template, + } ); + } + + registerBlockType( + 'test/test-inner-blocks-async-template', + { + title: 'Test Inner Blocks Async Template', + icon: 'cart', + category: 'text', + + edit: InnerBlocksAsyncTemplateEdit, + + save() { + return el( InnerBlocks.Content ); + }, + } + ); } )(); diff --git a/test/e2e/specs/editor/plugins/__snapshots__/templates-Using-a-CPT-with-a-predefined-templa-7538a--custom-post-types-with-a-predefined-template-1-chromium.txt b/test/e2e/specs/editor/plugins/__snapshots__/Post-type-templates-Using-a-CPT-with-a-predefi-fffe1--custom-post-types-with-a-predefined-template-1-chromium.txt similarity index 100% rename from test/e2e/specs/editor/plugins/__snapshots__/templates-Using-a-CPT-with-a-predefined-templa-7538a--custom-post-types-with-a-predefined-template-1-chromium.txt rename to test/e2e/specs/editor/plugins/__snapshots__/Post-type-templates-Using-a-CPT-with-a-predefi-fffe1--custom-post-types-with-a-predefined-template-1-chromium.txt diff --git a/test/e2e/specs/editor/plugins/templates.spec.js b/test/e2e/specs/editor/plugins/post-type-templates.spec.js similarity index 98% rename from test/e2e/specs/editor/plugins/templates.spec.js rename to test/e2e/specs/editor/plugins/post-type-templates.spec.js index bab5cdd739baf6..3c5a664259f2d2 100644 --- a/test/e2e/specs/editor/plugins/templates.spec.js +++ b/test/e2e/specs/editor/plugins/post-type-templates.spec.js @@ -3,7 +3,7 @@ */ const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' ); -test.describe( 'templates', () => { +test.describe( 'Post type templates', () => { test.describe( 'Using a CPT with a predefined template', () => { test.beforeAll( async ( { requestUtils } ) => { await requestUtils.activatePlugin( diff --git a/test/e2e/specs/editor/various/block-locking.spec.js b/test/e2e/specs/editor/various/block-locking.spec.js index bd549a0b7d4986..7398cc6be7b185 100644 --- a/test/e2e/specs/editor/various/block-locking.spec.js +++ b/test/e2e/specs/editor/various/block-locking.spec.js @@ -82,75 +82,5 @@ test.describe( 'Block Locking', () => {

Some paragraph

` ); } ); - - test( 'Applying block templates does not create a persistent change in the editor', async ( { editor, page, pageUtils } ) => { - // Create a new block template for the test. - // Should this live in a different file? - await page.evaluate( () => { - const el = window.wp.element.createElement; - const useState = window.wp.element.useState; - const InnerBlocks = window.wp.blockEditor.InnerBlocks; - const TEMPLATE_TWO_PARAGRAPHS = [ - [ - 'core/paragraph', - { - fontSize: 'large', - content: 'One', - }, - ], - [ - 'core/paragraph', - { - fontSize: 'large', - content: 'Two', - }, - ], - ]; - - window.wp.blocks.registerBlockType( 'test/test-inner-blocks-async-template', { - title: 'Test Inner Blocks no locking', - icon: 'cart', - category: 'text', - - edit() { - - const [ template, setTemplate ] = useState([]); - - setInterval( () => { - setTemplate( TEMPLATE_TWO_PARAGRAPHS ); - }, 1000 ); - - return el( InnerBlocks, { - template: template, - } ); - }, - - save() { - return el( InnerBlocks.Content ); - }, - } ); - - } ); - await editor.insertBlock( { name: 'test/test-inner-blocks-async-template' } ); - - await expect( await editor.getEditedPostContent() ) - .toBe( `` ); - - const undoButton = await page.locator( '.editor-history__undo' ); - - // Check is that the undo button is enabled. - // Unfortunately the button does not have a disabled attribute. - await expect( undoButton ).toHaveAttribute( 'aria-disabled', 'false' ); - - // Undo the change. - await pageUtils.pressKeyWithModifier( 'primary', 'z' ); - - await expect( await editor.getEditedPostContent() ) - .toBe( `` ); - - // There should be no more undo history. - // Unfortunately the button does not have a disabled attribute. - await expect( undoButton ).toHaveAttribute( 'aria-disabled', 'true' ); - } ); } ); } ); diff --git a/test/e2e/specs/editor/various/inner-blocks-templates.spec.js b/test/e2e/specs/editor/various/inner-blocks-templates.spec.js new file mode 100644 index 00000000000000..eaee49c52396e7 --- /dev/null +++ b/test/e2e/specs/editor/various/inner-blocks-templates.spec.js @@ -0,0 +1,53 @@ +/** + * WordPress dependencies + */ +const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' ); + +test.describe( 'Inner blocks templates', () => { + test.beforeAll( async ( { requestUtils } ) => { + await requestUtils.activatePlugin( + 'gutenberg-test-inner-blocks-templates' + ); + } ); + + test.beforeEach( async ( { admin } ) => { + await admin.createNewPost(); + } ); + + test.afterAll( async ( { requestUtils } ) => { + await requestUtils.deactivatePlugin( + 'gutenberg-test-inner-blocks-templates' + ); + } ); + + test( 'applying block templates asynchronously does not create a persistent change in the editor', async ( { + editor, + page, + } ) => { + await editor.insertBlock( { + name: 'test/test-inner-blocks-async-template', + } ); + + // Publish the post, then reload. + await editor.publishPost(); + await page.reload(); + + // Wait for the block that was inserted to appear with its templated content. + await page + .locator( + 'role=document[name="Block: Test Inner Blocks Async Template"i] >> text=OneTwo' + ) + .waitFor(); + + // The template resolution shouldn't cause the post to be dirty. + const editorTopBar = page.locator( + 'role=region[name="Editor top bar"i]' + ); + const undoButton = editorTopBar.locator( 'role=button[name="Undo"i]' ); + const updateButton = editorTopBar.locator( + 'role=button[name="Update"i]' + ); + await expect( undoButton ).toHaveAttribute( 'aria-disabled', 'true' ); + await expect( updateButton ).toHaveAttribute( 'aria-disabled', 'true' ); + } ); +} ); From 6c08063eec38cfd907567ce2a2aa7e77e6dd7c63 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Fri, 25 Nov 2022 12:05:08 +0800 Subject: [PATCH 4/5] Fix tests - Avoid saving inner blocks of the test block, as otherwise template sync won't run - Wait for template resolution before saving, as the test seems flakey otherwise --- .../plugins/inner-blocks-templates/index.js | 5 ++--- .../editor/various/inner-blocks-templates.spec.js | 13 ++++++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/e2e-tests/plugins/inner-blocks-templates/index.js b/packages/e2e-tests/plugins/inner-blocks-templates/index.js index ff5158627767f7..959f4a3eeb5a0b 100644 --- a/packages/e2e-tests/plugins/inner-blocks-templates/index.js +++ b/packages/e2e-tests/plugins/inner-blocks-templates/index.js @@ -196,9 +196,8 @@ edit: InnerBlocksAsyncTemplateEdit, - save() { - return el( InnerBlocks.Content ); - }, + // Purposely do not save inner blocks so that it's possible to test template resolution. + save() {}, } ); } )(); diff --git a/test/e2e/specs/editor/various/inner-blocks-templates.spec.js b/test/e2e/specs/editor/various/inner-blocks-templates.spec.js index eaee49c52396e7..1790e347952e13 100644 --- a/test/e2e/specs/editor/various/inner-blocks-templates.spec.js +++ b/test/e2e/specs/editor/various/inner-blocks-templates.spec.js @@ -28,16 +28,19 @@ test.describe( 'Inner blocks templates', () => { name: 'test/test-inner-blocks-async-template', } ); + const blockWithTemplateContent = page.locator( + 'role=document[name="Block: Test Inner Blocks Async Template"i] >> text=OneTwo' + ); + + // The block template content appears asynchronously, so wait for it. + await blockWithTemplateContent.waitFor(); + // Publish the post, then reload. await editor.publishPost(); await page.reload(); // Wait for the block that was inserted to appear with its templated content. - await page - .locator( - 'role=document[name="Block: Test Inner Blocks Async Template"i] >> text=OneTwo' - ) - .waitFor(); + await blockWithTemplateContent.waitFor(); // The template resolution shouldn't cause the post to be dirty. const editorTopBar = page.locator( From 862f4d70310fe9d94e8696ef44230c19b01f460c Mon Sep 17 00:00:00 2001 From: Ben Dwyer Date: Fri, 25 Nov 2022 10:18:48 +0000 Subject: [PATCH 5/5] make more explicit assetions --- test/e2e/specs/editor/various/inner-blocks-templates.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/e2e/specs/editor/various/inner-blocks-templates.spec.js b/test/e2e/specs/editor/various/inner-blocks-templates.spec.js index 1790e347952e13..87ad2604281983 100644 --- a/test/e2e/specs/editor/various/inner-blocks-templates.spec.js +++ b/test/e2e/specs/editor/various/inner-blocks-templates.spec.js @@ -33,14 +33,14 @@ test.describe( 'Inner blocks templates', () => { ); // The block template content appears asynchronously, so wait for it. - await blockWithTemplateContent.waitFor(); + await expect( blockWithTemplateContent ).toBeVisible(); // Publish the post, then reload. await editor.publishPost(); await page.reload(); // Wait for the block that was inserted to appear with its templated content. - await blockWithTemplateContent.waitFor(); + await expect( blockWithTemplateContent ).toBeVisible(); // The template resolution shouldn't cause the post to be dirty. const editorTopBar = page.locator(