diff --git a/packages/e2e-test-utils/src/click-block-toolbar-button.js b/packages/e2e-test-utils/src/click-block-toolbar-button.js index dc27849e36d5e6..3aa431bfe29ff9 100644 --- a/packages/e2e-test-utils/src/click-block-toolbar-button.js +++ b/packages/e2e-test-utils/src/click-block-toolbar-button.js @@ -15,12 +15,13 @@ export async function clickBlockToolbarButton( label, type = 'ariaLabel' ) { let button; if ( type === 'ariaLabel' ) { - const BUTTON_SELECTOR = `.${ BLOCK_TOOLBAR_SELECTOR } button[aria-label="${ label }"]`; - button = await page.waitForSelector( BUTTON_SELECTOR ); + button = await page.waitForSelector( + `.${ BLOCK_TOOLBAR_SELECTOR } button[aria-label="${ label }"]` + ); } if ( type === 'content' ) { - [ button ] = await page.$x( + button = await page.waitForXPath( `//*[@class='${ BLOCK_TOOLBAR_SELECTOR }']//button[contains(text(), '${ label }')]` ); } diff --git a/packages/e2e-tests/assets/10x10_e2e_test_image_z9T8jK.png b/packages/e2e-tests/assets/10x10_e2e_test_image_z9T8jK.png index 4d198c0023578e..a13b8d3415a5a9 100644 Binary files a/packages/e2e-tests/assets/10x10_e2e_test_image_z9T8jK.png and b/packages/e2e-tests/assets/10x10_e2e_test_image_z9T8jK.png differ diff --git a/packages/e2e-tests/specs/editor/blocks/__snapshots__/image.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/image.test.js.snap index d17e4a8d39f6ac..18b856a57a4303 100644 --- a/packages/e2e-tests/specs/editor/blocks/__snapshots__/image.test.js.snap +++ b/packages/e2e-tests/specs/editor/blocks/__snapshots__/image.test.js.snap @@ -1,5 +1,17 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Image allows changing aspect ratio using the crop tools 1`] = `"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAACQf/xAAgEAAAAwkBAAAAAAAAAAAAAAAABAUBAwYJNTh0d7K1/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhEDEQA/AJTJUuninX570U4K8rVU7kPOmgoZKl08U6/PeinBXlaqnch500B//9k="`; + +exports[`Image allows changing aspect ratio using the crop tools 2`] = `"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAGAAoDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAcJ/8QAIBAAAQIFBQAAAAAAAAAAAAAAAAQFAQMGCTU4dHeytf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwCU2VNU9U8frvRbjV52yq3cTO0QAP/Z"`; + +exports[`Image allows rotating using the crop tools 1`] = `"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAACQf/xAAgEAAAAwkBAAAAAAAAAAAAAAAABAUBAwYJNTh0d7K1/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhEDEQA/AJTJUuninX570U4K8rVU7kPOmgoZKl08U6/PeinBXlaqnch500B//9k="`; + +exports[`Image allows rotating using the crop tools 2`] = `"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAcJ/8QAIRAAAAILAQAAAAAAAAAAAAAAAAUCBAcIFRlVVpOV0dT/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AlMlR6e/mVbUx8ISVHp7+ZVtTHwjV6LGtTW8yXQixrU1vMl0B/9k="`; + +exports[`Image allows zooming using the crop tools 1`] = `"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAACQf/xAAgEAAAAwkBAAAAAAAAAAAAAAAABAUBAwYJNTh0d7K1/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhEDEQA/AJTJUuninX570U4K8rVU7kPOmgoZKl08U6/PeinBXlaqnch500B//9k="`; + +exports[`Image allows zooming using the crop tools 2`] = `"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAFAAUDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAj/xAAaEAEAAQUAAAAAAAAAAAAAAAAABAcJOIW1/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhEDEQA/AKptcYJ0y3XYmgA//9k="`; + exports[`Image should drag and drop files into media placeholder 1`] = ` "
\\"\\"/
diff --git a/packages/e2e-tests/specs/editor/blocks/image.test.js b/packages/e2e-tests/specs/editor/blocks/image.test.js index 5c4ce8b1cdf4fd..b254413a141df9 100644 --- a/packages/e2e-tests/specs/editor/blocks/image.test.js +++ b/packages/e2e-tests/specs/editor/blocks/image.test.js @@ -14,7 +14,10 @@ import { getEditedPostContent, createNewPost, clickButton, + clickBlockToolbarButton, + clickMenuItem, openDocumentSettingsSidebar, + pressKeyWithModifier, } from '@wordpress/e2e-test-utils'; async function upload( selector ) { @@ -41,6 +44,20 @@ async function waitForImage( filename ) { ); } +async function getSrc( elementHandle ) { + return elementHandle.evaluate( ( node ) => node.src ); +} +async function getDataURL( elementHandle ) { + return elementHandle.evaluate( ( node ) => { + const canvas = document.createElement( 'canvas' ); + const context = canvas.getContext( '2d' ); + canvas.width = node.width; + canvas.height = node.height; + context.drawImage( node, 0, 0 ); + return canvas.toDataURL( 'image/jpeg' ); + } ); +} + describe( 'Image', () => { beforeEach( async () => { await createNewPost(); @@ -161,4 +178,114 @@ describe( 'Image', () => { await waitForImage( fileName ); } ); + + it( 'allows zooming using the crop tools', async () => { + // Insert the block, upload a file and crop. + await insertBlock( 'Image' ); + const filename = await upload( '.wp-block-image input[type="file"]' ); + await waitForImage( filename ); + + // Assert that the image is initially unscaled and unedited. + const initialImage = await page.$( '.wp-block-image img' ); + const initialImageSrc = await getSrc( initialImage ); + const initialImageDataURL = await getDataURL( initialImage ); + expect( initialImageDataURL ).toMatchSnapshot(); + + // Zoom in to twice the amount using the zoom input. + await clickBlockToolbarButton( 'Crop' ); + await clickBlockToolbarButton( 'Zoom' ); + await page.waitForFunction( () => + document.activeElement.classList.contains( + 'components-range-control__slider' + ) + ); + await page.keyboard.press( 'Tab' ); + await page.waitForFunction( () => + document.activeElement.classList.contains( + 'components-input-control__input' + ) + ); + await pressKeyWithModifier( 'primary', 'a' ); + await page.keyboard.type( '200' ); + await page.keyboard.press( 'Escape' ); + await clickBlockToolbarButton( 'Apply', 'content' ); + + // Wait for the cropping tools to disappear. + await page.waitForSelector( + '.wp-block-image img:not( .reactEasyCrop_Image )' + ); + + // Assert that the image is edited. + const updatedImage = await page.$( '.wp-block-image img' ); + const updatedImageSrc = await getSrc( updatedImage ); + expect( initialImageSrc ).not.toEqual( updatedImageSrc ); + const updatedImageDataURL = await getDataURL( updatedImage ); + expect( initialImageDataURL ).not.toEqual( updatedImageDataURL ); + expect( updatedImageDataURL ).toMatchSnapshot(); + } ); + + it( 'allows changing aspect ratio using the crop tools', async () => { + // Insert the block, upload a file and crop. + await insertBlock( 'Image' ); + const filename = await upload( '.wp-block-image input[type="file"]' ); + await waitForImage( filename ); + + // Assert that the image is initially unscaled and unedited. + const initialImage = await page.$( '.wp-block-image img' ); + const initialImageSrc = await getSrc( initialImage ); + const initialImageDataURL = await getDataURL( initialImage ); + expect( initialImageDataURL ).toMatchSnapshot(); + + // Zoom in to twice the amount using the zoom input. + await clickBlockToolbarButton( 'Crop' ); + await clickBlockToolbarButton( 'Aspect Ratio' ); + await page.waitForFunction( () => + document.activeElement.classList.contains( + 'components-menu-item__button' + ) + ); + await clickMenuItem( '16:10' ); + await clickBlockToolbarButton( 'Apply', 'content' ); + + // Wait for the cropping tools to disappear. + await page.waitForSelector( + '.wp-block-image img:not( .reactEasyCrop_Image )' + ); + + // Assert that the image is edited. + const updatedImage = await page.$( '.wp-block-image img' ); + const updatedImageSrc = await getSrc( updatedImage ); + expect( initialImageSrc ).not.toEqual( updatedImageSrc ); + const updatedImageDataURL = await getDataURL( updatedImage ); + expect( initialImageDataURL ).not.toEqual( updatedImageDataURL ); + expect( updatedImageDataURL ).toMatchSnapshot(); + } ); + + it( 'allows rotating using the crop tools', async () => { + // Insert the block, upload a file and crop. + await insertBlock( 'Image' ); + const filename = await upload( '.wp-block-image input[type="file"]' ); + await waitForImage( filename ); + + // Assert that the image is initially unscaled and unedited. + const initialImage = await page.$( '.wp-block-image img' ); + const initialImageDataURL = await getDataURL( initialImage ); + expect( initialImageDataURL ).toMatchSnapshot(); + + // Double the image's size using the zoom input. + await clickBlockToolbarButton( 'Crop' ); + await page.waitForSelector( '.wp-block-image img.reactEasyCrop_Image' ); + await clickBlockToolbarButton( 'Rotate' ); + await clickBlockToolbarButton( 'Apply', 'content' ); + + await page.waitForSelector( + '.wp-block-image img:not( .reactEasyCrop_Image )' + ); + + // Assert that the image is edited. + const updatedImage = await page.$( '.wp-block-image img' ); + const updatedImageDataURL = await getDataURL( updatedImage ); + expect( initialImageDataURL ).not.toEqual( updatedImageDataURL ); + expect( updatedImageDataURL ).toMatchSnapshot(); + } ); } );