[e2e tests] Add new tests for up-sells and cross-sells (#44154)

* Add tests skeleton

* Add up-sell test

* Add changelog

* Add test for cross-sells

* Renamed spec file

* Add tests for remove up-sells and remove cross-sells

* Update the viewport

* Extract the update product action into a function

* Fix the expect for up-sells

* Add a poll mechanism when checking that up-sells were removed.

* * Use backspace to remove linked items

* Add a check for up-sells before removing them to prevent a false negative result

* Uncomment cleanup code

* Revert viewport height
This commit is contained in:
Adrian Moldovan 2024-02-08 00:28:56 +02:00 committed by GitHub
parent f7b92e8b6b
commit 035eb2dade
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 283 additions and 0 deletions

View File

@ -0,0 +1,4 @@
Significance: patch
Type: dev
E2E tests: add tests for up-sells and cross-sells

View File

@ -0,0 +1,279 @@
const { test: baseTest, expect } = require( '@playwright/test' );
const wcApi = require( '@woocommerce/woocommerce-rest-api' ).default;
baseTest.describe( 'Products > Related products', () => {
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 );
},
products: async ( { api }, use ) => {
const keys = [ 'main', 'linked1', 'linked2' ];
const products = {};
for ( const key of Object.values( keys ) ) {
await api
.post( 'products', {
name: `${ key } ${ Date.now() }`,
type: 'simple',
regular_price: '12.99',
} )
.then( ( response ) => {
products[ key ] = response.data;
} );
}
await use( products );
// Cleanup
for ( const product of Object.values( products ) ) {
await api.delete( `products/${ product.id }`, { force: true } );
}
},
} );
async function navigate( page, productId ) {
await test.step( 'Navigate to product edit page', async () => {
await page.goto(
`wp-admin/post.php?post=${ productId }&action=edit`
);
} );
await test.step( 'go to Linked Products', async () => {
await page.getByRole( 'link', { name: 'Linked Products' } ).click();
} );
}
async function updateProduct( page ) {
await test.step( 'update the product', async () => {
// extra click somewhere in the page as a workaround for update button click not always working
await page
.getByRole( 'heading', { name: 'Edit product', exact: true } )
.click();
await page.getByRole( 'button', { name: 'Update' } ).click();
await expect( page.getByText( 'Product updated.' ) ).toBeVisible();
} );
}
test( 'add up-sells', async ( { page, products } ) => {
await navigate( page, products.main.id );
const upsellTextBoxLocator = page
.locator( 'p' )
.filter( { hasText: 'Upsells' } )
.getByRole( 'textbox' );
await test.step( 'add an up-sell by searching for product name', async () => {
await upsellTextBoxLocator.click();
await upsellTextBoxLocator.fill( products.linked1.name );
await page.keyboard.press( 'Space' ); // This is needed to trigger the search
await page
.getByRole( 'option', { name: products.linked1.name } )
.click();
await expect(
page.getByRole( 'listitem', {
name: products.linked1.name,
} )
).toBeVisible();
} );
await test.step( 'add an up-sell by searching for product id', async () => {
await upsellTextBoxLocator.click();
await upsellTextBoxLocator.fill( `${ products.linked2.id }` );
await page.keyboard.press( 'Space' ); // This is needed to trigger the search
await page
.getByRole( 'option', { name: products.linked2.name } )
.click();
await expect(
page.getByRole( 'listitem', {
name: products.linked2.name,
} )
).toBeVisible();
await expect(
page.getByRole( 'listitem', {
name: products.linked1.name,
} )
).toBeVisible();
} );
await updateProduct( page );
await test.step( 'verify the up-sell in the store frontend', async () => {
await page.goto( products.main.permalink );
await expect(
page.locator( 'section.upsells' ).getByRole( 'heading', {
name: products.linked1.name,
} )
).toBeVisible();
await expect(
page.locator( 'section.upsells' ).getByRole( 'heading', {
name: products.linked2.name,
} )
).toBeVisible();
} );
} );
test( 'remove up-sells', async ( { page, api, products } ) => {
// Add up-sells
await api.put( `products/${ products.main.id }`, {
upsell_ids: [ products.linked1.id ],
} );
// Verify up-sells are present, so we can assert the opposite after removing them
// This should prevent a possible false negative result
await test.step( 'verify the up-sells in the store frontend', async () => {
await page.goto( products.main.permalink );
await expect(
page.locator( 'section.upsells' ).getByRole( 'heading', {
name: products.linked1.name,
} )
).toBeVisible();
} );
await navigate( page, products.main.id );
await test.step( 'remove up-sells for a product', async () => {
// Using backspace to remove the product because clicking the remove button is flaky
await page
.locator( 'p' )
.filter( { hasText: 'Upsells' } )
.getByRole( 'textbox' )
.click();
await page.keyboard.press( 'Backspace' );
await expect(
page.getByRole( 'listitem', { name: products.linked1.name } )
).toBeHidden();
} );
await updateProduct( page );
await test.step( 'verify the up-sells in the store frontend', async () => {
await page.goto( products.main.permalink );
await expect(
page.locator( 'section.upsells' ).getByRole( 'heading', {
name: products.linked1.name,
} )
).toBeHidden();
} );
} );
test( 'add cross-sells', async ( { page, products } ) => {
await navigate( page, products.main.id );
const upsellTextBoxLocator = page
.locator( 'p' )
.filter( { hasText: 'Cross-sells' } )
.getByRole( 'textbox' );
await test.step( 'add a cross-sell by searching for product name', async () => {
await upsellTextBoxLocator.click();
await upsellTextBoxLocator.fill( products.linked1.name );
await page.keyboard.press( 'Space' ); // This is needed to trigger the search
await page
.getByRole( 'option', { name: products.linked1.name } )
.click();
await expect(
page.getByRole( 'listitem', {
name: products.linked1.name,
} )
).toBeVisible();
} );
await test.step( 'add a cross-sell by searching for product id', async () => {
await upsellTextBoxLocator.click();
await upsellTextBoxLocator.fill( `${ products.linked2.id }` );
await page.keyboard.press( 'Space' ); // This is needed to trigger the search
await page
.getByRole( 'option', { name: products.linked2.name } )
.click();
await expect(
page.getByRole( 'listitem', {
name: products.linked2.name,
} )
).toBeVisible();
await expect(
page.getByRole( 'listitem', {
name: products.linked1.name,
} )
).toBeVisible();
} );
await updateProduct( page );
await test.step( 'verify the up-sell in the store frontend', async () => {
await page.goto( products.main.permalink );
// add to cart and view proceed to checkout
await page.getByRole( 'button', { name: 'Add to cart' } ).click();
await page.getByRole( 'link', { name: 'View cart' } ).click();
// check for cross-sells
const sectionLocator = page.locator( 'div' ).filter( {
has: page.getByRole( 'heading', {
name: 'You may be interested in',
} ),
} );
await expect(
sectionLocator.getByRole( 'heading', {
name: products.linked1.name,
} )
).toBeVisible();
await expect(
sectionLocator.getByRole( 'heading', {
name: products.linked2.name,
} )
).toBeVisible();
} );
} );
test( 'remove cross-sells', async ( { page, api, products } ) => {
// Add cross-sells
await api.put( `products/${ products.main.id }`, {
cross_sell_ids: [ products.linked1.id ],
} );
await navigate( page, products.main.id );
await test.step( 'remove cross-sells for a product', async () => {
// Using backspace to remove the product because clicking the remove button is flaky
await page
.locator( 'p' )
.filter( { hasText: 'Cross-sells' } )
.getByRole( 'textbox' )
.click();
await page.keyboard.press( 'Backspace' );
await expect(
page.getByRole( 'listitem', { name: products.linked1.name } )
).toBeHidden();
} );
await updateProduct( page );
await test.step( 'verify the cross-sells in the store frontend', async () => {
await page.goto( products.main.permalink );
// add to cart and view proceed to checkout
await page.getByRole( 'button', { name: 'Add to cart' } ).click();
await page.getByRole( 'link', { name: 'View cart' } ).click();
// check for cross-sells
await expect(
page.getByText( products.linked1.name )
).toBeHidden();
} );
} );
} );