diff --git a/.eslintrc.js b/.eslintrc.js index 44022b3b44bb3..22d522b723b64 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -249,12 +249,12 @@ module.exports = { 'no-restricted-syntax': [ 'error', { - selector: 'CallExpression[callee.name="$"]', + selector: 'CallExpression[callee.property.name="$"]', message: '`$` is discouraged, please use `locator` instead', }, { - selector: 'CallExpression[callee.name="$$"]', + selector: 'CallExpression[callee.property.name="$$"]', message: '`$$` is discouraged, please use `locator` instead', }, diff --git a/packages/e2e-test-utils-playwright/src/request/index.ts b/packages/e2e-test-utils-playwright/src/request/index.ts index 31a2df63448bd..8f35d0be38de6 100644 --- a/packages/e2e-test-utils-playwright/src/request/index.ts +++ b/packages/e2e-test-utils-playwright/src/request/index.ts @@ -12,6 +12,7 @@ import type { APIRequestContext, Cookie } from '@playwright/test'; import { WP_ADMIN_USER, WP_BASE_URL } from '../config'; import type { User } from './login'; import { login } from './login'; +import { listMedia, uploadMedia, deleteMedia, deleteAllMedia } from './media'; import { setupRest, rest, getMaxBatchSize, batchRest } from './rest'; import { getPluginsMap, activatePlugin, deactivatePlugin } from './plugins'; import { deleteAllTemplates } from './templates'; @@ -122,6 +123,10 @@ class RequestUtils { addWidgetBlock = addWidgetBlock; deleteAllTemplates = deleteAllTemplates; resetPreferences = resetPreferences; + listMedia = listMedia; + uploadMedia = uploadMedia; + deleteMedia = deleteMedia; + deleteAllMedia = deleteAllMedia; } export type { StorageState }; diff --git a/packages/e2e-test-utils-playwright/src/request/media.ts b/packages/e2e-test-utils-playwright/src/request/media.ts new file mode 100644 index 0000000000000..a93f4afd09503 --- /dev/null +++ b/packages/e2e-test-utils-playwright/src/request/media.ts @@ -0,0 +1,102 @@ +/** + * External dependencies + */ +import * as fs from 'fs'; + +/** + * Internal dependencies + */ +import type { RequestUtils } from './index'; + +interface Media { + id: number; + title: { + raw: string; + rendered: string; + }; + source_url: string; + slug: string; + alt_text: string; + caption: { rendered: string }; + link: string; +} + +/** + * List all media files. + * + * @see https://developer.wordpress.org/rest-api/reference/media/#list-media + * @param this + */ +async function listMedia( this: RequestUtils ) { + const response = await this.rest< Media[] >( { + method: 'GET', + path: '/wp/v2/media', + params: { + per_page: 100, + }, + } ); + + return response; +} + +/** + * Upload a media file. + * + * @see https://developer.wordpress.org/rest-api/reference/media/#create-a-media-item + * @param this + * @param filePathOrData The path or data of the file being uploaded. + */ +async function uploadMedia( + this: RequestUtils, + filePathOrData: string | fs.ReadStream +) { + const file = + typeof filePathOrData === 'string' + ? fs.createReadStream( filePathOrData ) + : filePathOrData; + + const response = await this.rest< Media >( { + method: 'POST', + path: '/wp/v2/media', + multipart: { + file, + }, + } ); + + return response; +} + +/** + * delete a media file. + * + * @see https://developer.wordpress.org/rest-api/reference/media/#delete-a-media-item + * @param this + * @param mediaId The ID of the media file. + */ +async function deleteMedia( this: RequestUtils, mediaId: number ) { + const response = await this.rest( { + method: 'DELETE', + path: `/wp/v2/media/${ mediaId }`, + params: { force: true }, + } ); + + return response; +} + +/** + * delete all media files. + * + * @param this + */ +async function deleteAllMedia( this: RequestUtils ) { + const files = await this.listMedia(); + + // The media endpoint doesn't support batch request yet. + const responses = await Promise.all( + files.map( ( media ) => this.deleteMedia( media.id ) ) + ); + + return responses; +} + +export { listMedia, uploadMedia, deleteMedia, deleteAllMedia }; diff --git a/test/e2e/specs/editor/plugins/image-size.spec.js b/test/e2e/specs/editor/plugins/image-size.spec.js index 55f462f640334..0cce224bdaab6 100644 --- a/test/e2e/specs/editor/plugins/image-size.spec.js +++ b/test/e2e/specs/editor/plugins/image-size.spec.js @@ -1,52 +1,60 @@ +/** + * External dependencies + */ +const path = require( 'path' ); + /** * WordPress dependencies */ const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' ); test.describe( 'changing image size', () => { - test.beforeEach( async ( { requestUtils, pageUtils } ) => { + test.beforeAll( async ( { requestUtils } ) => { await requestUtils.activatePlugin( 'gutenberg-test-image-size' ); - await pageUtils.createNewPost(); + await requestUtils.deleteAllMedia(); } ); test.afterEach( async ( { requestUtils } ) => { + await requestUtils.deleteAllMedia(); + } ); + + test.afterAll( async ( { requestUtils } ) => { await requestUtils.deactivatePlugin( 'gutenberg-test-image-size' ); } ); test( 'should insert and change my image size', async ( { page, pageUtils, + requestUtils, } ) => { - await pageUtils.insertBlock( { name: 'core/image' } ); - const inputElement = await page.$( - 'figure[aria-label="Block: Image"] input[type=file]' - ); - const filename = '1024x768_e2e_test_image_size.jpeg'; - const filepath = './test/e2e/assets/' + filename; - - await inputElement.setInputFiles( filepath ); + const filepath = path.join( './test/e2e/assets', filename ); - // // Wait for upload to finish. - const img = page.locator( `//img[contains(@src, "${ filename }")]` ); - await img.waitFor(); - - await expect( img ).toBeVisible(); + await pageUtils.createNewPost(); + const media = await requestUtils.uploadMedia( filepath ); + + await pageUtils.insertBlock( { + name: 'core/image', + attributes: { + // Specify alt text so that it can be queried by role selectors. + alt: filename, + id: media.id, + url: media.source_url, + }, + } ); // Select the new size updated with the plugin. await pageUtils.openDocumentSettingsSidebar(); - await page.selectOption( - '.components-select-control__input', - 'custom-size-one' - ); + await page.selectOption( 'role=combobox[name="Image size"i]', { + label: 'Custom Size One', + } ); // Verify that the custom size was applied to the image. - await page.waitForSelector( '.wp-block-image.size-custom-size-one' ); - await page.waitForFunction( - () => - document.querySelector( - '.block-editor-image-size-control__width input' - ).value === '499' - ); + await expect( + page.locator( `role=img[name="${ filename }"]` ) + ).toHaveCSS( 'width', '499px' ); + await expect( + page.locator( 'role=spinbutton[name="Width"i]' ) + ).toHaveValue( '499' ); } ); } );