Skip to content

Commit 0454bb5

Browse files
authored
Add multi-currency widget setup e2e tests (#10225)
1 parent f4b1d3a commit 0454bb5

File tree

4 files changed

+294
-7
lines changed

4 files changed

+294
-7
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Significance: patch
2+
Type: dev
3+
4+
Add e2e tests for the multi-currency widget setup.
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
/**
2+
* External dependencies
3+
*/
4+
import { test, expect, Page } from '@playwright/test';
5+
/**
6+
* Internal dependencies
7+
*/
8+
import { getMerchant, getShopper } from '../../utils/helpers';
9+
import {
10+
activateMulticurrency,
11+
addMulticurrencyWidget,
12+
deactivateMulticurrency,
13+
removeMulticurrencyWidget,
14+
} from '../../utils/merchant';
15+
import * as navigation from '../../utils/shopper-navigation';
16+
17+
test.describe( 'Multi-currency widget setup', () => {
18+
let merchantPage: Page;
19+
let shopperPage: Page;
20+
let wasMulticurrencyEnabled: boolean;
21+
// Values to test against. Defining nonsense values to ensure they are applied correctly.
22+
const settings = {
23+
borderRadius: '15',
24+
fontSize: '40',
25+
lineHeight: '2.3',
26+
textColor: 'rgb(155, 81, 224)',
27+
borderColor: 'rgb(252, 185, 0)',
28+
};
29+
30+
test.beforeAll( async ( { browser } ) => {
31+
shopperPage = ( await getShopper( browser ) ).shopperPage;
32+
merchantPage = ( await getMerchant( browser ) ).merchantPage;
33+
wasMulticurrencyEnabled = await activateMulticurrency( merchantPage );
34+
35+
await addMulticurrencyWidget( merchantPage, true );
36+
} );
37+
38+
test.afterAll( async () => {
39+
await removeMulticurrencyWidget( merchantPage, true );
40+
41+
if ( ! wasMulticurrencyEnabled ) {
42+
await deactivateMulticurrency( merchantPage );
43+
}
44+
45+
await merchantPage.close();
46+
} );
47+
48+
test( 'displays enabled currencies correctly in the admin', async () => {
49+
await expect(
50+
merchantPage
51+
.locator( 'select[name="currency"]' )
52+
.getByRole( 'option' )
53+
).toHaveCount( 3 );
54+
await expect(
55+
merchantPage
56+
.locator( 'select[name="currency"]' )
57+
.getByRole( 'option', { name: 'USD' } )
58+
).toBeAttached();
59+
await expect(
60+
merchantPage
61+
.locator( 'select[name="currency"]' )
62+
.getByRole( 'option', { name: 'EUR' } )
63+
).toBeAttached();
64+
await expect(
65+
merchantPage
66+
.locator( 'select[name="currency"]' )
67+
.getByRole( 'option', { name: 'GBP' } )
68+
).toBeAttached();
69+
} );
70+
71+
test( 'can update widget properties', async () => {
72+
await test.step( 'opens widget settings', async () => {
73+
await merchantPage
74+
.getByRole( 'button', { name: 'Settings' } )
75+
.click();
76+
await merchantPage
77+
.locator( '[data-title="Currency Switcher Block"]' )
78+
.click();
79+
} );
80+
81+
await test.step( 'checks display flags', async () => {
82+
await merchantPage
83+
.getByRole( 'checkbox', { name: 'Display flags' } )
84+
.check();
85+
await expect(
86+
await merchantPage
87+
.getByRole( 'checkbox', { name: 'Display flags' } )
88+
.isChecked()
89+
).toBeTruthy();
90+
} );
91+
92+
await test.step( 'checks display currency symbols', async () => {
93+
await merchantPage
94+
.getByRole( 'checkbox', { name: 'Display currency symbols' } )
95+
.check();
96+
await expect(
97+
await merchantPage
98+
.getByRole( 'checkbox', {
99+
name: 'Display currency symbols',
100+
} )
101+
.isChecked()
102+
).toBeTruthy();
103+
} );
104+
105+
await test.step( 'checks border', async () => {
106+
await merchantPage
107+
.getByRole( 'checkbox', { name: 'Border' } )
108+
.check();
109+
await expect(
110+
await merchantPage
111+
.getByRole( 'checkbox', { name: 'Border' } )
112+
.isChecked()
113+
).toBeTruthy();
114+
} );
115+
116+
await test.step( 'updates border radius', async () => {
117+
await merchantPage
118+
.getByRole( 'spinbutton', { name: 'Border radius' } )
119+
.fill( settings.borderRadius );
120+
} );
121+
122+
await test.step( 'updates font size', async () => {
123+
await merchantPage
124+
.getByRole( 'spinbutton', { name: 'Size' } )
125+
.fill( settings.fontSize );
126+
} );
127+
128+
await test.step( 'updates line height', async () => {
129+
await merchantPage
130+
.getByRole( 'spinbutton', { name: 'Line height' } )
131+
.fill( settings.lineHeight );
132+
} );
133+
134+
await test.step( 'updates text color', async () => {
135+
await merchantPage
136+
.locator( 'fieldset', { hasText: 'Text' } )
137+
.getByRole( 'listbox', { name: 'Custom color picker' } )
138+
.getByRole( 'option', { name: 'Vivid purple' } )
139+
.click();
140+
} );
141+
142+
await test.step( 'updates border color', async () => {
143+
await merchantPage
144+
.locator( 'fieldset', { hasText: 'Border' } )
145+
.getByRole( 'listbox', { name: 'Custom color picker' } )
146+
.getByRole( 'option', { name: 'Luminous vivid amber' } )
147+
.click();
148+
} );
149+
150+
await test.step( 'saves changes', async () => {
151+
await expect(
152+
merchantPage.getByRole( 'button', { name: 'Update' } )
153+
).toBeEnabled();
154+
await merchantPage
155+
.getByRole( 'button', { name: 'Update' } )
156+
.click();
157+
await expect(
158+
merchantPage.getByLabel( 'Dismiss this notice' )
159+
).toBeVisible( {
160+
timeout: 10000,
161+
} );
162+
} );
163+
} );
164+
165+
test( 'displays enabled currencies correctly in the frontend', async () => {
166+
await navigation.goToShop( shopperPage );
167+
168+
await expect(
169+
await shopperPage.locator( '.currency-switcher-holder' )
170+
).toBeVisible();
171+
await expect(
172+
shopperPage
173+
.locator( '.currency-switcher-holder' )
174+
.getByRole( 'option' )
175+
).toHaveCount( 3 );
176+
await expect(
177+
shopperPage
178+
.locator( '.currency-switcher-holder' )
179+
.getByRole( 'option', { name: 'USD' } )
180+
).toBeAttached();
181+
await expect(
182+
shopperPage
183+
.locator( '.currency-switcher-holder' )
184+
.getByRole( 'option', { name: 'EUR' } )
185+
).toBeAttached();
186+
await expect(
187+
shopperPage
188+
.locator( '.currency-switcher-holder' )
189+
.getByRole( 'option', { name: 'GBP' } )
190+
).toBeAttached();
191+
} );
192+
193+
test( 'widget settings are applied in the frontend', async () => {
194+
await navigation.goToShop( shopperPage );
195+
196+
// Asserts flags are displayed.
197+
await expect(
198+
await shopperPage.locator( '.currency-switcher-holder select' )
199+
).toContainText( '🇺🇸' );
200+
// Asserts currency symbols are displayed.
201+
await expect(
202+
await shopperPage.locator( '.currency-switcher-holder select' )
203+
).toContainText( '$' );
204+
// Asserts border is set.
205+
await expect(
206+
await shopperPage.locator( '.currency-switcher-holder select' )
207+
).toHaveCSS( 'border-top-width', '1px' );
208+
// Asserts border radius is set.
209+
await expect(
210+
await shopperPage.locator( '.currency-switcher-holder select' )
211+
).toHaveCSS( 'border-top-left-radius', `${ settings.borderRadius }px` );
212+
await expect(
213+
await shopperPage.locator( '.currency-switcher-holder select' )
214+
).toHaveCSS( 'font-size', `${ settings.fontSize }px` );
215+
await expect(
216+
await shopperPage.locator( '.currency-switcher-holder' )
217+
).toHaveAttribute( 'style', `line-height: ${ settings.lineHeight }; ` ); // Trailing space is expected.
218+
await expect(
219+
await shopperPage.locator( '.currency-switcher-holder select' )
220+
).toHaveCSS( 'color', settings.textColor );
221+
// Asserts border color is set.
222+
await expect(
223+
await shopperPage.locator( '.currency-switcher-holder select' )
224+
).toHaveCSS( 'border-top-color', settings.borderColor );
225+
} );
226+
} );

tests/e2e-pw/specs/merchant/multi-currency.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
addMulticurrencyWidget,
1212
deactivateMulticurrency,
1313
disableAllEnabledCurrencies,
14+
removeMulticurrencyWidget,
1415
restoreCurrencies,
1516
} from '../../utils/merchant';
1617
import * as navigation from '../../utils/merchant-navigation';
@@ -30,6 +31,7 @@ test.describe( 'Multi-currency', () => {
3031
} );
3132

3233
test.afterAll( async () => {
34+
await removeMulticurrencyWidget( page );
3335
await restoreCurrencies( page );
3436
if ( ! wasMulticurrencyEnabled ) {
3537
await deactivateMulticurrency( page );

tests/e2e-pw/utils/merchant.ts

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -107,26 +107,33 @@ export const deactivateMulticurrency = async ( page: Page ) => {
107107
await saveWooPaymentsSettings( page );
108108
};
109109

110-
export const addMulticurrencyWidget = async ( page: Page ) => {
110+
export const addMulticurrencyWidget = async (
111+
page: Page,
112+
blocksVersion = false
113+
) => {
111114
await navigation.goToWidgets( page );
112115
// Wait for all widgets to load. This is important to prevent flakiness.
113-
await page.locator( '.components-spinner' ).first().waitFor();
114116
await expect( page.locator( '.components-spinner' ) ).toHaveCount( 0 );
115117

116118
if ( await page.getByRole( 'button', { name: 'Close' } ).isVisible() ) {
117119
await page.getByRole( 'button', { name: 'Close' } ).click();
118120
}
119121

120-
const isWidgetAdded = await page
121-
.locator( 'iframe[srcdoc*=currency]' )
122-
.first()
123-
.isVisible();
122+
// At this point, widgets might still be loading individually.
123+
await expect( page.locator( '.components-spinner' ) ).toHaveCount( 0 );
124+
125+
const widgetName = blocksVersion
126+
? 'Currency Switcher Block'
127+
: 'Currency Switcher Widget';
128+
const isWidgetAdded = blocksVersion
129+
? await page.locator( `[data-title="${ widgetName }"]` ).isVisible()
130+
: await page.getByRole( 'heading', { name: widgetName } ).isVisible();
124131

125132
if ( ! isWidgetAdded ) {
126133
await page.getByRole( 'button', { name: 'Add block' } ).click();
127134
await page
128135
.locator( 'input[placeholder="Search"]' )
129-
.pressSequentially( 'switcher', { delay: 20 } );
136+
.pressSequentially( widgetName, { delay: 20 } );
130137
await expect(
131138
page.locator( 'button.components-button[role="option"]' ).first()
132139
).toBeVisible( { timeout: 5000 } );
@@ -143,6 +150,54 @@ export const addMulticurrencyWidget = async ( page: Page ) => {
143150
}
144151
};
145152

153+
export const removeMulticurrencyWidget = async (
154+
page: Page,
155+
blocksVersion = false
156+
) => {
157+
await navigation.goToWidgets( page );
158+
// Wait for all widgets to load. This is important to prevent flakiness.
159+
await expect( page.locator( '.components-spinner' ) ).toHaveCount( 0 );
160+
161+
if ( await page.getByRole( 'button', { name: 'Close' } ).isVisible() ) {
162+
await page.getByRole( 'button', { name: 'Close' } ).click();
163+
}
164+
165+
// At this point, widgets might still be loading individually.
166+
await expect( page.locator( '.components-spinner' ) ).toHaveCount( 0 );
167+
168+
const widgetName = blocksVersion
169+
? 'Currency Switcher Block'
170+
: 'Currency Switcher Widget';
171+
const isWidgetAdded = blocksVersion
172+
? await page.locator( `[data-title="${ widgetName }"]` ).isVisible()
173+
: await page.getByRole( 'heading', { name: widgetName } ).isVisible();
174+
175+
if ( isWidgetAdded ) {
176+
if ( blocksVersion ) {
177+
await page.locator( `[data-title="${ widgetName }"]` ).click();
178+
} else {
179+
await page
180+
.locator( '.wp-block.wp-block-legacy-widget' )
181+
.filter( {
182+
has: page.getByRole( 'heading', { name: widgetName } ),
183+
} )
184+
.click();
185+
}
186+
187+
await page.getByLabel( 'Block tools' ).getByLabel( 'Options' ).click();
188+
await page.getByRole( 'menuitem', { name: 'Delete' } ).click();
189+
await page.waitForTimeout( 2000 );
190+
191+
await expect(
192+
page.getByRole( 'button', { name: 'Update' } )
193+
).toBeEnabled();
194+
await page.getByRole( 'button', { name: 'Update' } ).click();
195+
await expect( page.getByLabel( 'Dismiss this notice' ) ).toBeVisible( {
196+
timeout: 10000,
197+
} );
198+
}
199+
};
200+
146201
export const getActiveThemeSlug = async ( page: Page ) => {
147202
await navigation.goToThemes( page );
148203

0 commit comments

Comments
 (0)