diff --git a/assets/js/src/utils/index.js b/assets/js/src/utils/index.js index dc314b00..789c209c 100644 --- a/assets/js/src/utils/index.js +++ b/assets/js/src/utils/index.js @@ -178,7 +178,7 @@ const formatCategoryKey = ( index ) => { */ export const getProductFromID = ( search, products, cart ) => { return ( - cart?.items?.find( ( { id } ) => id === search ) ?? - products?.find( ( { id } ) => id === search ) + products?.find( ( { id } ) => id === search ) ?? + cart?.items?.find( ( { id } ) => id === search ) ); }; diff --git a/includes/class-wc-abstract-google-analytics-js.php b/includes/class-wc-abstract-google-analytics-js.php index 38844cf7..902c408e 100644 --- a/includes/class-wc-abstract-google-analytics-js.php +++ b/includes/class-wc-abstract-google-analytics-js.php @@ -80,7 +80,7 @@ function () { add_action( 'woocommerce_add_to_cart', function ( $cart_item_key, $product_id, $quantity, $variation_id, $variation ) { - $this->set_script_data( 'added_to_cart', $this->get_formatted_product( wc_get_product( $product_id ), $variation_id, $variation ) ); + $this->set_script_data( 'added_to_cart', $this->get_formatted_product( wc_get_product( $product_id ), $variation_id, $variation, $quantity ) ); }, 10, 5 @@ -208,10 +208,11 @@ function ( $item ) { * @param int $variation_id Variation product ID. * @param array|bool $variation An array containing product variation attributes to include in the product data. * For the "variation" type products, we'll use product->get_attributes. + * @param bool|int $quantity Quantity to include in the formatted product object * * @return array */ - public function get_formatted_product( WC_Product $product, $variation_id = 0, $variation = false ): array { + public function get_formatted_product( WC_Product $product, $variation_id = 0, $variation = false, $quantity = false ): array { $product_id = $product->is_type( 'variation' ) ? $product->get_parent_id() : $product->get_id(); $price = $product->get_price(); @@ -241,6 +242,10 @@ public function get_formatted_product( WC_Product $product, $variation_id = 0, $ ), ); + if ( $quantity ) { + $formatted['quantity'] = (int) $quantity; + } + if ( $product->is_type( 'variation' ) ) { $variation = $product->get_attributes(); } diff --git a/tests/e2e/specs/gtag-events/blocks-pages.test.js b/tests/e2e/specs/gtag-events/blocks-pages.test.js index 404f6c87..5ba2213d 100644 --- a/tests/e2e/specs/gtag-events/blocks-pages.test.js +++ b/tests/e2e/specs/gtag-events/blocks-pages.test.js @@ -225,6 +225,41 @@ test.describe( 'GTag events on block pages', () => { } ); } ); + test( 'Add to cart has correct quantity when product is already in cart', async ( { + page, + } ) => { + const addToCart = `[data-product_id="${ simpleProductID }"]`; + + await createProductsBlockShopPage(); + await page.goto( `products-block-shop` ); + + const addToCartButton = await page.locator( addToCart ).first(); + + await addToCartButton.click(); + await expect( addToCartButton.getByText( '1 in cart' ) ).toBeVisible(); + await addToCartButton.click(); + await expect( addToCartButton.getByText( '2 in cart' ) ).toBeVisible(); + + await page.reload(); + + const event = trackGtagEvent( page, 'add_to_cart' ); + + const addToCartButton2 = await page.locator( addToCart ).first(); + await addToCartButton2.click(); + await expect( addToCartButton.getByText( '3 in cart' ) ).toBeVisible(); + + await event.then( ( request ) => { + const data = getEventData( request, 'add_to_cart' ); + expect( data.product1 ).toEqual( { + id: simpleProductID.toString(), + nm: 'Simple product', + ca: 'Uncategorized', + qt: '1', + pr: simpleProductPrice.toString(), + } ); + } ); + } ); + test( 'View item list event is sent from the products block shop page', async ( { page, } ) => { diff --git a/tests/e2e/specs/gtag-events/classic-pages.test.js b/tests/e2e/specs/gtag-events/classic-pages.test.js index c1bc2f93..fcfb0add 100644 --- a/tests/e2e/specs/gtag-events/classic-pages.test.js +++ b/tests/e2e/specs/gtag-events/classic-pages.test.js @@ -74,6 +74,32 @@ test.describe( 'GTag events on classic pages', () => { } ); } ); + test( 'Add to cart quantity is sent on a single product page', async ( { + page, + } ) => { + const event = trackGtagEvent( page, 'add_to_cart' ); + + await page.goto( `?p=${ simpleProductID }` ); + + await page.locator( '.quantity input.qty' ).first().fill( '3' ); + + const addToCart = `.single_add_to_cart_button[value="${ simpleProductID }"]`; + const addToCartButton = await page.locator( addToCart ).first(); + + await addToCartButton.click(); + + await event.then( ( request ) => { + const data = getEventData( request, 'add_to_cart' ); + expect( data.product1 ).toEqual( { + id: simpleProductID.toString(), + nm: 'Simple product', + ca: 'Uncategorized', + qt: '3', + pr: simpleProductPrice.toString(), + } ); + } ); + } ); + test( 'Add to cart event is sent on the home page when adding product through URL', async ( { page, } ) => {