Commit 15e4aebca16 for woocommerce

commit 15e4aebca16585d29f9154fb2435a5eb9624bca4
Author: Luigi Teschio <gigitux@gmail.com>
Date:   Tue Oct 6 10:26:02 2026 +0200

    Restore skipped Cart, Checkout, and Product Collection editor tests (#69397)

    * Restore skipped block editor integration tests

    * Add changelog entries for restored block editor tests

    * remove comment

    * Preserve the original empty cart editor test flow

    * Remove act lint suppressions from Cart editor tests

    * remove comment

    * fix configuration

diff --git a/plugins/woocommerce/changelog/dev-restore-skipped-block-editor-tests b/plugins/woocommerce/changelog/dev-restore-skipped-block-editor-tests
new file mode 100644
index 00000000000..02d667fbb20
--- /dev/null
+++ b/plugins/woocommerce/changelog/dev-restore-skipped-block-editor-tests
@@ -0,0 +1,3 @@
+Significance: patch
+Type: dev
+Comment: Restore Cart, Checkout, and Product Collection editor tests; no production change.
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/editor-integration.tsx b/plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/editor-integration.tsx
index 6bd0953ac54..c228511d4ac 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/editor-integration.tsx
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/editor-integration.tsx
@@ -1,10 +1,15 @@
 /**
  * External dependencies
  */
-import { act, screen, waitFor } from '@testing-library/react';
+import {
+	act,
+	screen,
+	waitFor,
+	getAllByRole,
+	getByLabelText,
+} from '@testing-library/react';
 import { registerCheckoutFilters } from '@woocommerce/blocks-checkout';
 import { type BlockAttributes } from '@wordpress/blocks';
-import { getAllByRole, getByLabelText } from '@testing-library/dom';
 import { userEvent } from '@testing-library/user-event';
 import { previewCart } from '@woocommerce/resource-previews';
 import { dispatch } from '@wordpress/data';
@@ -29,9 +34,12 @@ import '../../product-elements-blocks/title/index';
 import '../../product-template/index.tsx';
 import '../../product-collection/index.tsx';

-async function setup( attributes: BlockAttributes ) {
+async function setup(
+	attributes: BlockAttributes,
+	options: { useSubRegistry?: boolean } = {}
+) {
 	const testBlock = [ { name: 'woocommerce/cart', attributes } ];
-	return initializeEditor( testBlock );
+	return initializeEditor( testBlock, {}, options );
 }

 describe( 'Cart block editor integration', () => {
@@ -65,11 +73,9 @@ describe( 'Cart block editor integration', () => {
 		} );
 	} );

-	// Skipped: wp-6.8's block-editor rendering pipeline no longer renders
-	// inner blocks in Jest's jsdom environment. Gutenberg tests block
-	// rendering via Playwright E2E; these should be migrated similarly.
-	it.skip( 'inner blocks can be added/removed by filters', async () => {
+	it( 'inner blocks can be added/removed by filters', async () => {
 		await setup( {} );
+		await selectBlock( /^Block: Filled Cart$/i );

 		// Verify Cart block is properly initialized in the editor.
 		await waitFor( () => {
@@ -201,12 +207,9 @@ describe( 'Cart block editor integration', () => {
 		} );
 	} );

-	// Skipped: wp-6.8's block-editor rendering pipeline no longer renders
-	// inner blocks in Jest's jsdom environment. Gutenberg tests block
-	// rendering via Playwright E2E; these should be migrated similarly.
-	it.skip( 'can convert to Empty Cart block', async () => {
-		// Setup the cart block with default attributes (filled cart view)
-		await setup( {} );
+	it( 'can convert to Empty Cart block', async () => {
+		// The view switcher uses global data selectors and actions.
+		await setup( {}, { useSubRegistry: false } );

 		// Verify Cart block is properly initialized in the editor
 		expect( screen.getByLabelText( /^Block: Cart$/i ) ).toBeVisible();
@@ -217,9 +220,8 @@ describe( 'Cart block editor integration', () => {
 		const emptyCartBlock = screen.getByLabelText( /Block: Empty Cart/i );

 		expect( filledCartBlock ).toBeVisible();
-		expect( filledCartBlock ).not.toHaveAttribute( 'hidden' );
 		expect( emptyCartBlock ).toBeInTheDocument();
-		expect( emptyCartBlock ).toHaveAttribute( 'hidden' );
+		expect( emptyCartBlock ).not.toBeVisible();

 		await waitFor( () => {
 			expect(
@@ -235,7 +237,7 @@ describe( 'Cart block editor integration', () => {
 			await userEvent.click( selectParentBlockButton );
 		} );

-		const switchViewButton = screen.getByRole( 'button', {
+		let switchViewButton = screen.getByRole( 'button', {
 			name: /Switch view/i,
 		} );

@@ -256,10 +258,13 @@ describe( 'Cart block editor integration', () => {
 		expect(
 			screen.getByLabelText( /^Block: Empty Cart$/i )
 		).toBeInTheDocument();
-		expect( emptyCartBlock ).toHaveAttribute( 'hidden', '' );
-		expect( emptyCartBlock ).toHaveAttribute( 'hidden' );
+		expect( emptyCartBlock ).toBeVisible();
+		expect( filledCartBlock ).not.toBeVisible();

 		// Go back to filled cart
+		switchViewButton = screen.getByRole( 'button', {
+			name: /Switch view/i,
+		} );
 		await act( async () => {
 			await userEvent.click( switchViewButton );
 		} );
@@ -274,7 +279,7 @@ describe( 'Cart block editor integration', () => {
 			await userEvent.click( filledCartButton );
 		} );

-		expect( emptyCartBlock ).toHaveAttribute( 'hidden' );
-		expect( filledCartBlock ).not.toHaveAttribute( 'hidden' );
+		expect( emptyCartBlock ).not.toBeVisible();
+		expect( filledCartBlock ).toBeVisible();
 	} );
 } );
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/checkout/test/editor-integration.tsx b/plugins/woocommerce/client/blocks/assets/js/blocks/checkout/test/editor-integration.tsx
index 749db66c208..c76c64579d7 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/checkout/test/editor-integration.tsx
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/checkout/test/editor-integration.tsx
@@ -1,14 +1,19 @@
 /**
  * External dependencies
  */
-import { act, screen, waitFor } from '@testing-library/react';
+import {
+	act,
+	screen,
+	waitFor,
+	getByLabelText,
+	getByRole,
+} from '@testing-library/react';
 import { registerCheckoutFilters } from '@woocommerce/blocks-checkout';
 import { type BlockAttributes } from '@wordpress/blocks';
-import { getByLabelText, getByRole } from '@testing-library/dom';
 import { userEvent } from '@testing-library/user-event';

 jest.mock( '@wordpress/data', () =>
-	// eslint-disable-next-line @typescript-eslint/no-var-requires -- Must use require due to Jest mock hoisting
+	// eslint-disable-next-line @typescript-eslint/no-require-imports -- Must use require due to Jest mock hoisting
 	require( '@woocommerce/blocks-test-utils/mock-editor-store' ).mockWordPressDataWithEditorStore()
 );

@@ -47,11 +52,9 @@ describe( 'Checkout block editor integration', () => {
 		} );
 	} );

-	// Skipped: wp-6.8's block-editor rendering pipeline no longer renders
-	// inner blocks in Jest's jsdom environment. Gutenberg tests block
-	// rendering via Playwright E2E; these should be migrated similarly.
-	it.skip( 'inner blocks can be added/removed by filters', async () => {
+	it( 'inner blocks can be added/removed by filters', async () => {
 		await setup( {} );
+		await selectBlock( /^Block: Checkout$/i );

 		// Verify Checkout block is properly initialized in the editor.
 		expect( screen.getByLabelText( /^Block: Checkout$/i ) ).toBeVisible();
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/product-collection/test/carousel-layout-adjustments.ts b/plugins/woocommerce/client/blocks/assets/js/blocks/product-collection/test/carousel-layout-adjustments.ts
index 91e033032b9..1b33b1a6970 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/product-collection/test/carousel-layout-adjustments.ts
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/product-collection/test/carousel-layout-adjustments.ts
@@ -17,6 +17,12 @@ import {
 	initializeEditor,
 	selectBlock,
 } from '../../../../../tests/integration/helpers/integration-test-editor';
+import {
+	DEFAULT_QUERY,
+	headingBlockName,
+	INNER_BLOCKS_PAGINATION_TEMPLATE,
+	productTemplateBlockName,
+} from '../constants';
 import { LayoutOptions } from '../types';
 import '../';
 import '../../next-previous-buttons';
@@ -30,7 +36,7 @@ jest.mock( '@woocommerce/block-settings', () => ( {
 type SetupAttributes = {
 	query?: {
 		inherit?: boolean;
-		__woocommerceOnSale?: boolean;
+		woocommerceOnSale?: boolean;
 	};
 };

@@ -45,29 +51,29 @@ async function setup( {
 		name: 'woocommerce/product-collection',
 		attributes: {
 			query: {
-				type: 'product',
+				...DEFAULT_QUERY,
 				...attributes.query,
 			},
 			displayLayout: {
 				type: LayoutOptions.GRID,
 				columns: 3,
 			},
-			...attributes,
 		},
 		innerBlocks: withHeading
 			? [
-					{ name: 'core/heading' },
-					{ name: 'woocommerce/product-template' },
+					[ headingBlockName ],
+					[ productTemplateBlockName ],
+					INNER_BLOCKS_PAGINATION_TEMPLATE,
 			  ]
-			: [ { name: 'woocommerce/product-template' } ],
+			: [
+					[ productTemplateBlockName ],
+					INNER_BLOCKS_PAGINATION_TEMPLATE,
+			  ],
 	};
 	return initializeEditor( [ productCollectionBlock ] );
 }

-// Skipped: wp-6.8's block-editor rendering pipeline no longer renders
-// inner blocks in Jest's jsdom environment. Gutenberg tests block
-// rendering via Playwright E2E; these should be migrated similarly.
-describe.skip( 'Product Collection Block - Carousel Layout Adjustments', () => {
+describe( 'Product Collection Block - Carousel Layout Adjustments', () => {
 	describe( 'On Sale Collection with Heading', () => {
 		it( 'should handle transition to and from carousel layout correctly', async () => {
 			// 1. Add Product Collection in editor with On Sale query
@@ -76,7 +82,7 @@ describe.skip( 'Product Collection Block - Carousel Layout Adjustments', () => {
 				attributes: {
 					query: {
 						inherit: false,
-						__woocommerceOnSale: true,
+						woocommerceOnSale: true,
 					},
 				},
 			} );
@@ -129,10 +135,6 @@ describe.skip( 'Product Collection Block - Carousel Layout Adjustments', () => {
 			} );
 			expect( headingAfterGrid ).toBeInTheDocument();
 			expect( headingAfterGrid.parentElement ).not.toBe( groupBlock );
-
-			// wp-6.8: upstream @wordpress/* deprecation warnings that we cannot
-			// opt out of without changing the visual output.
-			expect( console ).toHaveWarned();
 		} );
 	} );

@@ -197,7 +199,6 @@ describe.skip( 'Product Collection Block - Carousel Layout Adjustments', () => {
 				screen.queryByRole( 'document', { name: /Block: Row/i } )
 			).not.toBeInTheDocument();

-			// Verify pagination is restored
 			expect(
 				screen.getByRole( 'document', {
 					name: /Block: Pagination/i,
diff --git a/plugins/woocommerce/client/blocks/changelog/dev-restore-skipped-block-editor-tests b/plugins/woocommerce/client/blocks/changelog/dev-restore-skipped-block-editor-tests
new file mode 100644
index 00000000000..02d667fbb20
--- /dev/null
+++ b/plugins/woocommerce/client/blocks/changelog/dev-restore-skipped-block-editor-tests
@@ -0,0 +1,3 @@
+Significance: patch
+Type: dev
+Comment: Restore Cart, Checkout, and Product Collection editor tests; no production change.
diff --git a/plugins/woocommerce/client/blocks/tests/integration/helpers/integration-test-editor.tsx b/plugins/woocommerce/client/blocks/tests/integration/helpers/integration-test-editor.tsx
index 4ddc3a2cfa6..014a8c4002f 100644
--- a/plugins/woocommerce/client/blocks/tests/integration/helpers/integration-test-editor.tsx
+++ b/plugins/woocommerce/client/blocks/tests/integration/helpers/integration-test-editor.tsx
@@ -2,6 +2,7 @@
  * External dependencies
  */
 import { useState } from '@wordpress/element';
+// eslint-disable-next-line import/named -- React Testing Library re-exports screen from DOM Testing Library.
 import { act, render, screen, type RenderResult } from '@testing-library/react';
 import userEvent from '@testing-library/user-event';
 import { registerCoreBlocks } from '@wordpress/block-library';
@@ -44,14 +45,17 @@ export async function selectBlock( name: string | RegExp ) {
 export function Editor( {
 	testBlocks,
 	settings = {},
+	useSubRegistry = true,
 }: {
 	testBlocks: BlockInstance< BlockAttributes >[];
 	settings?: Partial< EditorSettings & EditorBlockListSettings >;
+	useSubRegistry?: boolean;
 } ) {
 	const [ currentBlocks, updateBlocks ] = useState( testBlocks );

 	return (
 		<BlockEditorProvider
+			useSubRegistry={ useSubRegistry }
 			value={ currentBlocks }
 			onInput={ updateBlocks }
 			onChange={ updateBlocks }
@@ -68,12 +72,15 @@ let areCoreBlocksRegistered = false;
 /**
  * Registers the core block, creates the test block instances, and then instantiates the Editor.
  *
- * @param testBlocks Block or array of block settings for blocks to be tested.
- * @param settings   Any additional editor settings to be passed to the editor.
+ * @param testBlocks             Block or array of block settings for blocks to be tested.
+ * @param settings               Any additional editor settings to be passed to the editor.
+ * @param options                Options for the editor data registry.
+ * @param options.useSubRegistry Whether to isolate the editor data registry.
  */
 export async function initializeEditor(
 	testBlocks: BlockAttributes | BlockAttributes[],
-	settings: Partial< EditorSettings & EditorBlockListSettings > = {}
+	settings: Partial< EditorSettings & EditorBlockListSettings > = {},
+	options: { useSubRegistry?: boolean } = {}
 ): Promise< RenderResult > {
 	if ( ! areCoreBlocksRegistered ) {
 		registerCoreBlocks();
@@ -93,6 +100,12 @@ export async function initializeEditor(
 		)
 	);
 	return waitForStoreResolvers( () =>
-		render( <Editor testBlocks={ newBlocks } settings={ settings } /> )
+		render(
+			<Editor
+				testBlocks={ newBlocks }
+				settings={ settings }
+				useSubRegistry={ options.useSubRegistry }
+			/>
+		)
 	);
 }
diff --git a/plugins/woocommerce/client/blocks/tests/js/jest.config.js b/plugins/woocommerce/client/blocks/tests/js/jest.config.js
index 21fe0d2b23c..32f92e7d7a4 100644
--- a/plugins/woocommerce/client/blocks/tests/js/jest.config.js
+++ b/plugins/woocommerce/client/blocks/tests/js/jest.config.js
@@ -19,6 +19,7 @@ const singletonWpModules = [
 	'@wordpress/core-data',
 	'@wordpress/data',
 	'@wordpress/editor',
+	'@wordpress/hooks',
 	'@wordpress/html-entities',
 	'@wordpress/keyboard-shortcuts',
 	'@wordpress/patterns',