Checkout the new files
This commit is contained in:
parent
6fb55fc686
commit
054fa4f65a
|
@ -0,0 +1,131 @@
|
||||||
|
const { test, expect } = require( '@playwright/test' );
|
||||||
|
const { variableProducts: utils } = require( '../../../../utils' );
|
||||||
|
const {
|
||||||
|
createVariableProduct,
|
||||||
|
showVariableProductTour,
|
||||||
|
deleteProductsAddedByTests,
|
||||||
|
productAttributes,
|
||||||
|
} = utils;
|
||||||
|
|
||||||
|
let productId;
|
||||||
|
|
||||||
|
test.describe( 'Add product attributes', () => {
|
||||||
|
test.use( { storageState: process.env.ADMINSTATE } );
|
||||||
|
|
||||||
|
test.beforeAll( async ( { browser } ) => {
|
||||||
|
productId = await createVariableProduct();
|
||||||
|
|
||||||
|
await showVariableProductTour( browser, false );
|
||||||
|
} );
|
||||||
|
|
||||||
|
test.afterAll( async () => {
|
||||||
|
await deleteProductsAddedByTests();
|
||||||
|
} );
|
||||||
|
|
||||||
|
test( 'can add custom product attributes', async ( { page } ) => {
|
||||||
|
await test.step(
|
||||||
|
`Open "Edit product" page of product id ${ productId }`,
|
||||||
|
async () => {
|
||||||
|
await page.goto(
|
||||||
|
`/wp-admin/post.php?post=${ productId }&action=edit`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step( 'Go to the "Attributes" tab.', async () => {
|
||||||
|
const attributesTab = page
|
||||||
|
.locator( '.attribute_tab' )
|
||||||
|
.getByRole( 'link', { name: 'Attributes' } );
|
||||||
|
|
||||||
|
await attributesTab.click();
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
`Add ${ productAttributes.length } attributes.`,
|
||||||
|
async () => {
|
||||||
|
for ( let i = 0; i < productAttributes.length; i++ ) {
|
||||||
|
const attributeName = productAttributes[ i ].name;
|
||||||
|
const attributeValues = productAttributes[ i ].options.join(
|
||||||
|
'|'
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( i > 0 ) {
|
||||||
|
await test.step( "Click 'Add new'.", async () => {
|
||||||
|
await page
|
||||||
|
.locator( '#product_attributes .toolbar-top' )
|
||||||
|
.getByRole( 'button', { name: 'Add new' } )
|
||||||
|
.click();
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
`Add the attribute "${ attributeName }" with values "${ attributeValues }"`,
|
||||||
|
async () => {
|
||||||
|
await test.step(
|
||||||
|
`Type "${ attributeName }" in the "Attribute name" input field.`,
|
||||||
|
async () => {
|
||||||
|
await page
|
||||||
|
.getByPlaceholder(
|
||||||
|
'f.e. size or color'
|
||||||
|
)
|
||||||
|
.nth( i )
|
||||||
|
.type( attributeName );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
`Type the attribute values "${ attributeValues }".`,
|
||||||
|
async () => {
|
||||||
|
await page
|
||||||
|
.getByPlaceholder(
|
||||||
|
'Enter options for customers to choose from'
|
||||||
|
)
|
||||||
|
.nth( i )
|
||||||
|
.type( attributeValues );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
'Click "Save attributes".',
|
||||||
|
async () => {
|
||||||
|
await page
|
||||||
|
.getByRole( 'button', {
|
||||||
|
name: 'Save attributes',
|
||||||
|
} )
|
||||||
|
.click( { clickCount: 3 } );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
"Wait for the tour's dismissal to be saved",
|
||||||
|
async () => {
|
||||||
|
await page.waitForResponse(
|
||||||
|
( response ) =>
|
||||||
|
response
|
||||||
|
.url()
|
||||||
|
.includes( '/post.php' ) &&
|
||||||
|
response.status() === 200
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
`Expect the attribute "${ attributeName }" to be saved`,
|
||||||
|
async () => {
|
||||||
|
const savedAttributeHeading = page.getByRole(
|
||||||
|
'heading',
|
||||||
|
{ name: attributeName }
|
||||||
|
);
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
savedAttributeHeading
|
||||||
|
).toBeVisible();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
} );
|
|
@ -0,0 +1,120 @@
|
||||||
|
const { test, expect } = require( '@playwright/test' );
|
||||||
|
const { variableProducts: utils, api } = require( '../../../../utils' );
|
||||||
|
const { showVariableProductTour } = utils;
|
||||||
|
const productPageURL = 'wp-admin/post-new.php?post_type=product';
|
||||||
|
const variableProductName = 'Variable Product with Three Variations';
|
||||||
|
|
||||||
|
let productId;
|
||||||
|
|
||||||
|
test.describe( 'Add variable product', () => {
|
||||||
|
test.use( { storageState: process.env.ADMINSTATE } );
|
||||||
|
|
||||||
|
test.beforeAll( async ( { browser } ) => {
|
||||||
|
await showVariableProductTour( browser, true );
|
||||||
|
} );
|
||||||
|
|
||||||
|
test.afterAll( async ( { browser } ) => {
|
||||||
|
await showVariableProductTour( browser, false );
|
||||||
|
await api.deletePost.product( productId );
|
||||||
|
} );
|
||||||
|
|
||||||
|
test( 'can create a variable product', async ( { page } ) => {
|
||||||
|
await test.step( 'Go to the "Add new product" page', async () => {
|
||||||
|
await page.goto( productPageURL );
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
`Type "${ variableProductName }" into the "Product name" input field.`,
|
||||||
|
async () => {
|
||||||
|
await page
|
||||||
|
.getByLabel( 'Product name' )
|
||||||
|
.fill( variableProductName );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
'Select the "Variable product" product type.',
|
||||||
|
async () => {
|
||||||
|
await page.selectOption( '#product-type', 'variable' );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
'Scroll into the "Attributes" tab and click it.',
|
||||||
|
async () => {
|
||||||
|
const attributesTab = page
|
||||||
|
.locator( '.attribute_tab' )
|
||||||
|
.getByRole( 'link', { name: 'Attributes' } );
|
||||||
|
|
||||||
|
await attributesTab.scrollIntoViewIfNeeded();
|
||||||
|
|
||||||
|
await attributesTab.click();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// the tour only seems to display when not running headless, so just make sure
|
||||||
|
const tourWasDisplayed = await test.step(
|
||||||
|
'See if the tour was displayed.',
|
||||||
|
async () => {
|
||||||
|
return await page
|
||||||
|
.locator( '.woocommerce-tour-kit-step__heading' )
|
||||||
|
.isVisible();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( tourWasDisplayed ) {
|
||||||
|
await test.step( 'Tour was displayed, so dismiss it.', async () => {
|
||||||
|
await page
|
||||||
|
.getByRole( 'button', { name: 'Close Tour' } )
|
||||||
|
.click();
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
"Wait for the tour's dismissal to be saved",
|
||||||
|
async () => {
|
||||||
|
await page.waitForResponse(
|
||||||
|
( response ) =>
|
||||||
|
response.url().includes( '/users/' ) &&
|
||||||
|
response.status() === 200
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await test.step( `Expect the "Variations" tab to appear`, async () => {
|
||||||
|
const variationsTab = page.locator( 'li.variations_tab' );
|
||||||
|
|
||||||
|
await expect( variationsTab ).toBeVisible();
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step( 'Save draft.', async () => {
|
||||||
|
await page.locator( '#save-post' ).click();
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
'Expect the "Product draft updated." notice to appear.',
|
||||||
|
async () => {
|
||||||
|
await expect(
|
||||||
|
page.getByText( 'Product draft updated.' )
|
||||||
|
).toBeVisible();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
'Expect the product type to be "Variable product"',
|
||||||
|
async () => {
|
||||||
|
const selectedProductType = page.locator(
|
||||||
|
'select#product-type [selected]'
|
||||||
|
);
|
||||||
|
|
||||||
|
await expect( selectedProductType ).toHaveText(
|
||||||
|
'Variable product'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step( 'Save product ID for clean up.', async () => {
|
||||||
|
productId = page.url().match( /(?<=post=)\d+/ );
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
} );
|
|
@ -0,0 +1,194 @@
|
||||||
|
const { test, expect } = require( '@playwright/test' );
|
||||||
|
const { variableProducts: utils } = require( '../../../../utils' );
|
||||||
|
const {
|
||||||
|
createVariableProduct,
|
||||||
|
showVariableProductTour,
|
||||||
|
deleteProductsAddedByTests,
|
||||||
|
generateVariationsFromAttributes,
|
||||||
|
productAttributes,
|
||||||
|
} = utils;
|
||||||
|
|
||||||
|
let expectedGeneratedVariations,
|
||||||
|
productId_addManually,
|
||||||
|
productId_generateVariations,
|
||||||
|
variationsToManuallyCreate;
|
||||||
|
|
||||||
|
test.describe( 'Add variations', () => {
|
||||||
|
test.use( { storageState: process.env.ADMINSTATE } );
|
||||||
|
|
||||||
|
test.beforeAll( async ( { browser } ) => {
|
||||||
|
productId_generateVariations = await createVariableProduct(
|
||||||
|
productAttributes
|
||||||
|
);
|
||||||
|
|
||||||
|
productId_addManually = await createVariableProduct(
|
||||||
|
productAttributes
|
||||||
|
);
|
||||||
|
|
||||||
|
expectedGeneratedVariations = generateVariationsFromAttributes(
|
||||||
|
productAttributes
|
||||||
|
);
|
||||||
|
|
||||||
|
variationsToManuallyCreate = expectedGeneratedVariations.slice( 0, 3 );
|
||||||
|
|
||||||
|
await showVariableProductTour( browser, false );
|
||||||
|
} );
|
||||||
|
|
||||||
|
test.afterAll( async () => {
|
||||||
|
await deleteProductsAddedByTests();
|
||||||
|
} );
|
||||||
|
|
||||||
|
test( 'can generate variations from product attributes', async ( {
|
||||||
|
page,
|
||||||
|
} ) => {
|
||||||
|
await test.step(
|
||||||
|
`Open "Edit product" page of product id ${ productId_generateVariations }`,
|
||||||
|
async () => {
|
||||||
|
await page.goto(
|
||||||
|
`/wp-admin/post.php?post=${ productId_generateVariations }&action=edit`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step( 'Click on the "Variations" tab.', async () => {
|
||||||
|
await page.click( 'a[href="#variable_product_options"]' );
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
'Click on the "Generate variations" button.',
|
||||||
|
async () => {
|
||||||
|
// event listener for handling the link_all_variations confirmation dialog
|
||||||
|
page.on( 'dialog', ( dialog ) => dialog.accept() );
|
||||||
|
|
||||||
|
await page.click( 'button.generate_variations' );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
`Expect the number of variations to be ${ expectedGeneratedVariations.length }`,
|
||||||
|
async () => {
|
||||||
|
const variations = page.locator( '.woocommerce_variation' );
|
||||||
|
|
||||||
|
await expect( variations ).toHaveCount(
|
||||||
|
expectedGeneratedVariations.length
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
for ( const variation of expectedGeneratedVariations ) {
|
||||||
|
await test.step(
|
||||||
|
`Expect the variation "${ variation.join(
|
||||||
|
', '
|
||||||
|
) }" to be generated.`,
|
||||||
|
async () => {
|
||||||
|
let variationRow = page.locator(
|
||||||
|
'.woocommerce_variation h3'
|
||||||
|
);
|
||||||
|
|
||||||
|
for ( const attributeValue of variation ) {
|
||||||
|
variationRow = variationRow.filter( {
|
||||||
|
has: page.locator( 'option[selected]', {
|
||||||
|
hasText: attributeValue,
|
||||||
|
} ),
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
await expect( variationRow ).toBeVisible();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
test( 'can manually add a variation', async ( { page } ) => {
|
||||||
|
await test.step(
|
||||||
|
`Open "Edit product" page of product id ${ productId_addManually }`,
|
||||||
|
async () => {
|
||||||
|
await page.goto(
|
||||||
|
`/wp-admin/post.php?post=${ productId_addManually }&action=edit`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step( 'Click on the "Variations" tab.', async () => {
|
||||||
|
await page.click( 'a[href="#variable_product_options"]' );
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
`Manually add ${ variationsToManuallyCreate.length } variations`,
|
||||||
|
async () => {
|
||||||
|
const variationRows = page.locator(
|
||||||
|
'.woocommerce_variation h3'
|
||||||
|
);
|
||||||
|
let variationRowsCount = await variationRows.count();
|
||||||
|
|
||||||
|
for ( const variationToCreate of variationsToManuallyCreate ) {
|
||||||
|
await test.step( 'Click "Add manually"', async () => {
|
||||||
|
const addManuallyButton = page.getByRole( 'button', {
|
||||||
|
name: 'Add manually',
|
||||||
|
} );
|
||||||
|
|
||||||
|
await addManuallyButton.click();
|
||||||
|
|
||||||
|
await expect( variationRows ).toHaveCount(
|
||||||
|
++variationRowsCount
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
|
||||||
|
for ( const attributeValue of variationToCreate ) {
|
||||||
|
const attributeName = productAttributes.find(
|
||||||
|
( { options } ) =>
|
||||||
|
options.includes( attributeValue )
|
||||||
|
).name;
|
||||||
|
const addAttributeMenu = variationRows
|
||||||
|
.nth( 0 )
|
||||||
|
.locator( 'select', {
|
||||||
|
has: page.locator( 'option', {
|
||||||
|
hasText: attributeValue,
|
||||||
|
} ),
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
`Select "${ attributeValue }" from the "${ attributeName }" attribute menu`,
|
||||||
|
async () => {
|
||||||
|
await addAttributeMenu.selectOption(
|
||||||
|
attributeValue
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await test.step( 'Click "Save changes"', async () => {
|
||||||
|
await page
|
||||||
|
.getByRole( 'button', {
|
||||||
|
name: 'Save changes',
|
||||||
|
} )
|
||||||
|
.click();
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
`Expect the variation ${ variationToCreate.join(
|
||||||
|
', '
|
||||||
|
) } to be successfully saved.`,
|
||||||
|
async () => {
|
||||||
|
let newlyAddedVariationRow;
|
||||||
|
|
||||||
|
for ( const attributeValue of variationToCreate ) {
|
||||||
|
newlyAddedVariationRow = (
|
||||||
|
newlyAddedVariationRow || variationRows
|
||||||
|
).filter( {
|
||||||
|
has: page.locator( 'option[selected]', {
|
||||||
|
hasText: attributeValue,
|
||||||
|
} ),
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
newlyAddedVariationRow
|
||||||
|
).toBeVisible();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
} );
|
|
@ -0,0 +1,610 @@
|
||||||
|
const { test, expect } = require( '@playwright/test' );
|
||||||
|
const { variableProducts: utils } = require( '../../../../utils' );
|
||||||
|
const {
|
||||||
|
createVariableProduct,
|
||||||
|
showVariableProductTour,
|
||||||
|
deleteProductsAddedByTests,
|
||||||
|
productAttributes,
|
||||||
|
sampleVariations,
|
||||||
|
createVariations,
|
||||||
|
} = utils;
|
||||||
|
const variationOnePrice = '9.99';
|
||||||
|
const variationTwoPrice = '11.99';
|
||||||
|
const variationThreePrice = '20.00';
|
||||||
|
const productWeight = '200';
|
||||||
|
const productLength = '10';
|
||||||
|
const productWidth = '20';
|
||||||
|
const productHeight = '15';
|
||||||
|
const stockAmount = '100';
|
||||||
|
const lowStockAmount = '10';
|
||||||
|
|
||||||
|
let productId_indivEdit,
|
||||||
|
productId_bulkEdit,
|
||||||
|
productId_deleteAll,
|
||||||
|
productId_manageStock,
|
||||||
|
productId_variationDefaults,
|
||||||
|
productId_removeVariation,
|
||||||
|
defaultVariation,
|
||||||
|
variationIds_indivEdit;
|
||||||
|
|
||||||
|
test.describe( 'Update variations', () => {
|
||||||
|
test.use( { storageState: process.env.ADMINSTATE } );
|
||||||
|
|
||||||
|
test.beforeAll( async ( { browser } ) => {
|
||||||
|
await test.step(
|
||||||
|
'Create variable product for individual edit test',
|
||||||
|
async () => {
|
||||||
|
productId_indivEdit = await createVariableProduct(
|
||||||
|
productAttributes
|
||||||
|
);
|
||||||
|
|
||||||
|
variationIds_indivEdit = await createVariations(
|
||||||
|
productId_indivEdit,
|
||||||
|
sampleVariations
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
'Create variable product for bulk edit test',
|
||||||
|
async () => {
|
||||||
|
productId_bulkEdit = await createVariableProduct(
|
||||||
|
productAttributes
|
||||||
|
);
|
||||||
|
|
||||||
|
await createVariations( productId_bulkEdit, sampleVariations );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
'Create variable product for "delete all" test',
|
||||||
|
async () => {
|
||||||
|
productId_deleteAll = await createVariableProduct(
|
||||||
|
productAttributes
|
||||||
|
);
|
||||||
|
|
||||||
|
await createVariations( productId_deleteAll, sampleVariations );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
'Create variable product for "manage stock" test',
|
||||||
|
async () => {
|
||||||
|
productId_manageStock = await createVariableProduct(
|
||||||
|
productAttributes
|
||||||
|
);
|
||||||
|
|
||||||
|
const variation = sampleVariations.slice( -1 );
|
||||||
|
|
||||||
|
await createVariations( productId_manageStock, variation );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
'Create variable product for "variation defaults" test',
|
||||||
|
async () => {
|
||||||
|
productId_variationDefaults = await createVariableProduct(
|
||||||
|
productAttributes
|
||||||
|
);
|
||||||
|
|
||||||
|
await createVariations(
|
||||||
|
productId_variationDefaults,
|
||||||
|
sampleVariations
|
||||||
|
);
|
||||||
|
|
||||||
|
defaultVariation = sampleVariations[ 1 ].attributes;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
'Create variable product with 1 variation for "remove variation" test',
|
||||||
|
async () => {
|
||||||
|
productId_removeVariation = await createVariableProduct(
|
||||||
|
productAttributes
|
||||||
|
);
|
||||||
|
|
||||||
|
await createVariations(
|
||||||
|
productId_removeVariation,
|
||||||
|
sampleVariations.slice( -1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step( 'Hide variable product tour', async () => {
|
||||||
|
await showVariableProductTour( browser, false );
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
test.afterAll( async () => {
|
||||||
|
await deleteProductsAddedByTests();
|
||||||
|
} );
|
||||||
|
|
||||||
|
test( 'can individually edit variations', async ( { page } ) => {
|
||||||
|
const variationRows = page.locator( '.woocommerce_variation' );
|
||||||
|
const firstVariation = variationRows.filter( {
|
||||||
|
hasText: `#${ variationIds_indivEdit[ 0 ] }`,
|
||||||
|
} );
|
||||||
|
const secondVariation = variationRows.filter( {
|
||||||
|
hasText: `#${ variationIds_indivEdit[ 1 ] }`,
|
||||||
|
} );
|
||||||
|
const thirdVariation = variationRows.filter( {
|
||||||
|
hasText: `#${ variationIds_indivEdit[ 2 ] }`,
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step( 'Go to the "Edit product" page.', async () => {
|
||||||
|
await page.goto(
|
||||||
|
`/wp-admin/post.php?post=${ productId_indivEdit }&action=edit`
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step( 'Click on the "Variations" tab.', async () => {
|
||||||
|
await page.locator( 'a[href="#variable_product_options"]' ).click();
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step( 'Expand all variations.', async () => {
|
||||||
|
await page
|
||||||
|
.locator(
|
||||||
|
'#variable_product_options .toolbar-top a.expand_all'
|
||||||
|
)
|
||||||
|
.click();
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step( 'Edit the first variation.', async () => {
|
||||||
|
await test.step( 'Check the "Virtual" checkbox.', async () => {
|
||||||
|
await firstVariation
|
||||||
|
.getByRole( 'checkbox', {
|
||||||
|
name: 'Virtual',
|
||||||
|
} )
|
||||||
|
.check();
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
`Set regular price to "${ variationOnePrice }".`,
|
||||||
|
async () => {
|
||||||
|
await firstVariation
|
||||||
|
.getByRole( 'textbox', { name: 'Regular price' } )
|
||||||
|
.fill( variationOnePrice );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step( 'Edit the second variation.', async () => {
|
||||||
|
await test.step( 'Check the "Virtual" checkbox.', async () => {
|
||||||
|
await secondVariation
|
||||||
|
.getByRole( 'checkbox', {
|
||||||
|
name: 'Virtual',
|
||||||
|
} )
|
||||||
|
.check();
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
`Set regular price to "${ variationTwoPrice }".`,
|
||||||
|
async () => {
|
||||||
|
await secondVariation
|
||||||
|
.getByRole( 'textbox', { name: 'Regular price' } )
|
||||||
|
.fill( variationTwoPrice );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step( 'Edit the third variation.', async () => {
|
||||||
|
await test.step( 'Check "Manage stock?"', async () => {
|
||||||
|
await thirdVariation
|
||||||
|
.getByRole( 'checkbox', { name: 'Manage stock?' } )
|
||||||
|
.check();
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
`Set regular price to "${ variationThreePrice }".`,
|
||||||
|
async () => {
|
||||||
|
await thirdVariation
|
||||||
|
.getByRole( 'textbox', { name: 'Regular price' } )
|
||||||
|
.fill( variationThreePrice );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step( 'Set the weight and dimensions.', async () => {
|
||||||
|
await thirdVariation
|
||||||
|
.getByRole( 'textbox', { name: 'Weight' } )
|
||||||
|
.type( productWeight );
|
||||||
|
|
||||||
|
await thirdVariation
|
||||||
|
.getByRole( 'textbox', { name: 'Length' } )
|
||||||
|
.type( productLength );
|
||||||
|
|
||||||
|
await thirdVariation
|
||||||
|
.getByRole( 'textbox', { name: 'Width' } )
|
||||||
|
.type( productWidth );
|
||||||
|
|
||||||
|
await thirdVariation
|
||||||
|
.getByRole( 'textbox', { name: 'Height' } )
|
||||||
|
.type( productHeight );
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step( 'Click "Save changes".', async () => {
|
||||||
|
await page.locator( 'button.save-variation-changes' ).click();
|
||||||
|
await page.waitForLoadState( 'networkidle' );
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step( 'Click on the "Variations" tab.', async () => {
|
||||||
|
await page.locator( 'a[href="#variable_product_options"]' ).click();
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step( 'Expand all variations.', async () => {
|
||||||
|
await page
|
||||||
|
.locator(
|
||||||
|
'#variable_product_options .toolbar-top a.expand_all'
|
||||||
|
)
|
||||||
|
.click();
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
'Expect the first variation to be virtual.',
|
||||||
|
async () => {
|
||||||
|
await expect(
|
||||||
|
firstVariation.getByRole( 'checkbox', {
|
||||||
|
name: 'Virtual',
|
||||||
|
} )
|
||||||
|
).toBeChecked();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
`Expect the regular price of the first variation to be "${ variationOnePrice }".`,
|
||||||
|
async () => {
|
||||||
|
await expect(
|
||||||
|
firstVariation.getByRole( 'textbox', {
|
||||||
|
name: 'Regular price',
|
||||||
|
} )
|
||||||
|
).toHaveValue( variationOnePrice );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
'Expect the second variation to be virtual.',
|
||||||
|
async () => {
|
||||||
|
await expect(
|
||||||
|
secondVariation.getByRole( 'checkbox', {
|
||||||
|
name: 'Virtual',
|
||||||
|
} )
|
||||||
|
).toBeChecked();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
`Expect the regular price of the second variation to be "${ variationTwoPrice }".`,
|
||||||
|
async () => {
|
||||||
|
await expect(
|
||||||
|
secondVariation.getByRole( 'textbox', {
|
||||||
|
name: 'Regular price',
|
||||||
|
} )
|
||||||
|
).toHaveValue( variationTwoPrice );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
'Expect the "Manage stock?" checkbox of the third variation to be checked.',
|
||||||
|
async () => {
|
||||||
|
await expect(
|
||||||
|
thirdVariation.getByRole( 'checkbox', {
|
||||||
|
name: 'Manage stock?',
|
||||||
|
} )
|
||||||
|
).toBeChecked();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
`Expect the regular price of the third variation to be "${ variationThreePrice }".`,
|
||||||
|
async () => {
|
||||||
|
await expect(
|
||||||
|
thirdVariation.getByRole( 'textbox', {
|
||||||
|
name: 'Regular price',
|
||||||
|
} )
|
||||||
|
).toHaveValue( variationThreePrice );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
'Expect the weight and dimensions of the third variation to be correct.',
|
||||||
|
async () => {
|
||||||
|
await expect(
|
||||||
|
thirdVariation.getByRole( 'textbox', {
|
||||||
|
name: 'Weight',
|
||||||
|
} )
|
||||||
|
).toHaveValue( productWeight );
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
thirdVariation.getByRole( 'textbox', {
|
||||||
|
name: 'Length',
|
||||||
|
} )
|
||||||
|
).toHaveValue( productLength );
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
thirdVariation.getByRole( 'textbox', { name: 'Width' } )
|
||||||
|
).toHaveValue( productWidth );
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
thirdVariation.getByRole( 'textbox', {
|
||||||
|
name: 'Height',
|
||||||
|
} )
|
||||||
|
).toHaveValue( productHeight );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
|
||||||
|
test( 'can bulk edit variations', async ( { page } ) => {
|
||||||
|
await test.step( 'Go to the "Edit product" page.', async () => {
|
||||||
|
await page.goto(
|
||||||
|
`/wp-admin/post.php?post=${ productId_bulkEdit }&action=edit`
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step( 'Click on the "Variations" tab.', async () => {
|
||||||
|
await page.locator( 'a[href="#variable_product_options"]' ).click();
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
'Select the \'Toggle "Downloadable"\' bulk action.',
|
||||||
|
async () => {
|
||||||
|
await page
|
||||||
|
.locator( '#field_to_edit' )
|
||||||
|
.selectOption( 'toggle_downloadable' );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step( 'Expand all variations.', async () => {
|
||||||
|
await page
|
||||||
|
.locator(
|
||||||
|
'#variable_product_options .toolbar-top a.expand_all'
|
||||||
|
)
|
||||||
|
.click();
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
'Expect all "Downloadable" checkboxes to be checked.',
|
||||||
|
async () => {
|
||||||
|
const checkBoxes = page.locator(
|
||||||
|
'input[name^="variable_is_downloadable"]'
|
||||||
|
);
|
||||||
|
const count = await checkBoxes.count();
|
||||||
|
|
||||||
|
for ( let i = 0; i < count; i++ ) {
|
||||||
|
await expect( checkBoxes.nth( i ) ).toBeChecked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
|
||||||
|
test( 'can delete all variations', async ( { page } ) => {
|
||||||
|
await test.step( 'Go to the "Edit product" page.', async () => {
|
||||||
|
await page.goto(
|
||||||
|
`/wp-admin/post.php?post=${ productId_deleteAll }&action=edit`
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step( 'Click on the "Variations" tab.', async () => {
|
||||||
|
await page.locator( 'a[href="#variable_product_options"]' ).click();
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
'Select the bulk action "Delete all variations".',
|
||||||
|
async () => {
|
||||||
|
page.on( 'dialog', ( dialog ) => dialog.accept() );
|
||||||
|
await page
|
||||||
|
.locator( '#field_to_edit' )
|
||||||
|
.selectOption( 'delete_all' );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
'Expect that there are no more variations.',
|
||||||
|
async () => {
|
||||||
|
await expect(
|
||||||
|
page.locator( '.woocommerce_variation' )
|
||||||
|
).toHaveCount( 0 );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
|
||||||
|
test( 'can manage stock levels', async ( { page } ) => {
|
||||||
|
await test.step( 'Go to the "Edit product" page.', async () => {
|
||||||
|
await page.goto(
|
||||||
|
`/wp-admin/post.php?post=${ productId_manageStock }&action=edit`
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step( 'Click on the "Variations" tab.', async () => {
|
||||||
|
await page.locator( 'a[href="#variable_product_options"]' ).click();
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step( 'Expand all variations', async () => {
|
||||||
|
await page
|
||||||
|
.locator(
|
||||||
|
'#variable_product_options .toolbar-top a.expand_all'
|
||||||
|
)
|
||||||
|
.click();
|
||||||
|
} );
|
||||||
|
|
||||||
|
const variationContainer = page.locator(
|
||||||
|
'.woocommerce_variations .woocommerce_variation'
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step( 'Check the "Manage stock?" box', async () => {
|
||||||
|
await variationContainer
|
||||||
|
.locator( 'input.checkbox.variable_manage_stock' )
|
||||||
|
.check();
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
`Expect the "Stock status" text box to disappear`,
|
||||||
|
async () => {
|
||||||
|
await expect(
|
||||||
|
variationContainer.locator( 'p.variable_stock_status' )
|
||||||
|
).not.toBeVisible();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
`Enter "${ variationOnePrice }" as the regular price`,
|
||||||
|
async () => {
|
||||||
|
await variationContainer
|
||||||
|
.getByPlaceholder( 'Variation price (required)' )
|
||||||
|
.fill( variationOnePrice );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
`Enter "${ stockAmount }" as the stock quantity`,
|
||||||
|
async () => {
|
||||||
|
await variationContainer
|
||||||
|
.locator( 'input[name^="variable_stock"]' )
|
||||||
|
.fill( stockAmount );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
'Select "Allow, but notify customer" from the "Allow backorders?" menu',
|
||||||
|
async () => {
|
||||||
|
await variationContainer
|
||||||
|
.locator( 'select[name^="variable_backorders"]' )
|
||||||
|
.selectOption( 'notify' );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
`Enter "${ lowStockAmount }" in the "Low stock threshold" input field.`,
|
||||||
|
async () => {
|
||||||
|
await variationContainer
|
||||||
|
.getByPlaceholder( 'Store-wide threshold' )
|
||||||
|
.fill( lowStockAmount );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step( 'Click "Save changes"', async () => {
|
||||||
|
await page.locator( 'button.save-variation-changes' ).click();
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step( 'Expand all variations', async () => {
|
||||||
|
await page
|
||||||
|
.locator(
|
||||||
|
'#variable_product_options .toolbar-top a.expand_all'
|
||||||
|
)
|
||||||
|
.click();
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
'Expect the stock quantity to be saved correctly',
|
||||||
|
async () => {
|
||||||
|
await expect(
|
||||||
|
variationContainer.locator(
|
||||||
|
'input[name^="variable_stock"]'
|
||||||
|
)
|
||||||
|
).toHaveValue( stockAmount );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
'Expect the "Low stock threshold" value to be saved correctly',
|
||||||
|
async () => {
|
||||||
|
await expect(
|
||||||
|
variationContainer.getByPlaceholder(
|
||||||
|
'Store-wide threshold'
|
||||||
|
)
|
||||||
|
).toHaveValue( lowStockAmount );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
'Expect the "Allow backorders?" value to be saved correctly',
|
||||||
|
async () => {
|
||||||
|
await expect(
|
||||||
|
variationContainer.locator(
|
||||||
|
'select[name^="variable_backorders"] > option[selected]'
|
||||||
|
)
|
||||||
|
).toHaveText( 'Allow, but notify customer' );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
|
||||||
|
test( 'can set variation defaults', async ( { page } ) => {
|
||||||
|
await test.step( 'Go to the "Edit product" page.', async () => {
|
||||||
|
await page.goto(
|
||||||
|
`/wp-admin/post.php?post=${ productId_variationDefaults }&action=edit`
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step( 'Click on the "Variations" tab.', async () => {
|
||||||
|
await page.locator( 'a[href="#variable_product_options"]' ).click();
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step( 'Select variation defaults', async () => {
|
||||||
|
for ( const attribute of defaultVariation ) {
|
||||||
|
const defaultAttributeMenu = page.locator( 'select', {
|
||||||
|
hasText: `No default ${ attribute.name }…`,
|
||||||
|
} );
|
||||||
|
|
||||||
|
await defaultAttributeMenu.selectOption( attribute.option );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step( 'Click "Save changes"', async () => {
|
||||||
|
await page.getByRole( 'button', { name: 'Save changes' } ).click();
|
||||||
|
await page.waitForLoadState( 'networkidle' );
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step( 'View the product from the shop', async () => {
|
||||||
|
const permalink = await page
|
||||||
|
.locator( '#sample-permalink a' )
|
||||||
|
.getAttribute( 'href' );
|
||||||
|
|
||||||
|
await page.goto( permalink );
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step(
|
||||||
|
'Expect the default attributes to be pre-selected',
|
||||||
|
async () => {
|
||||||
|
for ( const attribute of defaultVariation ) {
|
||||||
|
await test.step(
|
||||||
|
`Expect "${ attribute.option }" is selected as the default "${ attribute.name }"`,
|
||||||
|
async () => {
|
||||||
|
const defaultSelectedAttribute = page
|
||||||
|
.getByRole( 'row', {
|
||||||
|
name: attribute.name,
|
||||||
|
} )
|
||||||
|
.locator( 'option[selected]' );
|
||||||
|
|
||||||
|
await expect( defaultSelectedAttribute ).toHaveText(
|
||||||
|
attribute.option
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
|
||||||
|
test( 'can remove a variation', async ( { page } ) => {
|
||||||
|
await test.step( 'Go to the "Edit product" page.', async () => {
|
||||||
|
await page.goto(
|
||||||
|
`/wp-admin/post.php?post=${ productId_removeVariation }&action=edit`
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step( 'Click on the "Variations" tab.', async () => {
|
||||||
|
await page.locator( 'a[href="#variable_product_options"]' ).click();
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step( 'Click "Remove" on a variation', async () => {
|
||||||
|
page.on( 'dialog', ( dialog ) => dialog.accept() );
|
||||||
|
await page.locator( '.woocommerce_variation' ).hover();
|
||||||
|
await page.locator( '.remove_variation.delete' ).click();
|
||||||
|
} );
|
||||||
|
|
||||||
|
await test.step( 'Expect the variation to be removed', async () => {
|
||||||
|
await expect(
|
||||||
|
page.locator( '.woocommerce_variation' )
|
||||||
|
).toHaveCount( 0 );
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
} );
|
Loading…
Reference in New Issue