diff --git a/plugins/woocommerce-blocks/tests/e2e/bin/posts/product-collection.html b/plugins/woocommerce-blocks/tests/e2e/bin/posts/product-collection.html
new file mode 100644
index 00000000000..fbd80fe8c74
--- /dev/null
+++ b/plugins/woocommerce-blocks/tests/e2e/bin/posts/product-collection.html
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-button/product-button.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-button/product-button.block_theme.side_effects.spec.ts
index 2c13ce636c1..e651e86044b 100644
--- a/plugins/woocommerce-blocks/tests/e2e/tests/product-button/product-button.block_theme.side_effects.spec.ts
+++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-button/product-button.block_theme.side_effects.spec.ts
@@ -24,6 +24,17 @@ test.describe( `${ blockData.name } Block`, () => {
blockData.selectors.frontend.productsToDisplay
);
} );
+
+ test( 'should not enqueue add-to-cart-script', async ( { page } ) => {
+ let isScriptEnqueued = false;
+ page.on( 'request', ( request ) => {
+ if ( request.url().includes( 'add-to-cart.min.js' ) )
+ isScriptEnqueued = true;
+ } );
+ await page.reload();
+ expect( isScriptEnqueued ).toBe( false );
+ } );
+
test( 'should add product to the cart', async ( {
frontendUtils,
page,
@@ -50,7 +61,7 @@ test.describe( `${ blockData.name } Block`, () => {
} );
await block.click();
await expect( block.getByRole( 'button' ) ).toHaveText( '1 in cart' );
- await expect( block.getByRole( 'link' ) ).toBeVisible();
+ await expect( block.getByRole( 'link' ) ).toHaveText( 'View cart' );
await frontendUtils.goToCheckout();
const productElement = page.getByText( productName, {
diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-button/product-button.classic_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-button/product-button.classic_theme.spec.ts
new file mode 100644
index 00000000000..12b70440d53
--- /dev/null
+++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-button/product-button.classic_theme.spec.ts
@@ -0,0 +1,73 @@
+/**
+ * External dependencies
+ */
+import { expect, test as base } from '@woocommerce/e2e-playwright-utils';
+
+/**
+ * Internal dependencies
+ */
+import { blockData } from './utils';
+import ProductCollectionPage from '../product-collection/product-collection.page';
+
+const test = base.extend< { productCollectionPage: ProductCollectionPage } >( {
+ productCollectionPage: async (
+ { page, admin, editor, templateApiUtils, editorUtils },
+ use
+ ) => {
+ const pageObject = new ProductCollectionPage( {
+ page,
+ admin,
+ editor,
+ templateApiUtils,
+ editorUtils,
+ } );
+ await use( pageObject );
+ },
+} );
+test.describe( `${ blockData.name } Block`, () => {
+ test.beforeEach( async ( { page } ) => {
+ await page.goto( '/product-collection/' );
+ } );
+
+ test( 'should be visible', async ( { frontendUtils } ) => {
+ const blocks = await frontendUtils.getBlockByName( blockData.slug );
+ await expect( blocks ).toHaveCount(
+ blockData.selectors.frontend.productsToDisplay
+ );
+ } );
+
+ test( 'should add product to the cart', async ( {
+ frontendUtils,
+ page,
+ } ) => {
+ const blocks = await frontendUtils.getBlockByName( blockData.slug );
+ const block = blocks.first();
+
+ const productId = await block
+ .locator( '[data-product_id]' )
+ .getAttribute( 'data-product_id' );
+
+ const productName = await page
+ .locator( `li.post-${ productId } h3` )
+ .textContent();
+
+ // We want to fail the test if the product name is not found.
+ // eslint-disable-next-line playwright/no-conditional-in-test
+ if ( ! productName ) {
+ return test.fail( ! productName, 'Product name was not found' );
+ }
+
+ await block.locator( 'loading' ).waitFor( {
+ state: 'detached',
+ } );
+ await block.click();
+ await expect( block.getByRole( 'button' ) ).toHaveText( '1 in cart' );
+ await expect( block.getByRole( 'link' ) ).toHaveText( 'View cart' );
+
+ await frontendUtils.goToCheckout();
+ const productElement = page.getByText( productName, {
+ exact: true,
+ } );
+ await expect( productElement ).toBeVisible();
+ } );
+} );
diff --git a/plugins/woocommerce/changelog/43325-43288-product-collection-block-add-to-cart-adds-two-products-to-the-cart b/plugins/woocommerce/changelog/43325-43288-product-collection-block-add-to-cart-adds-two-products-to-the-cart
new file mode 100644
index 00000000000..d4061805109
--- /dev/null
+++ b/plugins/woocommerce/changelog/43325-43288-product-collection-block-add-to-cart-adds-two-products-to-the-cart
@@ -0,0 +1,4 @@
+Significance: minor
+Type: fix
+
+Don't trigger jQuery add to cart function when the button is clicked on classic themes
diff --git a/plugins/woocommerce/client/legacy/js/frontend/add-to-cart.js b/plugins/woocommerce/client/legacy/js/frontend/add-to-cart.js
index e27baf072a4..046b466e037 100644
--- a/plugins/woocommerce/client/legacy/js/frontend/add-to-cart.js
+++ b/plugins/woocommerce/client/legacy/js/frontend/add-to-cart.js
@@ -14,7 +14,7 @@ jQuery( function( $ ) {
this.run = this.run.bind( this );
$( document.body )
- .on( 'click', '.add_to_cart_button', { addToCartHandler: this }, this.onAddToCart )
+ .on( 'click', '.add_to_cart_button:not(.wc-interactive)', { addToCartHandler: this }, this.onAddToCart )
.on( 'click', '.remove_from_cart_button', { addToCartHandler: this }, this.onRemoveFromCart )
.on( 'added_to_cart', this.updateButton )
.on( 'ajax_request_not_sent.adding_to_cart', this.updateButton )
@@ -71,7 +71,7 @@ jQuery( function( $ ) {
$thisbutton.addClass( 'loading' );
// Allow 3rd parties to validate and quit early.
- if ( false === $( document.body ).triggerHandler( 'should_send_ajax_request.adding_to_cart', [ $thisbutton ] ) ) {
+ if ( false === $( document.body ).triggerHandler( 'should_send_ajax_request.adding_to_cart', [ $thisbutton ] ) ) {
$( document.body ).trigger( 'ajax_request_not_sent.adding_to_cart', [ false, false, $thisbutton ] );
return true;
}
@@ -166,7 +166,7 @@ jQuery( function( $ ) {
if ( $button ) {
$button.removeClass( 'loading' );
-
+
if ( fragments ) {
$button.addClass( 'added' );
}
diff --git a/plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php b/plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php
index be627eb3638..77c03b2fd4c 100644
--- a/plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php
+++ b/plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php
@@ -52,8 +52,6 @@ class ProductButton extends AbstractBlock {
'wp_enqueue_scripts',
array( $this, 'dequeue_add_to_cart_scripts' )
);
- } else {
- $this->dequeue_add_to_cart_scripts();
}
}
@@ -216,7 +214,7 @@ class ProductButton extends AbstractBlock {
'{custom_classes}' => esc_attr( $classname . ' ' . $custom_width_classes . ' ' . $custom_align_classes ),
'{html_element}' => $html_element,
'{add_to_cart_url}' => esc_url( $product->add_to_cart_url() ),
- '{button_classes}' => isset( $args['class'] ) ? esc_attr( $args['class'] ) : '',
+ '{button_classes}' => isset( $args['class'] ) ? esc_attr( $args['class'] . ' wc-interactive' ) : 'wc-interactive',
'{button_styles}' => esc_attr( $styles_and_classes['styles'] ),
'{attributes}' => isset( $args['attributes'] ) ? wc_implode_html_attributes( $args['attributes'] ) : '',
'{add_to_cart_text}' => esc_html( $initial_product_text ),