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
deleted file mode 100644
index 6683872d66fc68..00000000000000
--- a/packages/e2e-tests/specs/editor/blocks/__snapshots__/image.test.js.snap
+++ /dev/null
@@ -1,25 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Image allows changing aspect ratio using the crop tools 1`] = `"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gIoSUNDX1BST0ZJTEUAAQEAAAIYAAAAAAQwAABtbnRyUkdCIFhZWiAAAAAAAAAAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAAHRyWFlaAAABZAAAABRnWFlaAAABeAAAABRiWFlaAAABjAAAABRyVFJDAAABoAAAAChnVFJDAAABoAAAAChiVFJDAAABoAAAACh3dHB0AAAByAAAABRjcHJ0AAAB3AAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAFgAAAAcAHMAUgBHAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABvogAAOPUAAAOQWFlaIAAAAAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAAAA+EAAC2z3BhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABYWVogAAAAAAAA9tYAAQAAAADTLW1sdWMAAAAAAAAAAQAAAAxlblVTAAAAIAAAABwARwBvAG8AZwBsAGUAIABJAG4AYwAuACAAMgAwADEANv/bAEMAAwICAgICAwICAgMDAwMEBgQEBAQECAYGBQYJCAoKCQgJCQoMDwwKCw4LCQkNEQ0ODxAQERAKDBITEhATDxAQEP/bAEMBAwMDBAMECAQECBALCQsQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEP/AABEIAAoACgMBIgACEQEDEQH/xAAVAAEBAAAAAAAAAAAAAAAAAAAJB//EACAQAAADCQEAAAAAAAAAAAAAAAAEBQEDBgk1OHR3srX/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AlMlS6eKdfnvRTgrytVTuQ86aChkqXTxTr896KcFeVqqdyHnTQH//2Q=="`;
-
-exports[`Image allows changing aspect ratio using the crop tools 2`] = `"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gIoSUNDX1BST0ZJTEUAAQEAAAIYAAAAAAQwAABtbnRyUkdCIFhZWiAAAAAAAAAAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAAHRyWFlaAAABZAAAABRnWFlaAAABeAAAABRiWFlaAAABjAAAABRyVFJDAAABoAAAAChnVFJDAAABoAAAAChiVFJDAAABoAAAACh3dHB0AAAByAAAABRjcHJ0AAAB3AAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAFgAAAAcAHMAUgBHAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABvogAAOPUAAAOQWFlaIAAAAAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAAAA+EAAC2z3BhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABYWVogAAAAAAAA9tYAAQAAAADTLW1sdWMAAAAAAAAAAQAAAAxlblVTAAAAIAAAABwARwBvAG8AZwBsAGUAIABJAG4AYwAuACAAMgAwADEANv/bAEMAAwICAgICAwICAgMDAwMEBgQEBAQECAYGBQYJCAoKCQgJCQoMDwwKCw4LCQkNEQ0ODxAQERAKDBITEhATDxAQEP/bAEMBAwMDBAMECAQECBALCQsQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEP/AABEIAAYACgMBIgACEQEDEQH/xAAWAAEBAQAAAAAAAAAAAAAAAAAABwn/xAAgEAABAgUFAAAAAAAAAAAAAAAABAUBAwYJNTh0d7K1/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhEDEQA/AJTZU1T1Tx+u9FuNXnbKrdxM7RAA/9k="`;
-
-exports[`Image allows rotating using the crop tools 1`] = `"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gIoSUNDX1BST0ZJTEUAAQEAAAIYAAAAAAQwAABtbnRyUkdCIFhZWiAAAAAAAAAAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAAHRyWFlaAAABZAAAABRnWFlaAAABeAAAABRiWFlaAAABjAAAABRyVFJDAAABoAAAAChnVFJDAAABoAAAAChiVFJDAAABoAAAACh3dHB0AAAByAAAABRjcHJ0AAAB3AAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAFgAAAAcAHMAUgBHAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABvogAAOPUAAAOQWFlaIAAAAAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAAAA+EAAC2z3BhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABYWVogAAAAAAAA9tYAAQAAAADTLW1sdWMAAAAAAAAAAQAAAAxlblVTAAAAIAAAABwARwBvAG8AZwBsAGUAIABJAG4AYwAuACAAMgAwADEANv/bAEMAAwICAgICAwICAgMDAwMEBgQEBAQECAYGBQYJCAoKCQgJCQoMDwwKCw4LCQkNEQ0ODxAQERAKDBITEhATDxAQEP/bAEMBAwMDBAMECAQECBALCQsQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEP/AABEIAAoACgMBIgACEQEDEQH/xAAVAAEBAAAAAAAAAAAAAAAAAAAJB//EACAQAAADCQEAAAAAAAAAAAAAAAAEBQEDBgk1OHR3srX/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AlMlS6eKdfnvRTgrytVTuQ86aChkqXTxTr896KcFeVqqdyHnTQH//2Q=="`;
-
-exports[`Image allows rotating using the crop tools 2`] = `"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gIoSUNDX1BST0ZJTEUAAQEAAAIYAAAAAAQwAABtbnRyUkdCIFhZWiAAAAAAAAAAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAAHRyWFlaAAABZAAAABRnWFlaAAABeAAAABRiWFlaAAABjAAAABRyVFJDAAABoAAAAChnVFJDAAABoAAAAChiVFJDAAABoAAAACh3dHB0AAAByAAAABRjcHJ0AAAB3AAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAFgAAAAcAHMAUgBHAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABvogAAOPUAAAOQWFlaIAAAAAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAAAA+EAAC2z3BhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABYWVogAAAAAAAA9tYAAQAAAADTLW1sdWMAAAAAAAAAAQAAAAxlblVTAAAAIAAAABwARwBvAG8AZwBsAGUAIABJAG4AYwAuACAAMgAwADEANv/bAEMAAwICAgICAwICAgMDAwMEBgQEBAQECAYGBQYJCAoKCQgJCQoMDwwKCw4LCQkNEQ0ODxAQERAKDBITEhATDxAQEP/bAEMBAwMDBAMECAQECBALCQsQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEP/AABEIAAoACgMBIgACEQEDEQH/xAAWAAEBAQAAAAAAAAAAAAAAAAAABwn/xAAhEAAAAgsBAAAAAAAAAAAAAAAABQIEBwgVGVVWk5XR1P/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwCUyVHp7+ZVtTHwhJUenv5lW1MfCNXosa1NbzJdCLGtTW8yXQH/2Q=="`;
-
-exports[`Image allows zooming using the crop tools 1`] = `"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gIoSUNDX1BST0ZJTEUAAQEAAAIYAAAAAAQwAABtbnRyUkdCIFhZWiAAAAAAAAAAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAAHRyWFlaAAABZAAAABRnWFlaAAABeAAAABRiWFlaAAABjAAAABRyVFJDAAABoAAAAChnVFJDAAABoAAAAChiVFJDAAABoAAAACh3dHB0AAAByAAAABRjcHJ0AAAB3AAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAFgAAAAcAHMAUgBHAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABvogAAOPUAAAOQWFlaIAAAAAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAAAA+EAAC2z3BhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABYWVogAAAAAAAA9tYAAQAAAADTLW1sdWMAAAAAAAAAAQAAAAxlblVTAAAAIAAAABwARwBvAG8AZwBsAGUAIABJAG4AYwAuACAAMgAwADEANv/bAEMAAwICAgICAwICAgMDAwMEBgQEBAQECAYGBQYJCAoKCQgJCQoMDwwKCw4LCQkNEQ0ODxAQERAKDBITEhATDxAQEP/bAEMBAwMDBAMECAQECBALCQsQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEP/AABEIAAoACgMBIgACEQEDEQH/xAAVAAEBAAAAAAAAAAAAAAAAAAAJB//EACAQAAADCQEAAAAAAAAAAAAAAAAEBQEDBgk1OHR3srX/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AlMlS6eKdfnvRTgrytVTuQ86aChkqXTxTr896KcFeVqqdyHnTQH//2Q=="`;
-
-exports[`Image allows zooming using the crop tools 2`] = `"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gIoSUNDX1BST0ZJTEUAAQEAAAIYAAAAAAQwAABtbnRyUkdCIFhZWiAAAAAAAAAAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAAHRyWFlaAAABZAAAABRnWFlaAAABeAAAABRiWFlaAAABjAAAABRyVFJDAAABoAAAAChnVFJDAAABoAAAAChiVFJDAAABoAAAACh3dHB0AAAByAAAABRjcHJ0AAAB3AAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAFgAAAAcAHMAUgBHAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABvogAAOPUAAAOQWFlaIAAAAAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAAAA+EAAC2z3BhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABYWVogAAAAAAAA9tYAAQAAAADTLW1sdWMAAAAAAAAAAQAAAAxlblVTAAAAIAAAABwARwBvAG8AZwBsAGUAIABJAG4AYwAuACAAMgAwADEANv/bAEMAAwICAgICAwICAgMDAwMEBgQEBAQECAYGBQYJCAoKCQgJCQoMDwwKCw4LCQkNEQ0ODxAQERAKDBITEhATDxAQEP/bAEMBAwMDBAMECAQECBALCQsQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEP/AABEIAAUABQMBIgACEQEDEQH/xAAVAAEBAAAAAAAAAAAAAAAAAAAACP/EABoQAQABBQAAAAAAAAAAAAAAAAAEBwk4hbX/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8Aqm1xgnTLddiaAD//2Q=="`;
-
-exports[`Image should drag and drop files into media placeholder 1`] = `
-"
-
-"
-`;
-
-exports[`Image should undo without broken temporary state 1`] = `
-"
-
-"
-`;
diff --git a/packages/e2e-tests/specs/editor/blocks/image.test.js b/packages/e2e-tests/specs/editor/blocks/image.test.js
deleted file mode 100644
index ac3ddba34b46ea..00000000000000
--- a/packages/e2e-tests/specs/editor/blocks/image.test.js
+++ /dev/null
@@ -1,373 +0,0 @@
-/**
- * External dependencies
- */
-import path from 'path';
-import fs from 'fs';
-import os from 'os';
-import { v4 as uuid } from 'uuid';
-
-/**
- * WordPress dependencies
- */
-import {
- insertBlock,
- getEditedPostContent,
- createNewPost,
- clickButton,
- clickBlockToolbarButton,
- clickMenuItem,
- openDocumentSettingsSidebar,
- pressKeyWithModifier,
-} from '@wordpress/e2e-test-utils';
-
-async function upload( selector ) {
- await page.waitForSelector( selector );
- const inputElement = await page.$( selector );
- const testImagePath = path.join(
- __dirname,
- '..',
- '..',
- '..',
- 'assets',
- '10x10_e2e_test_image_z9T8jK.png'
- );
- const filename = uuid();
- const tmpFileName = path.join( os.tmpdir(), filename + '.png' );
- fs.copyFileSync( testImagePath, tmpFileName );
- await inputElement.uploadFile( tmpFileName );
- return filename;
-}
-
-async function waitForImage( filename ) {
- await page.waitForSelector(
- `.wp-block-image img[src$="${ filename }.png"]`
- );
-}
-
-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();
- } );
-
- it( 'can be inserted', async () => {
- await insertBlock( 'Image' );
- const filename = await upload( '.wp-block-image input[type="file"]' );
- await waitForImage( filename );
-
- const regex = new RegExp(
- `\\s*
\\s*`
- );
- expect( await getEditedPostContent() ).toMatch( regex );
- } );
-
- it( 'should replace, reset size, and keep selection', async () => {
- await insertBlock( 'Image' );
- const filename1 = await upload( '.wp-block-image input[type="file"]' );
- await waitForImage( filename1 );
-
- const regex1 = new RegExp(
- `\\s*
\\s*`
- );
- expect( await getEditedPostContent() ).toMatch( regex1 );
-
- await openDocumentSettingsSidebar();
- await page.click( '[aria-label="Image size presets"] button' );
-
- const regex2 = new RegExp(
- `\\s*
<\\/figure>\\s*`
- );
-
- expect( await getEditedPostContent() ).toMatch( regex2 );
-
- await clickButton( 'Replace' );
- const filename2 = await upload(
- '.block-editor-media-replace-flow__options input[type="file"]'
- );
- await waitForImage( filename2 );
-
- const regex3 = new RegExp(
- `\\s*
\\s*`
- );
- expect( await getEditedPostContent() ).toMatch( regex3 );
- // Focus outside the block to avoid the image caption being selected
- // It can happen on CI specially.
- await page.click( '.wp-block-post-title' );
- await page.click( '.wp-block-image img' );
- await page.keyboard.press( 'Backspace' );
-
- expect( await getEditedPostContent() ).toBe( '' );
- } );
-
- it.skip( 'should place caret at end of caption after merging empty paragraph', async () => {
- await insertBlock( 'Image' );
- const fileName = await upload( '.wp-block-image input[type="file"]' );
- await waitForImage( fileName );
- await page.keyboard.type( '1' );
- await page.keyboard.press( 'Enter' );
- await page.keyboard.press( 'Backspace' );
- await page.keyboard.type( '2' );
-
- expect(
- await page.evaluate( () => document.activeElement.innerHTML )
- ).toBe( '12' );
- } );
-
- it( 'should allow soft line breaks in caption', async () => {
- await insertBlock( 'Image' );
- const fileName = await upload( '.wp-block-image input[type="file"]' );
- await waitForImage( fileName );
- await page.keyboard.type( '12' );
- await page.keyboard.press( 'ArrowLeft' );
- await page.keyboard.press( 'Enter' );
-
- expect(
- await page.evaluate( () => document.activeElement.innerHTML )
- ).toBe( '1
2' );
- } );
-
- it( 'should have keyboard navigable toolbar for caption', async () => {
- await insertBlock( 'Image' );
- const fileName = await upload( '.wp-block-image input[type="file"]' );
- await waitForImage( fileName );
- // Navigate to More, Link, Italic and finally Bold.
- await pressKeyWithModifier( 'shift', 'Tab' );
- await pressKeyWithModifier( 'shift', 'Tab' );
- await pressKeyWithModifier( 'shift', 'Tab' );
- await pressKeyWithModifier( 'shift', 'Tab' );
- await page.keyboard.press( 'Space' );
- await page.keyboard.press( 'a' );
- await page.keyboard.press( 'ArrowRight' );
-
- expect(
- await page.evaluate( () => document.activeElement.innerHTML )
- ).toBe( 'a' );
- } );
-
- it( 'should drag and drop files into media placeholder', async () => {
- await page.keyboard.press( 'Enter' );
- await insertBlock( 'Image' );
-
- // Confirm correct setup.
- expect( await getEditedPostContent() ).toMatchSnapshot();
-
- const image = await page.$( '[data-type="core/image"]' );
-
- await image.evaluate( () => {
- const input = document.createElement( 'input' );
- input.type = 'file';
- input.id = 'wp-temp-test-input';
- document.body.appendChild( input );
- } );
-
- const fileName = await upload( '#wp-temp-test-input' );
-
- const paragraphRect = await image.boundingBox();
- const pX = paragraphRect.x + paragraphRect.width / 2;
- const pY = paragraphRect.y + paragraphRect.height / 3;
-
- await image.evaluate(
- ( element, clientX, clientY ) => {
- const input = document.getElementById( 'wp-temp-test-input' );
- const dataTransfer = new DataTransfer();
- dataTransfer.items.add( input.files[ 0 ] );
- const event = new DragEvent( 'drop', {
- bubbles: true,
- clientX,
- clientY,
- dataTransfer,
- } );
- element.dispatchEvent( event );
- },
- pX,
- pY
- );
-
- 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();
- } );
-
- it( 'Should reset dimensions on change URL', async () => {
- const imageUrl = '/wp-includes/images/w-logo-blue.png';
-
- await insertBlock( 'Image' );
-
- // Upload an initial image.
- const filename = await upload( '.wp-block-image input[type="file"]' );
- await waitForImage( filename );
- // Resize the Uploaded Image.
- await openDocumentSettingsSidebar();
- await page.waitForSelector(
- '[aria-label="Image size presets"] button:first-child',
- { visible: true }
- );
- await page.click(
- '[aria-label="Image size presets"] button:first-child'
- );
-
- const regexBefore = new RegExp(
- `\\s*
<\\/figure>\\s*`
- );
-
- // Check if dimensions are changed.
- expect( await getEditedPostContent() ).toMatch( regexBefore );
-
- // Replace uploaded image with an URL.
- await clickButton( 'Replace' );
-
- const [ editButton ] = await page.$x(
- '//button[contains(@aria-label, "Edit")]'
- );
- await editButton.click();
-
- await page.waitForSelector( '.block-editor-url-input__input' );
-
- // Clear the input field. Delay added to account for typing delays.
- const inputField = await page.$( '.block-editor-url-input__input' );
- await inputField.click( { clickCount: 3, delay: 200 } );
-
- // Replace the url. Delay added to account for typing delays.
- await page.focus( '.block-editor-url-input__input' );
- await page.keyboard.type( imageUrl, { delay: 100 } );
- await page.click( '.block-editor-link-control__search-submit' );
-
- const regexAfter = new RegExp(
- `\\s*
\\s*`
- );
-
- // Check if dimensions are reset.
- expect( await getEditedPostContent() ).toMatch( regexAfter );
- } );
-
- it( 'should undo without broken temporary state', async () => {
- await insertBlock( 'Image' );
- const fileName = await upload( '.wp-block-image input[type="file"]' );
- await waitForImage( fileName );
- await pressKeyWithModifier( 'primary', 'z' );
- // Expect an empty image block (placeholder) rather than one with a
- // broken temporary URL.
- expect( await getEditedPostContent() ).toMatchSnapshot();
- } );
-} );
diff --git a/test/e2e/assets/10x10_e2e_test_image_z9T8jK.png b/test/e2e/assets/10x10_e2e_test_image_z9T8jK.png
new file mode 100644
index 00000000000000..a13b8d3415a5a9
Binary files /dev/null and b/test/e2e/assets/10x10_e2e_test_image_z9T8jK.png differ
diff --git a/test/e2e/specs/editor/blocks/__snapshots__/Image-allows-changing-aspect-ratio-using-the-crop-tools-1-chromium.txt b/test/e2e/specs/editor/blocks/__snapshots__/Image-allows-changing-aspect-ratio-using-the-crop-tools-1-chromium.txt
new file mode 100644
index 00000000000000..023f807dff9f36
--- /dev/null
+++ b/test/e2e/specs/editor/blocks/__snapshots__/Image-allows-changing-aspect-ratio-using-the-crop-tools-1-chromium.txt
@@ -0,0 +1,6 @@
+Snapshot Diff:
+- First value
++ Second value
+
+- data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gIoSUNDX1BST0ZJTEUAAQEAAAIYAAAAAAQwAABtbnRyUkdCIFhZWiAAAAAAAAAAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAAHRyWFlaAAABZAAAABRnWFlaAAABeAAAABRiWFlaAAABjAAAABRyVFJDAAABoAAAAChnVFJDAAABoAAAAChiVFJDAAABoAAAACh3dHB0AAAByAAAABRjcHJ0AAAB3AAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAFgAAAAcAHMAUgBHAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABvogAAOPUAAAOQWFlaIAAAAAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAAAA+EAAC2z3BhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABYWVogAAAAAAAA9tYAAQAAAADTLW1sdWMAAAAAAAAAAQAAAAxlblVTAAAAIAAAABwARwBvAG8AZwBsAGUAIABJAG4AYwAuACAAMgAwADEANv/bAEMAAwICAgICAwICAgMDAwMEBgQEBAQECAYGBQYJCAoKCQgJCQoMDwwKCw4LCQkNEQ0ODxAQERAKDBITEhATDxAQEP/bAEMBAwMDBAMECAQECBALCQsQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEP/AABEIAAoACgMBIgACEQEDEQH/xAAVAAEBAAAAAAAAAAAAAAAAAAAJB//EACAQAAADCQEAAAAAAAAAAAAAAAAEBQEDBgk1OHR3srX/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AlMlS6eKdfnvRTgrytVTuQ86aChkqXTxTr896KcFeVqqdyHnTQH//2Q==
++ data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gIoSUNDX1BST0ZJTEUAAQEAAAIYAAAAAAQwAABtbnRyUkdCIFhZWiAAAAAAAAAAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAAHRyWFlaAAABZAAAABRnWFlaAAABeAAAABRiWFlaAAABjAAAABRyVFJDAAABoAAAAChnVFJDAAABoAAAAChiVFJDAAABoAAAACh3dHB0AAAByAAAABRjcHJ0AAAB3AAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAFgAAAAcAHMAUgBHAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABvogAAOPUAAAOQWFlaIAAAAAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAAAA+EAAC2z3BhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABYWVogAAAAAAAA9tYAAQAAAADTLW1sdWMAAAAAAAAAAQAAAAxlblVTAAAAIAAAABwARwBvAG8AZwBsAGUAIABJAG4AYwAuACAAMgAwADEANv/bAEMAAwICAgICAwICAgMDAwMEBgQEBAQECAYGBQYJCAoKCQgJCQoMDwwKCw4LCQkNEQ0ODxAQERAKDBITEhATDxAQEP/bAEMBAwMDBAMECAQECBALCQsQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEP/AABEIAAYACgMBIgACEQEDEQH/xAAWAAEBAQAAAAAAAAAAAAAAAAAABwn/xAAgEAABAgUFAAAAAAAAAAAAAAAABAUBAwYJNTh0d7K1/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhEDEQA/AJTZU1T1Tx+u9FuNXnbKrdxM7RAA/9k=
\ No newline at end of file
diff --git a/test/e2e/specs/editor/blocks/__snapshots__/Image-allows-rotating-using-the-crop-tools-1-chromium.txt b/test/e2e/specs/editor/blocks/__snapshots__/Image-allows-rotating-using-the-crop-tools-1-chromium.txt
new file mode 100644
index 00000000000000..4409ceaca181e3
--- /dev/null
+++ b/test/e2e/specs/editor/blocks/__snapshots__/Image-allows-rotating-using-the-crop-tools-1-chromium.txt
@@ -0,0 +1,6 @@
+Snapshot Diff:
+- First value
++ Second value
+
+- data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gIoSUNDX1BST0ZJTEUAAQEAAAIYAAAAAAQwAABtbnRyUkdCIFhZWiAAAAAAAAAAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAAHRyWFlaAAABZAAAABRnWFlaAAABeAAAABRiWFlaAAABjAAAABRyVFJDAAABoAAAAChnVFJDAAABoAAAAChiVFJDAAABoAAAACh3dHB0AAAByAAAABRjcHJ0AAAB3AAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAFgAAAAcAHMAUgBHAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABvogAAOPUAAAOQWFlaIAAAAAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAAAA+EAAC2z3BhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABYWVogAAAAAAAA9tYAAQAAAADTLW1sdWMAAAAAAAAAAQAAAAxlblVTAAAAIAAAABwARwBvAG8AZwBsAGUAIABJAG4AYwAuACAAMgAwADEANv/bAEMAAwICAgICAwICAgMDAwMEBgQEBAQECAYGBQYJCAoKCQgJCQoMDwwKCw4LCQkNEQ0ODxAQERAKDBITEhATDxAQEP/bAEMBAwMDBAMECAQECBALCQsQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEP/AABEIAAoACgMBIgACEQEDEQH/xAAVAAEBAAAAAAAAAAAAAAAAAAAJB//EACAQAAADCQEAAAAAAAAAAAAAAAAEBQEDBgk1OHR3srX/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AlMlS6eKdfnvRTgrytVTuQ86aChkqXTxTr896KcFeVqqdyHnTQH//2Q==
++ data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gIoSUNDX1BST0ZJTEUAAQEAAAIYAAAAAAQwAABtbnRyUkdCIFhZWiAAAAAAAAAAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAAHRyWFlaAAABZAAAABRnWFlaAAABeAAAABRiWFlaAAABjAAAABRyVFJDAAABoAAAAChnVFJDAAABoAAAAChiVFJDAAABoAAAACh3dHB0AAAByAAAABRjcHJ0AAAB3AAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAFgAAAAcAHMAUgBHAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABvogAAOPUAAAOQWFlaIAAAAAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAAAA+EAAC2z3BhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABYWVogAAAAAAAA9tYAAQAAAADTLW1sdWMAAAAAAAAAAQAAAAxlblVTAAAAIAAAABwARwBvAG8AZwBsAGUAIABJAG4AYwAuACAAMgAwADEANv/bAEMAAwICAgICAwICAgMDAwMEBgQEBAQECAYGBQYJCAoKCQgJCQoMDwwKCw4LCQkNEQ0ODxAQERAKDBITEhATDxAQEP/bAEMBAwMDBAMECAQECBALCQsQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEP/AABEIAAoACgMBIgACEQEDEQH/xAAWAAEBAQAAAAAAAAAAAAAAAAAABwn/xAAhEAAAAgsBAAAAAAAAAAAAAAAABQIEBwgVGVVWk5XR1P/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwCUyVHp7+ZVtTHwhJUenv5lW1MfCNXosa1NbzJdCLGtTW8yXQH/2Q==
\ No newline at end of file
diff --git a/test/e2e/specs/editor/blocks/__snapshots__/Image-allows-zooming-using-the-crop-tools-1-chromium.txt b/test/e2e/specs/editor/blocks/__snapshots__/Image-allows-zooming-using-the-crop-tools-1-chromium.txt
new file mode 100644
index 00000000000000..5f53c934223d3c
--- /dev/null
+++ b/test/e2e/specs/editor/blocks/__snapshots__/Image-allows-zooming-using-the-crop-tools-1-chromium.txt
@@ -0,0 +1,6 @@
+Snapshot Diff:
+- First value
++ Second value
+
+- data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gIoSUNDX1BST0ZJTEUAAQEAAAIYAAAAAAQwAABtbnRyUkdCIFhZWiAAAAAAAAAAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAAHRyWFlaAAABZAAAABRnWFlaAAABeAAAABRiWFlaAAABjAAAABRyVFJDAAABoAAAAChnVFJDAAABoAAAAChiVFJDAAABoAAAACh3dHB0AAAByAAAABRjcHJ0AAAB3AAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAFgAAAAcAHMAUgBHAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABvogAAOPUAAAOQWFlaIAAAAAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAAAA+EAAC2z3BhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABYWVogAAAAAAAA9tYAAQAAAADTLW1sdWMAAAAAAAAAAQAAAAxlblVTAAAAIAAAABwARwBvAG8AZwBsAGUAIABJAG4AYwAuACAAMgAwADEANv/bAEMAAwICAgICAwICAgMDAwMEBgQEBAQECAYGBQYJCAoKCQgJCQoMDwwKCw4LCQkNEQ0ODxAQERAKDBITEhATDxAQEP/bAEMBAwMDBAMECAQECBALCQsQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEP/AABEIAAoACgMBIgACEQEDEQH/xAAVAAEBAAAAAAAAAAAAAAAAAAAJB//EACAQAAADCQEAAAAAAAAAAAAAAAAEBQEDBgk1OHR3srX/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AlMlS6eKdfnvRTgrytVTuQ86aChkqXTxTr896KcFeVqqdyHnTQH//2Q==
++ data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gIoSUNDX1BST0ZJTEUAAQEAAAIYAAAAAAQwAABtbnRyUkdCIFhZWiAAAAAAAAAAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAAHRyWFlaAAABZAAAABRnWFlaAAABeAAAABRiWFlaAAABjAAAABRyVFJDAAABoAAAAChnVFJDAAABoAAAAChiVFJDAAABoAAAACh3dHB0AAAByAAAABRjcHJ0AAAB3AAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAFgAAAAcAHMAUgBHAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABvogAAOPUAAAOQWFlaIAAAAAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAAAA+EAAC2z3BhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABYWVogAAAAAAAA9tYAAQAAAADTLW1sdWMAAAAAAAAAAQAAAAxlblVTAAAAIAAAABwARwBvAG8AZwBsAGUAIABJAG4AYwAuACAAMgAwADEANv/bAEMAAwICAgICAwICAgMDAwMEBgQEBAQECAYGBQYJCAoKCQgJCQoMDwwKCw4LCQkNEQ0ODxAQERAKDBITEhATDxAQEP/bAEMBAwMDBAMECAQECBALCQsQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEP/AABEIAAUABQMBIgACEQEDEQH/xAAVAAEBAAAAAAAAAAAAAAAAAAAACP/EABoQAQABBQAAAAAAAAAAAAAAAAAEBwk4hbX/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8Aqm1xgnTLddiaAD//2Q==
\ No newline at end of file
diff --git a/test/e2e/specs/editor/blocks/image.spec.js b/test/e2e/specs/editor/blocks/image.spec.js
new file mode 100644
index 00000000000000..8304533528ab87
--- /dev/null
+++ b/test/e2e/specs/editor/blocks/image.spec.js
@@ -0,0 +1,549 @@
+/**
+ * External dependencies
+ */
+const path = require( 'path' );
+const fs = require( 'fs/promises' );
+const os = require( 'os' );
+const { v4: uuid } = require( 'uuid' );
+const snapshotDiff = require( 'snapshot-diff' );
+
+/**
+ * WordPress dependencies
+ */
+const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' );
+
+test.use( {
+ imageBlockUtils: async ( { page }, use ) => {
+ await use( new ImageBlockUtils( { page } ) );
+ },
+} );
+
+test.describe( 'Image', () => {
+ test.beforeAll( async ( { requestUtils } ) => {
+ await requestUtils.deleteAllMedia();
+ } );
+
+ test.beforeEach( async ( { pageUtils } ) => {
+ await pageUtils.createNewPost();
+ } );
+
+ test.afterEach( async ( { requestUtils } ) => {
+ await requestUtils.deleteAllMedia();
+ } );
+
+ test( 'can be inserted', async ( { page, pageUtils, imageBlockUtils } ) => {
+ await pageUtils.insertBlock( { name: 'core/image' } );
+
+ const imageBlock = page.locator(
+ 'role=document[name="Block: Image"i]'
+ );
+ await expect( imageBlock ).toBeVisible();
+
+ const filename = await imageBlockUtils.upload(
+ imageBlock.locator( 'data-testid=form-file-upload-input' )
+ );
+
+ const image = imageBlock.locator( 'role=img' );
+ await expect( image ).toBeVisible();
+ await expect( image ).toHaveAttribute( 'src', new RegExp( filename ) );
+
+ const regex = new RegExp(
+ `
+
+`
+ );
+ expect( await pageUtils.getEditedPostContent() ).toMatch( regex );
+ } );
+
+ test( 'should replace, reset size, and keep selection', async ( {
+ page,
+ pageUtils,
+ imageBlockUtils,
+ } ) => {
+ await pageUtils.insertBlock( { name: 'core/image' } );
+
+ const imageBlock = page.locator(
+ 'role=document[name="Block: Image"i]'
+ );
+ const image = imageBlock.locator( 'role=img' );
+
+ const filename = await imageBlockUtils.upload(
+ imageBlock.locator( 'data-testid=form-file-upload-input' )
+ );
+
+ {
+ await expect( image ).toBeVisible();
+ await expect( image ).toHaveAttribute(
+ 'src',
+ new RegExp( filename )
+ );
+
+ const regex = new RegExp(
+ `
+
+`
+ );
+ expect( await pageUtils.getEditedPostContent() ).toMatch( regex );
+ }
+
+ {
+ await pageUtils.openDocumentSettingsSidebar();
+ await page.click(
+ 'role=group[name="Image size presets"i] >> role=button[name="25%"i]'
+ );
+
+ await expect( image ).toHaveCSS( 'width', '3px' );
+ await expect( image ).toHaveCSS( 'height', '3px' );
+
+ const regex = new RegExp(
+ `
+
<\\/figure>
+`
+ );
+
+ expect( await pageUtils.getEditedPostContent() ).toMatch( regex );
+ }
+
+ {
+ await pageUtils.showBlockToolbar();
+ await page.click( 'role=button[name="Replace"i]' );
+
+ const replacedFilename = await imageBlockUtils.upload(
+ page
+ // Ideally the menu should have the name of "Replace" but is currently missing.
+ // Hence, we fallback to using CSS classname instead.
+ .locator( '.block-editor-media-replace-flow__options' )
+ .locator( 'data-testid=form-file-upload-input' )
+ );
+
+ await expect( image ).toHaveAttribute(
+ 'src',
+ new RegExp( replacedFilename )
+ );
+ await expect( image ).toBeVisible();
+
+ const regex = new RegExp(
+ `
+
+`
+ );
+ expect( await pageUtils.getEditedPostContent() ).toMatch( regex );
+ }
+
+ {
+ // Focus outside the block to avoid the image caption being selected
+ // It can happen on CI specially.
+ await page.click( 'role=textbox[name="Add title"i]' );
+ await image.click();
+ await page.keyboard.press( 'Backspace' );
+
+ expect( await pageUtils.getEditedPostContent() ).toBe( '' );
+ }
+ } );
+
+ test( 'should place caret at end of caption after merging empty paragraph', async ( {
+ page,
+ pageUtils,
+ imageBlockUtils,
+ } ) => {
+ await pageUtils.insertBlock( { name: 'core/image' } );
+
+ const imageBlock = page.locator(
+ 'role=document[name="Block: Image"i]'
+ );
+ const image = imageBlock.locator( 'role=img' );
+
+ const filename = await imageBlockUtils.upload(
+ imageBlock.locator( 'data-testid=form-file-upload-input' )
+ );
+ await expect( image ).toHaveAttribute( 'src', new RegExp( filename ) );
+
+ await page.keyboard.type( '1' );
+ await page.keyboard.press( 'Enter' );
+ await page.keyboard.press( 'Backspace' );
+ await page.keyboard.type( '2' );
+
+ expect(
+ await page.evaluate( () => document.activeElement.innerHTML )
+ ).toBe( '12' );
+ } );
+
+ test( 'should allow soft line breaks in caption', async ( {
+ page,
+ pageUtils,
+ imageBlockUtils,
+ } ) => {
+ await pageUtils.insertBlock( { name: 'core/image' } );
+
+ const imageBlock = page.locator(
+ 'role=document[name="Block: Image"i]'
+ );
+ const image = imageBlock.locator( 'role=img' );
+
+ const fileName = await imageBlockUtils.upload(
+ imageBlock.locator( 'data-testid=form-file-upload-input' )
+ );
+
+ await expect( image ).toBeVisible();
+ await expect( image ).toHaveAttribute( 'src', new RegExp( fileName ) );
+
+ await page.keyboard.type( '12' );
+ await page.keyboard.press( 'ArrowLeft' );
+ await page.keyboard.press( 'Enter' );
+
+ expect(
+ await page.evaluate( () => document.activeElement.innerHTML )
+ ).toBe( '1
2' );
+ } );
+
+ test( 'should have keyboard navigable toolbar for caption', async ( {
+ page,
+ pageUtils,
+ imageBlockUtils,
+ } ) => {
+ await pageUtils.insertBlock( { name: 'core/image' } );
+
+ const imageBlock = page.locator(
+ 'role=document[name="Block: Image"i]'
+ );
+ const image = imageBlock.locator( 'role=img' );
+
+ const fileName = await imageBlockUtils.upload(
+ imageBlock.locator( 'data-testid=form-file-upload-input' )
+ );
+
+ await expect( image ).toBeVisible();
+ await expect( image ).toHaveAttribute( 'src', new RegExp( fileName ) );
+
+ // Navigate to More,
+ await pageUtils.pressKeyWithModifier( 'shift', 'Tab' );
+ // Link,
+ await pageUtils.pressKeyWithModifier( 'shift', 'Tab' );
+ // Italic,
+ await pageUtils.pressKeyWithModifier( 'shift', 'Tab' );
+ // and finally Bold.
+ await pageUtils.pressKeyWithModifier( 'shift', 'Tab' );
+
+ await page.keyboard.press( 'Space' );
+ await page.keyboard.press( 'a' );
+ await page.keyboard.press( 'ArrowRight' );
+
+ expect(
+ await page.evaluate( () => document.activeElement.innerHTML )
+ ).toBe( 'a' );
+ } );
+
+ test( 'should drag and drop files into media placeholder', async ( {
+ page,
+ pageUtils,
+ imageBlockUtils,
+ } ) => {
+ await pageUtils.insertBlock( { name: 'core/image' } );
+
+ const imageBlock = page.locator(
+ 'role=document[name="Block: Image"i]'
+ );
+ const image = imageBlock.locator( 'role=img' );
+
+ const tmpInput = await page.evaluateHandle( () => {
+ const input = document.createElement( 'input' );
+ input.type = 'file';
+ return input;
+ } );
+
+ const fileName = await imageBlockUtils.upload( tmpInput );
+
+ const paragraphRect = await imageBlock.boundingBox();
+ const pX = paragraphRect.x + paragraphRect.width / 2;
+ const pY = paragraphRect.y + paragraphRect.height / 3;
+
+ await imageBlock.evaluate(
+ ( element, [ input, clientX, clientY ] ) => {
+ const dataTransfer = new window.DataTransfer();
+ dataTransfer.items.add( input.files[ 0 ] );
+ const event = new window.DragEvent( 'drop', {
+ bubbles: true,
+ clientX,
+ clientY,
+ dataTransfer,
+ } );
+ element.dispatchEvent( event );
+ },
+ [ tmpInput, pX, pY ]
+ );
+
+ await expect( image ).toHaveAttribute( 'src', new RegExp( fileName ) );
+ } );
+
+ test( 'allows zooming using the crop tools', async ( {
+ page,
+ pageUtils,
+ imageBlockUtils,
+ } ) => {
+ // Insert the block, upload a file and crop.
+ await pageUtils.insertBlock( { name: 'core/image' } );
+
+ const imageBlock = page.locator(
+ 'role=document[name="Block: Image"i]'
+ );
+ const image = imageBlock.locator( 'role=img' );
+
+ const filename = await imageBlockUtils.upload(
+ imageBlock.locator( 'data-testid=form-file-upload-input' )
+ );
+
+ await expect( image ).toHaveAttribute( 'src', new RegExp( filename ) );
+
+ // Assert that the image is initially unscaled and unedited.
+ const initialImageSrc = await image.getAttribute( 'src' );
+ const initialImageDataURL = await imageBlockUtils.getDataURL( image );
+
+ // Zoom in to twice the amount using the zoom input.
+ await pageUtils.clickBlockToolbarButton( 'Crop' );
+ await pageUtils.clickBlockToolbarButton( 'Zoom' );
+ await expect(
+ page.locator( 'role=slider[name="Zoom"i]' )
+ ).toBeFocused();
+
+ await page.keyboard.press( 'Tab' );
+ await expect(
+ page.locator( 'role=spinbutton[name="Zoom"i]' )
+ ).toBeFocused();
+
+ await pageUtils.pressKeyWithModifier( 'primary', 'a' );
+ await page.keyboard.type( '200' );
+ await page.keyboard.press( 'Escape' );
+ await pageUtils.clickBlockToolbarButton( 'Apply' );
+
+ // Wait for the cropping tools to disappear.
+ await expect(
+ page.locator( 'role=button[name="Apply"i]' )
+ ).toBeHidden();
+
+ // Assert that the image is edited.
+ const updatedImageSrc = await image.getAttribute( 'src' );
+ expect( initialImageSrc ).not.toEqual( updatedImageSrc );
+
+ const updatedImageDataURL = await imageBlockUtils.getDataURL( image );
+ expect( initialImageDataURL ).not.toEqual( updatedImageDataURL );
+
+ expect(
+ snapshotDiff( initialImageDataURL, updatedImageDataURL )
+ ).toMatchSnapshot();
+ } );
+
+ test( 'allows changing aspect ratio using the crop tools', async ( {
+ page,
+ pageUtils,
+ imageBlockUtils,
+ } ) => {
+ // Insert the block, upload a file and crop.
+ await pageUtils.insertBlock( { name: 'core/image' } );
+
+ const imageBlock = page.locator(
+ 'role=document[name="Block: Image"i]'
+ );
+ const image = imageBlock.locator( 'role=img' );
+
+ const filename = await imageBlockUtils.upload(
+ imageBlock.locator( 'data-testid=form-file-upload-input' )
+ );
+
+ await expect( image ).toHaveAttribute( 'src', new RegExp( filename ) );
+
+ // Assert that the image is initially unscaled and unedited.
+ const initialImageSrc = await image.getAttribute( 'src' );
+ const initialImageDataURL = await imageBlockUtils.getDataURL( image );
+
+ // Zoom in to twice the amount using the zoom input.
+ await pageUtils.clickBlockToolbarButton( 'Crop' );
+ await pageUtils.clickBlockToolbarButton( 'Aspect Ratio' );
+ await page.click(
+ 'role=menu[name="Aspect Ratio"i] >> role=menuitemradio[name="16:10"i]'
+ );
+ await pageUtils.clickBlockToolbarButton( 'Apply' );
+
+ // Wait for the cropping tools to disappear.
+ await expect(
+ page.locator( 'role=button[name="Apply"i]' )
+ ).toBeHidden();
+
+ // Assert that the image is edited.
+ const updatedImageSrc = await image.getAttribute( 'src' );
+ const updatedImageDataURL = await imageBlockUtils.getDataURL( image );
+
+ expect( initialImageSrc ).not.toEqual( updatedImageSrc );
+ expect( initialImageDataURL ).not.toEqual( updatedImageDataURL );
+
+ expect(
+ snapshotDiff( initialImageDataURL, updatedImageDataURL )
+ ).toMatchSnapshot();
+ } );
+
+ test( 'allows rotating using the crop tools', async ( {
+ page,
+ pageUtils,
+ imageBlockUtils,
+ } ) => {
+ // Insert the block, upload a file and crop.
+ await pageUtils.insertBlock( { name: 'core/image' } );
+
+ const imageBlock = page.locator(
+ 'role=document[name="Block: Image"i]'
+ );
+ const image = imageBlock.locator( 'role=img' );
+
+ const filename = await imageBlockUtils.upload(
+ imageBlock.locator( 'data-testid=form-file-upload-input' )
+ );
+
+ await expect( image ).toHaveAttribute( 'src', new RegExp( filename ) );
+
+ // Assert that the image is initially unscaled and unedited.
+ const initialImageDataURL = await imageBlockUtils.getDataURL( image );
+
+ // Rotate the image.
+ await pageUtils.clickBlockToolbarButton( 'Crop' );
+ await pageUtils.clickBlockToolbarButton( 'Rotate' );
+ await pageUtils.clickBlockToolbarButton( 'Apply' );
+
+ // Wait for the cropping tools to disappear.
+ await expect(
+ page.locator( 'role=button[name="Apply"i]' )
+ ).toBeHidden();
+
+ // Assert that the image is edited.
+ const updatedImageDataURL = await imageBlockUtils.getDataURL( image );
+ expect( initialImageDataURL ).not.toEqual( updatedImageDataURL );
+
+ expect(
+ snapshotDiff( initialImageDataURL, updatedImageDataURL )
+ ).toMatchSnapshot();
+ } );
+
+ test( 'Should reset dimensions on change URL', async ( {
+ page,
+ pageUtils,
+ imageBlockUtils,
+ } ) => {
+ await pageUtils.insertBlock( { name: 'core/image' } );
+
+ const imageBlock = page.locator(
+ 'role=document[name="Block: Image"i]'
+ );
+ const image = imageBlock.locator( 'role=img' );
+
+ {
+ // Upload an initial image.
+ const filename = await imageBlockUtils.upload(
+ imageBlock.locator( 'data-testid=form-file-upload-input' )
+ );
+ await expect( image ).toHaveAttribute(
+ 'src',
+ new RegExp( filename )
+ );
+
+ // Resize the Uploaded Image.
+ await pageUtils.openDocumentSettingsSidebar();
+ await page.click(
+ 'role=group[name="Image size presets"i] >> role=button[name="25%"i]'
+ );
+
+ const regex = new RegExp(
+ `
+
+`
+ );
+
+ // Check if dimensions are changed.
+ expect( await pageUtils.getEditedPostContent() ).toMatch( regex );
+ }
+
+ {
+ const imageUrl = '/wp-includes/images/w-logo-blue.png';
+
+ // Replace uploaded image with an URL.
+ await pageUtils.clickBlockToolbarButton( 'Replace' );
+ await page.click( 'role=button[name="Edit"i]' );
+ // Replace the url.
+ await page.fill( 'role=combobox[name="URL"i]', imageUrl );
+ await page.click( 'role=button[name="Submit"i]' );
+
+ const regex = new RegExp(
+ `
+
+`
+ );
+
+ // Check if dimensions are reset.
+ expect( await pageUtils.getEditedPostContent() ).toMatch( regex );
+ }
+ } );
+
+ test( 'should undo without broken temporary state', async ( {
+ page,
+ pageUtils,
+ imageBlockUtils,
+ } ) => {
+ await pageUtils.insertBlock( { name: 'core/image' } );
+
+ const imageBlock = page.locator(
+ 'role=document[name="Block: Image"i]'
+ );
+ const image = imageBlock.locator( 'role=img' );
+
+ const filename = await imageBlockUtils.upload(
+ imageBlock.locator( 'data-testid=form-file-upload-input' )
+ );
+
+ await expect( image ).toHaveAttribute( 'src', new RegExp( filename ) );
+
+ await pageUtils.pressKeyWithModifier( 'primary', 'z' );
+
+ // Expect an empty image block (placeholder) rather than one with a
+ // broken temporary URL.
+ expect( await pageUtils.getEditedPostContent() )
+ .toBe( `
+
+` );
+ } );
+} );
+
+class ImageBlockUtils {
+ constructor( { page } ) {
+ this.page = page;
+
+ this.TEST_IMAGE_FILE_PATH = path.join(
+ __dirname,
+ '..',
+ '..',
+ '..',
+ 'assets',
+ '10x10_e2e_test_image_z9T8jK.png'
+ );
+ }
+
+ async upload( inputElement ) {
+ const tmpDirectory = await fs.mkdtemp(
+ path.join( os.tmpdir(), 'gutenberg-test-image-' )
+ );
+ const filename = uuid();
+ const tmpFileName = path.join( tmpDirectory, filename + '.png' );
+ await fs.copyFile( this.TEST_IMAGE_FILE_PATH, tmpFileName );
+
+ await inputElement.setInputFiles( tmpFileName );
+
+ return filename;
+ }
+
+ async getDataURL( element ) {
+ return element.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' );
+ } );
+ }
+}