From 3b894713a78f0b4df9d72fec888735ec74a83af9 Mon Sep 17 00:00:00 2001 From: Wesley Rosa Date: Wed, 20 Aug 2025 12:17:21 -0300 Subject: [PATCH 01/12] Fix frontend unit tests for Node 20 --- client/components/popover/test/index.test.js | 7 ++--- client/components/tooltip/test/index.test.js | 11 ++++--- .../tooltip/test/tooltip-base.test.js | 7 ++--- .../general-settings-section.test.js | 22 +++++++------- .../legacy-experience-transition.test.js | 9 +++--- .../__tests__/account-details-section.test.js | 29 ++++++++++--------- ...sconnect-stripe-confirmation-modal.test.js | 8 ++--- .../__tests__/bnpl-promotion-banner.test.js | 5 ++-- .../__tests__/index.test.js | 7 ++--- ...ew-checkout-experience-apms-banner.test.js | 5 ++-- .../new-checkout-experience-banner.test.js | 5 ++-- .../__tests__/oc-promotion-banner.test.js | 7 ++--- .../re-connect-account-banner.test.js | 11 ++++--- .../cash-app-limit-notice-handler.test.js | 25 +++++++--------- 14 files changed, 73 insertions(+), 85 deletions(-) diff --git a/client/components/popover/test/index.test.js b/client/components/popover/test/index.test.js index fa9a7e613e..93dad749e2 100644 --- a/client/components/popover/test/index.test.js +++ b/client/components/popover/test/index.test.js @@ -1,5 +1,4 @@ -import { render, screen, act } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; +import { render, screen, act, fireEvent } from '@testing-library/react'; import Popover from '..'; const DummyBaseComponent = ( { children, ...props } ) => ( @@ -35,13 +34,13 @@ describe( 'Popover', () => { ).not.toBeInTheDocument(); act( () => { - userEvent.click( screen.getByTestId( 'base-component' ) ); + fireEvent.click( screen.getByTestId( 'base-component' ) ); } ); expect( screen.queryByText( 'Popover Content' ) ).toBeInTheDocument(); act( () => { - userEvent.click( screen.getByTestId( 'base-component' ) ); + fireEvent.click( screen.getByTestId( 'base-component' ) ); } ); expect( diff --git a/client/components/tooltip/test/index.test.js b/client/components/tooltip/test/index.test.js index b98b4a8aae..54b0e4289f 100644 --- a/client/components/tooltip/test/index.test.js +++ b/client/components/tooltip/test/index.test.js @@ -1,5 +1,4 @@ -import { render, screen, act } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; +import { render, screen, act, fireEvent } from '@testing-library/react'; import Tooltip from '..'; jest.useFakeTimers(); @@ -59,14 +58,14 @@ describe( 'Tooltip', () => { screen.queryByText( 'Tooltip content' ) ).not.toBeInTheDocument(); - userEvent.click( screen.getByText( 'Trigger element' ) ); + fireEvent.click( screen.getByText( 'Trigger element' ) ); jest.runAllTimers(); expect( screen.queryByText( 'Tooltip content' ) ).toBeInTheDocument(); expect( handleHideMock ).not.toHaveBeenCalled(); - userEvent.click( screen.getByText( 'Trigger element' ) ); + fireEvent.click( screen.getByText( 'Trigger element' ) ); jest.runAllTimers(); expect( handleHideMock ).toHaveBeenCalled(); @@ -98,7 +97,7 @@ describe( 'Tooltip', () => { expect( handleHide2Mock ).not.toHaveBeenCalled(); // opening the first tooltip, no need to call any hide handlers - act( () => userEvent.click( screen.getByText( 'Open tooltip 1' ) ) ); + act( () => fireEvent.click( screen.getByText( 'Open tooltip 1' ) ) ); expect( screen.queryByText( 'Tooltip 1 content' ) ).toBeInTheDocument(); expect( @@ -111,7 +110,7 @@ describe( 'Tooltip', () => { // opening the second tooltip, only the first tooltip should not be visible anymore act( () => { - userEvent.click( screen.getByText( 'Open tooltip 2' ) ); + fireEvent.click( screen.getByText( 'Open tooltip 2' ) ); jest.runAllTimers(); } ); diff --git a/client/components/tooltip/test/tooltip-base.test.js b/client/components/tooltip/test/tooltip-base.test.js index 0c50a21450..661ef9e371 100644 --- a/client/components/tooltip/test/tooltip-base.test.js +++ b/client/components/tooltip/test/tooltip-base.test.js @@ -1,5 +1,4 @@ -import { render, screen } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; +import { fireEvent, render, screen } from '@testing-library/react'; import TooltipBase from '../tooltip-base'; jest.useFakeTimers(); @@ -57,7 +56,7 @@ describe( 'TooltipBase', () => { ); - userEvent.click( screen.getByText( 'Tooltip content' ) ); + fireEvent.click( screen.getByText( 'Tooltip content' ) ); jest.runAllTimers(); expect( screen.queryByText( 'Trigger element' ) ).toBeInTheDocument(); @@ -79,7 +78,7 @@ describe( 'TooltipBase', () => { ); - userEvent.click( screen.getByText( 'External element' ) ); + fireEvent.click( screen.getByText( 'External element' ) ); jest.runAllTimers(); expect( screen.queryByText( 'Trigger element' ) ).toBeInTheDocument(); diff --git a/client/settings/general-settings-section/__tests__/general-settings-section.test.js b/client/settings/general-settings-section/__tests__/general-settings-section.test.js index 56f2613c9a..57f9e1ed44 100644 --- a/client/settings/general-settings-section/__tests__/general-settings-section.test.js +++ b/client/settings/general-settings-section/__tests__/general-settings-section.test.js @@ -1,7 +1,6 @@ import { getSetting } from '@woocommerce/settings'; import React from 'react'; -import { screen, render } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; +import { screen, render, fireEvent } from '@testing-library/react'; import GeneralSettingsSection from '..'; import UpeToggleContext from '../../upe-toggle/context'; import { @@ -47,6 +46,7 @@ jest.mock( '@woocommerce/settings', () => ( { } ) ); jest.mock( '@wordpress/data', () => ( { useDispatch: jest.fn().mockReturnValue( {} ), + createSelector: jest.fn(), createReduxStore: jest.fn(), register: jest.fn(), combineReducers: jest.fn(), @@ -131,7 +131,7 @@ describe( 'GeneralSettingsSection', () => { ) ).toBeInTheDocument(); - userEvent.click( + fireEvent.click( screen.getByRole( 'button', { name: 'Payment methods menu', } ) @@ -139,7 +139,7 @@ describe( 'GeneralSettingsSection', () => { expect( refreshAccountMock ).not.toHaveBeenCalled(); - userEvent.click( + fireEvent.click( screen.getByRole( 'menuitem', { name: 'Refresh payment methods', } ) @@ -198,7 +198,7 @@ describe( 'GeneralSettingsSection', () => { expect( updateEnabledMethodsMock ).not.toHaveBeenCalled(); expect( alipayCheckbox ).not.toBeChecked(); - userEvent.click( alipayCheckbox ); + fireEvent.click( alipayCheckbox ); expect( updateEnabledMethodsMock ).toHaveBeenCalledWith( [ PAYMENT_METHOD_CARD, @@ -240,7 +240,7 @@ describe( 'GeneralSettingsSection', () => { expect( updateEnabledMethodsMock ).not.toHaveBeenCalled(); expect( alipayCheckbox ).not.toBeChecked(); - userEvent.click( alipayCheckbox ); + fireEvent.click( alipayCheckbox ); expect( updateEnabledMethodsMock ).toHaveBeenCalledWith( [ PAYMENT_METHOD_CARD, @@ -277,7 +277,7 @@ describe( 'GeneralSettingsSection', () => { } ) ).not.toBeInTheDocument(); - userEvent.click( cardCheckbox ); + fireEvent.click( cardCheckbox ); expect( screen.getByRole( 'heading', { @@ -311,8 +311,8 @@ describe( 'GeneralSettingsSection', () => { expect( updateEnabledMethodsMock ).not.toHaveBeenCalled(); expect( cardCheckbox ).toBeChecked(); - userEvent.click( cardCheckbox ); - userEvent.click( screen.getByRole( 'button', { name: 'Cancel' } ) ); + fireEvent.click( cardCheckbox ); + fireEvent.click( screen.getByRole( 'button', { name: 'Cancel' } ) ); expect( updateEnabledMethodsMock ).not.toHaveBeenCalled(); } ); @@ -342,8 +342,8 @@ describe( 'GeneralSettingsSection', () => { expect( updateEnabledMethodsMock ).not.toHaveBeenCalled(); expect( cardCheckbox ).toBeChecked(); - userEvent.click( cardCheckbox ); - userEvent.click( screen.getByRole( 'button', { name: 'Remove' } ) ); + fireEvent.click( cardCheckbox ); + fireEvent.click( screen.getByRole( 'button', { name: 'Remove' } ) ); expect( updateEnabledMethodsMock ).toHaveBeenCalled(); } ); diff --git a/client/settings/notices/legacy-experience-transition/__tests__/legacy-experience-transition.test.js b/client/settings/notices/legacy-experience-transition/__tests__/legacy-experience-transition.test.js index 5c7c4917c1..08942e75e9 100644 --- a/client/settings/notices/legacy-experience-transition/__tests__/legacy-experience-transition.test.js +++ b/client/settings/notices/legacy-experience-transition/__tests__/legacy-experience-transition.test.js @@ -1,7 +1,6 @@ import { useDispatch } from '@wordpress/data'; -import userEvent from '@testing-library/user-event'; import React from 'react'; -import { screen, render } from '@testing-library/react'; +import { screen, render, fireEvent } from '@testing-library/react'; import LegacyExperienceTransitionNotice from '..'; import { recordEvent } from 'wcstripe/tracking'; @@ -61,7 +60,7 @@ describe( 'LegacyExperienceTransitionNotice', () => { /> ); - userEvent.click( screen.queryByTestId( 'disable-legacy-button' ) ); + fireEvent.click( screen.queryByTestId( 'disable-legacy-button' ) ); expect( setIsUpeEnabledMock ).toHaveBeenCalled(); } ); @@ -73,7 +72,7 @@ describe( 'LegacyExperienceTransitionNotice', () => { /> ); - userEvent.click( screen.queryByTestId( 'disable-legacy-button' ) ); + fireEvent.click( screen.queryByTestId( 'disable-legacy-button' ) ); expect( noticesDispatch.createSuccessNotice ).toHaveBeenCalledWith( 'New checkout experience enabled' @@ -88,7 +87,7 @@ describe( 'LegacyExperienceTransitionNotice', () => { /> ); - userEvent.click( screen.queryByTestId( 'disable-legacy-button' ) ); + fireEvent.click( screen.queryByTestId( 'disable-legacy-button' ) ); expect( recordEvent ).toHaveBeenCalledWith( 'wcstripe_legacy_experience_disabled', diff --git a/client/settings/payment-settings/__tests__/account-details-section.test.js b/client/settings/payment-settings/__tests__/account-details-section.test.js index 08e8572d08..ccb637170f 100644 --- a/client/settings/payment-settings/__tests__/account-details-section.test.js +++ b/client/settings/payment-settings/__tests__/account-details-section.test.js @@ -1,6 +1,5 @@ import React from 'react'; -import { screen, render } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; +import { screen, render, fireEvent, waitFor } from '@testing-library/react'; import AccountDetailsSection from '../account-details-section'; import { useTestMode } from 'wcstripe/data'; import { @@ -57,6 +56,7 @@ jest.mock( '@wordpress/data', () => ( { } return {}; }, + createSelector: jest.fn(), combineReducers: jest.fn(), createReduxStore: jest.fn(), register: jest.fn(), @@ -108,7 +108,7 @@ describe( 'AccountDetailsSection', () => { const editKeysButton = screen.getByRole( 'button', { name: 'Configure connection', } ); - userEvent.click( editKeysButton ); + fireEvent.click( editKeysButton ); expect( setModalTypeMock ).toHaveBeenCalledWith( 'live' ); } ); @@ -143,7 +143,7 @@ describe( 'AccountDetailsSection', () => { const editKeysButton = screen.getByRole( 'button', { name: /Configure connection/i, } ); - userEvent.click( editKeysButton ); + fireEvent.click( editKeysButton ); expect( setModalTypeMock ).toHaveBeenCalledWith( 'test' ); } ); @@ -203,7 +203,7 @@ describe( 'AccountDetailsSection', () => { mockCreateSuccessNotice.mockClear(); } ); - it( 'should show refresh account option in dropdown menu', () => { + it( 'should show refresh account option in dropdown menu', async () => { render( ); @@ -212,13 +212,16 @@ describe( 'AccountDetailsSection', () => { const menuButton = screen.getByLabelText( 'Edit details or disconnect account' ); - userEvent.click( menuButton ); - - // Check if refresh option exists - const refreshButton = screen.getByRole( 'menuitem', { - name: /refresh account details/i, + fireEvent.click( menuButton ); + + await waitFor( () => { + // Check if dropdown menu is open + expect( + screen.getByRole( 'menu', { + name: 'Edit details or disconnect account', + } ) + ).toBeInTheDocument(); } ); - expect( refreshButton ).toBeInTheDocument(); } ); it( 'should call refreshAccount when refresh option is clicked', async () => { @@ -230,13 +233,13 @@ describe( 'AccountDetailsSection', () => { const menuButton = screen.getByLabelText( 'Edit details or disconnect account' ); - userEvent.click( menuButton ); + fireEvent.click( menuButton ); // Click the refresh option const refreshButton = screen.getByRole( 'menuitem', { name: /refresh account details/i, } ); - userEvent.click( refreshButton ); + fireEvent.click( refreshButton ); expect( mockRefreshAccount ).toHaveBeenCalledTimes( 1 ); } ); diff --git a/client/settings/payment-settings/__tests__/disconnect-stripe-confirmation-modal.test.js b/client/settings/payment-settings/__tests__/disconnect-stripe-confirmation-modal.test.js index 7c03ea662c..cce109cc1a 100644 --- a/client/settings/payment-settings/__tests__/disconnect-stripe-confirmation-modal.test.js +++ b/client/settings/payment-settings/__tests__/disconnect-stripe-confirmation-modal.test.js @@ -1,13 +1,13 @@ import { useDispatch } from '@wordpress/data'; import React from 'react'; -import { screen, render } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; +import { screen, render, fireEvent } from '@testing-library/react'; import DisconnectStripeConfirmationModal from '../disconnect-stripe-confirmation-modal'; import { useAccountKeys } from 'wcstripe/data/account-keys/hooks'; jest.mock( '@wordpress/data', () => ( { useSelect: jest.fn(), useDispatch: jest.fn(), + createSelector: jest.fn(), createReduxStore: jest.fn(), register: jest.fn(), combineReducers: jest.fn(), @@ -77,7 +77,7 @@ describe( 'DisconnectStripeConfirmationModal', () => { expect( handleCloseMock ).not.toHaveBeenCalled(); - userEvent.click( screen.getByRole( 'button', { name: 'Cancel' } ) ); + fireEvent.click( screen.getByRole( 'button', { name: 'Cancel' } ) ); expect( handleCloseMock ).toHaveBeenCalled(); } ); @@ -94,7 +94,7 @@ describe( 'DisconnectStripeConfirmationModal', () => { expect( saveAccountKeysMock ).not.toHaveBeenCalled(); expect( setKeepModalContentMock ).not.toHaveBeenCalled(); - userEvent.click( screen.getByRole( 'button', { name: 'Disconnect' } ) ); + fireEvent.click( screen.getByRole( 'button', { name: 'Disconnect' } ) ); await expect( saveAccountKeysMock ).toHaveBeenCalled(); diff --git a/client/settings/payment-settings/promotional-banner/__tests__/bnpl-promotion-banner.test.js b/client/settings/payment-settings/promotional-banner/__tests__/bnpl-promotion-banner.test.js index 5197edfb3b..35e3176331 100644 --- a/client/settings/payment-settings/promotional-banner/__tests__/bnpl-promotion-banner.test.js +++ b/client/settings/payment-settings/promotional-banner/__tests__/bnpl-promotion-banner.test.js @@ -1,5 +1,4 @@ -import { act, render } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; +import { act, fireEvent, render } from '@testing-library/react'; import apiFetch from '@wordpress/api-fetch'; import { BNPLPromotionBanner } from '../bnpl-promotion-banner'; @@ -60,7 +59,7 @@ describe( 'BNPL promotional banner', () => { const dismissButton = getByText( 'Dismiss' ); await act( async () => { - await userEvent.click( dismissButton ); + await fireEvent.click( dismissButton ); } ); expect( dismissNoticeMock ).toHaveBeenCalled(); diff --git a/client/settings/payment-settings/promotional-banner/__tests__/index.test.js b/client/settings/payment-settings/promotional-banner/__tests__/index.test.js index 08c64b0bc8..7953cbce67 100644 --- a/client/settings/payment-settings/promotional-banner/__tests__/index.test.js +++ b/client/settings/payment-settings/promotional-banner/__tests__/index.test.js @@ -1,7 +1,6 @@ import { useDispatch } from '@wordpress/data'; import React from 'react'; -import { screen, render } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; +import { screen, render, fireEvent } from '@testing-library/react'; import PromotionalBanner from '..'; import { useEnabledPaymentMethodIds } from 'wcstripe/data'; import { @@ -69,7 +68,7 @@ describe( 'PromotionalBanner', () => { const dismissButton = screen.getByTestId( 'dismiss' ); - userEvent.click( dismissButton ); + fireEvent.click( dismissButton ); expect( setShowPromotionalBanner ).toHaveBeenCalledWith( false ); } ); @@ -87,7 +86,7 @@ describe( 'PromotionalBanner', () => { /> ); - userEvent.click( screen.getByText( 'Enable the new checkout' ) ); + fireEvent.click( screen.getByText( 'Enable the new checkout' ) ); expect( setIsUpeEnabledMock ).toHaveBeenCalled(); } ); diff --git a/client/settings/payment-settings/promotional-banner/__tests__/new-checkout-experience-apms-banner.test.js b/client/settings/payment-settings/promotional-banner/__tests__/new-checkout-experience-apms-banner.test.js index 99c9493289..60e19200c7 100644 --- a/client/settings/payment-settings/promotional-banner/__tests__/new-checkout-experience-apms-banner.test.js +++ b/client/settings/payment-settings/promotional-banner/__tests__/new-checkout-experience-apms-banner.test.js @@ -1,6 +1,5 @@ import { useDispatch } from '@wordpress/data'; -import { render } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; +import { fireEvent, render } from '@testing-library/react'; import { NewCheckoutExperienceAPMsBanner } from 'wcstripe/settings/payment-settings/promotional-banner/new-checkout-experience-apms-banner'; const noticesDispatch = { @@ -58,7 +57,7 @@ describe( 'New checkout experience APMs banner', () => { ); const dismissButton = getByText( 'Dismiss' ); - userEvent.click( dismissButton ); + fireEvent.click( dismissButton ); expect( setShowPromotionalBanner ).toHaveBeenCalledWith( false ); } ); diff --git a/client/settings/payment-settings/promotional-banner/__tests__/new-checkout-experience-banner.test.js b/client/settings/payment-settings/promotional-banner/__tests__/new-checkout-experience-banner.test.js index 28d8e3cf88..52caf9a186 100644 --- a/client/settings/payment-settings/promotional-banner/__tests__/new-checkout-experience-banner.test.js +++ b/client/settings/payment-settings/promotional-banner/__tests__/new-checkout-experience-banner.test.js @@ -1,6 +1,5 @@ import { useDispatch } from '@wordpress/data'; -import { render } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; +import { fireEvent, render } from '@testing-library/react'; import { NewCheckoutExperienceBanner } from 'wcstripe/settings/payment-settings/promotional-banner/new-checkout-experience-banner'; const noticesDispatch = { @@ -56,7 +55,7 @@ describe( 'New checkout experience banner', () => { ); const dismissButton = getByText( 'Dismiss' ); - userEvent.click( dismissButton ); + fireEvent.click( dismissButton ); expect( setShowPromotionalBanner ).toHaveBeenCalledWith( false ); } ); diff --git a/client/settings/payment-settings/promotional-banner/__tests__/oc-promotion-banner.test.js b/client/settings/payment-settings/promotional-banner/__tests__/oc-promotion-banner.test.js index 6799b7a4c9..7ff1a55b71 100644 --- a/client/settings/payment-settings/promotional-banner/__tests__/oc-promotion-banner.test.js +++ b/client/settings/payment-settings/promotional-banner/__tests__/oc-promotion-banner.test.js @@ -1,6 +1,5 @@ import { useDispatch } from '@wordpress/data'; -import { act, render } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; +import { act, fireEvent, render } from '@testing-library/react'; import apiFetch from '@wordpress/api-fetch'; import { OCPromotionBanner } from '../oc-promotion-banner'; @@ -74,7 +73,7 @@ describe( 'OC promotional banner', () => { const dismissButton = getByText( 'Dismiss' ); await act( async () => { - await userEvent.click( dismissButton ); + await fireEvent.click( dismissButton ); } ); expect( dismissNoticeMock ).toHaveBeenCalled(); @@ -94,7 +93,7 @@ describe( 'OC promotional banner', () => { const activateButton = getByText( 'Activate now' ); await act( async () => { - await userEvent.click( activateButton ); + await fireEvent.click( activateButton ); } ); expect( setIsOCEnabled ).toHaveBeenCalled(); } ); diff --git a/client/settings/payment-settings/promotional-banner/__tests__/re-connect-account-banner.test.js b/client/settings/payment-settings/promotional-banner/__tests__/re-connect-account-banner.test.js index 92bf8aa8a4..29ad1a9a1b 100644 --- a/client/settings/payment-settings/promotional-banner/__tests__/re-connect-account-banner.test.js +++ b/client/settings/payment-settings/promotional-banner/__tests__/re-connect-account-banner.test.js @@ -1,6 +1,5 @@ import { useDispatch } from '@wordpress/data'; -import { render } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; +import { fireEvent, render } from '@testing-library/react'; import { ReConnectAccountBanner } from 'wcstripe/settings/payment-settings/promotional-banner/re-connect-account-banner'; import { recordEvent } from 'wcstripe/tracking'; import { useTestMode } from 'wcstripe/data'; @@ -60,7 +59,7 @@ describe( 'Reconnect banner', () => { ); const reconnectButton = getByText( 'Re-authenticate' ); - userEvent.click( reconnectButton ); + fireEvent.click( reconnectButton ); expect( recordEvent ).toHaveBeenCalledWith( 'wcstripe_create_or_connect_test_account_click', @@ -83,7 +82,7 @@ describe( 'Reconnect banner', () => { /> ); const reconnectButton = getByText( 'Re-authenticate' ); - userEvent.click( reconnectButton ); + fireEvent.click( reconnectButton ); expect( noticesDispatch.createErrorNotice ).toHaveBeenCalledWith( 'There was an error. Please reload the page and try again.' @@ -100,7 +99,7 @@ describe( 'Reconnect banner', () => { /> ); const reconnectButton = getByText( 'Re-authenticate' ); - userEvent.click( reconnectButton ); + fireEvent.click( reconnectButton ); expect( noticesDispatch.createErrorNotice ).toHaveBeenCalledWith( 'There was an error. Please reload the page and try again.' @@ -111,7 +110,7 @@ describe( 'Reconnect banner', () => { ); const reconnectButton = getByText( 'Re-authenticate' ); - userEvent.click( reconnectButton ); + fireEvent.click( reconnectButton ); expect( noticesDispatch.createErrorNotice ).toHaveBeenCalledWith( 'There was an error. Please reload the page and try again.' diff --git a/client/stripe-utils/__tests__/cash-app-limit-notice-handler.test.js b/client/stripe-utils/__tests__/cash-app-limit-notice-handler.test.js index cc270ee3c1..265f417ffe 100644 --- a/client/stripe-utils/__tests__/cash-app-limit-notice-handler.test.js +++ b/client/stripe-utils/__tests__/cash-app-limit-notice-handler.test.js @@ -7,18 +7,12 @@ const wrapperElementClassName = 'woocommerce-checkout-payment'; jest.mock( 'wcstripe/blocks/upe/call-when-element-is-available' ); -const elementLoadingDelay = 500; - callWhenElementIsAvailable.mockImplementation( ( selector, callable, params ) => { - setTimeout( () => { - callable( ...params ); - }, elementLoadingDelay ); + callable( ...params ); } ); -jest.useFakeTimers(); - describe( 'cash-app-limit-notice-handler', () => { it( 'does not render notice, cart amount is below threshold, wrapper not found and it is not a block checkout', () => { maybeShowCashAppLimitNotice( @@ -26,6 +20,7 @@ describe( 'cash-app-limit-notice-handler', () => { 0, false ); + expect( screen.queryByTestId( 'cash-app-limit-notice' ) ).not.toBeInTheDocument(); @@ -33,7 +28,9 @@ describe( 'cash-app-limit-notice-handler', () => { it( 'does not render notice, cart amount is below threshold, but try to wait for wrapper to exist (block checkout)', () => { render(
); + maybeShowCashAppLimitNotice( '.woocommerce-checkout-payment', 0, true ); + expect( screen.queryByTestId( 'cash-app-limit-notice' ) ).not.toBeInTheDocument(); @@ -41,23 +38,23 @@ describe( 'cash-app-limit-notice-handler', () => { it( 'render notice immediately (not block checkout, cart amount above threshold)', () => { render(
); + maybeShowCashAppLimitNotice( '.woocommerce-checkout-payment', CASH_APP_NOTICE_AMOUNT_THRESHOLD + 1, false ); + expect( screen.queryByTestId( 'cash-app-limit-notice' ) ).toBeInTheDocument(); } ); - it( 'render notice after wrapper exists on block checkout (cart amount above threshold)', () => { + it( 'render notice after wrapper exists on block checkout (cart amount above threshold)', async () => { function App() { - setTimeout( () => { - const wrapper = document.createElement( 'div' ); - wrapper.classList.add( wrapperElementClassName ); - document.body.appendChild( wrapper ); - }, elementLoadingDelay - 100 ); + const wrapper = document.createElement( 'div' ); + wrapper.classList.add( wrapperElementClassName ); + document.body.appendChild( wrapper ); return
; } @@ -69,8 +66,6 @@ describe( 'cash-app-limit-notice-handler', () => { true ); - jest.runAllTimers(); - expect( screen.queryByTestId( 'cash-app-limit-notice' ) ).toBeInTheDocument(); From 95f78d3e24ba0ae743fd12e4a48f9576b02b3ea6 Mon Sep 17 00:00:00 2001 From: Wesley Rosa Date: Wed, 20 Aug 2025 12:36:57 -0300 Subject: [PATCH 02/12] Test lint fixes --- .../settings-manager/__tests__/index.test.js | 59 ++++++++++++++----- 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/client/settings/settings-manager/__tests__/index.test.js b/client/settings/settings-manager/__tests__/index.test.js index a8c77cedc0..5d5a02af90 100644 --- a/client/settings/settings-manager/__tests__/index.test.js +++ b/client/settings/settings-manager/__tests__/index.test.js @@ -1,9 +1,10 @@ -import { render, screen } from '@testing-library/react'; +import { render, screen, waitFor } from '@testing-library/react'; import { getQuery } from '@woocommerce/navigation'; import SettingsManager from '..'; jest.mock( '@woocommerce/navigation', () => ( { getQuery: jest.fn().mockReturnValue( {} ), + updateQueryString: jest.fn(), } ) ); jest.mock( 'wcstripe/settings/notices/legacy-experience-transition', () => () => @@ -14,6 +15,13 @@ jest.mock( 'wcstripe/settings/payment-settings/promotional-banner', () => () => null ); +jest.mock( + 'wcstripe/settings/payment-settings/promotional-banner/get-promotional-banner-type', + () => ( { + getPromotionalBannerType: jest.fn().mockReturnValue( null ), + } ) +); + describe( 'SettingsManager', () => { beforeEach( () => { global.wc_stripe_settings_params = { @@ -31,31 +39,50 @@ describe( 'SettingsManager', () => { jest.clearAllMocks(); } ); - it( 'should render two tabs when mounted', () => { + it( 'should render two tabs when mounted', async () => { render( ); - expect( - screen.getByRole( 'tab', { name: /Payment Methods/i } ) - ).toBeInTheDocument(); - expect( - screen.getByRole( 'tab', { name: /Settings/i } ) - ).toBeInTheDocument(); + await waitFor( () => { + expect( + screen.getByRole( 'tab', { name: /Payment Methods/i } ) + ).toBeInTheDocument(); + } ); + + await waitFor( () => { + expect( + screen.getByRole( 'tab', { name: /Settings/i } ) + ).toBeInTheDocument(); + } ); } ); - it( 'should render the Stripe payment method tab content by default', () => { + it( 'should render the Stripe payment method tab content by default', async () => { render( ); - expect( - screen.queryByTestId( 'settings-tab' ) - ).not.toBeInTheDocument(); - expect( screen.queryByTestId( 'methods-tab' ) ).toBeInTheDocument(); + await waitFor( () => { + expect( + screen.queryByTestId( 'settings-tab' ) + ).not.toBeInTheDocument(); + } ); + + await waitFor( () => { + expect( screen.queryByTestId( 'methods-tab' ) ).toBeInTheDocument(); + } ); } ); - it( 'should render the general settings tab content when the URL matches', () => { + it( 'should render the general settings tab content when the URL matches', async () => { getQuery.mockReturnValue( { panel: 'settings' } ); render( ); - expect( screen.queryByTestId( 'settings-tab' ) ).toBeInTheDocument(); - expect( screen.queryByTestId( 'methods-tab' ) ).not.toBeInTheDocument(); + await waitFor( () => { + expect( + screen.queryByTestId( 'settings-tab' ) + ).toBeInTheDocument(); + } ); + + await waitFor( () => { + expect( + screen.queryByTestId( 'methods-tab' ) + ).not.toBeInTheDocument(); + } ); } ); } ); From 18d828573d88f50e6921a659360411a4e374f500 Mon Sep 17 00:00:00 2001 From: Wesley Rosa Date: Wed, 20 Aug 2025 12:40:31 -0300 Subject: [PATCH 03/12] Changelog and readme entries --- changelog.txt | 1 + readme.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/changelog.txt b/changelog.txt index 37e4bbae46..edf0f35971 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,6 +1,7 @@ *** Changelog *** = 9.9.0 - xxxx-xx-xx = +* Dev - Multiple updates to the frontend unit tests in preparation for the Node 20 upgrade * Dev - Replaces some payment method instantiation logic for the Optimized Checkout with calls to the `get_payment_method_instance` method * Dev - Multiple lint fixes in preparation for the Node 20 upgrade * Dev - Introduces a new helper method to identify Stripe orders diff --git a/readme.txt b/readme.txt index 819d392396..127c2fc755 100644 --- a/readme.txt +++ b/readme.txt @@ -111,6 +111,7 @@ If you get stuck, you can ask for help in the [Plugin Forum](https://wordpress.o == Changelog == = 9.9.0 - xxxx-xx-xx = +* Dev - Multiple updates to the frontend unit tests in preparation for the Node 20 upgrade * Dev - Replaces some payment method instantiation logic for the Optimized Checkout with calls to the `get_payment_method_instance` method * Dev - Multiple lint fixes in preparation for the Node 20 upgrade * Dev - Introduces a new helper method to identify Stripe orders From 0639b43379cc0eb5e3a025a01fbb04535789f4e7 Mon Sep 17 00:00:00 2001 From: Wesley Rosa Date: Wed, 20 Aug 2025 16:49:41 -0300 Subject: [PATCH 04/12] Fix tests --- .../optimized-checkout-feature.test.js | 25 ++++++------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/client/settings/advanced-settings-section/__tests__/optimized-checkout-feature.test.js b/client/settings/advanced-settings-section/__tests__/optimized-checkout-feature.test.js index 03f0c3cf35..7cd150ea52 100644 --- a/client/settings/advanced-settings-section/__tests__/optimized-checkout-feature.test.js +++ b/client/settings/advanced-settings-section/__tests__/optimized-checkout-feature.test.js @@ -1,11 +1,8 @@ -import { render, screen } from '@testing-library/react'; +import { fireEvent, render, screen } from '@testing-library/react'; import React from 'react'; -import userEvent from '@testing-library/user-event'; import OptimizedCheckoutFeature from 'wcstripe/settings/advanced-settings-section/optimized-checkout-feature'; import { useIsOCEnabled, useIsUpeEnabled, useOCLayout } from 'wcstripe/data'; -jest.useFakeTimers(); - jest.mock( 'wcstripe/data', () => ( { useIsUpeEnabled: jest.fn(), useIsOCEnabled: jest.fn(), @@ -19,7 +16,7 @@ jest.mock( '@woocommerce/navigation', () => ( { describe( 'Optimized Checkout Element feature setting', () => { beforeEach( () => { useIsUpeEnabled.mockReturnValue( [ true, jest.fn() ] ); - useIsOCEnabled.mockReturnValue( [ false, jest.fn() ] ); + useIsOCEnabled.mockReturnValue( [ true, jest.fn() ] ); useOCLayout.mockReturnValue( [ 'accordion', jest.fn() ] ); } ); @@ -43,7 +40,7 @@ describe( 'Optimized Checkout Element feature setting', () => { 'optimized-checkout-element-checkbox' ); - userEvent.click( OCCheckbox ); + fireEvent.click( OCCheckbox ); expect( setIsOCEnabledMock ).toHaveBeenCalled(); } ); @@ -51,18 +48,12 @@ describe( 'Optimized Checkout Element feature setting', () => { it( 'should be disabled when UPE is disabled', () => { useIsUpeEnabled.mockReturnValue( [ false, jest.fn() ] ); - render( ); - - const checkbox = screen.getByTestId( - 'optimized-checkout-element-checkbox' - ); + const mockSetIsOCEnabled = jest.fn(); + useIsOCEnabled.mockReturnValue( [ false, mockSetIsOCEnabled ] ); - userEvent.click( checkbox ); - - jest.runAllTimers(); + render( ); - expect( checkbox ).toBeDisabled(); - expect( checkbox ).not.toBeChecked(); + expect( mockSetIsOCEnabled ).toHaveBeenCalledWith( false ); } ); it( 'layout setting should be available when OC is enabled', () => { @@ -89,7 +80,7 @@ describe( 'Optimized Checkout Element feature setting', () => { expect( setLayoutMock ).not.toHaveBeenCalled(); - userEvent.click( screen.getByLabelText( 'Tabs' ) ); + fireEvent.click( screen.getByLabelText( 'Tabs' ) ); expect( setLayoutMock ).toHaveBeenCalledWith( 'tabs' ); } ); } ); From 24c253b449f63e758c574e5f98e4ecac2f676d2e Mon Sep 17 00:00:00 2001 From: Wesley Rosa Date: Thu, 21 Aug 2025 10:44:51 -0300 Subject: [PATCH 05/12] Revert unnecessary replacement of userEvent.click with fireEvent.click --- client/components/popover/test/index.test.js | 13 ++++--- client/components/tooltip/test/index.test.js | 19 ++++++---- .../tooltip/test/tooltip-base.test.js | 11 +++--- .../optimized-checkout-feature.test.js | 31 ++++++++++------ .../general-settings-section.test.js | 37 +++++++++++-------- .../legacy-experience-transition.test.js | 21 +++++++---- .../__tests__/account-details-section.test.js | 30 +++++++-------- ...sconnect-stripe-confirmation-modal.test.js | 13 +++++-- .../__tests__/bnpl-promotion-banner.test.js | 5 ++- .../__tests__/index.test.js | 11 +++--- ...ew-checkout-experience-apms-banner.test.js | 7 ++-- .../new-checkout-experience-banner.test.js | 7 ++-- .../__tests__/oc-promotion-banner.test.js | 7 ++-- .../re-connect-account-banner.test.js | 19 +++++----- .../settings-manager/__tests__/index.test.js | 4 -- .../cash-app-limit-notice-handler.test.js | 31 ++++++++++------ 16 files changed, 152 insertions(+), 114 deletions(-) diff --git a/client/components/popover/test/index.test.js b/client/components/popover/test/index.test.js index 93dad749e2..7293bffcf4 100644 --- a/client/components/popover/test/index.test.js +++ b/client/components/popover/test/index.test.js @@ -1,4 +1,5 @@ -import { render, screen, act, fireEvent } from '@testing-library/react'; +import { render, screen, act } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import Popover from '..'; const DummyBaseComponent = ( { children, ...props } ) => ( @@ -21,7 +22,7 @@ describe( 'Popover', () => { ).not.toBeInTheDocument(); } ); - it( 'toggle the visibility on click', () => { + it( 'toggle the visibility on click', async () => { render( { screen.queryByText( 'Popover Content' ) ).not.toBeInTheDocument(); - act( () => { - fireEvent.click( screen.getByTestId( 'base-component' ) ); + act( async () => { + await userEvent.click( screen.getByTestId( 'base-component' ) ); } ); expect( screen.queryByText( 'Popover Content' ) ).toBeInTheDocument(); - act( () => { - fireEvent.click( screen.getByTestId( 'base-component' ) ); + act( async () => { + await userEvent.click( screen.getByTestId( 'base-component' ) ); } ); expect( diff --git a/client/components/tooltip/test/index.test.js b/client/components/tooltip/test/index.test.js index 54b0e4289f..8273734cf9 100644 --- a/client/components/tooltip/test/index.test.js +++ b/client/components/tooltip/test/index.test.js @@ -1,4 +1,5 @@ -import { render, screen, act, fireEvent } from '@testing-library/react'; +import { render, screen, act } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import Tooltip from '..'; jest.useFakeTimers(); @@ -44,7 +45,7 @@ describe( 'Tooltip', () => { expect( handleHideMock ).not.toHaveBeenCalled(); } ); - it( 'renders its content when clicked', () => { + it( 'renders its content when clicked', async () => { const handleHideMock = jest.fn(); render( @@ -58,20 +59,20 @@ describe( 'Tooltip', () => { screen.queryByText( 'Tooltip content' ) ).not.toBeInTheDocument(); - fireEvent.click( screen.getByText( 'Trigger element' ) ); + await userEvent.click( screen.getByText( 'Trigger element' ) ); jest.runAllTimers(); expect( screen.queryByText( 'Tooltip content' ) ).toBeInTheDocument(); expect( handleHideMock ).not.toHaveBeenCalled(); - fireEvent.click( screen.getByText( 'Trigger element' ) ); + await userEvent.click( screen.getByText( 'Trigger element' ) ); jest.runAllTimers(); expect( handleHideMock ).toHaveBeenCalled(); } ); - it( 'asks other Tooltips to hide, when multiple are opened', () => { + it( 'asks other Tooltips to hide, when multiple are opened', async () => { const handleHide1Mock = jest.fn(); const handleHide2Mock = jest.fn(); render( @@ -97,7 +98,9 @@ describe( 'Tooltip', () => { expect( handleHide2Mock ).not.toHaveBeenCalled(); // opening the first tooltip, no need to call any hide handlers - act( () => fireEvent.click( screen.getByText( 'Open tooltip 1' ) ) ); + await act( async () => { + await userEvent.click( screen.getByText( 'Open tooltip 1' ) ); + } ); expect( screen.queryByText( 'Tooltip 1 content' ) ).toBeInTheDocument(); expect( @@ -109,8 +112,8 @@ describe( 'Tooltip', () => { jest.runAllTimers(); // opening the second tooltip, only the first tooltip should not be visible anymore - act( () => { - fireEvent.click( screen.getByText( 'Open tooltip 2' ) ); + await act( async () => { + await userEvent.click( screen.getByText( 'Open tooltip 2' ) ); jest.runAllTimers(); } ); diff --git a/client/components/tooltip/test/tooltip-base.test.js b/client/components/tooltip/test/tooltip-base.test.js index 661ef9e371..7108ec0331 100644 --- a/client/components/tooltip/test/tooltip-base.test.js +++ b/client/components/tooltip/test/tooltip-base.test.js @@ -1,4 +1,5 @@ -import { fireEvent, render, screen } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import TooltipBase from '../tooltip-base'; jest.useFakeTimers(); @@ -44,7 +45,7 @@ describe( 'TooltipBase', () => { expect( handleHideMock ).not.toHaveBeenCalled(); } ); - it( 'does not call onHide when an internal element is clicked', () => { + it( 'does not call onHide when an internal element is clicked', async () => { const handleHideMock = jest.fn(); render( { ); - fireEvent.click( screen.getByText( 'Tooltip content' ) ); + await userEvent.click( screen.getByText( 'Tooltip content' ) ); jest.runAllTimers(); expect( screen.queryByText( 'Trigger element' ) ).toBeInTheDocument(); expect( handleHideMock ).not.toHaveBeenCalled(); } ); - it( 'calls onHide when an external element is clicked', () => { + it( 'calls onHide when an external element is clicked', async () => { const handleHideMock = jest.fn(); render( <> @@ -78,7 +79,7 @@ describe( 'TooltipBase', () => { ); - fireEvent.click( screen.getByText( 'External element' ) ); + await userEvent.click( screen.getByText( 'External element' ) ); jest.runAllTimers(); expect( screen.queryByText( 'Trigger element' ) ).toBeInTheDocument(); diff --git a/client/settings/advanced-settings-section/__tests__/optimized-checkout-feature.test.js b/client/settings/advanced-settings-section/__tests__/optimized-checkout-feature.test.js index 7cd150ea52..d43a64e17c 100644 --- a/client/settings/advanced-settings-section/__tests__/optimized-checkout-feature.test.js +++ b/client/settings/advanced-settings-section/__tests__/optimized-checkout-feature.test.js @@ -1,8 +1,11 @@ -import { fireEvent, render, screen } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; import React from 'react'; +import userEvent from '@testing-library/user-event'; import OptimizedCheckoutFeature from 'wcstripe/settings/advanced-settings-section/optimized-checkout-feature'; import { useIsOCEnabled, useIsUpeEnabled, useOCLayout } from 'wcstripe/data'; +jest.useFakeTimers(); + jest.mock( 'wcstripe/data', () => ( { useIsUpeEnabled: jest.fn(), useIsOCEnabled: jest.fn(), @@ -16,7 +19,7 @@ jest.mock( '@woocommerce/navigation', () => ( { describe( 'Optimized Checkout Element feature setting', () => { beforeEach( () => { useIsUpeEnabled.mockReturnValue( [ true, jest.fn() ] ); - useIsOCEnabled.mockReturnValue( [ true, jest.fn() ] ); + useIsOCEnabled.mockReturnValue( [ false, jest.fn() ] ); useOCLayout.mockReturnValue( [ 'accordion', jest.fn() ] ); } ); @@ -30,7 +33,7 @@ describe( 'Optimized Checkout Element feature setting', () => { ).toBeInTheDocument(); } ); - it( 'should disable the OC setting on click', () => { + it( 'should disable the OC setting on click', async () => { const setIsOCEnabledMock = jest.fn(); useIsOCEnabled.mockReturnValue( [ true, setIsOCEnabledMock ] ); @@ -40,20 +43,26 @@ describe( 'Optimized Checkout Element feature setting', () => { 'optimized-checkout-element-checkbox' ); - fireEvent.click( OCCheckbox ); + await userEvent.click( OCCheckbox ); expect( setIsOCEnabledMock ).toHaveBeenCalled(); } ); - it( 'should be disabled when UPE is disabled', () => { + it( 'should be disabled when UPE is disabled', async () => { useIsUpeEnabled.mockReturnValue( [ false, jest.fn() ] ); - const mockSetIsOCEnabled = jest.fn(); - useIsOCEnabled.mockReturnValue( [ false, mockSetIsOCEnabled ] ); - render( ); - expect( mockSetIsOCEnabled ).toHaveBeenCalledWith( false ); + const checkbox = screen.getByTestId( + 'optimized-checkout-element-checkbox' + ); + + await userEvent.click( checkbox ); + + jest.runAllTimers(); + + expect( checkbox ).toBeDisabled(); + expect( checkbox ).not.toBeChecked(); } ); it( 'layout setting should be available when OC is enabled', () => { @@ -70,7 +79,7 @@ describe( 'Optimized Checkout Element feature setting', () => { expect( help ).toBeInTheDocument(); } ); - it( 'triggers the hook when changing the layout setting', () => { + it( 'triggers the hook when changing the layout setting', async () => { useIsOCEnabled.mockReturnValue( [ true, jest.fn() ] ); const setLayoutMock = jest.fn(); @@ -80,7 +89,7 @@ describe( 'Optimized Checkout Element feature setting', () => { expect( setLayoutMock ).not.toHaveBeenCalled(); - fireEvent.click( screen.getByLabelText( 'Tabs' ) ); + await userEvent.click( screen.getByLabelText( 'Tabs' ) ); expect( setLayoutMock ).toHaveBeenCalledWith( 'tabs' ); } ); } ); diff --git a/client/settings/general-settings-section/__tests__/general-settings-section.test.js b/client/settings/general-settings-section/__tests__/general-settings-section.test.js index 57f9e1ed44..91da133543 100644 --- a/client/settings/general-settings-section/__tests__/general-settings-section.test.js +++ b/client/settings/general-settings-section/__tests__/general-settings-section.test.js @@ -1,6 +1,7 @@ import { getSetting } from '@woocommerce/settings'; import React from 'react'; -import { screen, render, fireEvent } from '@testing-library/react'; +import { screen, render } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import GeneralSettingsSection from '..'; import UpeToggleContext from '../../upe-toggle/context'; import { @@ -110,7 +111,7 @@ describe( 'GeneralSettingsSection', () => { global.wcSettings = globalValues; } ); - it( 'should show information to screen readers about the payment methods being updated', () => { + it( 'should show information to screen readers about the payment methods being updated', async () => { const refreshAccountMock = jest.fn(); useAccount.mockReturnValue( { isRefreshing: true, @@ -131,7 +132,7 @@ describe( 'GeneralSettingsSection', () => { ) ).toBeInTheDocument(); - fireEvent.click( + await userEvent.click( screen.getByRole( 'button', { name: 'Payment methods menu', } ) @@ -139,7 +140,7 @@ describe( 'GeneralSettingsSection', () => { expect( refreshAccountMock ).not.toHaveBeenCalled(); - fireEvent.click( + await userEvent.click( screen.getByRole( 'menuitem', { name: 'Refresh payment methods', } ) @@ -164,7 +165,7 @@ describe( 'GeneralSettingsSection', () => { ).toBeInTheDocument(); } ); - it( 'should allow to enable a payment method when UPE is enabled', () => { + it( 'should allow to enable a payment method when UPE is enabled', async () => { useGetAvailablePaymentMethodIds.mockReturnValue( [ PAYMENT_METHOD_CARD, PAYMENT_METHOD_ALIPAY, @@ -198,7 +199,7 @@ describe( 'GeneralSettingsSection', () => { expect( updateEnabledMethodsMock ).not.toHaveBeenCalled(); expect( alipayCheckbox ).not.toBeChecked(); - fireEvent.click( alipayCheckbox ); + await userEvent.click( alipayCheckbox ); expect( updateEnabledMethodsMock ).toHaveBeenCalledWith( [ PAYMENT_METHOD_CARD, @@ -206,7 +207,7 @@ describe( 'GeneralSettingsSection', () => { ] ); } ); - it( 'should allow to enable a payment method when UPE is disabled', () => { + it( 'should allow to enable a payment method when UPE is disabled', async () => { useGetAvailablePaymentMethodIds.mockReturnValue( [ PAYMENT_METHOD_CARD, PAYMENT_METHOD_ALIPAY, @@ -240,7 +241,7 @@ describe( 'GeneralSettingsSection', () => { expect( updateEnabledMethodsMock ).not.toHaveBeenCalled(); expect( alipayCheckbox ).not.toBeChecked(); - fireEvent.click( alipayCheckbox ); + await userEvent.click( alipayCheckbox ); expect( updateEnabledMethodsMock ).toHaveBeenCalledWith( [ PAYMENT_METHOD_CARD, @@ -248,7 +249,7 @@ describe( 'GeneralSettingsSection', () => { ] ); } ); - it( 'should show modal to disable a payment method', () => { + it( 'should show modal to disable a payment method', async () => { useGetAvailablePaymentMethodIds.mockReturnValue( [ PAYMENT_METHOD_CARD, PAYMENT_METHOD_ALIPAY, @@ -277,7 +278,7 @@ describe( 'GeneralSettingsSection', () => { } ) ).not.toBeInTheDocument(); - fireEvent.click( cardCheckbox ); + await userEvent.click( cardCheckbox ); expect( screen.getByRole( 'heading', { @@ -286,7 +287,7 @@ describe( 'GeneralSettingsSection', () => { ).toBeInTheDocument(); } ); - it( 'should not allow to disable a payment method when canceled via modal', () => { + it( 'should not allow to disable a payment method when canceled via modal', async () => { useGetAvailablePaymentMethodIds.mockReturnValue( [ PAYMENT_METHOD_CARD, PAYMENT_METHOD_ALIPAY, @@ -311,13 +312,15 @@ describe( 'GeneralSettingsSection', () => { expect( updateEnabledMethodsMock ).not.toHaveBeenCalled(); expect( cardCheckbox ).toBeChecked(); - fireEvent.click( cardCheckbox ); - fireEvent.click( screen.getByRole( 'button', { name: 'Cancel' } ) ); + await userEvent.click( cardCheckbox ); + await userEvent.click( + screen.getByRole( 'button', { name: 'Cancel' } ) + ); expect( updateEnabledMethodsMock ).not.toHaveBeenCalled(); } ); - it( 'should allow to disable a payment method when confirmed via modal', () => { + it( 'should allow to disable a payment method when confirmed via modal', async () => { useGetAvailablePaymentMethodIds.mockReturnValue( [ PAYMENT_METHOD_CARD, PAYMENT_METHOD_ALIPAY, @@ -342,8 +345,10 @@ describe( 'GeneralSettingsSection', () => { expect( updateEnabledMethodsMock ).not.toHaveBeenCalled(); expect( cardCheckbox ).toBeChecked(); - fireEvent.click( cardCheckbox ); - fireEvent.click( screen.getByRole( 'button', { name: 'Remove' } ) ); + await userEvent.click( cardCheckbox ); + await userEvent.click( + screen.getByRole( 'button', { name: 'Remove' } ) + ); expect( updateEnabledMethodsMock ).toHaveBeenCalled(); } ); diff --git a/client/settings/notices/legacy-experience-transition/__tests__/legacy-experience-transition.test.js b/client/settings/notices/legacy-experience-transition/__tests__/legacy-experience-transition.test.js index 08942e75e9..e9fd679f8d 100644 --- a/client/settings/notices/legacy-experience-transition/__tests__/legacy-experience-transition.test.js +++ b/client/settings/notices/legacy-experience-transition/__tests__/legacy-experience-transition.test.js @@ -1,6 +1,7 @@ import { useDispatch } from '@wordpress/data'; +import userEvent from '@testing-library/user-event'; import React from 'react'; -import { screen, render, fireEvent } from '@testing-library/react'; +import { screen, render } from '@testing-library/react'; import LegacyExperienceTransitionNotice from '..'; import { recordEvent } from 'wcstripe/tracking'; @@ -50,7 +51,7 @@ describe( 'LegacyExperienceTransitionNotice', () => { ).not.toBeInTheDocument(); } ); - it( 'should enable UPE when clicking on the CTA button', () => { + it( 'should enable UPE when clicking on the CTA button', async () => { const setIsUpeEnabledMock = jest.fn().mockResolvedValue( true ); render( @@ -60,11 +61,13 @@ describe( 'LegacyExperienceTransitionNotice', () => { /> ); - fireEvent.click( screen.queryByTestId( 'disable-legacy-button' ) ); + await userEvent.click( + screen.queryByTestId( 'disable-legacy-button' ) + ); expect( setIsUpeEnabledMock ).toHaveBeenCalled(); } ); - it( 'should display a success message when clicking on the CTA button', () => { + it( 'should display a success message when clicking on the CTA button', async () => { render( { /> ); - fireEvent.click( screen.queryByTestId( 'disable-legacy-button' ) ); + await userEvent.click( + screen.queryByTestId( 'disable-legacy-button' ) + ); expect( noticesDispatch.createSuccessNotice ).toHaveBeenCalledWith( 'New checkout experience enabled' ); } ); - it( 'should record a Track event when clicking on the CTA button', () => { + it( 'should record a Track event when clicking on the CTA button', async () => { render( { /> ); - fireEvent.click( screen.queryByTestId( 'disable-legacy-button' ) ); + await userEvent.click( + screen.queryByTestId( 'disable-legacy-button' ) + ); expect( recordEvent ).toHaveBeenCalledWith( 'wcstripe_legacy_experience_disabled', diff --git a/client/settings/payment-settings/__tests__/account-details-section.test.js b/client/settings/payment-settings/__tests__/account-details-section.test.js index ccb637170f..b8fbd45389 100644 --- a/client/settings/payment-settings/__tests__/account-details-section.test.js +++ b/client/settings/payment-settings/__tests__/account-details-section.test.js @@ -1,5 +1,6 @@ import React from 'react'; -import { screen, render, fireEvent, waitFor } from '@testing-library/react'; +import { screen, render } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import AccountDetailsSection from '../account-details-section'; import { useTestMode } from 'wcstripe/data'; import { @@ -77,7 +78,7 @@ describe( 'AccountDetailsSection', () => { jest.restoreAllMocks(); } ); - it( 'should open live account keys modal when Configure connection clicked in live mode', () => { + it( 'should open live account keys modal when Configure connection clicked in live mode', async () => { useAccount.mockReturnValue( { data: { webhook_url: 'example.com', @@ -108,11 +109,11 @@ describe( 'AccountDetailsSection', () => { const editKeysButton = screen.getByRole( 'button', { name: 'Configure connection', } ); - fireEvent.click( editKeysButton ); + await userEvent.click( editKeysButton ); expect( setModalTypeMock ).toHaveBeenCalledWith( 'live' ); } ); - it( 'should open test account keys modal when Configure connection clicked in test mode', () => { + it( 'should open test account keys modal when Configure connection clicked in test mode', async () => { useAccount.mockReturnValue( { data: { webhook_url: 'example.com', @@ -143,7 +144,7 @@ describe( 'AccountDetailsSection', () => { const editKeysButton = screen.getByRole( 'button', { name: /Configure connection/i, } ); - fireEvent.click( editKeysButton ); + await userEvent.click( editKeysButton ); expect( setModalTypeMock ).toHaveBeenCalledWith( 'test' ); } ); @@ -212,16 +213,13 @@ describe( 'AccountDetailsSection', () => { const menuButton = screen.getByLabelText( 'Edit details or disconnect account' ); - fireEvent.click( menuButton ); - - await waitFor( () => { - // Check if dropdown menu is open - expect( - screen.getByRole( 'menu', { - name: 'Edit details or disconnect account', - } ) - ).toBeInTheDocument(); + await userEvent.click( menuButton ); + + // Check if refresh option exists + const refreshButton = screen.getByRole( 'menuitem', { + name: /refresh account details/i, } ); + expect( refreshButton ).toBeInTheDocument(); } ); it( 'should call refreshAccount when refresh option is clicked', async () => { @@ -233,13 +231,13 @@ describe( 'AccountDetailsSection', () => { const menuButton = screen.getByLabelText( 'Edit details or disconnect account' ); - fireEvent.click( menuButton ); + await userEvent.click( menuButton ); // Click the refresh option const refreshButton = screen.getByRole( 'menuitem', { name: /refresh account details/i, } ); - fireEvent.click( refreshButton ); + await userEvent.click( refreshButton ); expect( mockRefreshAccount ).toHaveBeenCalledTimes( 1 ); } ); diff --git a/client/settings/payment-settings/__tests__/disconnect-stripe-confirmation-modal.test.js b/client/settings/payment-settings/__tests__/disconnect-stripe-confirmation-modal.test.js index cce109cc1a..d6f00da9f4 100644 --- a/client/settings/payment-settings/__tests__/disconnect-stripe-confirmation-modal.test.js +++ b/client/settings/payment-settings/__tests__/disconnect-stripe-confirmation-modal.test.js @@ -1,6 +1,7 @@ import { useDispatch } from '@wordpress/data'; import React from 'react'; -import { screen, render, fireEvent } from '@testing-library/react'; +import { screen, render } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import DisconnectStripeConfirmationModal from '../disconnect-stripe-confirmation-modal'; import { useAccountKeys } from 'wcstripe/data/account-keys/hooks'; @@ -67,7 +68,7 @@ describe( 'DisconnectStripeConfirmationModal', () => { ).toBeInTheDocument(); } ); - it( 'should call onClose when the action is cancelled', () => { + it( 'should call onClose when the action is cancelled', async () => { render( { expect( handleCloseMock ).not.toHaveBeenCalled(); - fireEvent.click( screen.getByRole( 'button', { name: 'Cancel' } ) ); + await userEvent.click( + screen.getByRole( 'button', { name: 'Cancel' } ) + ); expect( handleCloseMock ).toHaveBeenCalled(); } ); @@ -94,7 +97,9 @@ describe( 'DisconnectStripeConfirmationModal', () => { expect( saveAccountKeysMock ).not.toHaveBeenCalled(); expect( setKeepModalContentMock ).not.toHaveBeenCalled(); - fireEvent.click( screen.getByRole( 'button', { name: 'Disconnect' } ) ); + await userEvent.click( + screen.getByRole( 'button', { name: 'Disconnect' } ) + ); await expect( saveAccountKeysMock ).toHaveBeenCalled(); diff --git a/client/settings/payment-settings/promotional-banner/__tests__/bnpl-promotion-banner.test.js b/client/settings/payment-settings/promotional-banner/__tests__/bnpl-promotion-banner.test.js index 35e3176331..5197edfb3b 100644 --- a/client/settings/payment-settings/promotional-banner/__tests__/bnpl-promotion-banner.test.js +++ b/client/settings/payment-settings/promotional-banner/__tests__/bnpl-promotion-banner.test.js @@ -1,4 +1,5 @@ -import { act, fireEvent, render } from '@testing-library/react'; +import { act, render } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import apiFetch from '@wordpress/api-fetch'; import { BNPLPromotionBanner } from '../bnpl-promotion-banner'; @@ -59,7 +60,7 @@ describe( 'BNPL promotional banner', () => { const dismissButton = getByText( 'Dismiss' ); await act( async () => { - await fireEvent.click( dismissButton ); + await userEvent.click( dismissButton ); } ); expect( dismissNoticeMock ).toHaveBeenCalled(); diff --git a/client/settings/payment-settings/promotional-banner/__tests__/index.test.js b/client/settings/payment-settings/promotional-banner/__tests__/index.test.js index 7953cbce67..b5ec26b6eb 100644 --- a/client/settings/payment-settings/promotional-banner/__tests__/index.test.js +++ b/client/settings/payment-settings/promotional-banner/__tests__/index.test.js @@ -1,6 +1,7 @@ import { useDispatch } from '@wordpress/data'; import React from 'react'; -import { screen, render, fireEvent } from '@testing-library/react'; +import { screen, render } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import PromotionalBanner from '..'; import { useEnabledPaymentMethodIds } from 'wcstripe/data'; import { @@ -57,7 +58,7 @@ describe( 'PromotionalBanner', () => { jest.restoreAllMocks(); } ); - it( 'dismiss function should be called', () => { + it( 'dismiss function should be called', async () => { render( { const dismissButton = screen.getByTestId( 'dismiss' ); - fireEvent.click( dismissButton ); + await userEvent.click( dismissButton ); expect( setShowPromotionalBanner ).toHaveBeenCalledWith( false ); } ); - it( 'Main CTA link for the first version should disable the legacy checkout experience', () => { + it( 'Main CTA link for the first version should disable the legacy checkout experience', async () => { const setIsUpeEnabledMock = jest.fn().mockResolvedValue( true ); render( @@ -86,7 +87,7 @@ describe( 'PromotionalBanner', () => { /> ); - fireEvent.click( screen.getByText( 'Enable the new checkout' ) ); + await userEvent.click( screen.getByText( 'Enable the new checkout' ) ); expect( setIsUpeEnabledMock ).toHaveBeenCalled(); } ); diff --git a/client/settings/payment-settings/promotional-banner/__tests__/new-checkout-experience-apms-banner.test.js b/client/settings/payment-settings/promotional-banner/__tests__/new-checkout-experience-apms-banner.test.js index 60e19200c7..2fdc30b161 100644 --- a/client/settings/payment-settings/promotional-banner/__tests__/new-checkout-experience-apms-banner.test.js +++ b/client/settings/payment-settings/promotional-banner/__tests__/new-checkout-experience-apms-banner.test.js @@ -1,5 +1,6 @@ import { useDispatch } from '@wordpress/data'; -import { fireEvent, render } from '@testing-library/react'; +import { render } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import { NewCheckoutExperienceAPMsBanner } from 'wcstripe/settings/payment-settings/promotional-banner/new-checkout-experience-apms-banner'; const noticesDispatch = { @@ -49,7 +50,7 @@ describe( 'New checkout experience APMs banner', () => { ).toBeInTheDocument(); expect( getByText( 'Enable the new checkout' ) ).toBeInTheDocument(); } ); - it( 'should dismiss on button click', () => { + it( 'should dismiss on button click', async () => { const { getByText } = render( { ); const dismissButton = getByText( 'Dismiss' ); - fireEvent.click( dismissButton ); + await userEvent.click( dismissButton ); expect( setShowPromotionalBanner ).toHaveBeenCalledWith( false ); } ); diff --git a/client/settings/payment-settings/promotional-banner/__tests__/new-checkout-experience-banner.test.js b/client/settings/payment-settings/promotional-banner/__tests__/new-checkout-experience-banner.test.js index 52caf9a186..792e453e81 100644 --- a/client/settings/payment-settings/promotional-banner/__tests__/new-checkout-experience-banner.test.js +++ b/client/settings/payment-settings/promotional-banner/__tests__/new-checkout-experience-banner.test.js @@ -1,5 +1,6 @@ import { useDispatch } from '@wordpress/data'; -import { fireEvent, render } from '@testing-library/react'; +import { render } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import { NewCheckoutExperienceBanner } from 'wcstripe/settings/payment-settings/promotional-banner/new-checkout-experience-banner'; const noticesDispatch = { @@ -47,7 +48,7 @@ describe( 'New checkout experience banner', () => { ).toBeInTheDocument(); expect( getByText( 'Enable the new checkout' ) ).toBeInTheDocument(); } ); - it( 'should dismiss on button click', () => { + it( 'should dismiss on button click', async () => { const { getByText } = render( { ); const dismissButton = getByText( 'Dismiss' ); - fireEvent.click( dismissButton ); + await userEvent.click( dismissButton ); expect( setShowPromotionalBanner ).toHaveBeenCalledWith( false ); } ); diff --git a/client/settings/payment-settings/promotional-banner/__tests__/oc-promotion-banner.test.js b/client/settings/payment-settings/promotional-banner/__tests__/oc-promotion-banner.test.js index 7ff1a55b71..6799b7a4c9 100644 --- a/client/settings/payment-settings/promotional-banner/__tests__/oc-promotion-banner.test.js +++ b/client/settings/payment-settings/promotional-banner/__tests__/oc-promotion-banner.test.js @@ -1,5 +1,6 @@ import { useDispatch } from '@wordpress/data'; -import { act, fireEvent, render } from '@testing-library/react'; +import { act, render } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import apiFetch from '@wordpress/api-fetch'; import { OCPromotionBanner } from '../oc-promotion-banner'; @@ -73,7 +74,7 @@ describe( 'OC promotional banner', () => { const dismissButton = getByText( 'Dismiss' ); await act( async () => { - await fireEvent.click( dismissButton ); + await userEvent.click( dismissButton ); } ); expect( dismissNoticeMock ).toHaveBeenCalled(); @@ -93,7 +94,7 @@ describe( 'OC promotional banner', () => { const activateButton = getByText( 'Activate now' ); await act( async () => { - await fireEvent.click( activateButton ); + await userEvent.click( activateButton ); } ); expect( setIsOCEnabled ).toHaveBeenCalled(); } ); diff --git a/client/settings/payment-settings/promotional-banner/__tests__/re-connect-account-banner.test.js b/client/settings/payment-settings/promotional-banner/__tests__/re-connect-account-banner.test.js index 29ad1a9a1b..d17970564b 100644 --- a/client/settings/payment-settings/promotional-banner/__tests__/re-connect-account-banner.test.js +++ b/client/settings/payment-settings/promotional-banner/__tests__/re-connect-account-banner.test.js @@ -1,5 +1,6 @@ import { useDispatch } from '@wordpress/data'; -import { fireEvent, render } from '@testing-library/react'; +import { render } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import { ReConnectAccountBanner } from 'wcstripe/settings/payment-settings/promotional-banner/re-connect-account-banner'; import { recordEvent } from 'wcstripe/tracking'; import { useTestMode } from 'wcstripe/data'; @@ -46,7 +47,7 @@ describe( 'Reconnect banner', () => { ).toBeInTheDocument(); expect( getByText( 'Re-authenticate' ) ).toBeInTheDocument(); } ); - it( 'should record event on button click', () => { + it( 'should record event on button click', async () => { // Keep the original function at hand. const assign = window.location.assign; @@ -59,7 +60,7 @@ describe( 'Reconnect banner', () => { ); const reconnectButton = getByText( 'Re-authenticate' ); - fireEvent.click( reconnectButton ); + await userEvent.click( reconnectButton ); expect( recordEvent ).toHaveBeenCalledWith( 'wcstripe_create_or_connect_test_account_click', @@ -73,7 +74,7 @@ describe( 'Reconnect banner', () => { value: { assign }, } ); } ); - it( 'should create error notice when test oauth URL is invalid, and test mode is enabled', () => { + it( 'should create error notice when test oauth URL is invalid, and test mode is enabled', async () => { const oauthUrl = 'http://example.com/test-oauth'; const { getByText } = render( { /> ); const reconnectButton = getByText( 'Re-authenticate' ); - fireEvent.click( reconnectButton ); + await userEvent.click( reconnectButton ); expect( noticesDispatch.createErrorNotice ).toHaveBeenCalledWith( 'There was an error. Please reload the page and try again.' ); } ); - it( 'should create error notice when live oauth URL is invalid, and test mode is disabled', () => { + it( 'should create error notice when live oauth URL is invalid, and test mode is disabled', async () => { useTestMode.mockReturnValue( [ false, jest.fn() ] ); const oauthUrl = 'http://example.com/test-oauth'; @@ -99,18 +100,18 @@ describe( 'Reconnect banner', () => { /> ); const reconnectButton = getByText( 'Re-authenticate' ); - fireEvent.click( reconnectButton ); + await userEvent.click( reconnectButton ); expect( noticesDispatch.createErrorNotice ).toHaveBeenCalledWith( 'There was an error. Please reload the page and try again.' ); } ); - it( 'should create error notice when both oauth URLs are invalid', () => { + it( 'should create error notice when both oauth URLs are invalid', async () => { const { getByText } = render( ); const reconnectButton = getByText( 'Re-authenticate' ); - fireEvent.click( reconnectButton ); + await userEvent.click( reconnectButton ); expect( noticesDispatch.createErrorNotice ).toHaveBeenCalledWith( 'There was an error. Please reload the page and try again.' diff --git a/client/settings/settings-manager/__tests__/index.test.js b/client/settings/settings-manager/__tests__/index.test.js index 5d5a02af90..d0493cd265 100644 --- a/client/settings/settings-manager/__tests__/index.test.js +++ b/client/settings/settings-manager/__tests__/index.test.js @@ -11,10 +11,6 @@ jest.mock( 'wcstripe/settings/notices/legacy-experience-transition', () => () => null ); -jest.mock( 'wcstripe/settings/payment-settings/promotional-banner', () => () => - null -); - jest.mock( 'wcstripe/settings/payment-settings/promotional-banner/get-promotional-banner-type', () => ( { diff --git a/client/stripe-utils/__tests__/cash-app-limit-notice-handler.test.js b/client/stripe-utils/__tests__/cash-app-limit-notice-handler.test.js index 265f417ffe..d9ca393bdb 100644 --- a/client/stripe-utils/__tests__/cash-app-limit-notice-handler.test.js +++ b/client/stripe-utils/__tests__/cash-app-limit-notice-handler.test.js @@ -1,18 +1,26 @@ import { render, screen } from '@testing-library/react'; -import { maybeShowCashAppLimitNotice } from 'wcstripe/stripe-utils/cash-app-limit-notice-handler'; +import { + CASH_APP_NOTICE_AMOUNT_THRESHOLD, + maybeShowCashAppLimitNotice, +} from 'wcstripe/stripe-utils/cash-app-limit-notice-handler'; import { callWhenElementIsAvailable } from 'wcstripe/blocks/upe/call-when-element-is-available'; -import { CASH_APP_NOTICE_AMOUNT_THRESHOLD } from 'wcstripe/data/constants'; const wrapperElementClassName = 'woocommerce-checkout-payment'; jest.mock( 'wcstripe/blocks/upe/call-when-element-is-available' ); +const elementLoadingDelay = 500; + callWhenElementIsAvailable.mockImplementation( ( selector, callable, params ) => { - callable( ...params ); + setTimeout( () => { + callable( ...params ); + }, elementLoadingDelay ); } ); +jest.useFakeTimers(); + describe( 'cash-app-limit-notice-handler', () => { it( 'does not render notice, cart amount is below threshold, wrapper not found and it is not a block checkout', () => { maybeShowCashAppLimitNotice( @@ -20,7 +28,6 @@ describe( 'cash-app-limit-notice-handler', () => { 0, false ); - expect( screen.queryByTestId( 'cash-app-limit-notice' ) ).not.toBeInTheDocument(); @@ -28,9 +35,7 @@ describe( 'cash-app-limit-notice-handler', () => { it( 'does not render notice, cart amount is below threshold, but try to wait for wrapper to exist (block checkout)', () => { render(
); - maybeShowCashAppLimitNotice( '.woocommerce-checkout-payment', 0, true ); - expect( screen.queryByTestId( 'cash-app-limit-notice' ) ).not.toBeInTheDocument(); @@ -38,23 +43,23 @@ describe( 'cash-app-limit-notice-handler', () => { it( 'render notice immediately (not block checkout, cart amount above threshold)', () => { render(
); - maybeShowCashAppLimitNotice( '.woocommerce-checkout-payment', CASH_APP_NOTICE_AMOUNT_THRESHOLD + 1, false ); - expect( screen.queryByTestId( 'cash-app-limit-notice' ) ).toBeInTheDocument(); } ); - it( 'render notice after wrapper exists on block checkout (cart amount above threshold)', async () => { + it( 'render notice after wrapper exists on block checkout (cart amount above threshold)', () => { function App() { - const wrapper = document.createElement( 'div' ); - wrapper.classList.add( wrapperElementClassName ); - document.body.appendChild( wrapper ); + setTimeout( () => { + const wrapper = document.createElement( 'div' ); + wrapper.classList.add( wrapperElementClassName ); + document.body.appendChild( wrapper ); + }, elementLoadingDelay - 100 ); return
; } @@ -66,6 +71,8 @@ describe( 'cash-app-limit-notice-handler', () => { true ); + jest.runAllTimers(); + expect( screen.queryByTestId( 'cash-app-limit-notice' ) ).toBeInTheDocument(); From 5200f39f16dc8506880e8d272480257673ac7bd9 Mon Sep 17 00:00:00 2001 From: Wesley Rosa Date: Thu, 21 Aug 2025 10:46:13 -0300 Subject: [PATCH 06/12] Update changelog.txt Co-authored-by: daledupreez --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index edf0f35971..e60773d547 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,6 +1,7 @@ *** Changelog *** = 9.9.0 - xxxx-xx-xx = +* Dev - Update Javascript unit tests for compatibility with Node 20 * Dev - Multiple updates to the frontend unit tests in preparation for the Node 20 upgrade * Dev - Replaces some payment method instantiation logic for the Optimized Checkout with calls to the `get_payment_method_instance` method * Dev - Multiple lint fixes in preparation for the Node 20 upgrade From 08ca91755026d94447586994761c0ebe3ea335c1 Mon Sep 17 00:00:00 2001 From: Wesley Rosa Date: Thu, 21 Aug 2025 10:46:57 -0300 Subject: [PATCH 07/12] Readme entry --- readme.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.txt b/readme.txt index 127c2fc755..94f7c85159 100644 --- a/readme.txt +++ b/readme.txt @@ -111,6 +111,7 @@ If you get stuck, you can ask for help in the [Plugin Forum](https://wordpress.o == Changelog == = 9.9.0 - xxxx-xx-xx = +* Dev - Update Javascript unit tests for compatibility with Node 20 * Dev - Multiple updates to the frontend unit tests in preparation for the Node 20 upgrade * Dev - Replaces some payment method instantiation logic for the Optimized Checkout with calls to the `get_payment_method_instance` method * Dev - Multiple lint fixes in preparation for the Node 20 upgrade From 065be1363f374c9a4ea5b5c80921a7f8c2ab6abc Mon Sep 17 00:00:00 2001 From: Wesley Rosa Date: Fri, 22 Aug 2025 15:27:20 -0300 Subject: [PATCH 08/12] Fix rebase --- changelog.txt | 1 - readme.txt | 1 - 2 files changed, 2 deletions(-) diff --git a/changelog.txt b/changelog.txt index e60773d547..191a7ea05e 100644 --- a/changelog.txt +++ b/changelog.txt @@ -2,7 +2,6 @@ = 9.9.0 - xxxx-xx-xx = * Dev - Update Javascript unit tests for compatibility with Node 20 -* Dev - Multiple updates to the frontend unit tests in preparation for the Node 20 upgrade * Dev - Replaces some payment method instantiation logic for the Optimized Checkout with calls to the `get_payment_method_instance` method * Dev - Multiple lint fixes in preparation for the Node 20 upgrade * Dev - Introduces a new helper method to identify Stripe orders diff --git a/readme.txt b/readme.txt index 94f7c85159..2754d050fd 100644 --- a/readme.txt +++ b/readme.txt @@ -112,7 +112,6 @@ If you get stuck, you can ask for help in the [Plugin Forum](https://wordpress.o = 9.9.0 - xxxx-xx-xx = * Dev - Update Javascript unit tests for compatibility with Node 20 -* Dev - Multiple updates to the frontend unit tests in preparation for the Node 20 upgrade * Dev - Replaces some payment method instantiation logic for the Optimized Checkout with calls to the `get_payment_method_instance` method * Dev - Multiple lint fixes in preparation for the Node 20 upgrade * Dev - Introduces a new helper method to identify Stripe orders From 2c6d0674a29fa2e1dc39d0f89fea9375e06fc8b5 Mon Sep 17 00:00:00 2001 From: Wesley Rosa Date: Fri, 22 Aug 2025 17:27:26 -0300 Subject: [PATCH 09/12] Reflecting latest changes from the main PR --- .../__tests__/optimized-checkout-feature.test.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/client/settings/advanced-settings-section/__tests__/optimized-checkout-feature.test.js b/client/settings/advanced-settings-section/__tests__/optimized-checkout-feature.test.js index d43a64e17c..b62c2a3f11 100644 --- a/client/settings/advanced-settings-section/__tests__/optimized-checkout-feature.test.js +++ b/client/settings/advanced-settings-section/__tests__/optimized-checkout-feature.test.js @@ -1,4 +1,4 @@ -import { render, screen } from '@testing-library/react'; +import { render, screen, waitFor } from '@testing-library/react'; import React from 'react'; import userEvent from '@testing-library/user-event'; import OptimizedCheckoutFeature from 'wcstripe/settings/advanced-settings-section/optimized-checkout-feature'; @@ -45,7 +45,9 @@ describe( 'Optimized Checkout Element feature setting', () => { await userEvent.click( OCCheckbox ); - expect( setIsOCEnabledMock ).toHaveBeenCalled(); + await waitFor( () => { + expect( setIsOCEnabledMock ).toHaveBeenCalled(); + } ); } ); it( 'should be disabled when UPE is disabled', async () => { @@ -89,7 +91,10 @@ describe( 'Optimized Checkout Element feature setting', () => { expect( setLayoutMock ).not.toHaveBeenCalled(); - await userEvent.click( screen.getByLabelText( 'Tabs' ) ); - expect( setLayoutMock ).toHaveBeenCalledWith( 'tabs' ); + userEvent.click( screen.getByLabelText( 'Tabs' ) ); + + await waitFor( async () => { + expect( setLayoutMock ).toHaveBeenCalledWith( 'tabs' ); + } ); } ); } ); From 4b4dfa912ee75234f9ec1c2d39e073c0a668c9ef Mon Sep 17 00:00:00 2001 From: Wesley Rosa Date: Mon, 25 Aug 2025 07:07:29 -0300 Subject: [PATCH 10/12] Update client/components/popover/test/index.test.js Co-authored-by: Mayisha <33387139+Mayisha@users.noreply.github.com> --- client/components/popover/test/index.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/components/popover/test/index.test.js b/client/components/popover/test/index.test.js index 7293bffcf4..4fc5e38065 100644 --- a/client/components/popover/test/index.test.js +++ b/client/components/popover/test/index.test.js @@ -40,7 +40,7 @@ describe( 'Popover', () => { expect( screen.queryByText( 'Popover Content' ) ).toBeInTheDocument(); - act( async () => { + await act( async () => { await userEvent.click( screen.getByTestId( 'base-component' ) ); } ); From 44f8c580bb48b6d649154ad85ae53c6ab8d71a18 Mon Sep 17 00:00:00 2001 From: Wesley Rosa Date: Mon, 25 Aug 2025 07:09:46 -0300 Subject: [PATCH 11/12] Update client/components/popover/test/index.test.js Co-authored-by: Mayisha <33387139+Mayisha@users.noreply.github.com> --- client/components/popover/test/index.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/components/popover/test/index.test.js b/client/components/popover/test/index.test.js index 4fc5e38065..0e45ab8d3a 100644 --- a/client/components/popover/test/index.test.js +++ b/client/components/popover/test/index.test.js @@ -34,7 +34,7 @@ describe( 'Popover', () => { screen.queryByText( 'Popover Content' ) ).not.toBeInTheDocument(); - act( async () => { + await act( async () => { await userEvent.click( screen.getByTestId( 'base-component' ) ); } ); From 748c9d8226a66e6ac67b126c0af8838dabcecb7a Mon Sep 17 00:00:00 2001 From: Wesley Rosa Date: Mon, 25 Aug 2025 07:10:00 -0300 Subject: [PATCH 12/12] Update client/settings/advanced-settings-section/__tests__/optimized-checkout-feature.test.js Co-authored-by: Mayisha <33387139+Mayisha@users.noreply.github.com> --- .../__tests__/optimized-checkout-feature.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/settings/advanced-settings-section/__tests__/optimized-checkout-feature.test.js b/client/settings/advanced-settings-section/__tests__/optimized-checkout-feature.test.js index b62c2a3f11..ce58e198d7 100644 --- a/client/settings/advanced-settings-section/__tests__/optimized-checkout-feature.test.js +++ b/client/settings/advanced-settings-section/__tests__/optimized-checkout-feature.test.js @@ -91,7 +91,7 @@ describe( 'Optimized Checkout Element feature setting', () => { expect( setLayoutMock ).not.toHaveBeenCalled(); - userEvent.click( screen.getByLabelText( 'Tabs' ) ); + await userEvent.click( screen.getByLabelText( 'Tabs' ) ); await waitFor( async () => { expect( setLayoutMock ).toHaveBeenCalledWith( 'tabs' );