[e2e tests] Add tests for product inventory in product block editor (#44699)

* Remove describe blocks and duplicated page fixture

* Add test `can update sku`

* Add changelog

* Finish test 'can update sku'

* Add test 'can update stock status'

* Add test 'can track stock quantity'

* Add test 'can limit purchases'

* Remove extra whitespace

* Disable product editor tour

* Revert timeout update
This commit is contained in:
Adrian Moldovan 2024-02-21 00:25:16 +02:00 committed by GitHub
parent 487f230f0a
commit f4f4d798fe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 516 additions and 310 deletions

View File

@ -0,0 +1,4 @@
Significance: patch
Type: dev
E2E tests: add tests for product inventory in product block editor

View File

@ -18,5 +18,15 @@ exports.test = base.test.extend( {
await use( api ); await use( api );
}, },
wcAdminApi: async ( { baseURL }, use ) => {
const wcAdminApi = new wcApi( {
url: baseURL,
consumerKey: process.env.CONSUMER_KEY,
consumerSecret: process.env.CONSUMER_SECRET,
version: 'wc-admin', // Use wc-admin namespace
} );
await use( wcAdminApi );
},
} ); } );
exports.expect = base.expect; exports.expect = base.expect;

View File

@ -1,7 +1,8 @@
const { test } = require( '../../../../fixtures' ); const { test } = require( '../../../../fixtures' );
exports.test = test.extend( { exports.test = test.extend( {
page: async ( { page, api }, use ) => { page: async ( { page, api, wcAdminApi }, use ) => {
// Enable product block editor
await api.put( await api.put(
'settings/advanced/woocommerce_feature_product_block_editor_enabled', 'settings/advanced/woocommerce_feature_product_block_editor_enabled',
{ {
@ -9,8 +10,14 @@ exports.test = test.extend( {
} }
); );
// Disable the product editor tour
await wcAdminApi.post( 'options', {
woocommerce_block_product_tour_shown: 'yes',
} );
await use( page ); await use( page );
// Disable product block editor
await api.put( await api.put(
'settings/advanced/woocommerce_feature_product_block_editor_enabled', 'settings/advanced/woocommerce_feature_product_block_editor_enabled',
{ {

View File

@ -1,118 +1,100 @@
const { test: baseTest } = require( './block-editor-fixtures' ); const { test: baseTest } = require( './block-editor-fixtures' );
const { expect } = require( '../../../../fixtures' ); const { expect } = require( '../../../../fixtures' );
baseTest.describe( 'Products > Edit Product', () => {
const test = baseTest.extend( {
product: async ( { api }, use ) => {
let product;
await api const test = baseTest.extend( {
.post( 'products', { product: async ( { api }, use ) => {
id: 0, let product;
name: `Product ${ Date.now() }`,
type: 'simple',
description: `This product is a longer description of the awesome product ${ Date.now() }`,
short_description: `This product is pretty awesome ${ Date.now() }`,
regular_price: '12.99',
} )
.then( ( response ) => {
product = response.data;
} );
await use( product ); await api
.post( 'products', {
id: 0,
name: `Product ${ Date.now() }`,
type: 'simple',
description: `This product is a longer description of the awesome product ${ Date.now() }`,
short_description: `This product is pretty awesome ${ Date.now() }`,
regular_price: '12.99',
} )
.then( ( response ) => {
product = response.data;
} );
// Cleanup await use( product );
await api.delete( `products/${ product.id }`, { force: true } );
},
page: async ( { page, api }, use ) => {
await api.put(
'settings/advanced/woocommerce_feature_product_block_editor_enabled',
{
value: 'yes',
}
);
await use( page ); // Cleanup
await api.delete( `products/${ product.id }`, { force: true } );
},
} );
await api.put( test( 'can update the general information of a product', async ( {
'settings/advanced/woocommerce_feature_product_block_editor_enabled', page,
{ product,
value: 'no', } ) => {
} await page.goto( `wp-admin/post.php?post=${ product.id }&action=edit` );
);
}, const updatedProduct = {
name: `Product ${ Date.now() }`,
description: `Updated description for the awesome product ${ Date.now() }`,
short_description: `Updated summary for the awesome product ${ Date.now() }`,
regularPrice: '100.05',
salePrice: '99.05',
};
const nameTextbox = page.getByLabel( 'Name' ).getByRole( 'textbox' );
const summaryTextbox = page
.getByLabel( 'Block: Product textarea block' )
.getByRole( 'textbox' );
const descriptionTextbox = page
.getByLabel( 'Block: Product description' )
.getByRole( 'textbox' );
const listPriceTextbox = page.getByRole( 'textbox', {
name: 'List price',
} );
const salePriceTextbox = page.getByRole( 'textbox', {
name: 'Sale price',
} ); } );
test( 'can update the general information of a product', async ( { await test.step( 'edit the product name', async () => {
page, await nameTextbox.fill( updatedProduct.name );
product, } );
} ) => {
await page.goto( `wp-admin/post.php?post=${ product.id }&action=edit` );
const updatedProduct = { await test.step( 'edit the product price', async () => {
name: `Product ${ Date.now() }`, await listPriceTextbox.fill( updatedProduct.regularPrice );
description: `Updated description for the awesome product ${ Date.now() }`, await salePriceTextbox.fill( updatedProduct.salePrice );
short_description: `Updated summary for the awesome product ${ Date.now() }`, } );
regularPrice: '100.05',
salePrice: '99.05',
};
const nameTextbox = page.getByLabel( 'Name' ).getByRole( 'textbox' ); await test.step( 'edit the product description and summary', async () => {
const summaryTextbox = page // Need to clear the textbox before filling it, otherwise the text will be appended.
.getByLabel( 'Block: Product textarea block' ) await descriptionTextbox.clear();
.getByRole( 'textbox' ); await descriptionTextbox.fill( updatedProduct.description );
const descriptionTextbox = page
.getByLabel( 'Block: Product description' )
.getByRole( 'textbox' );
const listPriceTextbox = page.getByRole( 'textbox', {
name: 'List price',
} );
const salePriceTextbox = page.getByRole( 'textbox', {
name: 'Sale price',
} );
await test.step( 'edit the product name', async () => { await summaryTextbox.clear();
await nameTextbox.fill( updatedProduct.name ); await summaryTextbox.fill( updatedProduct.short_description );
} ); } );
await test.step( 'edit the product price', async () => { await test.step( 'publish the updated product', async () => {
await listPriceTextbox.fill( updatedProduct.regularPrice ); await page.getByRole( 'button', { name: 'Update' } ).click();
await salePriceTextbox.fill( updatedProduct.salePrice );
} );
await test.step( 'edit the product description and summary', async () => { await expect( page.getByLabel( 'Dismiss this notice' ) ).toContainText(
// Need to clear the textbox before filling it, otherwise the text will be appended. 'Product updated'
await descriptionTextbox.clear(); );
await descriptionTextbox.fill( updatedProduct.description ); } );
await summaryTextbox.clear(); await test.step( 'verify the changes', async () => {
await summaryTextbox.fill( updatedProduct.short_description ); await expect.soft( nameTextbox ).toHaveValue( updatedProduct.name );
} );
await test.step( 'publish the updated product', async () => { await expect
await page.getByRole( 'button', { name: 'Update' } ).click(); .soft( summaryTextbox )
.toHaveText( updatedProduct.short_description );
await expect( await expect
page.getByLabel( 'Dismiss this notice' ) .soft( descriptionTextbox )
).toContainText( 'Product updated' ); .toHaveText( updatedProduct.description );
} );
await test.step( 'verify the changes', async () => { await expect
await expect.soft( nameTextbox ).toHaveValue( updatedProduct.name ); .soft( listPriceTextbox )
.toHaveValue( updatedProduct.regularPrice );
await expect await expect
.soft( summaryTextbox ) .soft( salePriceTextbox )
.toHaveText( updatedProduct.short_description ); .toHaveValue( updatedProduct.salePrice );
await expect
.soft( descriptionTextbox )
.toHaveText( updatedProduct.description );
await expect
.soft( listPriceTextbox )
.toHaveValue( updatedProduct.regularPrice );
await expect
.soft( salePriceTextbox )
.toHaveValue( updatedProduct.salePrice );
} );
} ); } );
} ); } );

View File

@ -23,230 +23,223 @@ async function selectImagesInLibrary( page, imagesNames ) {
return dataIds; return dataIds;
} }
baseTest.describe( 'Products > Edit Product', () => { const test = baseTest.extend( {
const test = baseTest.extend( { product: async ( { api }, use ) => {
product: async ( { api }, use ) => { let product;
let product;
await api await api
.post( 'products', { .post( 'products', {
name: `Product ${ Date.now() }`, name: `Product ${ Date.now() }`,
type: 'simple', type: 'simple',
description: `This is a description of the awesome product ${ Date.now() }`, description: `This is a description of the awesome product ${ Date.now() }`,
short_description: `This product is pretty awesome ${ Date.now() }`, short_description: `This product is pretty awesome ${ Date.now() }`,
regular_price: '12.99', regular_price: '12.99',
} ) } )
.then( ( response ) => { .then( ( response ) => {
product = response.data; product = response.data;
} ); } );
await use( product ); await use( product );
// Cleanup // Cleanup
await api.delete( `products/${ product.id }`, { force: true } ); await api.delete( `products/${ product.id }`, { force: true } );
}, },
productWithGallery: async ( { api, product }, use ) => { productWithGallery: async ( { api, product }, use ) => {
let productWithGallery; let productWithGallery;
await api await api
.put( `products/${ product.id }`, { .put( `products/${ product.id }`, {
images: [ 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_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_2_back.jpg',
}, },
{ {
src: 'http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/T_3_front.jpg', src: 'http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/T_3_front.jpg',
}, },
], ],
} ) } )
.then( ( response ) => { .then( ( response ) => {
productWithGallery = response.data; productWithGallery = response.data;
} ); } );
await use( productWithGallery ); await use( productWithGallery );
}, },
} );
test( 'can add images', async ( { page, product } ) => {
const images = [ 'image-01', 'image-02' ];
await test.step( 'navigate to product edit page', async () => {
await page.goto( `wp-admin/post.php?post=${ product.id }&action=edit` );
} ); } );
test( 'can add images', async ( { page, product } ) => { await test.step( 'add images', async () => {
const images = [ 'image-01', 'image-02' ]; await page.getByText( 'Choose an image' ).click();
const dataIds = await selectImagesInLibrary( page, images );
await test.step( 'navigate to product edit page', async () => { await expect(
await page.goto( page.getByLabel( 'Block: Product images' ).locator( 'img' )
`wp-admin/post.php?post=${ product.id }&action=edit` ).toHaveCount( images.length );
);
} );
await test.step( 'add images', async () => {
await page.getByText( 'Choose an image' ).click();
const dataIds = await selectImagesInLibrary( page, images );
for ( const dataId of dataIds ) {
await expect( await expect(
page.getByLabel( 'Block: Product images' ).locator( 'img' ) page
).toHaveCount( images.length ); .getByLabel( 'Block: Product images' )
.locator( `img[id="${ dataId }"]` )
for ( const dataId of dataIds ) { ).toBeVisible();
await expect( }
page
.getByLabel( 'Block: Product images' )
.locator( `img[id="${ dataId }"]` )
).toBeVisible();
}
} );
await test.step( 'update the product', async () => {
await page.getByRole( 'button', { name: 'Update' } ).click();
// Verify product was updated
await expect(
page.getByLabel( 'Dismiss this notice' )
).toContainText( 'Product updated' );
} );
await test.step( 'verify product image was set', async () => {
// Verify image in store frontend
await page.goto( product.permalink );
for ( const image of images ) {
await expect( page.getByTitle( image ) ).toBeVisible();
}
} );
} ); } );
test( 'can replace an image', async ( { page, productWithGallery } ) => { await test.step( 'update the product', async () => {
const initialImagesCount = productWithGallery.images.length; await page.getByRole( 'button', { name: 'Update' } ).click();
const newImageName = 'image-01'; // Verify product was updated
const replacedImgLocator = page await expect( page.getByLabel( 'Dismiss this notice' ) ).toContainText(
.getByLabel( 'Block: Product images' ) 'Product updated'
.locator( 'img' ) );
.nth( 1 );
let dataIds = [];
await test.step( 'navigate to product edit page', async () => {
await page.goto(
`wp-admin/post.php?post=${ productWithGallery.id }&action=edit`
);
} );
await test.step( 'replace an image', async () => {
await replacedImgLocator.click();
await page
.getByRole( 'toolbar', { name: 'Options' } )
.getByLabel( 'Options' )
.click();
await page.getByRole( 'menuitem', { name: 'Replace' } ).click();
dataIds = await selectImagesInLibrary( page, [ newImageName ] );
expect( await replacedImgLocator.getAttribute( 'src' ) ).toContain(
newImageName
);
} );
await test.step( 'update the product', async () => {
await page.getByRole( 'button', { name: 'Update' } ).click();
// Verify product was updated
await expect(
page.getByLabel( 'Dismiss this notice' )
).toContainText( 'Product updated' );
} );
await test.step( 'verify product image was set', async () => {
await expect( replacedImgLocator ).toHaveId( dataIds[ 0 ] );
await expect(
page.getByLabel( 'Block: Product images' ).locator( 'img' )
).toHaveCount( initialImagesCount );
// Verify image in store frontend
await page.goto( productWithGallery.permalink );
await expect( page.getByTitle( newImageName ) ).toBeVisible();
} );
} ); } );
test( 'can remove an image', async ( { page, productWithGallery } ) => { await test.step( 'verify product image was set', async () => {
const initialImagesCount = productWithGallery.images.length; // Verify image in store frontend
const removedImgLocator = page await page.goto( product.permalink );
.getByLabel( 'Block: Product images' )
.locator( 'img' )
.nth( 1 );
await test.step( 'navigate to product edit page', async () => { for ( const image of images ) {
await page.goto( await expect( page.getByTitle( image ) ).toBeVisible();
`wp-admin/post.php?post=${ productWithGallery.id }&action=edit` }
); } );
} ); } );
await test.step( 'remove an image', async () => { test( 'can replace an image', async ( { page, productWithGallery } ) => {
await removedImgLocator.click(); const initialImagesCount = productWithGallery.images.length;
await page const newImageName = 'image-01';
.getByRole( 'toolbar', { name: 'Options' } ) const replacedImgLocator = page
.getByLabel( 'Options' ) .getByLabel( 'Block: Product images' )
.click(); .locator( 'img' )
await page.getByRole( 'menuitem', { name: 'Remove' } ).click(); .nth( 1 );
let dataIds = [];
await expect(
page.getByLabel( 'Block: Product images' ).locator( 'img' ) await test.step( 'navigate to product edit page', async () => {
).toHaveCount( initialImagesCount - 1 ); await page.goto(
} ); `wp-admin/post.php?post=${ productWithGallery.id }&action=edit`
);
await test.step( 'update the product', async () => { } );
await page.getByRole( 'button', { name: 'Update' } ).click();
// Verify product was updated await test.step( 'replace an image', async () => {
await expect( await replacedImgLocator.click();
page.getByLabel( 'Dismiss this notice' ) await page
).toContainText( 'Product updated' ); .getByRole( 'toolbar', { name: 'Options' } )
} ); .getByLabel( 'Options' )
.click();
await test.step( 'verify product image was set', async () => { await page.getByRole( 'menuitem', { name: 'Replace' } ).click();
await expect( dataIds = await selectImagesInLibrary( page, [ newImageName ] );
page.getByLabel( 'Block: Product images' ).locator( 'img' )
).toHaveCount( initialImagesCount - 1 ); expect( await replacedImgLocator.getAttribute( 'src' ) ).toContain(
newImageName
// Verify image in store frontend );
await page.goto( productWithGallery.permalink ); } );
await expect(
page.locator( `#product-${ productWithGallery.id } ol img` ) await test.step( 'update the product', async () => {
).toHaveCount( initialImagesCount - 1 ); await page.getByRole( 'button', { name: 'Update' } ).click();
} ); // Verify product was updated
} ); await expect( page.getByLabel( 'Dismiss this notice' ) ).toContainText(
'Product updated'
test( 'can set an image as cover', async ( { );
page, } );
productWithGallery,
} ) => { await test.step( 'verify product image was set', async () => {
const newCoverImgLocator = page await expect( replacedImgLocator ).toHaveId( dataIds[ 0 ] );
.getByLabel( 'Block: Product images' ) await expect(
.locator( 'img' ) page.getByLabel( 'Block: Product images' ).locator( 'img' )
.nth( 1 ); ).toHaveCount( initialImagesCount );
await test.step( 'navigate to product edit page', async () => { // Verify image in store frontend
await page.goto( await page.goto( productWithGallery.permalink );
`wp-admin/post.php?post=${ productWithGallery.id }&action=edit` await expect( page.getByTitle( newImageName ) ).toBeVisible();
); } );
} ); } );
const newCoverImgId = await newCoverImgLocator.getAttribute( 'id' ); test( 'can remove an image', async ( { page, productWithGallery } ) => {
const initialImagesCount = productWithGallery.images.length;
await test.step( 'remove an image', async () => { const removedImgLocator = page
await newCoverImgLocator.click(); .getByLabel( 'Block: Product images' )
await page.getByLabel( 'Set as cover' ).click(); .locator( 'img' )
.nth( 1 );
await expect(
page.getByRole( 'button', { name: 'Cover' } ).locator( 'img' ) await test.step( 'navigate to product edit page', async () => {
).toHaveId( newCoverImgId ); await page.goto(
} ); `wp-admin/post.php?post=${ productWithGallery.id }&action=edit`
);
await test.step( 'update the product', async () => { } );
await page.getByRole( 'button', { name: 'Update' } ).click();
// Verify product was updated await test.step( 'remove an image', async () => {
await expect( await removedImgLocator.click();
page.getByLabel( 'Dismiss this notice' ) await page
).toContainText( 'Product updated' ); .getByRole( 'toolbar', { name: 'Options' } )
} ); .getByLabel( 'Options' )
.click();
await test.step( 'verify product image was set', async () => { await page.getByRole( 'menuitem', { name: 'Remove' } ).click();
await expect(
page.getByRole( 'button', { name: 'Cover' } ).locator( 'img' ) await expect(
).toHaveId( newCoverImgId ); page.getByLabel( 'Block: Product images' ).locator( 'img' )
} ); ).toHaveCount( initialImagesCount - 1 );
} );
await test.step( 'update the product', async () => {
await page.getByRole( 'button', { name: 'Update' } ).click();
// Verify product was updated
await expect( page.getByLabel( 'Dismiss this notice' ) ).toContainText(
'Product updated'
);
} );
await test.step( 'verify product image was set', async () => {
await expect(
page.getByLabel( 'Block: Product images' ).locator( 'img' )
).toHaveCount( initialImagesCount - 1 );
// Verify image in store frontend
await page.goto( productWithGallery.permalink );
await expect(
page.locator( `#product-${ productWithGallery.id } ol img` )
).toHaveCount( initialImagesCount - 1 );
} );
} );
test( 'can set an image as cover', async ( { page, productWithGallery } ) => {
const newCoverImgLocator = page
.getByLabel( 'Block: Product images' )
.locator( 'img' )
.nth( 1 );
await test.step( 'navigate to product edit page', async () => {
await page.goto(
`wp-admin/post.php?post=${ productWithGallery.id }&action=edit`
);
} );
const newCoverImgId = await newCoverImgLocator.getAttribute( 'id' );
await test.step( 'remove an image', async () => {
await newCoverImgLocator.click();
await page.getByLabel( 'Set as cover' ).click();
await expect(
page.getByRole( 'button', { name: 'Cover' } ).locator( 'img' )
).toHaveId( newCoverImgId );
} );
await test.step( 'update the product', async () => {
await page.getByRole( 'button', { name: 'Update' } ).click();
// Verify product was updated
await expect( page.getByLabel( 'Dismiss this notice' ) ).toContainText(
'Product updated'
);
} );
await test.step( 'verify product image was set', async () => {
await expect(
page.getByRole( 'button', { name: 'Cover' } ).locator( 'img' )
).toHaveId( newCoverImgId );
} ); } );
} ); } );

View File

@ -0,0 +1,210 @@
const { test: baseTest } = require( './block-editor-fixtures' );
const { expect } = require( '../../../../fixtures' );
const test = baseTest.extend( {
product: async ( { api }, use ) => {
let product;
await api
.post( 'products', {
name: `Product ${ Date.now() }`,
type: 'simple',
regular_price: '12.99',
stock_status: 'instock',
} )
.then( ( response ) => {
product = response.data;
} );
await use( product );
// Cleanup
await api.delete( `products/${ product.id }`, { force: true } );
},
page: async ( { page, product }, use ) => {
await test.step( 'go to product editor, inventory tab', async () => {
await page.goto(
`wp-admin/post.php?post=${ product.id }&action=edit`
);
await page.getByRole( 'button', { name: 'Inventory' } ).click();
} );
await use( page );
},
} );
test( 'can update sku', async ( { page, product } ) => {
const sku = `SKU_${ Date.now() }`;
await test.step( 'update the sku value', async () => {
await page.locator( '[name="woocommerce-product-sku"]' ).fill( sku );
} );
await test.step( 'update the product', async () => {
await page.getByRole( 'button', { name: 'Update' } ).click();
// Verify product was updated
await expect( page.getByLabel( 'Dismiss this notice' ) ).toContainText(
'Product updated'
);
} );
await test.step( 'verify the change in product editor', async () => {
await expect(
page.locator( '[name="woocommerce-product-sku"]' )
).toHaveValue( sku );
} );
await test.step( 'verify the changes in the store frontend', async () => {
// Verify image in store frontend
await page.goto( product.permalink );
await expect( page.getByText( `SKU: ${ sku }` ) ).toBeVisible();
} );
} );
test( 'can update stock status', async ( { page, product } ) => {
await test.step( 'update the sku value', async () => {
await page.getByLabel( 'Out of stock' ).check();
} );
await test.step( 'update the product', async () => {
await page.getByRole( 'button', { name: 'Update' } ).click();
// Verify product was updated
await expect( page.getByLabel( 'Dismiss this notice' ) ).toContainText(
'Product updated'
);
} );
await test.step( 'verify the change in product editor', async () => {
await expect( page.getByLabel( 'Out of stock' ) ).toBeChecked();
} );
await test.step( 'verify the changes in the store frontend', async () => {
// Verify image in store frontend
await page.goto( product.permalink );
await expect( page.getByText( 'Out of stock' ) ).toBeVisible();
} );
} );
test( 'can track stock quantity', async ( { page, product } ) => {
await test.step( 'enable track stock quantity', async () => {
await page.getByLabel( 'Track stock quantity for this' ).check();
// await closeTourModal( { page, timeout: 2000 } );
await page.getByRole( 'button', { name: 'Advanced' } ).click();
await page.getByLabel( "Don't allow purchases" ).check();
} );
const quantity = '1';
await test.step( 'update available quantity', async () => {
await page.locator( '[name="stock_quantity"]' ).fill( quantity );
} );
await test.step( 'update the product', async () => {
await page.getByRole( 'button', { name: 'Update' } ).click();
// Verify product was updated
await expect( page.getByLabel( 'Dismiss this notice' ) ).toContainText(
'Product updated'
);
} );
await test.step( 'verify the change in product editor', async () => {
await expect( page.locator( '[name="stock_quantity"]' ) ).toHaveValue(
quantity
);
} );
await test.step( 'verify the changes in the store frontend', async () => {
// Verify image in store frontend
await page.goto( product.permalink );
await expect(
page.getByText( `${ quantity } in stock` )
).toBeVisible();
} );
await test.step( 'return to product editor', async () => {
await page.goto( `wp-admin/post.php?post=${ product.id }&action=edit` );
await page.getByRole( 'button', { name: 'Inventory' } ).click();
} );
await test.step( 'update available quantity', async () => {
await page.locator( '[name="stock_quantity"]' ).fill( '0' );
} );
await test.step( 'update the product', async () => {
await page.getByRole( 'button', { name: 'Update' } ).click();
// Verify product was updated
await expect( page.getByLabel( 'Dismiss this notice' ) ).toContainText(
'Product updated'
);
} );
await test.step( 'verify the change in product editor', async () => {
await expect( page.locator( '[name="stock_quantity"]' ) ).toHaveValue(
'0'
);
} );
await test.step( 'verify the changes in the store frontend', async () => {
// Verify image in store frontend
await page.goto( product.permalink );
await expect( page.getByText( 'Out of stock' ) ).toBeVisible();
} );
} );
test( 'can limit purchases', async ( { page, product } ) => {
await test.step( 'ensure limit purchases is disabled', async () => {
// await closeTourModal( { page, timeout: 2000 } );
await page.getByRole( 'button', { name: 'Advanced' } ).click();
await expect(
page.getByLabel( 'Limit purchases to 1 item per order' )
).not.toBeChecked();
} );
await test.step( 'add 2 items to cart', async () => {
// Verify image in store frontend
await page.goto( product.permalink );
await page.getByLabel( 'Product quantity' ).fill( '2' );
await page.getByRole( 'button', { name: 'Add to cart' } ).click();
await expect(
page.getByText(
`2 ×${ product.name }” have been added to your cart.`
)
).toBeVisible();
} );
await test.step( 'return to product editor', async () => {
await page.goto( `wp-admin/post.php?post=${ product.id }&action=edit` );
await page.getByRole( 'button', { name: 'Inventory' } ).click();
} );
await test.step( 'enable limit purchases', async () => {
await page.getByRole( 'button', { name: 'Advanced' } ).click();
await page.getByLabel( 'Limit purchases to 1 item per order' ).check();
} );
await test.step( 'update the product', async () => {
await page.getByRole( 'button', { name: 'Update' } ).click();
// Verify product was updated
await expect( page.getByLabel( 'Dismiss this notice' ) ).toContainText(
'Product updated'
);
} );
await test.step( 'verify you cannot order more than 1 item', async () => {
// Verify image in store frontend
await page.goto( product.permalink );
await page.getByRole( 'button', { name: 'Add to cart' } ).click();
await page.getByRole( 'button', { name: 'Add to cart' } ).click();
await expect(
page.getByText(
`You cannot add another "${ product.name }" to your cart.`
)
).toBeVisible();
} );
} );