From 03193d2b5dfadc00bd7fd3df04cacf05c63367f7 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Fri, 18 Aug 2023 14:38:05 +0200 Subject: [PATCH 1/9] Add initial look of Full Grid Product Collection pattern --- patterns/product-collection-full-grid.php | 34 +++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 patterns/product-collection-full-grid.php diff --git a/patterns/product-collection-full-grid.php b/patterns/product-collection-full-grid.php new file mode 100644 index 00000000000..29e3f5151b4 --- /dev/null +++ b/patterns/product-collection-full-grid.php @@ -0,0 +1,34 @@ + + + +
+ + + + + + + + + + + + + + + + + + + +

+ +
+ From b508cc6c67f9dc9bb546f7ba1a515a10ae57e0eb Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Fri, 18 Aug 2023 15:32:57 +0200 Subject: [PATCH 2/9] Refactor textAlign property of Product Button so it uses flex rather than text-align --- .../blocks/product-elements/button/block.tsx | 36 +------------------ .../blocks/product-elements/button/style.scss | 8 +++++ src/BlockTypes/ProductButton.php | 20 +++++------ 3 files changed, 19 insertions(+), 45 deletions(-) diff --git a/assets/js/atomic/blocks/product-elements/button/block.tsx b/assets/js/atomic/blocks/product-elements/button/block.tsx index c3ed224b08f..2199c1e3613 100644 --- a/assets/js/atomic/blocks/product-elements/button/block.tsx +++ b/assets/js/atomic/blocks/product-elements/button/block.tsx @@ -27,22 +27,10 @@ import type { AddToCartButtonPlaceholderAttributes, } from './types'; -/** - * Product Button Block Component. - * - * @param {Object} props Incoming props. - * @param {Object} [props.product] Product. - * @param {Object} [props.style] Object contains CSS Styles. - * @param {string} [props.className] String contains CSS class. - * @param {Object} [props.textAlign] Text alignment. - * - * @return {*} The component. - */ const AddToCartButton = ( { product, className, style, - textAlign, }: AddToCartButtonAttributes ): JSX.Element => { const { id, @@ -117,9 +105,6 @@ const AddToCartButton = ( { { loading: addingToCart, added: addedToCart, - }, - { - [ `has-text-align-${ textAlign }` ]: textAlign, } ) } style={ style } @@ -129,15 +114,6 @@ const AddToCartButton = ( { ); }; -/** - * Product Button Block Component. - * - * @param {Object} props Incoming props. - * @param {Object} [props.style] Object contains CSS Styles. - * @param {string} [props.className] String contains CSS class. - * - * @return {*} The component. - */ const AddToCartButtonPlaceholder = ( { className, style, @@ -158,14 +134,6 @@ const AddToCartButtonPlaceholder = ( { ); }; -/** - * Product Button Block Component. - * - * @param {Object} props Incoming props. - * @param {string} [props.className] CSS Class name for the component. - * @param {string} [props.textAlign] Text alignment. - * @return {*} The component. - */ export const Block = ( props: BlockAttributes ): JSX.Element => { const { className, textAlign } = props; const styleProps = useStyleProps( props ); @@ -181,9 +149,7 @@ export const Block = ( props: BlockAttributes ): JSX.Element => { { [ `${ parentClassName }__product-add-to-cart` ]: parentClassName, - }, - { - [ `has-text-align-${ textAlign }` ]: textAlign, + [ `align-${ textAlign }` ]: textAlign, } ) } > diff --git a/assets/js/atomic/blocks/product-elements/button/style.scss b/assets/js/atomic/blocks/product-elements/button/style.scss index 6bcdaaf834d..1f63c4354f7 100644 --- a/assets/js/atomic/blocks/product-elements/button/style.scss +++ b/assets/js/atomic/blocks/product-elements/button/style.scss @@ -55,6 +55,14 @@ } } + &.align-left { + justify-content: left; + } + + &.align-right { + justify-content: right; + } + .wc-block-components-product-button__button { border-style: none; display: inline-flex; diff --git a/src/BlockTypes/ProductButton.php b/src/BlockTypes/ProductButton.php index 6bd773a5912..737895f62cb 100644 --- a/src/BlockTypes/ProductButton.php +++ b/src/BlockTypes/ProductButton.php @@ -84,15 +84,15 @@ protected function render( $attributes, $content, $block ) { __( '%s in cart', 'woo-gutenberg-products-block' ), $number_of_items_in_cart ) : $product->add_to_cart_text(); - $cart_redirect_after_add = get_option( 'woocommerce_cart_redirect_after_add' ) === 'yes'; - $ajax_add_to_cart_enabled = get_option( 'woocommerce_enable_ajax_add_to_cart' ) === 'yes'; - $is_ajax_button = $ajax_add_to_cart_enabled && ! $cart_redirect_after_add && $product->supports( 'ajax_add_to_cart' ) && $product->is_purchasable() && $product->is_in_stock(); - $html_element = $is_ajax_button ? 'button' : 'a'; - $styles_and_classes = StyleAttributesUtils::get_classes_and_styles_by_attributes( $attributes ); - $text_align_styles_and_classes = StyleAttributesUtils::get_text_align_class_and_style( $attributes ); - $classname = $attributes['className'] ?? ''; - $custom_width_classes = isset( $attributes['width'] ) ? 'has-custom-width wp-block-button__width-' . $attributes['width'] : ''; - $html_classes = implode( + $cart_redirect_after_add = get_option( 'woocommerce_cart_redirect_after_add' ) === 'yes'; + $ajax_add_to_cart_enabled = get_option( 'woocommerce_enable_ajax_add_to_cart' ) === 'yes'; + $is_ajax_button = $ajax_add_to_cart_enabled && ! $cart_redirect_after_add && $product->supports( 'ajax_add_to_cart' ) && $product->is_purchasable() && $product->is_in_stock(); + $html_element = $is_ajax_button ? 'button' : 'a'; + $styles_and_classes = StyleAttributesUtils::get_classes_and_styles_by_attributes( $attributes ); + $classname = $attributes['className'] ?? ''; + $custom_width_classes = isset( $attributes['width'] ) ? 'has-custom-width wp-block-button__width-' . $attributes['width'] : ''; + $custom_align_classes = isset( $attributes['textAlign'] ) ? 'align-' . $attributes['textAlign'] : ''; + $html_classes = implode( ' ', array_filter( array( @@ -208,7 +208,7 @@ class="{button_classes}" ', array( '{classes}' => esc_attr( $text_align_styles_and_classes['class'] ?? '' ), - '{custom_classes}' => esc_attr( $classname . ' ' . $custom_width_classes ), + '{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'] ) : '', From e163e48003d8d273d0a8d30e67587cf988fe44db Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Fri, 18 Aug 2023 15:34:30 +0200 Subject: [PATCH 3/9] Update Product Button text align after the fix --- patterns/product-collection-full-grid.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patterns/product-collection-full-grid.php b/patterns/product-collection-full-grid.php index 29e3f5151b4..a30d5649c83 100644 --- a/patterns/product-collection-full-grid.php +++ b/patterns/product-collection-full-grid.php @@ -15,7 +15,7 @@ - + From 2c9c9788676ad95bdc54e37291c81f955e1ba5a3 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 24 Aug 2023 09:29:50 +0200 Subject: [PATCH 4/9] Remove debug log (#10719) --- assets/js/interactivity/index.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/assets/js/interactivity/index.js b/assets/js/interactivity/index.js index 00008625110..9cfeac7be27 100644 --- a/assets/js/interactivity/index.js +++ b/assets/js/interactivity/index.js @@ -12,6 +12,4 @@ document.addEventListener( 'DOMContentLoaded', async () => { registerDirectives(); await init(); afterLoads.forEach( ( afterLoad ) => afterLoad( rawStore ) ); - // eslint-disable-next-line no-console - console.log( 'Interactivity API started' ); } ); From 3af096fbfd3a5c7f48bffe7445b2cb5fef56b20f Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 24 Aug 2023 09:59:08 +0200 Subject: [PATCH 5/9] Add Product Collection Grid pattern (#10660) --- patterns/product-collection-grid.php | 32 ++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 patterns/product-collection-grid.php diff --git a/patterns/product-collection-grid.php b/patterns/product-collection-grid.php new file mode 100644 index 00000000000..b15fc6c8bca --- /dev/null +++ b/patterns/product-collection-grid.php @@ -0,0 +1,32 @@ + + + +
+ + + + + + + + + + + + + + + + + +

+ +
+ From c9e79283c2b556b5ac32e957587d023ad6ba3157 Mon Sep 17 00:00:00 2001 From: Thomas Roberts <5656702+opr@users.noreply.github.com> Date: Thu, 24 Aug 2023 09:37:14 +0100 Subject: [PATCH 6/9] Dispatch the `wc-blocks_render_blocks_frontend` event when rendering the empty cart block (#10619) --- .../blocks/cart/inner-blocks/empty-cart-block/frontend.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/assets/js/blocks/cart/inner-blocks/empty-cart-block/frontend.tsx b/assets/js/blocks/cart/inner-blocks/empty-cart-block/frontend.tsx index e92c59769a5..b75d4972473 100644 --- a/assets/js/blocks/cart/inner-blocks/empty-cart-block/frontend.tsx +++ b/assets/js/blocks/cart/inner-blocks/empty-cart-block/frontend.tsx @@ -19,12 +19,15 @@ const FrontendBlock = ( { } ): JSX.Element | null => { const { cartItems, cartIsLoading } = useStoreCart(); useEffect( () => { + if ( cartItems.length !== 0 || cartIsLoading ) { + return; + } dispatchEvent( 'wc-blocks_render_blocks_frontend', { element: document.body.querySelector( '.wp-block-woocommerce-cart' ), } ); - }, [] ); + }, [ cartIsLoading, cartItems ] ); if ( ! cartIsLoading && cartItems.length === 0 ) { return
{ children }
; } From 5852c45c59854514fc9aa3ef4cf415926e0f66cd Mon Sep 17 00:00:00 2001 From: Tung Du Date: Thu, 24 Aug 2023 20:33:20 +0700 Subject: [PATCH 7/9] E2E: Refactor Mini Cart to be ready for fully parallel (#10704) --- tests/e2e/bin/posts/mini-cart.html | 4 + .../mini-cart/mini-cart.block_theme.spec.ts | 179 ++++++------------ ...ct-gallery-large-image.block_theme.spec.ts | 2 +- 3 files changed, 68 insertions(+), 117 deletions(-) rename tests/{e2e-pw => e2e}/tests/product-gallery/inner-blocks/product-gallery-large-image/product-gallery-large-image.block_theme.spec.ts (98%) diff --git a/tests/e2e/bin/posts/mini-cart.html b/tests/e2e/bin/posts/mini-cart.html index 03d808aa790..8f2ba8a14eb 100644 --- a/tests/e2e/bin/posts/mini-cart.html +++ b/tests/e2e/bin/posts/mini-cart.html @@ -1 +1,5 @@ + + +
+ diff --git a/tests/e2e/tests/mini-cart/mini-cart.block_theme.spec.ts b/tests/e2e/tests/mini-cart/mini-cart.block_theme.spec.ts index df57b7e8b27..a321d00cb9f 100644 --- a/tests/e2e/tests/mini-cart/mini-cart.block_theme.spec.ts +++ b/tests/e2e/tests/mini-cart/mini-cart.block_theme.spec.ts @@ -1,132 +1,79 @@ /** * External dependencies */ -import { BlockData } from '@woocommerce/e2e-types'; import { test, expect } from '@woocommerce/e2e-playwright-utils'; +import { Page } from '@playwright/test'; -const blockData: BlockData = { - name: 'woocommerce/mini-cart', - mainClass: '.wc-block-mini-cart', - selectors: { - frontend: { - drawer: '.wc-block-mini-cart__drawer', - drawerCloseButton: 'button[aria-label="Close"]', - }, - editor: {}, - }, +const openMiniCart = async ( page: Page ) => { + await page.getByLabel( 'items in cart,' ).hover(); + await page.getByLabel( 'items in cart,' ).click(); }; -const getMiniCartButton = async ( { page } ) => { - return page.getByLabel( '0 items in cart, total price of $0.00' ); -}; +test.describe( `Mini Cart Block`, () => { + /** + * This is a workaround to run tests in isolation. + * Ideally, the test should be run in isolation by default. But we're + * overriding the storageState in config which make all tests run with admin + * user. + */ + test.use( { + storageState: { + origins: [], + cookies: [], + }, + } ); + + test.beforeEach( async ( { page } ) => { + await page.goto( `/mini-cart-block`, { waitUntil: 'commit' } ); + } ); + + test( 'should open the empty cart drawer', async ( { page } ) => { + await openMiniCart( page ); + + await expect( page.getByRole( 'dialog' ) ).toContainText( + 'Your cart is currently empty!' + ); + } ); + + test( 'should close the drawer when clicking on the close button', async ( { + page, + } ) => { + await openMiniCart( page ); + + await expect( page.getByRole( 'dialog' ) ).toContainText( + 'Your cart is currently empty!' + ); + + await page.getByRole( 'button', { name: 'Close' } ).click(); -test.describe( `${ blockData.name } Block`, () => { - test.describe( `standalone`, () => { - test.beforeEach( async ( { admin, page, editor } ) => { - await admin.createNewPost( { legacyCanvas: true } ); - await editor.insertBlock( { name: blockData.name } ); - await editor.publishPost(); - const url = new URL( page.url() ); - const postId = url.searchParams.get( 'post' ); - await page.goto( `/?p=${ postId }`, { waitUntil: 'commit' } ); - } ); - - test( 'should open the empty cart drawer', async ( { page } ) => { - const miniCartButton = await getMiniCartButton( { page } ); - - await miniCartButton.click(); - - await expect( - page.locator( blockData.selectors.frontend.drawer ).first() - ).toHaveText( 'Your cart is currently empty!' ); - } ); - - test( 'should close the drawer when clicking on the close button', async ( { - page, - } ) => { - const miniCartButton = await getMiniCartButton( { page } ); - - await miniCartButton.click(); - - await expect( - page.locator( blockData.selectors.frontend.drawer ).first() - ).toHaveText( 'Your cart is currently empty!' ); - - // Wait for the drawer to fully open. - await page.waitForSelector( - blockData.selectors.frontend.drawerCloseButton - ); - - const closeButton = page.locator( - blockData.selectors.frontend.drawerCloseButton - ); - - await closeButton?.click(); - - // Wait for the drawer to fully close. - await page.waitForSelector( blockData.selectors.frontend.drawer, { - state: 'detached', - } ); - - expect( - await page - .locator( blockData.selectors.frontend.drawer ) - .count() - ).toEqual( 0 ); - } ); - - test( 'should close the drawer when clicking outside the drawer', async ( { - page, - } ) => { - const miniCartButton = await getMiniCartButton( { page } ); - - await miniCartButton.click(); - - await expect( - page.locator( blockData.selectors.frontend.drawer ).first() - ).toHaveText( 'Your cart is currently empty!' ); - - // Wait for the drawer to fully open. - await page.waitForSelector( - blockData.selectors.frontend.drawerCloseButton - ); - - await page.mouse.click( 50, 200 ); - - // Wait for the drawer to fully close. - await page.waitForSelector( blockData.selectors.frontend.drawer, { - state: 'detached', - } ); - - expect( - await page - .locator( blockData.selectors.frontend.drawer ) - .count() - ).toEqual( 0 ); - } ); + await expect( page.getByRole( 'dialog' ) ).toHaveCount( 0 ); } ); - test.describe( `with All products Block`, () => { - test.beforeEach( async ( { admin, page, editor } ) => { - await admin.createNewPost( { legacyCanvas: true } ); - await editor.insertBlock( { name: blockData.name } ); - await editor.insertBlock( { name: 'woocommerce/all-products' } ); - await editor.publishPost(); - const url = new URL( page.url() ); - const postId = url.searchParams.get( 'post' ); - await page.goto( `/?p=${ postId }`, { waitUntil: 'commit' } ); - } ); + test( 'should close the drawer when clicking outside the drawer', async ( { + page, + } ) => { + await openMiniCart( page ); - test( 'should open the filled cart drawer', async ( { page } ) => { - const miniCartButton = await getMiniCartButton( { page } ); + await expect( page.getByRole( 'dialog' ) ).toContainText( + 'Your cart is currently empty!' + ); + + await expect( + page.getByRole( 'button', { name: 'Close' } ) + ).toBeInViewport(); + + await page.mouse.click( 50, 200 ); + + await expect( page.getByRole( 'dialog' ) ).toHaveCount( 0 ); + } ); - await page.click( 'text=Add to cart' ); + test( 'should open the filled cart drawer', async ( { page } ) => { + await page.click( 'text=Add to cart' ); - await miniCartButton.click(); + await openMiniCart( page ); - await expect( - page.locator( '.wc-block-mini-cart__title' ).first() - ).toHaveText( 'Your cart (1 item)' ); - } ); + await expect( page.getByRole( 'dialog' ) ).toContainText( + 'Your cart (1 item)' + ); } ); } ); diff --git a/tests/e2e-pw/tests/product-gallery/inner-blocks/product-gallery-large-image/product-gallery-large-image.block_theme.spec.ts b/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-large-image/product-gallery-large-image.block_theme.spec.ts similarity index 98% rename from tests/e2e-pw/tests/product-gallery/inner-blocks/product-gallery-large-image/product-gallery-large-image.block_theme.spec.ts rename to tests/e2e/tests/product-gallery/inner-blocks/product-gallery-large-image/product-gallery-large-image.block_theme.spec.ts index ee30a29630c..7f2ce1619dd 100644 --- a/tests/e2e-pw/tests/product-gallery/inner-blocks/product-gallery-large-image/product-gallery-large-image.block_theme.spec.ts +++ b/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-large-image/product-gallery-large-image.block_theme.spec.ts @@ -49,7 +49,7 @@ test.describe( `${ blockData.name }`, () => { ] ); await page.goto( blockData.productPage, { - waitUntil: 'networkidle', + waitUntil: 'commit', } ); const blockFrontend = await frontendUtils.getBlockByName( From 73adb8debec2d9b38037a787deeeeafd5e42b44e Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 24 Aug 2023 19:17:37 +0200 Subject: [PATCH 8/9] Revert dequeue add-to-cart-variation script which is needed to properly handle variable products in single product page (#10723) --- src/BlockTypes/ProductButton.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/BlockTypes/ProductButton.php b/src/BlockTypes/ProductButton.php index 737895f62cb..507d4355c00 100644 --- a/src/BlockTypes/ProductButton.php +++ b/src/BlockTypes/ProductButton.php @@ -61,7 +61,6 @@ protected function enqueue_assets( array $attributes ) { */ public function dequeue_add_to_cart_scripts() { wp_dequeue_script( 'wc-add-to-cart' ); - wp_dequeue_script( 'wc-add-to-cart-variation' ); } /** From 00f1e0d2c12f54cf5752cb4757f22a6691f66119 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Fri, 25 Aug 2023 16:10:01 +0200 Subject: [PATCH 9/9] Update alignment options to new setting --- assets/js/atomic/blocks/product-elements/button/style.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/js/atomic/blocks/product-elements/button/style.scss b/assets/js/atomic/blocks/product-elements/button/style.scss index 22b7d72d855..ae7792cca37 100644 --- a/assets/js/atomic/blocks/product-elements/button/style.scss +++ b/assets/js/atomic/blocks/product-elements/button/style.scss @@ -57,11 +57,11 @@ } &.align-left { - justify-content: left; + align-items: flex-start; } &.align-right { - justify-content: right; + align-items: flex-end; } .wc-block-components-product-button__button {