Skip to content

Commit 8ced045

Browse files
committed
Add PayPal processor tests
1 parent cf6615a commit 8ced045

File tree

5 files changed

+187
-4
lines changed

5 files changed

+187
-4
lines changed

tests/fixtures/checkout-types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ export const CHECKOUT_TYPES: Record<string, CheckoutType> = {
1616
CLASSIC: {
1717
id: 'classic',
1818
name: 'Classic Checkout',
19-
url: '/checkout/',
19+
url: '/checkout-shortcode/',
2020
isBlockCheckout: false
2121
},
2222

2323
// WooCommerce Blocks checkout
2424
BLOCK: {
2525
id: 'block',
2626
name: 'Block Checkout',
27-
url: '/checkout-block/',
27+
url: '/checkout/',
2828
isBlockCheckout: true
2929
},
3030

tests/fixtures/payment-test-data.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,14 @@ export const PAYMENT_TEST_DATA = {
2727
phoneNumber: '+34500000000'
2828
}
2929
},
30+
paypal: {
31+
success: {
32+
user: 'paypal-personal@monei.net',
33+
pw: 'monei12345'
34+
},
35+
fail: {
36+
user: 'CCREJECT-REFUSED@paypal.com',
37+
pw: 'PayPal2016'
38+
}
39+
}
3040
};

tests/fixtures/test-configurations.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,17 @@ export const TEST_CONFIGURATIONS = {
7676
userStates: [USER_STATES.GUEST],
7777
userTypes: [USER_TYPES.ES_USER]
7878
}),
79+
//PayPal Tests
80+
PAYPAL_TESTS: [
81+
{
82+
paymentMethod: PAYMENT_METHODS.PAYPAL,
83+
checkoutType: [CHECKOUT_TYPES.CLASSIC, CHECKOUT_TYPES.BLOCK],
84+
productType: PRODUCT_TYPES.SIMPLE,
85+
userState: USER_STATES.GUEST,
86+
userType: USER_TYPES.ES_USER,
87+
expectSuccess: true
88+
},
89+
],
7990
// Bizum-specific tests
8091
BIZUM_TESTS: [
8192
// Bizum success scenario
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
import { Page } from '@playwright/test';
2+
import { BasePaymentProcessor } from "./base-payment-processor";
3+
import { PAYMENT_TEST_DATA } from "../../fixtures/payment-test-data";
4+
5+
export class PayPalProcessor extends BasePaymentProcessor {
6+
7+
// Locators
8+
readonly paypalContainerSelector = '#paypal-container';
9+
readonly emailInput = '#email';
10+
readonly passwordInput = '#password';
11+
readonly nextButton = '#btnNext'
12+
readonly loginButton = '#btnLogin';
13+
readonly submitButton = '[data-testid="submit-button-initial"]';
14+
readonly paymentConfirmationMessage = '.payment-confirmation';
15+
readonly errorMessage = '.paypal-error-message';
16+
17+
constructor(page: Page) {
18+
super(page);
19+
}
20+
21+
/**
22+
* Feature: PayPal payment processing
23+
* Scenario: User can pay with PayPal in block checkout
24+
* Given the user has selected PayPal payment method
25+
* When the user clicks the PayPal container
26+
* And is redirected to PayPal login
27+
* And enters valid credentials
28+
* And clicks submit button
29+
* Then the payment should be processed successfully
30+
*
31+
* Scenario: User can pay with PayPal in classic checkout
32+
* Given the user has selected PayPal payment method
33+
* When the user clicks process payment
34+
* And is redirected to PayPal login
35+
* And enters valid credentials
36+
* And clicks submit button
37+
* Then the payment should be processed successfully
38+
*/
39+
async processPayment(expectSuccess: boolean = true, preset: string = 'success') {
40+
const paypalDetails = PAYMENT_TEST_DATA.paypal[preset];
41+
42+
await this.page.waitForTimeout(1000);
43+
const paypalContainer = await this.page.$(this.paypalContainerSelector);
44+
45+
if (paypalContainer) {
46+
console.log('Block checkout detected - clicking PayPal container');
47+
await this.page.click(this.paypalContainerSelector);
48+
} else {
49+
console.log('Classic checkout detected - clicking process payment button');
50+
await this.clickWooSubmitButton();
51+
}
52+
53+
await this.handlePayPalLogin(paypalDetails);
54+
55+
if (expectSuccess) {
56+
await this.page.waitForNavigation({ waitUntil: 'networkidle' });
57+
}
58+
}
59+
60+
/**
61+
* Feature: PayPal login with retry logic
62+
* Scenario: User login credentials may need to be entered twice
63+
* Given the user is on PayPal login page
64+
* When the user enters credentials
65+
* And sometimes needs to retry entering credentials
66+
* Then the user should be able to login successfully
67+
*/
68+
private async handlePayPalLogin(paypalDetails: { user: string; pw: string }) {
69+
await this.page.waitForSelector(this.emailInput, { timeout: 10000 });
70+
71+
const maxRetries = 2;
72+
let attempt = 0;
73+
74+
while (attempt < maxRetries) {
75+
attempt++;
76+
console.log(`PayPal login attempt ${attempt}/${maxRetries}`);
77+
78+
try {
79+
await this.page.fill(this.emailInput, paypalDetails.user);
80+
await this.page.waitForTimeout(500);
81+
await this.page.click(this.nextButton);
82+
await this.page.fill(this.passwordInput, paypalDetails.pw);
83+
await this.page.waitForTimeout(500);
84+
85+
await this.page.click(this.loginButton);
86+
await this.page.waitForTimeout(2000);
87+
88+
const stillOnLoginPage = await this.page.$(this.emailInput);
89+
90+
if (!stillOnLoginPage) {
91+
console.log('Login successful, proceeding to payment confirmation');
92+
break;
93+
} else if (attempt < maxRetries) {
94+
console.log('Still on login page, retrying credentials...');
95+
// Clear the fields before retry
96+
await this.page.fill(this.emailInput, '');
97+
await this.page.fill(this.passwordInput, '');
98+
await this.page.waitForTimeout(1000);
99+
} else {
100+
console.log('Max login attempts reached');
101+
}
102+
103+
} catch (error) {
104+
console.log(`Login attempt ${attempt} failed:`, error.message);
105+
if (attempt >= maxRetries) {
106+
throw error;
107+
}
108+
}
109+
}
110+
111+
await this.page.waitForSelector(this.submitButton, { timeout: 10000 });
112+
await this.page.click(this.submitButton);
113+
}
114+
115+
/**
116+
* Feature: PayPal login error handling
117+
* Scenario: User enters invalid PayPal credentials
118+
* Given the user is on the PayPal login page
119+
* When the user enters invalid credentials
120+
* Then an error message should be displayed
121+
*/
122+
async handleLoginError(invalidCredentials: {
123+
user: string;
124+
pw: string;
125+
}) {
126+
await this.page.waitForSelector(this.emailInput);
127+
128+
await this.page.fill(this.emailInput, invalidCredentials.user);
129+
await this.page.fill(this.passwordInput, invalidCredentials.pw);
130+
await this.page.click(this.loginButton);
131+
132+
const errorSelector = '#errorSection';
133+
await this.page.waitForSelector(errorSelector);
134+
return this.page.textContent(errorSelector);
135+
}
136+
137+
/**
138+
* Feature: PayPal payment cancellation
139+
* Scenario: User cancels PayPal payment
140+
* Given the user is on the PayPal payment confirmation page
141+
* When the user clicks the cancel link
142+
* Then they should be redirected back to the merchant site
143+
*/
144+
async cancelPayment() {
145+
const cancelLinkSelector = '#cancelLink';
146+
await this.page.waitForSelector(cancelLinkSelector);
147+
await this.page.click(cancelLinkSelector);
148+
await this.page.waitForNavigation({ waitUntil: 'networkidle' });
149+
}
150+
151+
/**
152+
* Feature: PayPal error handling
153+
* Scenario: PayPal payment fails
154+
* Given the user has initiated a PayPal payment
155+
* When there's an error processing the payment
156+
* Then an error message should be displayed
157+
*/
158+
async handlePaymentError() {
159+
await this.page.waitForSelector(this.errorMessage);
160+
return this.page.textContent(this.errorMessage);
161+
}
162+
}

tests/specs/payment-gateway-matrix.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { getPaymentProcessor } from '../helpers/payment-processors';
66
import { OrderVerification } from '../verification/order-verification';
77
import {CartPage} from "../pages/cart-page";
88

9-
const configName = process.env.TEST_CONFIG || 'BIZUM_TESTS';
9+
const configName = process.env.TEST_CONFIG || 'PAYPAL_TESTS';
1010
const configurations = TEST_CONFIGURATIONS[configName];
1111

1212
// Each configuration is a complete test case with all the properties needed for the test
@@ -18,6 +18,7 @@ const testCombinations = configurations.map(config => ({
1818
expectSuccess: config.expectSuccess,
1919
userType: config.userType
2020
}));
21+
console.log(testCombinations);
2122
test.describe('Payment Gateway Matrix Tests', () => {
2223
testCombinations.forEach(({ paymentMethod, checkoutType, productType, userState, expectSuccess, userType }) => {
2324
test(`${paymentMethod.name} - ${checkoutType.name} - ${productType.name} - ${userState.name}`, async ({ page }) => {
@@ -30,7 +31,6 @@ test.describe('Payment Gateway Matrix Tests', () => {
3031
await checkoutPage.goToCheckout(checkoutType.isBlockCheckout);
3132
await checkoutPage.fillBillingDetails(userType);
3233
const selector = paymentMethod.selector[checkoutType.isBlockCheckout? 'block' : 'classic'];
33-
console.log(selector);
3434
await page.click(selector);
3535

3636
await paymentProcessor.processPayment(paymentMethod.isHostedPayment, paymentMethod.presetCredentials);

0 commit comments

Comments
 (0)