From 0454bb5837477a99728497e263a188c66810b643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Costa?= <10233985+cesarcosta99@users.noreply.github.com> Date: Mon, 27 Jan 2025 15:05:55 -0300 Subject: [PATCH] Add multi-currency widget setup e2e tests (#10225) --- ...7348-multi-currency-widget-setup-e2e-tests | 4 + .../merchant/multi-currency-widget.spec.ts | 226 ++++++++++++++++++ .../specs/merchant/multi-currency.spec.ts | 2 + tests/e2e-pw/utils/merchant.ts | 69 +++++- 4 files changed, 294 insertions(+), 7 deletions(-) create mode 100644 changelog/add-7348-multi-currency-widget-setup-e2e-tests create mode 100644 tests/e2e-pw/specs/merchant/multi-currency-widget.spec.ts diff --git a/changelog/add-7348-multi-currency-widget-setup-e2e-tests b/changelog/add-7348-multi-currency-widget-setup-e2e-tests new file mode 100644 index 00000000000..a278d17d57e --- /dev/null +++ b/changelog/add-7348-multi-currency-widget-setup-e2e-tests @@ -0,0 +1,4 @@ +Significance: patch +Type: dev + +Add e2e tests for the multi-currency widget setup. diff --git a/tests/e2e-pw/specs/merchant/multi-currency-widget.spec.ts b/tests/e2e-pw/specs/merchant/multi-currency-widget.spec.ts new file mode 100644 index 00000000000..32702571f74 --- /dev/null +++ b/tests/e2e-pw/specs/merchant/multi-currency-widget.spec.ts @@ -0,0 +1,226 @@ +/** + * External dependencies + */ +import { test, expect, Page } from '@playwright/test'; +/** + * Internal dependencies + */ +import { getMerchant, getShopper } from '../../utils/helpers'; +import { + activateMulticurrency, + addMulticurrencyWidget, + deactivateMulticurrency, + removeMulticurrencyWidget, +} from '../../utils/merchant'; +import * as navigation from '../../utils/shopper-navigation'; + +test.describe( 'Multi-currency widget setup', () => { + let merchantPage: Page; + let shopperPage: Page; + let wasMulticurrencyEnabled: boolean; + // Values to test against. Defining nonsense values to ensure they are applied correctly. + const settings = { + borderRadius: '15', + fontSize: '40', + lineHeight: '2.3', + textColor: 'rgb(155, 81, 224)', + borderColor: 'rgb(252, 185, 0)', + }; + + test.beforeAll( async ( { browser } ) => { + shopperPage = ( await getShopper( browser ) ).shopperPage; + merchantPage = ( await getMerchant( browser ) ).merchantPage; + wasMulticurrencyEnabled = await activateMulticurrency( merchantPage ); + + await addMulticurrencyWidget( merchantPage, true ); + } ); + + test.afterAll( async () => { + await removeMulticurrencyWidget( merchantPage, true ); + + if ( ! wasMulticurrencyEnabled ) { + await deactivateMulticurrency( merchantPage ); + } + + await merchantPage.close(); + } ); + + test( 'displays enabled currencies correctly in the admin', async () => { + await expect( + merchantPage + .locator( 'select[name="currency"]' ) + .getByRole( 'option' ) + ).toHaveCount( 3 ); + await expect( + merchantPage + .locator( 'select[name="currency"]' ) + .getByRole( 'option', { name: 'USD' } ) + ).toBeAttached(); + await expect( + merchantPage + .locator( 'select[name="currency"]' ) + .getByRole( 'option', { name: 'EUR' } ) + ).toBeAttached(); + await expect( + merchantPage + .locator( 'select[name="currency"]' ) + .getByRole( 'option', { name: 'GBP' } ) + ).toBeAttached(); + } ); + + test( 'can update widget properties', async () => { + await test.step( 'opens widget settings', async () => { + await merchantPage + .getByRole( 'button', { name: 'Settings' } ) + .click(); + await merchantPage + .locator( '[data-title="Currency Switcher Block"]' ) + .click(); + } ); + + await test.step( 'checks display flags', async () => { + await merchantPage + .getByRole( 'checkbox', { name: 'Display flags' } ) + .check(); + await expect( + await merchantPage + .getByRole( 'checkbox', { name: 'Display flags' } ) + .isChecked() + ).toBeTruthy(); + } ); + + await test.step( 'checks display currency symbols', async () => { + await merchantPage + .getByRole( 'checkbox', { name: 'Display currency symbols' } ) + .check(); + await expect( + await merchantPage + .getByRole( 'checkbox', { + name: 'Display currency symbols', + } ) + .isChecked() + ).toBeTruthy(); + } ); + + await test.step( 'checks border', async () => { + await merchantPage + .getByRole( 'checkbox', { name: 'Border' } ) + .check(); + await expect( + await merchantPage + .getByRole( 'checkbox', { name: 'Border' } ) + .isChecked() + ).toBeTruthy(); + } ); + + await test.step( 'updates border radius', async () => { + await merchantPage + .getByRole( 'spinbutton', { name: 'Border radius' } ) + .fill( settings.borderRadius ); + } ); + + await test.step( 'updates font size', async () => { + await merchantPage + .getByRole( 'spinbutton', { name: 'Size' } ) + .fill( settings.fontSize ); + } ); + + await test.step( 'updates line height', async () => { + await merchantPage + .getByRole( 'spinbutton', { name: 'Line height' } ) + .fill( settings.lineHeight ); + } ); + + await test.step( 'updates text color', async () => { + await merchantPage + .locator( 'fieldset', { hasText: 'Text' } ) + .getByRole( 'listbox', { name: 'Custom color picker' } ) + .getByRole( 'option', { name: 'Vivid purple' } ) + .click(); + } ); + + await test.step( 'updates border color', async () => { + await merchantPage + .locator( 'fieldset', { hasText: 'Border' } ) + .getByRole( 'listbox', { name: 'Custom color picker' } ) + .getByRole( 'option', { name: 'Luminous vivid amber' } ) + .click(); + } ); + + await test.step( 'saves changes', async () => { + await expect( + merchantPage.getByRole( 'button', { name: 'Update' } ) + ).toBeEnabled(); + await merchantPage + .getByRole( 'button', { name: 'Update' } ) + .click(); + await expect( + merchantPage.getByLabel( 'Dismiss this notice' ) + ).toBeVisible( { + timeout: 10000, + } ); + } ); + } ); + + test( 'displays enabled currencies correctly in the frontend', async () => { + await navigation.goToShop( shopperPage ); + + await expect( + await shopperPage.locator( '.currency-switcher-holder' ) + ).toBeVisible(); + await expect( + shopperPage + .locator( '.currency-switcher-holder' ) + .getByRole( 'option' ) + ).toHaveCount( 3 ); + await expect( + shopperPage + .locator( '.currency-switcher-holder' ) + .getByRole( 'option', { name: 'USD' } ) + ).toBeAttached(); + await expect( + shopperPage + .locator( '.currency-switcher-holder' ) + .getByRole( 'option', { name: 'EUR' } ) + ).toBeAttached(); + await expect( + shopperPage + .locator( '.currency-switcher-holder' ) + .getByRole( 'option', { name: 'GBP' } ) + ).toBeAttached(); + } ); + + test( 'widget settings are applied in the frontend', async () => { + await navigation.goToShop( shopperPage ); + + // Asserts flags are displayed. + await expect( + await shopperPage.locator( '.currency-switcher-holder select' ) + ).toContainText( '🇺🇸' ); + // Asserts currency symbols are displayed. + await expect( + await shopperPage.locator( '.currency-switcher-holder select' ) + ).toContainText( '$' ); + // Asserts border is set. + await expect( + await shopperPage.locator( '.currency-switcher-holder select' ) + ).toHaveCSS( 'border-top-width', '1px' ); + // Asserts border radius is set. + await expect( + await shopperPage.locator( '.currency-switcher-holder select' ) + ).toHaveCSS( 'border-top-left-radius', `${ settings.borderRadius }px` ); + await expect( + await shopperPage.locator( '.currency-switcher-holder select' ) + ).toHaveCSS( 'font-size', `${ settings.fontSize }px` ); + await expect( + await shopperPage.locator( '.currency-switcher-holder' ) + ).toHaveAttribute( 'style', `line-height: ${ settings.lineHeight }; ` ); // Trailing space is expected. + await expect( + await shopperPage.locator( '.currency-switcher-holder select' ) + ).toHaveCSS( 'color', settings.textColor ); + // Asserts border color is set. + await expect( + await shopperPage.locator( '.currency-switcher-holder select' ) + ).toHaveCSS( 'border-top-color', settings.borderColor ); + } ); +} ); diff --git a/tests/e2e-pw/specs/merchant/multi-currency.spec.ts b/tests/e2e-pw/specs/merchant/multi-currency.spec.ts index 7a6122446fa..4b41b337367 100644 --- a/tests/e2e-pw/specs/merchant/multi-currency.spec.ts +++ b/tests/e2e-pw/specs/merchant/multi-currency.spec.ts @@ -11,6 +11,7 @@ import { addMulticurrencyWidget, deactivateMulticurrency, disableAllEnabledCurrencies, + removeMulticurrencyWidget, restoreCurrencies, } from '../../utils/merchant'; import * as navigation from '../../utils/merchant-navigation'; @@ -30,6 +31,7 @@ test.describe( 'Multi-currency', () => { } ); test.afterAll( async () => { + await removeMulticurrencyWidget( page ); await restoreCurrencies( page ); if ( ! wasMulticurrencyEnabled ) { await deactivateMulticurrency( page ); diff --git a/tests/e2e-pw/utils/merchant.ts b/tests/e2e-pw/utils/merchant.ts index 95fb0eababb..caa72a62ce4 100644 --- a/tests/e2e-pw/utils/merchant.ts +++ b/tests/e2e-pw/utils/merchant.ts @@ -107,26 +107,33 @@ export const deactivateMulticurrency = async ( page: Page ) => { await saveWooPaymentsSettings( page ); }; -export const addMulticurrencyWidget = async ( page: Page ) => { +export const addMulticurrencyWidget = async ( + page: Page, + blocksVersion = false +) => { await navigation.goToWidgets( page ); // Wait for all widgets to load. This is important to prevent flakiness. - await page.locator( '.components-spinner' ).first().waitFor(); await expect( page.locator( '.components-spinner' ) ).toHaveCount( 0 ); if ( await page.getByRole( 'button', { name: 'Close' } ).isVisible() ) { await page.getByRole( 'button', { name: 'Close' } ).click(); } - const isWidgetAdded = await page - .locator( 'iframe[srcdoc*=currency]' ) - .first() - .isVisible(); + // At this point, widgets might still be loading individually. + await expect( page.locator( '.components-spinner' ) ).toHaveCount( 0 ); + + const widgetName = blocksVersion + ? 'Currency Switcher Block' + : 'Currency Switcher Widget'; + const isWidgetAdded = blocksVersion + ? await page.locator( `[data-title="${ widgetName }"]` ).isVisible() + : await page.getByRole( 'heading', { name: widgetName } ).isVisible(); if ( ! isWidgetAdded ) { await page.getByRole( 'button', { name: 'Add block' } ).click(); await page .locator( 'input[placeholder="Search"]' ) - .pressSequentially( 'switcher', { delay: 20 } ); + .pressSequentially( widgetName, { delay: 20 } ); await expect( page.locator( 'button.components-button[role="option"]' ).first() ).toBeVisible( { timeout: 5000 } ); @@ -143,6 +150,54 @@ export const addMulticurrencyWidget = async ( page: Page ) => { } }; +export const removeMulticurrencyWidget = async ( + page: Page, + blocksVersion = false +) => { + await navigation.goToWidgets( page ); + // Wait for all widgets to load. This is important to prevent flakiness. + await expect( page.locator( '.components-spinner' ) ).toHaveCount( 0 ); + + if ( await page.getByRole( 'button', { name: 'Close' } ).isVisible() ) { + await page.getByRole( 'button', { name: 'Close' } ).click(); + } + + // At this point, widgets might still be loading individually. + await expect( page.locator( '.components-spinner' ) ).toHaveCount( 0 ); + + const widgetName = blocksVersion + ? 'Currency Switcher Block' + : 'Currency Switcher Widget'; + const isWidgetAdded = blocksVersion + ? await page.locator( `[data-title="${ widgetName }"]` ).isVisible() + : await page.getByRole( 'heading', { name: widgetName } ).isVisible(); + + if ( isWidgetAdded ) { + if ( blocksVersion ) { + await page.locator( `[data-title="${ widgetName }"]` ).click(); + } else { + await page + .locator( '.wp-block.wp-block-legacy-widget' ) + .filter( { + has: page.getByRole( 'heading', { name: widgetName } ), + } ) + .click(); + } + + await page.getByLabel( 'Block tools' ).getByLabel( 'Options' ).click(); + await page.getByRole( 'menuitem', { name: 'Delete' } ).click(); + await page.waitForTimeout( 2000 ); + + await expect( + page.getByRole( 'button', { name: 'Update' } ) + ).toBeEnabled(); + await page.getByRole( 'button', { name: 'Update' } ).click(); + await expect( page.getByLabel( 'Dismiss this notice' ) ).toBeVisible( { + timeout: 10000, + } ); + } +}; + export const getActiveThemeSlug = async ( page: Page ) => { await navigation.goToThemes( page );