[e2e] Product Editor: Add SKU, GTIN, shipping, and custom fields to simple product creation test (#50241)
* Refactor to add steps in 'can create a simple product' test * Remove unnecessary await * Fill in shipping dimensions * Add frontend verification step * Get permalink from editor page * Verify shipping dimensions * Verify sku and gtin * Fix label association for sku field * Fill in shipping class * Fill custom field * Handle SKU auto-update before filling in SKU * Changelog * Changelog * Add more specific locator for attributes "Add new" button * Update comment for why click() is used instead of check() for toggle * Fix incorrect selector for attributes "Add new" button * Remove check for toggle being checked, as it is flaky * Await isChecked() * Scroll custom fields toggle into view if needed * Make custom field toggling more reliable * Break filling into a separate step * Break filling and verifying of full description into separate steps * Verify the description and fix verifying shipping details * Make showing of description toolbar more reliable * Suppress errant warning * Suppress warning for conditional and add comment about why it is okay * Remove unused const
This commit is contained in:
parent
7fd864d234
commit
fe7fafa729
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: fix
|
||||
|
||||
Fix association of label and input for SKU field.
|
|
@ -3,6 +3,7 @@
|
|||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { BlockAttributes } from '@wordpress/blocks';
|
||||
import { useInstanceId } from '@wordpress/compose';
|
||||
import { createElement, createInterpolateElement } from '@wordpress/element';
|
||||
import { useWooBlockProps } from '@woocommerce/block-templates';
|
||||
import { Product } from '@woocommerce/data';
|
||||
|
@ -46,10 +47,15 @@ export function Edit( {
|
|||
[ sku ]
|
||||
);
|
||||
|
||||
const inputControlId = useInstanceId(
|
||||
BaseControl,
|
||||
'product_sku'
|
||||
) as string;
|
||||
|
||||
return (
|
||||
<div { ...blockProps }>
|
||||
<BaseControl
|
||||
id={ 'product_sku' }
|
||||
id={ inputControlId }
|
||||
className="woocommerce-product-form_inventory-sku"
|
||||
label={ createInterpolateElement(
|
||||
__( 'Sku <description />', 'woocommerce' ),
|
||||
|
@ -64,6 +70,7 @@ export function Edit( {
|
|||
>
|
||||
<InputControl
|
||||
ref={ skuRef }
|
||||
id={ inputControlId }
|
||||
name={ 'woocommerce-product-sku' }
|
||||
onChange={ setSku }
|
||||
value={ sku || '' }
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: update
|
||||
|
||||
Add additional fields to new product editor e2e tests.
|
|
@ -20,6 +20,18 @@ const productData = {
|
|||
descriptionSimple: 'This is a product simple description',
|
||||
productPrice: '100',
|
||||
salePrice: '90',
|
||||
customFields: [
|
||||
{ name: `custom-field_${ Date.now() }`, value: 'custom_1' },
|
||||
],
|
||||
sku: `sku_${ Date.now() }`,
|
||||
gtin: `gtin_${ Date.now() }`,
|
||||
shipping: {
|
||||
shippingClassName: `shipping-class_${ Date.now() }`,
|
||||
weight: '2',
|
||||
length: '20',
|
||||
width: '10',
|
||||
height: '30',
|
||||
},
|
||||
};
|
||||
|
||||
test.describe.configure( { mode: 'serial' } );
|
||||
|
@ -41,187 +53,428 @@ test.describe( 'General tab', { tag: '@gutenberg' }, () => {
|
|||
let productId;
|
||||
|
||||
test.skip(
|
||||
// skip(condition, description) can be used at runtime to skip a test
|
||||
// eslint-disable-next-line jest/valid-title
|
||||
isTrackingSupposedToBeEnabled,
|
||||
'The block product editor is not being tested'
|
||||
);
|
||||
|
||||
test( 'can create a simple product', async ( { page } ) => {
|
||||
await page.goto( NEW_EDITOR_ADD_PRODUCT_URL );
|
||||
await clickOnTab( 'General', page );
|
||||
await page
|
||||
.getByPlaceholder( 'e.g. 12 oz Coffee Mug' )
|
||||
.fill( productData.name );
|
||||
await test.step( 'add new product', async () => {
|
||||
await page.goto( NEW_EDITOR_ADD_PRODUCT_URL );
|
||||
} );
|
||||
|
||||
await page
|
||||
.locator(
|
||||
await test.step( 'add product name', async () => {
|
||||
await clickOnTab( 'General', page );
|
||||
await page
|
||||
.getByPlaceholder( 'e.g. 12 oz Coffee Mug' )
|
||||
// Have to use pressSequentially in order for the SKU to be auto-updated
|
||||
// before we move to the SKU field and attempt to fill it in; otherwise,
|
||||
// the SKU field can sometimes end up getting auto-updated after we have filled it in,
|
||||
// wiping out the value we entered.
|
||||
.pressSequentially( productData.name );
|
||||
} );
|
||||
|
||||
await test.step( 'add simple product description', async () => {
|
||||
const descriptionSimpleParagraph = page.locator(
|
||||
'[data-template-block-id="product-description__content"] > p'
|
||||
)
|
||||
.fill( productData.descriptionSimple );
|
||||
);
|
||||
|
||||
await page.getByText( 'Full editor' ).click();
|
||||
await descriptionSimpleParagraph.fill(
|
||||
productData.descriptionSimple
|
||||
);
|
||||
} );
|
||||
|
||||
const wordPressVersion = await getInstalledWordPressVersion();
|
||||
await insertBlock( page, 'Heading', wordPressVersion );
|
||||
await test.step( 'add full product description', async () => {
|
||||
// Helps to ensure that block toolbar appears, by letting the editor
|
||||
// know that the user is done typing.
|
||||
await page.keyboard.press( 'Escape' );
|
||||
|
||||
const editorCanvasLocator = page.frameLocator(
|
||||
'iframe[name="editor-canvas"]'
|
||||
);
|
||||
await page.getByText( 'Full editor' ).click();
|
||||
|
||||
await editorCanvasLocator
|
||||
.locator( '[data-title="Heading"]' )
|
||||
.fill( productData.descriptionTitle );
|
||||
const wordPressVersion = await getInstalledWordPressVersion();
|
||||
await insertBlock( page, 'Heading', wordPressVersion );
|
||||
|
||||
await editorCanvasLocator
|
||||
.locator( '[data-title="Heading"]' )
|
||||
.blur();
|
||||
const editorCanvasLocator = page.frameLocator(
|
||||
'iframe[name="editor-canvas"]'
|
||||
);
|
||||
|
||||
await insertBlock( page, 'Paragraph', wordPressVersion );
|
||||
await editorCanvasLocator
|
||||
.locator( '[data-title="Heading"]' )
|
||||
.fill( productData.descriptionTitle );
|
||||
|
||||
await editorCanvasLocator
|
||||
.locator( '[data-title="Paragraph"]' )
|
||||
.last()
|
||||
.fill( productData.descriptionParagraph );
|
||||
await editorCanvasLocator
|
||||
.locator( '[data-title="Heading"]' )
|
||||
.blur();
|
||||
|
||||
await page.getByRole( 'button', { name: 'Done' } ).click();
|
||||
await insertBlock( page, 'Paragraph', wordPressVersion );
|
||||
|
||||
const previewContainerIframe = page
|
||||
.locator( '.block-editor-block-preview__container' )
|
||||
.frameLocator( 'iframe[title="Editor canvas"]' );
|
||||
await editorCanvasLocator
|
||||
.locator( '[data-title="Paragraph"]' )
|
||||
.last()
|
||||
.fill( productData.descriptionParagraph );
|
||||
|
||||
const descriptionTitle = previewContainerIframe.locator(
|
||||
'[data-title="Heading"]'
|
||||
);
|
||||
const descriptionInitialParagraph = previewContainerIframe
|
||||
.locator( '[data-title="Paragraph"]' )
|
||||
.first();
|
||||
const descriptionSecondParagraph = previewContainerIframe
|
||||
.locator( '[data-title="Paragraph"]' )
|
||||
.last();
|
||||
await page.getByRole( 'button', { name: 'Done' } ).click();
|
||||
} );
|
||||
|
||||
await expect( descriptionTitle ).toHaveText(
|
||||
productData.descriptionTitle
|
||||
);
|
||||
await expect( descriptionInitialParagraph ).toHaveText(
|
||||
productData.descriptionSimple
|
||||
);
|
||||
await expect( descriptionSecondParagraph ).toHaveText(
|
||||
productData.descriptionParagraph
|
||||
);
|
||||
await test.step( 'verify full product description', async () => {
|
||||
const previewContainerIframe = page
|
||||
.locator( '.block-editor-block-preview__container' )
|
||||
.frameLocator( 'iframe[title="Editor canvas"]' );
|
||||
|
||||
await descriptionTitle.click();
|
||||
const descriptionTitle = previewContainerIframe.locator(
|
||||
'[data-title="Heading"]'
|
||||
);
|
||||
const descriptionInitialParagraph = previewContainerIframe
|
||||
.locator( '[data-title="Paragraph"]' )
|
||||
.first();
|
||||
const descriptionSecondParagraph = previewContainerIframe
|
||||
.locator( '[data-title="Paragraph"]' )
|
||||
.last();
|
||||
|
||||
await expect(
|
||||
page.getByText( 'Edit in full editor' )
|
||||
).toBeVisible();
|
||||
await expect( descriptionTitle ).toHaveText(
|
||||
productData.descriptionTitle
|
||||
);
|
||||
await expect( descriptionInitialParagraph ).toHaveText(
|
||||
productData.descriptionSimple
|
||||
);
|
||||
await expect( descriptionSecondParagraph ).toHaveText(
|
||||
productData.descriptionParagraph
|
||||
);
|
||||
|
||||
await page
|
||||
.locator(
|
||||
'[data-template-block-id="basic-details"] .components-summary-control'
|
||||
)
|
||||
.last()
|
||||
.fill( productData.summary );
|
||||
await descriptionTitle.click();
|
||||
|
||||
// We blur the summary field to hide the toolbar before clicking on the regular price field.
|
||||
await page
|
||||
.locator(
|
||||
'[data-template-block-id="basic-details"] .components-summary-control'
|
||||
)
|
||||
.last()
|
||||
.blur();
|
||||
await expect(
|
||||
page.getByText( 'Edit in full editor' )
|
||||
).toBeVisible();
|
||||
} );
|
||||
|
||||
const regularPrice = page
|
||||
.locator( 'input[name="regular_price"]' )
|
||||
.first();
|
||||
await regularPrice.waitFor( { state: 'visible' } );
|
||||
await regularPrice.click();
|
||||
await regularPrice.fill( productData.productPrice );
|
||||
await test.step( 'add product summary', async () => {
|
||||
await page
|
||||
.locator(
|
||||
'[data-template-block-id="basic-details"] .components-summary-control'
|
||||
)
|
||||
.last()
|
||||
.fill( productData.summary );
|
||||
|
||||
const salePrice = page
|
||||
.locator( 'input[name="sale_price"]' )
|
||||
.first();
|
||||
await salePrice.waitFor( { state: 'visible' } );
|
||||
await salePrice.click();
|
||||
await salePrice.fill( productData.salePrice );
|
||||
// Blur the summary field to hide the toolbar before clicking on the regular price field.
|
||||
await page
|
||||
.locator(
|
||||
'[data-template-block-id="basic-details"] .components-summary-control'
|
||||
)
|
||||
.last()
|
||||
.blur();
|
||||
} );
|
||||
|
||||
await page
|
||||
.locator( '.woocommerce-product-header__actions' )
|
||||
.getByRole( 'button', {
|
||||
name: 'Publish',
|
||||
} )
|
||||
.click();
|
||||
await test.step( 'add product price', async () => {
|
||||
const regularPrice = page
|
||||
.locator( 'input[name="regular_price"]' )
|
||||
.first();
|
||||
await regularPrice.waitFor( { state: 'visible' } );
|
||||
await regularPrice.click();
|
||||
await regularPrice.fill( productData.productPrice );
|
||||
|
||||
await expect(
|
||||
page.getByLabel( 'Dismiss this notice' )
|
||||
).toContainText( 'Product published' );
|
||||
const salePrice = page
|
||||
.locator( 'input[name="sale_price"]' )
|
||||
.first();
|
||||
await salePrice.waitFor( { state: 'visible' } );
|
||||
await salePrice.click();
|
||||
await salePrice.fill( productData.salePrice );
|
||||
} );
|
||||
|
||||
const title = page.locator( '.woocommerce-product-header__title' );
|
||||
await test.step( 'add custom fields', async () => {
|
||||
await clickOnTab( 'Organization', page );
|
||||
|
||||
// Save product ID
|
||||
const productIdRegex = /product%2F(\d+)/;
|
||||
const url = page.url();
|
||||
const productIdMatch = productIdRegex.exec( url );
|
||||
productId = productIdMatch ? productIdMatch[ 1 ] : null;
|
||||
const customFieldsAddNewButton = page
|
||||
.getByLabel( 'Block: Product custom fields toggle control' )
|
||||
.getByRole( 'button', { name: 'Add new' } );
|
||||
|
||||
await expect( productId ).toBeDefined();
|
||||
await expect( title ).toHaveText( productData.name );
|
||||
// When re-running the test without resetting the env,
|
||||
// the custom fields toggle might be already checked,
|
||||
// so we need to check if the "Add new" button is already visible.
|
||||
//
|
||||
// eslint-disable-next-line playwright/no-conditional-in-test
|
||||
if ( ! ( await customFieldsAddNewButton.isVisible() ) ) {
|
||||
// Toggle the "Show custom fields" so that the "Add new" button is visible
|
||||
|
||||
const customFieldsToggle = page.getByRole( 'checkbox', {
|
||||
name: 'Show custom fields',
|
||||
} );
|
||||
|
||||
await customFieldsToggle.scrollIntoViewIfNeeded();
|
||||
|
||||
// click() is used instead of check() because
|
||||
// Playwright sometimes has issues with custom checkboxes:
|
||||
// - https://github.com/microsoft/playwright/issues/13470
|
||||
// - https://github.com/microsoft/playwright/issues/20893
|
||||
// - https://github.com/microsoft/playwright/issues/27016
|
||||
//
|
||||
// eslint-disable-next-line playwright/no-conditional-in-test
|
||||
if ( ! ( await customFieldsToggle.isChecked() ) ) {
|
||||
await customFieldsToggle.click();
|
||||
}
|
||||
|
||||
await customFieldsToggle.isEnabled();
|
||||
}
|
||||
|
||||
await expect( customFieldsAddNewButton ).toBeVisible();
|
||||
|
||||
await customFieldsAddNewButton.click();
|
||||
|
||||
// Add custom fields modal
|
||||
const modal = page.locator(
|
||||
'.woocommerce-product-custom-fields__create-modal'
|
||||
);
|
||||
|
||||
await expect(
|
||||
modal.getByText( 'Add custom fields' )
|
||||
).toBeVisible();
|
||||
|
||||
const nameInput = modal.getByLabel( 'Name' );
|
||||
// Have to use pressSequentially in order to get the dropdown to show up and be able to select the option
|
||||
await nameInput.pressSequentially(
|
||||
productData.customFields[ 0 ].name
|
||||
);
|
||||
|
||||
await expect(
|
||||
modal.getByRole(
|
||||
'option',
|
||||
productData.customFields[ 0 ].name
|
||||
)
|
||||
).toBeVisible();
|
||||
|
||||
await nameInput.press( 'Enter' );
|
||||
|
||||
const valueInput = modal.getByLabel( 'Value' );
|
||||
await valueInput.fill( productData.customFields[ 0 ].value );
|
||||
|
||||
await modal
|
||||
.getByRole( 'button', { name: 'Add', exact: true } )
|
||||
.click();
|
||||
|
||||
await expect(
|
||||
modal.getByText( 'Add custom fields' )
|
||||
).toBeHidden();
|
||||
|
||||
await expect(
|
||||
page.getByText( productData.customFields[ 0 ].name )
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByText( productData.customFields[ 0 ].value )
|
||||
).toBeVisible();
|
||||
} );
|
||||
|
||||
await test.step( 'add inventory details', async () => {
|
||||
await clickOnTab( 'Inventory', page );
|
||||
|
||||
await page
|
||||
.getByLabel( 'SKU (Stock Keeping Unit)' )
|
||||
.fill( productData.sku );
|
||||
await page
|
||||
.getByLabel( 'GTIN, UPC, EAN, or ISBN' )
|
||||
.fill( productData.gtin );
|
||||
} );
|
||||
|
||||
await test.step( 'add shipping details', async () => {
|
||||
await clickOnTab( 'Shipping', page );
|
||||
|
||||
// Shipping class
|
||||
await page
|
||||
.getByLabel( 'Shipping class', { exact: true } )
|
||||
//.locator( 'select[name="shipping_class"]' )
|
||||
.selectOption( 'Add new shipping class' );
|
||||
|
||||
// New shipping class modal
|
||||
const modal = page.locator(
|
||||
'.woocommerce-add-new-shipping-class-modal'
|
||||
);
|
||||
|
||||
await expect(
|
||||
modal.getByText( 'New shipping class' )
|
||||
).toBeVisible();
|
||||
|
||||
await modal
|
||||
.getByLabel( 'Name (Required)' )
|
||||
.fill( productData.shipping.shippingClassName );
|
||||
|
||||
await modal.getByText( 'Add' ).click();
|
||||
|
||||
await expect(
|
||||
modal.getByText( 'New shipping class' )
|
||||
).toBeHidden();
|
||||
|
||||
await expect(
|
||||
page.getByLabel( 'Shipping class', { exact: true } )
|
||||
).toHaveValue( productData.shipping.shippingClassName );
|
||||
|
||||
// Shipping dimensions
|
||||
await page
|
||||
.getByLabel( 'Width A' )
|
||||
.fill( productData.shipping.width );
|
||||
await page
|
||||
.getByLabel( 'Length B' )
|
||||
.fill( productData.shipping.length );
|
||||
await page
|
||||
.getByLabel( 'Height C' )
|
||||
.fill( productData.shipping.height );
|
||||
await page
|
||||
.getByLabel( 'Weight' )
|
||||
.fill( productData.shipping.weight );
|
||||
} );
|
||||
|
||||
await test.step( 'publish the product', async () => {
|
||||
await page
|
||||
.locator( '.woocommerce-product-header__actions' )
|
||||
.getByRole( 'button', {
|
||||
name: 'Publish',
|
||||
} )
|
||||
.click();
|
||||
|
||||
await expect(
|
||||
page.getByLabel( 'Dismiss this notice' )
|
||||
).toContainText( 'Product published' );
|
||||
|
||||
const title = page.locator(
|
||||
'.woocommerce-product-header__title'
|
||||
);
|
||||
|
||||
// Save product ID
|
||||
const productIdRegex = /product%2F(\d+)/;
|
||||
const url = page.url();
|
||||
const productIdMatch = productIdRegex.exec( url );
|
||||
// This isn't really a conditional branch in the test;
|
||||
// just making sure we don't blow up if the regex doesn't match
|
||||
// (it will be caught in the expect below).
|
||||
// eslint-disable-next-line playwright/no-conditional-in-test
|
||||
productId = productIdMatch ? productIdMatch[ 1 ] : null;
|
||||
|
||||
expect( productId ).toBeDefined();
|
||||
await expect( title ).toHaveText( productData.name );
|
||||
} );
|
||||
|
||||
// Note for future refactoring: It would be good to reuse the verification step
|
||||
// from product-create-simple.spec.js, as both tests are just verifying that the
|
||||
// product was created correctly by looking at the front end.
|
||||
await test.step( 'verify the saved product in frontend', async () => {
|
||||
const permalink = await page
|
||||
.locator( '.product-details-section__product-link a' )
|
||||
.getAttribute( 'href' );
|
||||
|
||||
await page.goto( permalink );
|
||||
|
||||
// Verify product name
|
||||
await expect(
|
||||
page.getByRole( 'heading', {
|
||||
name: productData.name,
|
||||
} )
|
||||
).toBeVisible();
|
||||
|
||||
// Verify price
|
||||
await expect(
|
||||
page.getByText( productData.productPrice ).first()
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByText( productData.salePrice ).first()
|
||||
).toBeVisible();
|
||||
|
||||
// Verify summary
|
||||
await expect(
|
||||
page.getByText( productData.summary )
|
||||
).toBeVisible();
|
||||
|
||||
// Verify description
|
||||
await page.getByRole( 'tab', { name: 'Description' } ).click();
|
||||
|
||||
await expect(
|
||||
page.getByText( productData.descriptionTitle )
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByText( productData.descriptionSimple )
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByText( productData.descriptionParagraph )
|
||||
).toBeVisible();
|
||||
|
||||
// Verify inventory details
|
||||
await expect(
|
||||
page.getByText( `SKU: ${ productData.sku }` )
|
||||
).toBeVisible();
|
||||
// Note: GTIN is not displayed in the front end in the theme used in the test
|
||||
|
||||
// Note: Shipping class is not displayed in the front end in the theme used in the test
|
||||
|
||||
// Verify shipping dimensions
|
||||
await page
|
||||
.getByRole( 'tab', { name: 'Additional information' } )
|
||||
.click();
|
||||
|
||||
await expect(
|
||||
page.getByText( `Weight ${ productData.shipping.weight }` )
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByText(
|
||||
`Dimensions ${ productData.shipping.length } × ${ productData.shipping.width } × ${ productData.shipping.height }`
|
||||
)
|
||||
).toBeVisible();
|
||||
} );
|
||||
} );
|
||||
|
||||
test( 'can not create a product with duplicated SKU', async ( {
|
||||
page,
|
||||
} ) => {
|
||||
await page.goto( NEW_EDITOR_ADD_PRODUCT_URL );
|
||||
await clickOnTab( 'General', page );
|
||||
await page
|
||||
.locator( '//input[@placeholder="e.g. 12 oz Coffee Mug"]' )
|
||||
.fill( productData.name );
|
||||
await page
|
||||
.locator(
|
||||
'[data-template-block-id="basic-details"] .components-summary-control'
|
||||
)
|
||||
.fill( productData.summary );
|
||||
await test.step( 'add new product', async () => {
|
||||
await page.goto( NEW_EDITOR_ADD_PRODUCT_URL );
|
||||
} );
|
||||
|
||||
await page
|
||||
.locator(
|
||||
'[id^="wp-block-woocommerce-product-regular-price-field"]'
|
||||
)
|
||||
.first()
|
||||
.fill( productData.productPrice );
|
||||
await page
|
||||
.locator( '.woocommerce-product-header__actions' )
|
||||
.getByRole( 'button', {
|
||||
name: 'Publish',
|
||||
} )
|
||||
.click();
|
||||
await test.step( 'add product name', async () => {
|
||||
await clickOnTab( 'General', page );
|
||||
await page
|
||||
.locator( '//input[@placeholder="e.g. 12 oz Coffee Mug"]' )
|
||||
// Have to use pressSequentially in order for the SKU to be auto-updated
|
||||
// before we move to the SKU field and attempt to fill it in; otherwise,
|
||||
// the SKU field can sometimes end up getting auto-updated after we have filled it in,
|
||||
// wiping out the value we entered.
|
||||
.pressSequentially( productData.name );
|
||||
} );
|
||||
|
||||
await expect(
|
||||
page.locator( '.components-snackbar__content' )
|
||||
).toContainText( 'Invalid or duplicated SKU.' );
|
||||
await test.step( 'add product price', async () => {
|
||||
const regularPrice = page
|
||||
.locator( 'input[name="regular_price"]' )
|
||||
.first();
|
||||
await regularPrice.waitFor( { state: 'visible' } );
|
||||
await regularPrice.click();
|
||||
await regularPrice.fill( productData.productPrice );
|
||||
} );
|
||||
|
||||
await test.step( 'add inventory details', async () => {
|
||||
await clickOnTab( 'Inventory', page );
|
||||
|
||||
await page
|
||||
.getByLabel( 'SKU (Stock Keeping Unit)' )
|
||||
.fill( productData.sku );
|
||||
} );
|
||||
|
||||
await test.step( 'publish the product', async () => {
|
||||
await page
|
||||
.locator( '.woocommerce-product-header__actions' )
|
||||
.getByRole( 'button', {
|
||||
name: 'Publish',
|
||||
} )
|
||||
.click();
|
||||
|
||||
await expect(
|
||||
page.locator( '.components-snackbar__content' )
|
||||
).toContainText( 'Invalid or duplicated SKU.' );
|
||||
} );
|
||||
} );
|
||||
|
||||
// Note for future refactoring: It would be good to reuse the verification step
|
||||
// from product-create-simple.spec.js, as both tests are just verifying that the
|
||||
// product that was created can be added to the cart in the front end.
|
||||
test( 'can a shopper add the simple product to the cart', async ( {
|
||||
page,
|
||||
} ) => {
|
||||
await page.goto( `/?post_type=product&p=${ productId }` );
|
||||
await expect(
|
||||
page.getByRole( 'heading', { name: productData.name } )
|
||||
).toBeVisible();
|
||||
|
||||
await expect
|
||||
.soft(
|
||||
await page
|
||||
.locator( 'del' )
|
||||
.getByText( `$${ productData.productPrice }` )
|
||||
.count()
|
||||
)
|
||||
.toBeGreaterThan( 0 );
|
||||
await expect
|
||||
.soft(
|
||||
await page
|
||||
.locator( 'ins' )
|
||||
.getByText( `$${ productData.salePrice }` )
|
||||
.count()
|
||||
)
|
||||
.toBeGreaterThan( 0 );
|
||||
|
||||
await page.locator( 'button[name="add-to-cart"]' ).click();
|
||||
await page.getByRole( 'link', { name: 'View cart' } ).click();
|
||||
|
|
|
@ -113,7 +113,10 @@ test(
|
|||
.getByRole( 'heading', { name: 'Attributes' } )
|
||||
.isVisible();
|
||||
|
||||
await page.getByRole( 'button', { name: 'Add new' } ).click();
|
||||
await page
|
||||
// Using a selector because there are many "Add new" buttons on the page
|
||||
.locator( '.woocommerce-add-attribute-list-item__add-button' )
|
||||
.click();
|
||||
|
||||
await page
|
||||
.getByRole( 'heading', { name: 'Add variation options' } )
|
||||
|
|
Loading…
Reference in New Issue