Skip to content

Commit e863f37

Browse files
kcp tests (#2981)
1 parent 7854997 commit e863f37

File tree

9 files changed

+190
-343
lines changed

9 files changed

+190
-343
lines changed

packages/e2e-playwright/fixtures/URL_MAP.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export const URL_MAP = {
1616
cardWithAvs: '/iframe.html?args=&globals=&id=cards-card--with-avs&viewMode=story',
1717
cardWithPartialAvs: '/iframe.html?args=&globals=&id=cards-card--with-partial-avs&viewMode=story',
1818
cardWithInstallments: '/iframe.html?args=&id=cards-card--with-installments&viewMode=story',
19-
cardWithKcp: '/iframe.html?args=&id=cards-card--kcp&viewMode=story',
19+
cardWithKcp: '/iframe.html?args=&globals=&id=cards-card--with-kcp&viewMode=story',
2020
cardWithClickToPay: '/iframe.html?args=&id=cards-card--with-click-to-pay&viewMode=story',
2121
fullAvsWithoutPrefilledDataUrl: '/iframe.html?args=componentConfiguration.data:!undefined&globals=&id=cards-card--with-avs&viewMode=story',
2222
fullAvsWithPrefilledDataUrl: '/iframe.html?globals=&args=&id=cards-card--with-avs&viewMode=story',

packages/e2e-playwright/mocks/payments/payments.mock.ts

+14-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { Page } from '@playwright/test';
22

33
const PAYMENTS_URL = 'https://checkoutshopper-*.adyen.com/checkoutshopper/v1/sessions/*/payments?*';
4+
45
const paymentsMock = async (page: Page, mockedResponse: any): Promise<void> => {
5-
await page.route(PAYMENTS_URL, (route, request) => {
6+
await page.route(PAYMENTS_URL, async (route, request) => {
67
const requestData = JSON.parse(request.postData() || '');
78

8-
route.fulfill({
9+
await route.fulfill({
910
status: 200,
1011
contentType: 'application/json',
1112
body: JSON.stringify({
@@ -19,4 +20,14 @@ const paymentsMock = async (page: Page, mockedResponse: any): Promise<void> => {
1920
});
2021
};
2122

22-
export { paymentsMock };
23+
const paymentSuccessfulMock = async (page: Page) => {
24+
await page.route(PAYMENTS_URL, async route => {
25+
await route.fulfill({
26+
json: {
27+
resultCode: 'Authorised'
28+
}
29+
});
30+
});
31+
};
32+
33+
export { paymentsMock, paymentSuccessfulMock };

packages/e2e-playwright/models/card-kcp.ts

+23-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,35 @@
11
import { Card } from './card';
22
import { type Locator, Page } from '@playwright/test';
3+
import { USER_TYPE_DELAY } from '../tests/utils/constants';
34

45
class CardWithKCP extends Card {
5-
readonly kcpTaxNumberField: Locator;
6-
76
constructor(page: Page) {
87
super(page);
9-
this.kcpTaxNumberField = this.rootElement.locator('.adyen-checkout__field--kcp-taxNumber'); // Holder
108
}
119

1210
get taxNumberInput() {
13-
return this.kcpTaxNumberField.getByRole('textbox', { name: /Cardholder birthdate/i });
11+
return this.rootElement.getByRole('textbox', { name: /Cardholder birthdate/i });
12+
}
13+
14+
get taxNumberErrorLocator() {
15+
return this.rootElement.locator('.adyen-checkout__field--kcp-taxNumber .adyen-checkout-contextual-text--error');
16+
}
17+
18+
get passwordInput() {
19+
const passwordIframe = this.rootElement.frameLocator('[title="Iframe for password"]');
20+
return passwordIframe.locator('input[aria-label="First 2 digits of card password"]');
21+
}
22+
23+
get passwordErrorLocator() {
24+
return this.rootElement.locator('.adyen-checkout__field--koreanAuthentication-encryptedPassword .adyen-checkout-contextual-text--error');
25+
}
26+
27+
async typeTaxNumber(taxNumber: string) {
28+
return this.taxNumberInput.pressSequentially(taxNumber, { delay: USER_TYPE_DELAY });
29+
}
30+
31+
async typePassword(password: string) {
32+
return this.passwordInput.pressSequentially(password, { delay: USER_TYPE_DELAY });
1433
}
1534
}
1635

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
import { expect, test } from '../../../../fixtures/card.fixture';
2+
import { URL_MAP } from '../../../../fixtures/URL_MAP';
3+
import {
4+
KOREAN_TEST_CARD,
5+
PAYMENT_RESULT,
6+
REGULAR_TEST_CARD,
7+
TEST_CVC_VALUE,
8+
TEST_DATE_VALUE,
9+
TEST_PWD_VALUE,
10+
TEST_TAX_NUMBER_VALUE
11+
} from '../../../utils/constants';
12+
import { getStoryUrl } from '../../../utils/getStoryUrl';
13+
import { paymentSuccessfulMock } from '../../../../mocks/payments/payments.mock';
14+
15+
test.describe('Card with KCP fields', () => {
16+
test.describe('Displaying KCP fields by default', () => {
17+
test('should hide KCP fields if Card is not korean and make the payment', async ({ cardWithKCP }) => {
18+
await cardWithKCP.goto(URL_MAP.cardWithKcp);
19+
await cardWithKCP.typeCardNumber(REGULAR_TEST_CARD);
20+
21+
await expect(cardWithKCP.passwordInput).not.toBeVisible();
22+
await expect(cardWithKCP.taxNumberInput).not.toBeVisible();
23+
24+
await cardWithKCP.typeCvc(TEST_CVC_VALUE);
25+
await cardWithKCP.typeExpiryDate(TEST_DATE_VALUE);
26+
await cardWithKCP.pay();
27+
28+
await expect(cardWithKCP.paymentResult).toContainText(PAYMENT_RESULT.authorised);
29+
});
30+
31+
test('should hide KCP fields if Card is not korean, then show them again once the Card is replaced by korean card and make the payment', async ({
32+
cardWithKCP,
33+
page
34+
}) => {
35+
await paymentSuccessfulMock(page);
36+
const paymentsRequestPromise = page.waitForRequest(request => request.url().includes('/payments') && request.method() === 'POST');
37+
38+
await cardWithKCP.goto(URL_MAP.cardWithKcp);
39+
await cardWithKCP.typeCardNumber(REGULAR_TEST_CARD);
40+
41+
await expect(cardWithKCP.passwordInput).not.toBeVisible();
42+
await expect(cardWithKCP.taxNumberInput).not.toBeVisible();
43+
44+
await cardWithKCP.deleteCardNumber();
45+
46+
await cardWithKCP.typeCardNumber(KOREAN_TEST_CARD);
47+
await cardWithKCP.typeCvc(TEST_CVC_VALUE);
48+
await cardWithKCP.typeExpiryDate(TEST_DATE_VALUE);
49+
await cardWithKCP.typeTaxNumber(TEST_TAX_NUMBER_VALUE);
50+
await cardWithKCP.typePassword(TEST_PWD_VALUE);
51+
await cardWithKCP.pay();
52+
53+
// Check that KCP fields are passed in
54+
const request = await paymentsRequestPromise;
55+
const paymentMethod = await request.postDataJSON().paymentMethod;
56+
expect(paymentMethod.encryptedPassword).not.toBeNull();
57+
expect(paymentMethod.taxNumber).not.toBeNull();
58+
59+
await expect(cardWithKCP.paymentResult).toContainText(PAYMENT_RESULT.authorised);
60+
});
61+
test('should fill in KCP fields, then replace with non-korean Card and make a payment', async ({ cardWithKCP }) => {
62+
await cardWithKCP.goto(URL_MAP.cardWithKcp);
63+
64+
await cardWithKCP.typeCardNumber(KOREAN_TEST_CARD);
65+
await cardWithKCP.typeCvc(TEST_CVC_VALUE);
66+
await cardWithKCP.typeExpiryDate(TEST_DATE_VALUE);
67+
await cardWithKCP.typeTaxNumber(TEST_TAX_NUMBER_VALUE);
68+
await cardWithKCP.typePassword(TEST_PWD_VALUE);
69+
70+
await cardWithKCP.deleteCardNumber();
71+
await cardWithKCP.typeCardNumber(REGULAR_TEST_CARD);
72+
73+
await expect(cardWithKCP.passwordInput).not.toBeVisible();
74+
await expect(cardWithKCP.taxNumberInput).not.toBeVisible();
75+
76+
await cardWithKCP.pay();
77+
78+
await expect(cardWithKCP.paymentResult).toContainText(PAYMENT_RESULT.authorised);
79+
});
80+
});
81+
82+
test.describe('Displaying KCP fields once Korean card is detected', () => {
83+
const url = getStoryUrl({
84+
baseUrl: URL_MAP.card,
85+
componentConfig: {
86+
brands: ['mc', 'visa', 'amex', 'korean_local_card'],
87+
configuration: {
88+
koreanAuthenticationRequired: true
89+
}
90+
}
91+
});
92+
93+
test('should display KCP fields once korean card is entered and make the payment', async ({ cardWithKCP, page }) => {
94+
await paymentSuccessfulMock(page);
95+
96+
await cardWithKCP.goto(url);
97+
98+
await expect(cardWithKCP.passwordInput).not.toBeVisible();
99+
await expect(cardWithKCP.taxNumberInput).not.toBeVisible();
100+
101+
await cardWithKCP.typeCardNumber(KOREAN_TEST_CARD);
102+
103+
await expect(cardWithKCP.passwordInput).toBeVisible();
104+
await expect(cardWithKCP.taxNumberInput).toBeVisible();
105+
106+
await cardWithKCP.typeCvc(TEST_CVC_VALUE);
107+
await cardWithKCP.typeExpiryDate(TEST_DATE_VALUE);
108+
await cardWithKCP.typeTaxNumber(TEST_TAX_NUMBER_VALUE);
109+
await cardWithKCP.typePassword(TEST_PWD_VALUE);
110+
await cardWithKCP.pay();
111+
112+
await expect(cardWithKCP.paymentResult).toContainText(PAYMENT_RESULT.authorised);
113+
});
114+
115+
test('should display KCP fields once korean card is entered, then replace by regular Card and make the payment', async ({ cardWithKCP }) => {
116+
await cardWithKCP.goto(url);
117+
118+
await cardWithKCP.typeCardNumber(KOREAN_TEST_CARD);
119+
120+
await expect(cardWithKCP.passwordInput).toBeVisible();
121+
await expect(cardWithKCP.taxNumberInput).toBeVisible();
122+
123+
await cardWithKCP.deleteCardNumber();
124+
125+
await cardWithKCP.typeCardNumber(REGULAR_TEST_CARD);
126+
await cardWithKCP.typeCvc(TEST_CVC_VALUE);
127+
await cardWithKCP.typeExpiryDate(TEST_DATE_VALUE);
128+
129+
await expect(cardWithKCP.passwordInput).not.toBeVisible();
130+
await expect(cardWithKCP.taxNumberInput).not.toBeVisible();
131+
132+
await cardWithKCP.pay();
133+
134+
await expect(cardWithKCP.paymentResult).toContainText(PAYMENT_RESULT.authorised);
135+
});
136+
137+
test('should apply validation to KCP fields', async ({ cardWithKCP }) => {
138+
await cardWithKCP.goto(url);
139+
140+
await cardWithKCP.typeCardNumber(KOREAN_TEST_CARD);
141+
await cardWithKCP.typeCvc(TEST_CVC_VALUE);
142+
await cardWithKCP.typeExpiryDate(TEST_DATE_VALUE);
143+
await cardWithKCP.pay();
144+
145+
await expect(cardWithKCP.taxNumberErrorLocator).toHaveText('Invalid Cardholder birthdate or Corporate registration number');
146+
await expect(cardWithKCP.passwordErrorLocator).toHaveText('Enter the password');
147+
});
148+
});
149+
});

packages/e2e-playwright/tests/ui/card/kcp/startWithKCP/startWithKCP.clientScripts.js

-11
This file was deleted.

packages/e2e-playwright/tests/ui/card/kcp/startWithKCP/startWithKCP.spec.ts

-137
This file was deleted.

packages/e2e-playwright/tests/ui/card/kcp/startWithoutKCP/startWithoutKCP.clientScripts.js

-10
This file was deleted.

0 commit comments

Comments
 (0)