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 results found

+ + + +

You can try clearing any filters or head to our store's home

+ +
+ + +
+ \ 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 ),