diff --git a/packages/block-editor/src/components/block-popover/inbetween.js b/packages/block-editor/src/components/block-popover/inbetween.js index b980293acc5ec..37fb597d790b9 100644 --- a/packages/block-editor/src/components/block-popover/inbetween.js +++ b/packages/block-editor/src/components/block-popover/inbetween.js @@ -154,7 +154,10 @@ function BlockPopoverInbetween( { const popoverScrollRef = usePopoverScroll( __unstableContentRef ); - if ( ! previousElement || ! nextElement || ! isVisible ) { + // If there's either a previous or a next element, show the inbetween popover. + // Note that drag and drop uses the inbetween popover to show the drop indicator + // before the first block and after the last block. + if ( ( ! previousElement && ! nextElement ) || ! isVisible ) { return null; } diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/draggable-block.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/draggable-block.test.js.snap index ae7c7c14b20b0..cef8263aca7c6 100644 --- a/packages/e2e-tests/specs/editor/various/__snapshots__/draggable-block.test.js.snap +++ b/packages/e2e-tests/specs/editor/various/__snapshots__/draggable-block.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Draggable block should drag and drop 1`] = ` +exports[`Draggable block can drag and drop to the bottom of a block list 1`] = ` "

1

@@ -10,7 +10,27 @@ exports[`Draggable block should drag and drop 1`] = ` " `; -exports[`Draggable block should drag and drop 2`] = ` +exports[`Draggable block can drag and drop to the bottom of a block list 2`] = ` +" +

2

+ + + +

1

+" +`; + +exports[`Draggable block can drag and drop to the top of a block list 1`] = ` +" +

1

+ + + +

2

+" +`; + +exports[`Draggable block can drag and drop to the top of a block list 2`] = ` "

2

diff --git a/packages/e2e-tests/specs/editor/various/draggable-block.test.js b/packages/e2e-tests/specs/editor/various/draggable-block.test.js index 772f2dedfac39..03ce983b75f23 100644 --- a/packages/e2e-tests/specs/editor/various/draggable-block.test.js +++ b/packages/e2e-tests/specs/editor/various/draggable-block.test.js @@ -7,51 +7,120 @@ import { deactivatePlugin, activatePlugin, showBlockToolbar, + setBrowserViewport, + waitForWindowDimensions, } from '@wordpress/e2e-test-utils'; describe( 'Draggable block', () => { - beforeAll( async () => { - await page.setDragInterception( true ); + // Tests don't seem to pass if beforeAll and afterAll are used. + // Unsure why. + beforeEach( async () => { await deactivatePlugin( 'gutenberg-test-plugin-disables-the-css-animations' ); + + // Set the viewport at a larger size than normal to ensure scrolling doesn't occur. + // Scrolling can interfere with the drag coordinates. + await page.setViewport( { width: 960, height: 1024 } ); + await waitForWindowDimensions( 960, 1024 ); + await createNewPost(); + await page.setDragInterception( true ); } ); - afterAll( async () => { + afterEach( async () => { await page.setDragInterception( false ); + + // Reset the viewport to normal large size. + await setBrowserViewport( 'large' ); await activatePlugin( 'gutenberg-test-plugin-disables-the-css-animations' ); } ); - beforeEach( async () => { - await createNewPost(); + it( 'can drag and drop to the top of a block list', async () => { + await page.keyboard.press( 'Enter' ); + await page.keyboard.type( '1' ); + await page.keyboard.press( 'Enter' ); + await page.keyboard.type( '2' ); + + // Confirm correct setup. + expect( await getEditedPostContent() ).toMatchSnapshot(); + + await showBlockToolbar(); + const dragHandle = await page.waitForSelector( + '.block-editor-block-mover__drag-handle' + ); + const dragHandlePoint = await dragHandle.clickablePoint(); + + const firstParagraph = await page.$( '[data-type="core/paragraph"]' ); + const targetPoint = await firstParagraph.clickablePoint(); + const targetRect = await firstParagraph.boundingBox(); + const target = { + x: targetPoint.x, + // Drag to the top half. + y: targetPoint.y - targetRect.height * 0.25, + }; + + const dragData = await page.mouse.drag( dragHandlePoint, target ); + await page.mouse.dragEnter( target, dragData ); + await page.mouse.dragOver( target, dragData ); + + // Wait for the insertion point to be visible. + const insertionPoint = await page.waitForSelector( + '.block-editor-block-list__insertion-point' + ); + + // Expect the insertion point to be visible above the first paragraph. + const insertionPointBoundingBox = await insertionPoint.boundingBox(); + expect( insertionPointBoundingBox.y ).toBeLessThan( target.y ); + + await page.mouse.drop( target, dragData ); + + expect( await getEditedPostContent() ).toMatchSnapshot(); } ); - it( 'should drag and drop', async () => { + it( 'can drag and drop to the bottom of a block list', async () => { await page.keyboard.press( 'Enter' ); await page.keyboard.type( '1' ); await page.keyboard.press( 'Enter' ); await page.keyboard.type( '2' ); + await page.keyboard.press( 'ArrowUp' ); // Confirm correct setup. expect( await getEditedPostContent() ).toMatchSnapshot(); + const [ , secondParagraph ] = await page.$$( + '[data-type="core/paragraph"]' + ); + await showBlockToolbar(); const dragHandle = await page.waitForSelector( '.block-editor-block-mover__drag-handle' ); const dragHandlePoint = await dragHandle.clickablePoint(); - const paragraph = await page.$( '[data-type="core/paragraph"]' ); - const paragraphPoint = await paragraph.clickablePoint(); - const paragraphRect = await paragraph.boundingBox(); + const targetPoint = await secondParagraph.clickablePoint(); + const targetRect = await secondParagraph.boundingBox(); + const target = { + x: targetPoint.x, + // Drag to the bottom half. + y: targetPoint.y + targetRect.height * 0.25, + }; - await page.mouse.dragAndDrop( dragHandlePoint, { - x: paragraphPoint.x, - // Drag to the top half. - y: paragraphPoint.y - paragraphRect.height / 4, - } ); + const dragData = await page.mouse.drag( dragHandlePoint, target ); + await page.mouse.dragEnter( target, dragData ); + await page.mouse.dragOver( target, dragData ); + + // Wait for the insertion point to be visible. + const insertionPoint = await page.waitForSelector( + '.block-editor-block-list__insertion-point' + ); + + // Expect the insertion point to be visible below the first paragraph. + const insertionPointBoundingBox = await insertionPoint.boundingBox(); + expect( insertionPointBoundingBox.y ).toBeGreaterThan( target.y ); + + await page.mouse.drop( target, dragData ); expect( await getEditedPostContent() ).toMatchSnapshot(); } );