[e2e tests] Add tests for product images (#43775)
* Import media on environment setup * Add product-images.spec with one complete test and all other skeleton tests * Add changelog * Implement can update the product image * Implement can delete the product image * Implement can delete the product image * Skip not implemented test * Merge fixtures * Add productWithImage fixture * Remove unused variable `api` * Partial implementation of can create a product gallery * Check the image gallery in store frontend * Added `can update a product gallery` test * Run all tests * Search for image in media library * Check that the remove gallery image is not displayed * Add repeatEach configuration * eslint formatting * Extract some repeating steps into a function * Update check for thumbnail * Fix test image name
This commit is contained in:
parent
c7d4c88270
commit
d66a48e8e5
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"phpVersion": "7.4",
|
||||
"plugins": [ "." ],
|
||||
"plugins": [
|
||||
"."
|
||||
],
|
||||
"config": {
|
||||
"JETPACK_AUTOLOAD_DEV": true,
|
||||
"WP_DEBUG_LOG": true,
|
||||
|
@ -11,7 +13,8 @@
|
|||
"wp-cli.yml": "./tests/wp-cli.yml",
|
||||
"wp-content/plugins/filter-setter.php": "./tests/e2e-pw/bin/filter-setter.php",
|
||||
"wp-content/plugins/process-waiting-actions.php": "./tests/e2e-pw/bin/process-waiting-actions.php",
|
||||
"wp-content/plugins/test-helper-apis.php": "./tests/e2e-pw/bin/test-helper-apis.php"
|
||||
"wp-content/plugins/test-helper-apis.php": "./tests/e2e-pw/bin/test-helper-apis.php",
|
||||
"test-data/images/": "./tests/e2e-pw/test-data/images/"
|
||||
},
|
||||
"lifecycleScripts": {
|
||||
"afterStart": "./tests/e2e-pw/bin/test-env-setup.sh",
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: dev
|
||||
|
||||
E2E tests: Add checks for product images
|
|
@ -37,3 +37,7 @@ if [ $ENABLE_TRACKING == 1 ]; then
|
|||
echo -e 'Enable tracking\n'
|
||||
wp-env run tests-cli wp option update woocommerce_allow_tracking 'yes'
|
||||
fi
|
||||
|
||||
echo -e 'Upload test images \n'
|
||||
wp-env run tests-cli wp media import './test-data/images/image-01.png' './test-data/images/image-02.png' './test-data/images/image-03.png'
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ const {
|
|||
DEFAULT_TIMEOUT_OVERRIDE,
|
||||
E2E_MAX_FAILURES,
|
||||
PLAYWRIGHT_HTML_REPORT,
|
||||
REPEAT_EACH,
|
||||
} = process.env;
|
||||
|
||||
const config = {
|
||||
|
@ -20,6 +21,7 @@ const config = {
|
|||
globalTeardown: require.resolve( './global-teardown' ),
|
||||
testDir: 'tests',
|
||||
retries: 2,
|
||||
repeatEach: REPEAT_EACH ? Number( REPEAT_EACH ) : 1,
|
||||
workers: CI ? 1 : 4,
|
||||
reporter: [
|
||||
[ 'list' ],
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 8.8 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
|
@ -4,7 +4,7 @@ const wcApi = require('@woocommerce/woocommerce-rest-api').default;
|
|||
baseTest.describe('Products > Delete Product', () => {
|
||||
baseTest.use({storageState: process.env.ADMINSTATE});
|
||||
|
||||
const apiFixture = baseTest.extend({
|
||||
const test = baseTest.extend({
|
||||
api: async ({baseURL}, use) => {
|
||||
const api = new wcApi({
|
||||
url: baseURL,
|
||||
|
@ -21,9 +21,7 @@ baseTest.describe('Products > Delete Product', () => {
|
|||
|
||||
await use(api);
|
||||
},
|
||||
});
|
||||
|
||||
const test = apiFixture.extend({
|
||||
product: async ({api}, use) => {
|
||||
const product = {
|
||||
id: 0,
|
||||
|
|
|
@ -0,0 +1,285 @@
|
|||
const { test: baseTest, expect } = require( '@playwright/test' );
|
||||
const wcApi = require( '@woocommerce/woocommerce-rest-api' ).default;
|
||||
|
||||
async function addImageFromLibrary( page, imageName, actionButtonName ) {
|
||||
await page.getByRole( 'tab', { name: 'Media Library' } ).click();
|
||||
await page.getByRole( 'searchbox', { name: 'Search' } ).fill( imageName );
|
||||
const imageLocator = page.getByLabel( imageName ).nth( 0 );
|
||||
await imageLocator.click();
|
||||
const dataId = await imageLocator.getAttribute( 'data-id' );
|
||||
await expect( imageLocator ).toBeChecked();
|
||||
await page.getByRole( 'button', { name: actionButtonName } ).click();
|
||||
return dataId;
|
||||
}
|
||||
|
||||
baseTest.describe( 'Products > Product Images', () => {
|
||||
baseTest.use( { storageState: process.env.ADMINSTATE } );
|
||||
|
||||
const test = baseTest.extend( {
|
||||
api: async ( { baseURL }, use ) => {
|
||||
const api = new wcApi( {
|
||||
url: baseURL,
|
||||
consumerKey: process.env.CONSUMER_KEY,
|
||||
consumerSecret: process.env.CONSUMER_SECRET,
|
||||
version: 'wc/v3',
|
||||
} );
|
||||
|
||||
await use( api );
|
||||
},
|
||||
product: async ( { api }, use ) => {
|
||||
let product = {
|
||||
id: 0,
|
||||
name: `Product ${ Date.now() }`,
|
||||
type: 'simple',
|
||||
regular_price: '12.99',
|
||||
sale_price: '11.59',
|
||||
};
|
||||
|
||||
await api.post( 'products', product ).then( ( response ) => {
|
||||
product = response.data;
|
||||
} );
|
||||
|
||||
await use( product );
|
||||
|
||||
// Cleanup
|
||||
await api.delete( `products/${ product.id }`, { force: true } );
|
||||
},
|
||||
productWithImage: async ( { api, product }, use ) => {
|
||||
let productWithImage;
|
||||
await api
|
||||
.put( `products/${ product.id }`, {
|
||||
images: [
|
||||
{
|
||||
src: 'http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/T_2_front.jpg',
|
||||
},
|
||||
],
|
||||
} )
|
||||
.then( ( response ) => {
|
||||
productWithImage = response.data;
|
||||
} );
|
||||
|
||||
await use( productWithImage );
|
||||
},
|
||||
productWithGallery: async ( { api, product }, use ) => {
|
||||
let productWithGallery;
|
||||
await api
|
||||
.put( `products/${ product.id }`, {
|
||||
images: [
|
||||
{
|
||||
src: 'http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/T_2_front.jpg',
|
||||
},
|
||||
{
|
||||
src: 'http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/T_2_back.jpg',
|
||||
},
|
||||
{
|
||||
src: 'http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/T_3_front.jpg',
|
||||
},
|
||||
],
|
||||
} )
|
||||
.then( ( response ) => {
|
||||
productWithGallery = response.data;
|
||||
} );
|
||||
|
||||
await use( productWithGallery );
|
||||
},
|
||||
} );
|
||||
|
||||
test( 'can set product image', async ( { page, product } ) => {
|
||||
await test.step( 'Navigate to product edit page', async () => {
|
||||
await page.goto(
|
||||
`wp-admin/post.php?post=${ product.id }&action=edit`
|
||||
);
|
||||
} );
|
||||
|
||||
await test.step( 'Set product image', async () => {
|
||||
await page
|
||||
.getByRole( 'link', { name: 'Set product image' } )
|
||||
.click();
|
||||
await addImageFromLibrary( page, 'image-01', 'Set product image' );
|
||||
|
||||
// Wait for the product image thumbnail to be updated.
|
||||
// Clicking the "Update" button before this happens will not update the image.
|
||||
// Use src* (contains) instead of src$ (ends with) to match duplicated images, like image-01-1.png
|
||||
await expect(
|
||||
page.locator( '#set-post-thumbnail img[src*="image-01"]' )
|
||||
).toBeVisible();
|
||||
|
||||
await page.getByRole( 'button', { name: 'Update' } ).click();
|
||||
} );
|
||||
|
||||
await test.step( 'Verify product image was set', async () => {
|
||||
// Verify product was updated
|
||||
await expect( page.getByText( 'Product updated.' ) ).toBeVisible();
|
||||
|
||||
// Verify image in store frontend
|
||||
await page.goto( product.permalink );
|
||||
await expect( page.getByTitle( `image-01` ) ).toBeVisible();
|
||||
} );
|
||||
} );
|
||||
|
||||
test( 'can update the product image', async ( {
|
||||
page,
|
||||
productWithImage,
|
||||
} ) => {
|
||||
await test.step( 'Navigate to product edit page', async () => {
|
||||
await page.goto(
|
||||
`wp-admin/post.php?post=${ productWithImage.id }&action=edit`
|
||||
);
|
||||
} );
|
||||
|
||||
await test.step( 'Update product image', async () => {
|
||||
await page.locator( '#set-post-thumbnail' ).click();
|
||||
await addImageFromLibrary( page, 'image-02', 'Set product image' );
|
||||
|
||||
// Wait for the product image thumbnail to be updated.
|
||||
// Clicking the "Update" button before this happens will not update the image.
|
||||
// Use src* (contains) instead of src$ (ends with) to match duplicated images, like image-01-1.png
|
||||
await expect(
|
||||
page.locator( '#set-post-thumbnail img[src*="image-02"]' )
|
||||
).toBeVisible();
|
||||
|
||||
await page.getByRole( 'button', { name: 'Update' } ).click();
|
||||
} );
|
||||
|
||||
await test.step( 'Verify product image was set', async () => {
|
||||
// Verify product was updated
|
||||
await expect( page.getByText( 'Product updated.' ) ).toBeVisible();
|
||||
|
||||
// Verify image in store frontend
|
||||
await page.goto( productWithImage.permalink );
|
||||
await expect( page.getByTitle( `image-02` ) ).toBeVisible();
|
||||
} );
|
||||
} );
|
||||
|
||||
test( 'can delete the product image', async ( {
|
||||
page,
|
||||
productWithImage,
|
||||
} ) => {
|
||||
await test.step( 'Navigate to product edit page', async () => {
|
||||
await page.goto(
|
||||
`wp-admin/post.php?post=${ productWithImage.id }&action=edit`
|
||||
);
|
||||
} );
|
||||
|
||||
await test.step( 'Remove product image', async () => {
|
||||
await page
|
||||
.getByRole( 'link', { name: 'Remove product image' } )
|
||||
.click();
|
||||
await expect(
|
||||
page.getByRole( 'link', { name: 'Set product image' } )
|
||||
).toBeVisible();
|
||||
|
||||
await page.getByRole( 'button', { name: 'Update' } ).click();
|
||||
} );
|
||||
|
||||
await test.step( 'Verify product image was removed', async () => {
|
||||
// Verify product was updated
|
||||
await expect( page.getByText( 'Product updated.' ) ).toBeVisible();
|
||||
|
||||
// Verify image in store frontend
|
||||
await page.goto( productWithImage.permalink );
|
||||
await expect(
|
||||
page.getByAltText( 'Awaiting product image' )
|
||||
).toBeVisible();
|
||||
} );
|
||||
} );
|
||||
|
||||
test( 'can create a product gallery', async ( {
|
||||
page,
|
||||
productWithImage,
|
||||
} ) => {
|
||||
const images = [ 'image-02', 'image-03' ];
|
||||
|
||||
await test.step( 'Navigate to product edit page', async () => {
|
||||
await page.goto(
|
||||
`wp-admin/post.php?post=${ productWithImage.id }&action=edit`
|
||||
);
|
||||
} );
|
||||
|
||||
await test.step( 'Add product gallery images', async () => {
|
||||
const imageSelector = '#product_images_container img';
|
||||
let initialImagesCount = await page
|
||||
.locator( imageSelector )
|
||||
.count();
|
||||
|
||||
for ( const image of images ) {
|
||||
await page
|
||||
.getByRole( 'link', { name: 'Add product gallery images' } )
|
||||
.click();
|
||||
const dataId = await addImageFromLibrary(
|
||||
page,
|
||||
image,
|
||||
'Add to gallery'
|
||||
);
|
||||
|
||||
await expect(
|
||||
page.locator( `li[data-attachment_id="${ dataId }"]` ),
|
||||
'thumbnail should be visible'
|
||||
).toBeVisible();
|
||||
const currentImagesCount = await page
|
||||
.locator( imageSelector )
|
||||
.count();
|
||||
await expect(
|
||||
currentImagesCount,
|
||||
'number of images should increase'
|
||||
).toEqual( initialImagesCount + 1 );
|
||||
initialImagesCount = currentImagesCount;
|
||||
}
|
||||
|
||||
await page.getByRole( 'button', { name: 'Update' } ).click();
|
||||
} );
|
||||
|
||||
await test.step( 'Verify product gallery', async () => {
|
||||
// Verify gallery in store frontend
|
||||
await page.goto( productWithImage.permalink );
|
||||
await expect(
|
||||
page
|
||||
.locator( `#product-${ productWithImage.id } ol img` )
|
||||
.nth( images.length ),
|
||||
'all gallery images should be visible'
|
||||
).toBeVisible(); // +1 for the featured image
|
||||
} );
|
||||
} );
|
||||
|
||||
test( 'can update a product gallery', async ( {
|
||||
page,
|
||||
productWithGallery,
|
||||
} ) => {
|
||||
let imagesCount;
|
||||
|
||||
await test.step( 'Navigate to product edit page', async () => {
|
||||
await page.goto(
|
||||
`wp-admin/post.php?post=${ productWithGallery.id }&action=edit`
|
||||
);
|
||||
} );
|
||||
|
||||
await test.step( 'Remove images from product gallery', async () => {
|
||||
const imageSelector = '#product_images_container img';
|
||||
imagesCount = await page.locator( imageSelector ).count();
|
||||
|
||||
await page.locator( imageSelector ).first().hover();
|
||||
await page.getByRole( 'link', { name: ' Delete' } ).click();
|
||||
|
||||
await expect(
|
||||
await page.locator( imageSelector ).count(),
|
||||
'number of images should decrease'
|
||||
).toEqual( imagesCount - 1 );
|
||||
|
||||
await page.getByRole( 'button', { name: 'Update' } ).click();
|
||||
} );
|
||||
|
||||
await test.step( 'Verify product gallery', async () => {
|
||||
// Verify gallery in store frontend
|
||||
await page.goto( productWithGallery.permalink );
|
||||
const selector = `#product-${ productWithGallery.id } ol img`;
|
||||
await expect(
|
||||
page.locator( selector ).nth( imagesCount - 1 ),
|
||||
'gallery images should be visible'
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.locator( selector ).nth( imagesCount ),
|
||||
'one gallery image should not be visible'
|
||||
).toBeHidden();
|
||||
} );
|
||||
} );
|
||||
} );
|
Loading…
Reference in New Issue