Checkout the new files

This commit is contained in:
rodelgc 2023-05-17 23:25:35 +08:00
parent 6fb55fc686
commit 054fa4f65a
4 changed files with 1055 additions and 0 deletions

View File

@ -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();
}
);
}
);
}
}
);
} );
} );

View File

@ -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+/ );
} );
} );
} );

View File

@ -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();
}
);
}
}
);
} );
} );

View File

@ -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 );
} );
} );
} );