Skip to content

Commit

Permalink
Merge branch 'develop' into update/deprecating-sofort-from-checkout
Browse files Browse the repository at this point in the history
  • Loading branch information
FangedParakeet authored Jan 23, 2025
2 parents bade6cc + ff92692 commit c356ff5
Show file tree
Hide file tree
Showing 11 changed files with 495 additions and 334 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: dev

Convert shopper checkout with UPE methods E2E test to Playwright, split saving card tests to separate file
40 changes: 37 additions & 3 deletions tests/e2e-pw/config/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,35 @@ export const config = {
email: 'e2e-wcpay-customer@woo.com',
},
},
'upe-customer': {
billing: {
be: {
firstname: 'I am',
lastname: 'Customer',
company: 'Automattic',
country: 'Belgium',
addressfirstline: 'Rue de l’Étuve, 1000',
addresssecondline: 'billing-be',
city: 'Bruxelles',
postcode: '1000',
phone: '123456789',
email: 'e2e-wcpay-customer@woocommerce.com',
},
de: {
firstname: 'I am',
lastname: 'Customer',
company: 'Automattic',
country: 'Germany',
addressfirstline: 'Petuelring 130',
addresssecondline: 'billing-de',
city: 'München',
postcode: '80809',
state: 'DE-BY',
phone: '123456789',
email: 'e2e-wcpay-customer@woocommerce.com',
},
},
},
'subscriptions-customer': {
billing: {
firstname: 'I am',
Expand Down Expand Up @@ -125,11 +154,11 @@ export const config = {
basic3: {
number: '378282246310005',
expires: {
month: '11',
month: '12',
year: '45',
},
cvc: '1234',
label: 'Amex ending in 0005',
label: 'American Express ending in 0005',
},
'3ds': {
number: '4000002760003184',
Expand Down Expand Up @@ -272,4 +301,9 @@ export const config = {
},
};

export type CustomerAddress = typeof config.addresses.customer.billing;
export type CustomerAddress = Omit<
typeof config.addresses.customer.billing,
'state'
> & {
state?: string;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/**

Check failure on line 1 in tests/e2e-pw/specs/shopper/shopper-checkout-purchase-with-upe-methods.spec.ts

View workflow job for this annotation

GitHub Actions / WC - latest

[shopper] › shopper/shopper-checkout-purchase-with-upe-methods.spec.ts:103:7 › Enable UPE with deferred intent creation › Card testing prevention enabled › should successfully place order with Bancontact

1) [shopper] › shopper/shopper-checkout-purchase-with-upe-methods.spec.ts:103:7 › Enable UPE with deferred intent creation › Card testing prevention enabled › should successfully place order with Bancontact Test timeout of 120000ms exceeded.

Check failure on line 1 in tests/e2e-pw/specs/shopper/shopper-checkout-purchase-with-upe-methods.spec.ts

View workflow job for this annotation

GitHub Actions / WC - latest

[shopper] › shopper/shopper-checkout-purchase-with-upe-methods.spec.ts:103:7 › Enable UPE with deferred intent creation › Card testing prevention enabled › should successfully place order with Bancontact

1) [shopper] › shopper/shopper-checkout-purchase-with-upe-methods.spec.ts:103:7 › Enable UPE with deferred intent creation › Card testing prevention enabled › should successfully place order with Bancontact Retry #1 ─────────────────────────────────────────────────────────────────────────────────────── Test timeout of 120000ms exceeded.
* External dependencies
*/
import test, { Page, expect } from '@playwright/test';

/**
* Internal dependencies
*/
import {
activateMulticurrency,
addCurrency,
deactivateMulticurrency,
disablePaymentMethods,
enablePaymentMethods,
restoreCurrencies,
} from '../../utils/merchant';
import { getShopper, getMerchant } from '../../utils/helpers';
import {
disableCardTestingProtection,
enableCardTestingProtection,
} from '../../utils/devtools';
import {
addToCartFromShopPage,
changeAccountCurrency,
emptyCart,
expectFraudPreventionToken,
fillBillingAddress,
focusPlaceOrderButton,
placeOrder,
} from '../../utils/shopper';
import { config } from '../../config/default';
import { goToCheckout, goToShop } from '../../utils/shopper-navigation';

test.describe( 'Enable UPE with deferred intent creation', () => {
let wasMultiCurrencyEnabled = false;
let merchantPage: Page, shopperPage: Page;
test.beforeAll( async ( { browser } ) => {
// Open browsers.
merchantPage = ( await getMerchant( browser ) ).merchantPage;
shopperPage = ( await getShopper( browser ) ).shopperPage;

// Prepare merchant side of tests.
wasMultiCurrencyEnabled = await activateMulticurrency( merchantPage );
await addCurrency( merchantPage, 'EUR' );
await enablePaymentMethods( merchantPage, [ 'bancontact' ] );
// Prepare shopper side of tests.
await changeAccountCurrency(
shopperPage,
config.addresses.customer.billing,
'EUR'
);
await emptyCart( shopperPage );
} );

test.afterAll( async () => {
// Restore shopper side of tests.
await emptyCart( shopperPage );

// Restore merchant side of tests
await disablePaymentMethods( merchantPage, [ 'bancontact' ] );
await restoreCurrencies( merchantPage );
if ( ! wasMultiCurrencyEnabled ) {
await deactivateMulticurrency( merchantPage );
}
} );

const testBancontactOrder = async (
cardTestingPreventionState: boolean
) => {
await goToShop( shopperPage );
await addToCartFromShopPage( shopperPage, 'Beanie' );
await goToCheckout( shopperPage );
await fillBillingAddress(
shopperPage,
config.addresses[ 'upe-customer' ].billing.be
);
await shopperPage.waitForLoadState( 'networkidle' );
await expectFraudPreventionToken(
shopperPage,
cardTestingPreventionState
);
await shopperPage.getByText( 'Bancontact' ).click();
await focusPlaceOrderButton( shopperPage );
await placeOrder( shopperPage );
await shopperPage.waitForLoadState( 'networkidle' );
await shopperPage
.getByRole( 'link', {
name: 'Authorize Test Payment',
} )
.click();
await expect(
shopperPage.getByText( 'Order received' ).first()
).toBeVisible();
};

test.describe( 'Card testing prevention enabled', () => {
test.beforeAll( async () => {
await enableCardTestingProtection( merchantPage );
} );
test.afterAll( async () => {
await disableCardTestingProtection( merchantPage );
} );
test( 'should successfully place order with Bancontact', async () => {
await testBancontactOrder( true );
} );
} );

test.describe( 'Card testing prevention disabled', () => {
test( 'should successfully place order with Bancontact', async () => {
await testBancontactOrder( false );
} );
} );
} );
199 changes: 199 additions & 0 deletions tests/e2e-pw/specs/shopper/shopper-myaccount-saved-cards.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
/**

Check failure on line 1 in tests/e2e-pw/specs/shopper/shopper-myaccount-saved-cards.spec.ts

View workflow job for this annotation

GitHub Actions / WC - latest

[shopper] › shopper/shopper-myaccount-saved-cards.spec.ts:101:8 › Shopper can save and delete cards › Testing card: 3ds › should add the 3ds card as a new payment method

2) [shopper] › shopper/shopper-myaccount-saved-cards.spec.ts:101:8 › Shopper can save and delete cards › Testing card: 3ds › should add the 3ds card as a new payment method Test timeout of 120000ms exceeded.

Check failure on line 1 in tests/e2e-pw/specs/shopper/shopper-myaccount-saved-cards.spec.ts

View workflow job for this annotation

GitHub Actions / WC - latest

[shopper] › shopper/shopper-myaccount-saved-cards.spec.ts:101:8 › Shopper can save and delete cards › Testing card: 3ds2 › should add the 3ds2 card as a new payment method

3) [shopper] › shopper/shopper-myaccount-saved-cards.spec.ts:101:8 › Shopper can save and delete cards › Testing card: 3ds2 › should add the 3ds2 card as a new payment method Test timeout of 120000ms exceeded.
* External dependencies
*/
import test, { Page, expect } from '@playwright/test';

/**
* Internal dependencies
*/
import { config } from '../../config/default';
import { goToMyAccount, goToShop } from '../../utils/shopper-navigation';
import { getAnonymousShopper } from '../../utils/helpers';
import {
addSavedCard,
confirmCardAuthentication,
deleteSavedCard,
placeOrder,
placeOrderWithOptions,
selectSavedCardOnCheckout,
setDefaultPaymentMethod,
setupProductCheckout,
} from '../../utils/shopper';
import RestAPI from '../../utils/rest-api';

const cards = {
basic: config.cards.basic,
'3ds': config.cards[ '3ds' ],
'3ds2': config.cards[ '3ds2' ],
} as { [ key: string ]: typeof config.cards.basic };

test.describe( 'Shopper can save and delete cards', () => {
let timeAdded: number;
// Use cards different than other tests to prevent conflicts.
const card2 = config.cards.basic3;
let shopperPage: Page = null;
const customerBillingConfig =
config.addresses[ 'subscriptions-customer' ].billing;

test.beforeAll( async ( { browser }, { project } ) => {
// Delete the user, if present, and create a new one with a new order.
// This is required to avoid running this test on a customer that already has a saved card.
const restApi = new RestAPI( project.use.baseURL );
await restApi.deleteCustomerByEmailAddress(
customerBillingConfig.email
);

shopperPage = ( await getAnonymousShopper( browser ) ).shopperPage;
await placeOrderWithOptions( shopperPage, {
billingAddress: customerBillingConfig,
createAccount: true,
} );
} );

async function waitTwentySecondsSinceLastCardAdded( page: Page ) {
// Make sure that at least 20s had already elapsed since the last card was added.
// Otherwise, you will get the error message,
// "You cannot add a new payment method so soon after the previous one."
// Source: /docker/wordpress/wp-content/plugins/woocommerce/includes/class-wc-form-handler.php#L509-L521
const timeTestFinished = Date.now();
const elapsedWaitTime = timeTestFinished - timeAdded;
const remainingWaitTime =
20000 > elapsedWaitTime ? 20000 - elapsedWaitTime : 0;

await page.waitForTimeout( remainingWaitTime );
}

// No need to run this test for all card types.
test( 'prevents adding another card for 20 seconds after a card is added', async () => {
await goToMyAccount( shopperPage, 'payment-methods' );
// Take note of the time when we added this card
await addSavedCard( shopperPage, config.cards.basic, 'US', '94110' );
timeAdded = +Date.now();

// Try to add a new card before 20 seconds have passed
await addSavedCard( shopperPage, config.cards.basic2, 'US', '94110' );

// Verify that the card was not added
await expect(
shopperPage.getByText(
'You cannot add a new payment method so soon after the previous one. Please wait for 20 seconds.'
)
).toBeVisible();

await expect(
shopperPage.getByText( 'Payment method successfully added' )
).not.toBeVisible();

await expect(
shopperPage.getByText(
`${ config.cards.basic2.expires.month }/${ config.cards.basic2.expires.year }`
)
).not.toBeVisible();

await waitTwentySecondsSinceLastCardAdded( shopperPage );
// cleanup for the next tests
await goToMyAccount( shopperPage, 'payment-methods' );
await deleteSavedCard( shopperPage, config.cards.basic );
} );

Object.entries( cards ).forEach( ( [ cardName, card ] ) => {
test.describe( 'Testing card: ' + cardName, () => {
test( `should add the ${ cardName } card as a new payment method`, async () => {
await goToMyAccount( shopperPage, 'payment-methods' );
await addSavedCard( shopperPage, card, 'US', '94110' );
// Take note of the time when we added this card
timeAdded = +Date.now();

if ( cardName === '3ds' || cardName === '3ds2' ) {
await confirmCardAuthentication( shopperPage );
}

await shopperPage.waitForURL( /\/my-account\/payment-methods/, {

Check failure on line 111 in tests/e2e-pw/specs/shopper/shopper-myaccount-saved-cards.spec.ts

View workflow job for this annotation

GitHub Actions / WC - latest

[shopper] › shopper/shopper-myaccount-saved-cards.spec.ts:101:8 › Shopper can save and delete cards › Testing card: 3ds › should add the 3ds card as a new payment method

2) [shopper] › shopper/shopper-myaccount-saved-cards.spec.ts:101:8 › Shopper can save and delete cards › Testing card: 3ds › should add the 3ds card as a new payment method Error: page.waitForURL: Test ended. =========================== logs =========================== waiting for navigation until "load" navigated to "http://localhost:8084/my-account/add-payment-method/" ============================================================ 109 | } 110 | > 111 | await shopperPage.waitForURL( /\/my-account\/payment-methods/, { | ^ 112 | waitUntil: 'load', 113 | } ); 114 | at /home/runner/work/woocommerce-payments/woocommerce-payments/tests/e2e-pw/specs/shopper/shopper-myaccount-saved-cards.spec.ts:111:23

Check failure on line 111 in tests/e2e-pw/specs/shopper/shopper-myaccount-saved-cards.spec.ts

View workflow job for this annotation

GitHub Actions / WC - latest

[shopper] › shopper/shopper-myaccount-saved-cards.spec.ts:101:8 › Shopper can save and delete cards › Testing card: 3ds2 › should add the 3ds2 card as a new payment method

3) [shopper] › shopper/shopper-myaccount-saved-cards.spec.ts:101:8 › Shopper can save and delete cards › Testing card: 3ds2 › should add the 3ds2 card as a new payment method Error: page.waitForURL: Test ended. =========================== logs =========================== waiting for navigation until "load" navigated to "http://localhost:8084/my-account/add-payment-method/" ============================================================ 109 | } 110 | > 111 | await shopperPage.waitForURL( /\/my-account\/payment-methods/, { | ^ 112 | waitUntil: 'load', 113 | } ); 114 | at /home/runner/work/woocommerce-payments/woocommerce-payments/tests/e2e-pw/specs/shopper/shopper-myaccount-saved-cards.spec.ts:111:23
waitUntil: 'load',
} );

// Verify that the card was added
await expect(
shopperPage.getByText(
'You cannot add a new payment method so soon after the previous one. Please wait for 20 seconds.'
)
).not.toBeVisible();

await expect(
shopperPage.getByText( 'Payment method successfully added' )
).toBeVisible();

await expect(
shopperPage.getByText(
`${ card.expires.month }/${ card.expires.year }`
)
).toBeVisible();

await waitTwentySecondsSinceLastCardAdded( shopperPage );
} );

test( `should be able to purchase with the saved ${ cardName } card`, async () => {
await goToShop( shopperPage );
await setupProductCheckout( shopperPage );
await selectSavedCardOnCheckout( shopperPage, card );
if ( cardName === 'basic' ) {
await placeOrder( shopperPage );
} else {
await shopperPage
.getByRole( 'button', { name: 'Place order' } )
.click();
await confirmCardAuthentication( shopperPage );
}

await shopperPage.waitForURL( /\/order-received\//, {
waitUntil: 'load',
} );
await expect(
shopperPage.getByRole( 'heading', {
name: 'Order received',
} )
).toBeVisible();
} );

test( `should be able to set the ${ cardName } card as default payment method`, async () => {
await goToMyAccount( shopperPage, 'payment-methods' );
await addSavedCard( shopperPage, card2, 'US', '94110' );
// Take note of the time when we added this card
timeAdded = +Date.now();

await expect(
shopperPage.getByText( 'Payment method successfully added' )
).toBeVisible();
await expect(
shopperPage.getByText(
`${ card2.expires.month }/${ card2.expires.year }`
)
).toBeVisible();
await setDefaultPaymentMethod( shopperPage, card2 );
// Verify that the card was set as default
await expect(
shopperPage.getByText(
'This payment method was successfully set as your default.'
)
).toBeVisible();
} );

test( `should be able to delete ${ cardName } card`, async () => {
await goToMyAccount( shopperPage, 'payment-methods' );
await deleteSavedCard( shopperPage, card );
await expect(
shopperPage.getByText( 'Payment method deleted.' )
).toBeVisible();

await deleteSavedCard( shopperPage, card2 );
await expect(
shopperPage.getByText( 'Payment method deleted.' )
).toBeVisible();
} );

test.afterAll( async () => {
waitTwentySecondsSinceLastCardAdded( shopperPage );
} );
} );
} );
} );
Loading

0 comments on commit c356ff5

Please sign in to comment.