Commit da78473f05 for woocommerce
commit da78473f050d6a26284a2a37c92d8033bb50d584
Author: Luigi Teschio <gigitux@gmail.com>
Date: Thu May 29 15:01:07 2025 +0200
Blocks: Remove multiple div wrappers (#58081)
* Refactor ProductPicker component avoid not necessary re-rendering removing useBlockProps
* fix lint errors
* Add changefile(s) from automation for the following project(s): woocommerce
* fix E2E test
* fix lint error
* fix E2E test
* fix Product Collection wrapper
* Add changefile(s) from automation for the following project(s): woocommerce
* fix lint errors
* Add changefile(s) from automation for the following project(s): woocommerce
* remove old changelog
* remove not necessary check
---------
Co-authored-by: github-actions <github-actions@github.com>
diff --git a/plugins/woocommerce/changelog/58081-fix-wooplug-2976-product-collection-cross-sells-product-selection-error-when b/plugins/woocommerce/changelog/58081-fix-wooplug-2976-product-collection-cross-sells-product-selection-error-when
new file mode 100644
index 0000000000..22d3dbeb1c
--- /dev/null
+++ b/plugins/woocommerce/changelog/58081-fix-wooplug-2976-product-collection-cross-sells-product-selection-error-when
@@ -0,0 +1,4 @@
+Significance: minor
+Type: fix
+
+Blocks: Remove multiple div wrappers
\ No newline at end of file
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/product-collection/edit/ProductPicker.tsx b/plugins/woocommerce/client/blocks/assets/js/blocks/product-collection/edit/ProductPicker.tsx
index 927d3d31ab..e04e48741a 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/product-collection/edit/ProductPicker.tsx
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/product-collection/edit/ProductPicker.tsx
@@ -2,18 +2,16 @@
* External dependencies
*/
import { __, sprintf } from '@wordpress/i18n';
-import { useBlockProps } from '@wordpress/block-editor';
import { Icon, info } from '@wordpress/icons';
import ProductControl from '@woocommerce/editor-components/product-control';
import type { SelectedOption } from '@woocommerce/block-hocs';
import { createInterpolateElement } from '@wordpress/element';
import {
Placeholder,
- // @ts-expect-error Using experimental features
__experimentalHStack as HStack,
- // @ts-expect-error Using experimental features
__experimentalText as Text,
} from '@wordpress/components';
+import { useBlockProps } from '@wordpress/block-editor';
/**
* Internal dependencies
@@ -26,9 +24,10 @@ const ProductPicker = (
isDeletedProductReference: boolean;
}
) => {
- const blockProps = useBlockProps();
const { attributes, isDeletedProductReference } = props;
+ const blockProps = useBlockProps();
+
const collection = getCollectionByName( attributes.collection );
if ( ! collection ) {
return null;
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/product-collection/edit/inspector-controls/index.tsx b/plugins/woocommerce/client/blocks/assets/js/blocks/product-collection/edit/inspector-controls/index.tsx
index ca5409d141..d665e29585 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/product-collection/edit/inspector-controls/index.tsx
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/product-collection/edit/inspector-controls/index.tsx
@@ -349,7 +349,7 @@ const CollectionSpecificControls = (
const withCollectionSpecificControls =
< T extends EditorBlock< T > >( BlockEdit: ElementType ) =>
( props: ProductCollectionEditComponentProps ) => {
- if ( ! isProductCollection( props.name ) || ! props.isSelected ) {
+ if ( ! isProductCollection( props.name ) ) {
return <BlockEdit { ...props } />;
}
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/product-collection/edit/product-collection-content.tsx b/plugins/woocommerce/client/blocks/assets/js/blocks/product-collection/edit/product-collection-content.tsx
index 7ef304bc31..d242689078 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/product-collection/edit/product-collection-content.tsx
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/product-collection/edit/product-collection-content.tsx
@@ -88,9 +88,12 @@ const ProductCollectionContent = ( {
} );
const blockProps = useBlockProps();
- const innerBlocksProps = useInnerBlocksProps( blockProps, {
- template: INNER_BLOCKS_TEMPLATE,
- } );
+ const innerBlocksProps = useInnerBlocksProps(
+ {},
+ {
+ template: INNER_BLOCKS_TEMPLATE,
+ }
+ );
const queryId = useQueryId(
clientId,
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/reviews/editor-container-block.tsx b/plugins/woocommerce/client/blocks/assets/js/blocks/reviews/editor-container-block.tsx
index 0c1329bc02..384a9f5252 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/reviews/editor-container-block.tsx
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/reviews/editor-container-block.tsx
@@ -4,14 +4,13 @@
import { __ } from '@wordpress/i18n';
import { debounce } from '@woocommerce/base-utils';
import { Placeholder } from '@wordpress/components';
-import { useBlockProps } from '@wordpress/block-editor';
import { EditorContainerBlockProps } from '@woocommerce/blocks/reviews/types';
/**
* Internal dependencies
*/
import EditorBlock from './editor-block';
-import { getBlockClassName, getSortArgs } from './utils.js';
+import { getSortArgs } from './utils.js';
const EditorContainerBlock = ( {
attributes,
@@ -39,10 +38,6 @@ const EditorContainerBlock = ( {
! showReviewImage &&
! showProductName;
- const blockProps = useBlockProps( {
- className: getBlockClassName( attributes ),
- } );
-
if ( isAllContentHidden ) {
return (
<Placeholder icon={ icon } label={ name }>
@@ -55,7 +50,7 @@ const EditorContainerBlock = ( {
}
return (
- <div { ...blockProps }>
+ <>
<EditorBlock
attributes={ attributes }
categoryIds={ categoryIds }
@@ -68,7 +63,7 @@ const EditorContainerBlock = ( {
productId={ productId }
reviewsToDisplay={ reviewsOnPageLoad }
/>
- </div>
+ </>
);
};
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/reviews/reviews-by-product/edit.tsx b/plugins/woocommerce/client/blocks/assets/js/blocks/reviews/reviews-by-product/edit.tsx
index 4afd650603..c423479ab0 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/reviews/reviews-by-product/edit.tsx
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/reviews/reviews-by-product/edit.tsx
@@ -2,7 +2,7 @@
* External dependencies
*/
import { __, _n, sprintf } from '@wordpress/i18n';
-import { InspectorControls } from '@wordpress/block-editor';
+import { InspectorControls, useBlockProps } from '@wordpress/block-editor';
import {
Button,
PanelBody,
@@ -33,6 +33,8 @@ const ReviewsByProductEditor = ( {
}: ReviewsByProductEditorProps ) => {
const { editMode, productId } = attributes;
+ const blockProps = useBlockProps();
+
const renderProductControlItem = ( args ) => {
const { item = 0 } = args;
@@ -149,7 +151,7 @@ const ReviewsByProductEditor = ( {
const buttonTitle = __( 'Edit selected product', 'woocommerce' );
return (
- <>
+ <div { ...blockProps }>
{ getBlockControls( editMode, setAttributes, buttonTitle ) }
{ getInspectorControls() }
<EditorContainerBlock
@@ -163,7 +165,7 @@ const ReviewsByProductEditor = ( {
name={ __( 'Reviews by Product', 'woocommerce' ) }
noReviewsPlaceholder={ NoReviewsPlaceholder }
/>
- </>
+ </div>
);
};
diff --git a/plugins/woocommerce/client/blocks/tests/e2e/tests/product-collection/register-product-collection.block_theme.spec.ts b/plugins/woocommerce/client/blocks/tests/e2e/tests/product-collection/register-product-collection.block_theme.spec.ts
index fd454ae3de..9c10e17a9c 100644
--- a/plugins/woocommerce/client/blocks/tests/e2e/tests/product-collection/register-product-collection.block_theme.spec.ts
+++ b/plugins/woocommerce/client/blocks/tests/e2e/tests/product-collection/register-product-collection.block_theme.spec.ts
@@ -242,8 +242,7 @@ test.describe( 'Product Collection: Register Product Collection', () => {
.locator( 'visible=true' );
await expect( products ).toHaveCount( 9 );
- // Check if the preview button is visible
- const previewButtonLocator = block.getByTestId(
+ const previewButtonLocator = editor.canvas.getByTestId(
SELECTORS.previewButtonTestID
);
await expect( previewButtonLocator ).toBeVisible();
@@ -305,10 +304,10 @@ test.describe( 'Product Collection: Register Product Collection', () => {
.label
);
- // Check if the preview button is visible
- const previewButtonLocator = block.getByTestId(
+ const previewButtonLocator = editor.canvas.getByTestId(
SELECTORS.previewButtonTestID
);
+
await expect( previewButtonLocator ).toBeVisible();
// Check if products are visible
@@ -375,8 +374,8 @@ test.describe( 'Product Collection: Register Product Collection', () => {
collection.id as Collections
);
- const block = editor.canvas.getByLabel( collection.label );
- const previewButtonLocator = block.getByTestId(
+ // Check if the preview button is visible
+ const previewButtonLocator = editor.canvas.getByTestId(
SELECTORS.previewButtonTestID
);
@@ -392,8 +391,7 @@ test.describe( 'Product Collection: Register Product Collection', () => {
collection.id as Collections
);
- const block = editor.canvas.getByLabel( collection.label );
- const previewButtonLocator = block.getByTestId(
+ const previewButtonLocator = editor.canvas.getByTestId(
SELECTORS.previewButtonTestID
);
@@ -408,8 +406,7 @@ test.describe( 'Product Collection: Register Product Collection', () => {
collection.id as Collections
);
- const block = editor.canvas.getByLabel( collection.label );
- const previewButtonLocator = block.getByTestId(
+ const previewButtonLocator = editor.canvas.getByTestId(
SELECTORS.previewButtonTestID
);
@@ -565,8 +562,7 @@ test.describe( 'Product Collection: Register Product Collection', () => {
collection.id as Collections
);
- const block = editor.canvas.getByLabel( collection.label );
- const previewButtonLocator = block.getByTestId(
+ const previewButtonLocator = editor.canvas.getByTestId(
SELECTORS.previewButtonTestID
);
@@ -604,8 +600,7 @@ test.describe( 'Product Collection: Register Product Collection', () => {
await expect( editorProductPicker ).toBeHidden();
// Check visibility of preview label
- const block = editor.canvas.getByLabel( collection.label );
- const previewButtonLocator = block.getByTestId(
+ const previewButtonLocator = editor.canvas.getByTestId(
SELECTORS.previewButtonTestID
);
@@ -620,8 +615,7 @@ test.describe( 'Product Collection: Register Product Collection', () => {
collection.id as Collections
);
- const block = editor.canvas.getByLabel( collection.label );
- const previewButtonLocator = block.getByTestId(
+ const previewButtonLocator = editor.canvas.getByTestId(
SELECTORS.previewButtonTestID
);
diff --git a/plugins/woocommerce/tests/e2e-pw/tests/editor/create-woocommerce-blocks.spec.js b/plugins/woocommerce/tests/e2e-pw/tests/editor/create-woocommerce-blocks.spec.js
index a23d762c3c..8441f4e058 100644
--- a/plugins/woocommerce/tests/e2e-pw/tests/editor/create-woocommerce-blocks.spec.js
+++ b/plugins/woocommerce/tests/e2e-pw/tests/editor/create-woocommerce-blocks.spec.js
@@ -24,27 +24,117 @@ const singleProductPrice = '555.00';
// All WooCommerce blocks except:
// - default cart and checkout blocks, mini-cart
// - Product Gallery (Beta) - it's not intended to be used in posts
-const blocks = [
- 'All Reviews',
- 'Best Sellers',
- 'Cross-Sells',
- 'Customer account',
- 'Featured Category',
- 'Featured Product',
- 'Featured Products',
- 'Hand-Picked Products',
- 'New Arrivals',
- 'On Sale Products',
- 'Product Categories List',
- 'Product Collection',
- 'Product Search',
- 'Reviews by Category',
- 'Reviews by Product',
- 'Single Product',
- 'Store Notices',
- 'Top Rated Products',
- 'Upsells',
-];
+
+/**
+ * The key of the object is the block name
+ * The value is custom function to check the block
+ * If the value is null, there is a default check for the block
+ */
+const blocks = {
+ 'All Reviews': null,
+ 'Best Sellers': null,
+ 'Cross-Sells': async ( canvas ) => {
+ await canvas
+ .getByRole( 'listitem' )
+ .filter( { hasText: /^Simplest Product$/ } )
+ .click();
+ await expect(
+ canvas
+ .getByRole( 'document', {
+ name: `Block: Cross-Sells`,
+ exact: true,
+ } )
+ .first()
+ ).toBeVisible();
+ },
+ 'Customer account': null,
+ 'Featured Category': async ( canvas ) => {
+ await canvas
+ .getByRole( 'listitem' )
+ .filter( { hasText: 'simple category' } )
+ .click();
+
+ await canvas.getByRole( 'button', { name: 'Done' } ).click();
+
+ await expect(
+ canvas.getByRole( 'document', { name: `Block: Featured Category` } )
+ ).toBeVisible();
+ },
+ 'Featured Product': async ( canvas ) => {
+ await canvas
+ .getByRole( 'listitem' )
+ .filter( { hasText: /^Simplest Product$/ } )
+ .click();
+
+ await canvas.getByRole( 'button', { name: 'Done' } ).click();
+
+ await expect(
+ canvas.getByRole( 'document', { name: `Block: Featured Product` } )
+ ).toBeVisible();
+ },
+ 'Featured Products': null,
+ 'Hand-Picked Products': null,
+ 'New Arrivals': null,
+ 'On Sale Products': null,
+ 'Product Categories List': null,
+ 'Product Collection': null,
+ 'Product Search': null,
+ 'Reviews by Category': async ( canvas ) => {
+ const block = canvas.getByRole( 'document', {
+ name: `Block: Reviews by Category`,
+ } );
+
+ await block.filter( { hasText: 'simple category' } ).click();
+ await canvas.getByRole( 'button', { name: 'Done' } ).click();
+
+ await expect( block ).toBeVisible();
+ },
+ 'Reviews by Product': async ( canvas ) => {
+ await canvas
+ .locator( '.wc-block-reviews-by-product' )
+ .getByLabel( simpleProductName )
+ .click();
+ await canvas
+ .locator( '.wc-block-reviews-by-product' )
+ .getByRole( 'button', {
+ name: 'Done',
+ exact: true,
+ } )
+ .click();
+
+ // verify added blocks into page
+ await expect(
+ canvas.getByRole( 'document', {
+ name: `Block: Reviews by Product`,
+ exact: true,
+ } )
+ ).toBeVisible();
+ },
+ 'Single Product': async ( canvas ) => {
+ await canvas
+ .getByRole( 'listitem' )
+ .filter( { hasText: /^Simplest Product$/ } )
+ .click();
+
+ await canvas.getByRole( 'button', { name: 'Done' } ).click();
+
+ await expect(
+ canvas.getByRole( 'document', { name: `Block: Single Product` } )
+ ).toBeVisible();
+ },
+ 'Store Notices': null,
+ 'Top Rated Products': null,
+ Upsells: async ( canvas ) => {
+ await canvas
+ .getByRole( 'listitem' )
+ .filter( { hasText: /^Simplest Product$/ } )
+ .click();
+
+ await expect(
+ canvas.getByRole( 'document', { name: `Block: Upsells` } )
+ ).toBeVisible();
+ },
+};
let productId, shippingZoneId, productTagId, attributeId, productCategoryId;
@@ -168,39 +258,23 @@ test.describe(
const wordPressVersion = await getInstalledWordPressVersion();
- for ( let i = 0; i < blocks.length; i++ ) {
- await test.step( `Insert ${ blocks[ i ] } block`, async () => {
- await insertBlock( page, blocks[ i ], wordPressVersion );
+ for ( const [ blockName, check ] of Object.entries( blocks ) ) {
+ await test.step( `Insert ${ blockName } block`, async () => {
+ await insertBlock( page, blockName, wordPressVersion );
const canvas = await getCanvas( page );
// eslint-disable-next-line playwright/no-conditional-in-test
- if ( blocks[ i ] === 'Reviews by Product' ) {
- // Use click() instead of check().
- // check() causes occasional flakiness:
- // - "Error: locator.check: Clicking the checkbox did not change its state"
- await canvas
- .locator( '.wc-block-reviews-by-product' )
- .getByLabel( simpleProductName )
- .click();
- await canvas
- .locator( '.wc-block-reviews-by-product' )
- .getByRole( 'button', {
- name: 'Done',
- exact: true,
- } )
- .click();
- // Click on the Reviews by Product block to show the Block Tools to be used later.
- await canvas
- .getByLabel( 'Block: Reviews by Product' )
- .click();
+ if ( check ) {
+ await check( canvas );
+ return;
}
// verify added blocks into page
await expect(
canvas
.getByRole( 'document', {
- name: `Block: ${ blocks[ i ] }`,
+ name: `Block: ${ blockName }`,
exact: true,
} )
.first()
@@ -220,12 +294,12 @@ test.describe(
// check all blocks inside the page after publishing
// except the product price due to invisibility and false-positive
const canvas = await getCanvas( page );
- for ( let i = 1; i < blocks.length; i++ ) {
+ for ( const [ blockName ] of Object.entries( blocks ) ) {
// verify added blocks into page
await expect(
canvas
.getByRole( 'document', {
- name: `Block: ${ blocks[ i ] }`,
+ name: `Block: ${ blockName }`,
exact: true,
} )
.first()