Skip to content

Commit f87ea8e

Browse files
authored
Dev: Move Klarna E2E tests to Playwright (#9377)
1 parent 2eea958 commit f87ea8e

File tree

7 files changed

+145
-176
lines changed

7 files changed

+145
-176
lines changed

changelog/dev-update-klarna-e2e-tests

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+
Migrate Klarna E2E tests to playwright. Reduce noise in E2E tests console output.
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/**
2+
* External dependencies
3+
*/
4+
import { test, expect, Page } from '@playwright/test';
5+
6+
/**
7+
* Internal dependencies
8+
*/
9+
import * as shopper from '../../utils/shopper';
10+
import { getMerchant, getShopper } from '../../utils/helpers';
11+
import * as merchant from '../../utils/merchant';
12+
import { config } from '../../config/default';
13+
import {
14+
goToProductPageBySlug,
15+
goToShop,
16+
} from '../../utils/shopper-navigation';
17+
18+
test.describe( 'Klarna Checkout', () => {
19+
let merchantPage: Page;
20+
let shopperPage: Page;
21+
let wasMulticurrencyEnabled: boolean;
22+
23+
test.beforeAll( async ( { browser } ) => {
24+
shopperPage = ( await getShopper( browser ) ).shopperPage;
25+
merchantPage = ( await getMerchant( browser ) ).merchantPage;
26+
wasMulticurrencyEnabled = await merchant.isMulticurrencyEnabled(
27+
merchantPage
28+
);
29+
if ( wasMulticurrencyEnabled ) {
30+
await merchant.deactivateMulticurrency( merchantPage );
31+
}
32+
await merchant.enablePaymentMethods( merchantPage, [ 'klarna' ] );
33+
} );
34+
35+
test.afterAll( async () => {
36+
await shopper.emptyCart( shopperPage );
37+
38+
await merchant.disablePaymentMethods( merchantPage, [ 'klarna' ] );
39+
40+
if ( wasMulticurrencyEnabled ) {
41+
await merchant.activateMulticurrency( merchantPage );
42+
}
43+
} );
44+
45+
test( 'shows the message in the product page', async () => {
46+
await goToProductPageBySlug( shopperPage, 'belt' );
47+
48+
// Since we cant' control the exact contents of the iframe, we just make sure it's there.
49+
await expect(
50+
shopperPage
51+
.frameLocator( '#payment-method-message iframe' )
52+
.locator( 'body' )
53+
).not.toBeEmpty();
54+
} );
55+
56+
test( 'allows to use Klarna as a payment method', async () => {
57+
await goToShop( shopperPage );
58+
await shopper.setupProductCheckout( shopperPage, [ [ 'Belt', 1 ] ], {
59+
...config.addresses.customer.billing,
60+
// these are Klarna-specific values:
61+
// https://docs.klarna.com/resources/test-environment/sample-customer-data/#united-states-of-america
62+
63+
phone: '+13106683312',
64+
firstname: 'Test',
65+
lastname: 'Person-us',
66+
} );
67+
68+
await shopperPage
69+
.locator( '.wc_payment_methods' )
70+
.getByText( 'Klarna' )
71+
.click();
72+
73+
await shopper.placeOrder( shopperPage );
74+
75+
// Since we don't have control over the html in the Klarna playground page,
76+
// verifying the redirect is all we can do consistently without introducing a
77+
// flaky test.
78+
await expect( shopperPage ).toHaveURL( /.*klarna\.com/ );
79+
} );
80+
} );

tests/e2e-pw/utils/merchant.ts

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,20 @@ export const saveWooPaymentsSettings = async ( page: Page ) => {
2121
} );
2222
};
2323

24+
export const isMulticurrencyEnabled = async ( page: Page ) => {
25+
await navigation.goToWooPaymentsSettings( page );
26+
27+
const checkboxTestId = 'multi-currency-toggle';
28+
const isEnabled = await page.getByTestId( checkboxTestId ).isChecked();
29+
30+
return isEnabled;
31+
};
32+
2433
export const activateMulticurrency = async ( page: Page ) => {
2534
await navigation.goToWooPaymentsSettings( page );
2635

2736
const checkboxTestId = 'multi-currency-toggle';
28-
const wasInitiallyEnabled = await page
29-
.getByTestId( checkboxTestId )
30-
.isChecked();
37+
const wasInitiallyEnabled = await isMulticurrencyEnabled( page );
3138

3239
if ( ! wasInitiallyEnabled ) {
3340
await page.getByTestId( checkboxTestId ).check();
@@ -212,3 +219,34 @@ export const setCurrencyCharmPricing = async (
212219
await page.getByTestId( 'price_charm' ).selectOption( charmPricing );
213220
await saveWooPaymentsSettings( page );
214221
};
222+
223+
export const enablePaymentMethods = async (
224+
page: Page,
225+
paymentMethods: string[]
226+
) => {
227+
await navigation.goToWooPaymentsSettings( page );
228+
229+
for ( const paymentMethodName of paymentMethods ) {
230+
await page.getByLabel( paymentMethodName ).check();
231+
}
232+
233+
await saveWooPaymentsSettings( page );
234+
};
235+
236+
export const disablePaymentMethods = async (
237+
page: Page,
238+
paymentMethods: string[]
239+
) => {
240+
await navigation.goToWooPaymentsSettings( page );
241+
242+
for ( const paymentMethodName of paymentMethods ) {
243+
const checkbox = await page.getByLabel( paymentMethodName );
244+
245+
if ( await checkbox.isChecked() ) {
246+
await checkbox.click();
247+
await page.getByRole( 'button', { name: 'Remove' } ).click();
248+
}
249+
}
250+
251+
await saveWooPaymentsSettings( page );
252+
};

tests/e2e-pw/utils/shopper-navigation.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ import { Page } from 'playwright/test';
77
*/
88
import { isUIUnblocked } from './shopper';
99

10+
export const goToShop = async ( page: Page ) => {
11+
await page.goto( `/shop/`, { waitUntil: 'load' } );
12+
};
13+
1014
export const goToShopWithCurrency = async ( page: Page, currency: string ) => {
1115
await page.goto( `/shop/?currency=${ currency }`, { waitUntil: 'load' } );
1216
};

tests/e2e-pw/utils/shopper.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,17 @@ export const fillBillingAddress = async (
3737
await page.locator( '#billing_email' ).fill( billingAddress.email );
3838
};
3939

40+
// This is currently the source of some flaky tests since sometimes the form is not submitted
41+
// after the first click, so we retry until the ui is blocked.
4042
export const placeOrder = async ( page: Page ) => {
41-
await page.locator( '#place_order' ).click();
43+
let orderPlaced = false;
44+
while ( ! orderPlaced ) {
45+
await page.locator( '#place_order' ).click();
46+
47+
if ( await page.$( '.blockUI' ) ) {
48+
orderPlaced = true;
49+
}
50+
}
4251
};
4352

4453
export const addCartProduct = async (
@@ -192,19 +201,19 @@ export const setupCheckout = async (
192201
/**
193202
* Sets up checkout with any number of products.
194203
*
195-
* @param {CustomerAddress} billingAddress The billing address to use for the checkout.
196204
* @param {Array<[string, number]>} lineItems A 2D array of line items where each line item is an array
197205
* that contains the product title as the first element, and the quantity as the second.
198206
* For example, if you want to checkout x2 "Hoodie" and x3 "Belt" then set this parameter like this:
199207
*
200208
* `[ [ "Hoodie", 2 ], [ "Belt", 3 ] ]`.
209+
* @param {CustomerAddress} billingAddress The billing address to use for the checkout.
201210
*/
202211
export async function setupProductCheckout(
203212
page: Page,
204-
billingAddress: CustomerAddress,
205213
lineItems: Array< [ string, number ] > = [
206214
[ config.products.simple.name, 1 ],
207-
]
215+
],
216+
billingAddress: CustomerAddress = config.addresses.customer.billing
208217
) {
209218
const cartSizeText = await page
210219
.locator( '.cart-contents .count' )
@@ -241,9 +250,7 @@ export const placeOrderWithCurrency = async (
241250
currency: string
242251
) => {
243252
await navigation.goToShopWithCurrency( page, currency );
244-
await setupProductCheckout( page, config.addresses.customer.billing, [
245-
[ config.products.simple.name, 1 ],
246-
] );
253+
await setupProductCheckout( page, [ [ config.products.simple.name, 1 ] ] );
247254
await fillCardDetails( page, config.cards.basic );
248255
// Takes off the focus out of the Stripe elements to let Stripe logic
249256
// wrap up and make sure the Place Order button is clickable.

tests/e2e/config/jest.setup.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ const ERROR_MESSAGES_TO_IGNORE = [
3636
'Failed to load resource: the server responded with a status of 400 (Bad Request)',
3737
'No Amplitude API key provided',
3838
'is registered with an invalid category',
39-
'"Heading" is not a supported class',
39+
'is not a supported class', // Silence stripe.js warnings regarding styles.
40+
'is not a supported property for', // Silence stripe.js warnings regarding styles.
4041
];
4142

4243
ERROR_MESSAGES_TO_IGNORE.forEach( ( errorMessage ) => {

tests/e2e/specs/wcpay/shopper/shopper-klarna-checkout.spec.js

Lines changed: 0 additions & 165 deletions
This file was deleted.

0 commit comments

Comments
 (0)