Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KCP tests #2981

Merged
merged 1 commit into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/e2e-playwright/fixtures/URL_MAP.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const URL_MAP = {
cardWithAvs: '/iframe.html?args=&globals=&id=cards-card--with-avs&viewMode=story',
cardWithPartialAvs: '/iframe.html?args=&globals=&id=cards-card--with-partial-avs&viewMode=story',
cardWithInstallments: '/iframe.html?args=&id=cards-card--with-installments&viewMode=story',
cardWithKcp: '/iframe.html?args=&id=cards-card--kcp&viewMode=story',
cardWithKcp: '/iframe.html?args=&globals=&id=cards-card--with-kcp&viewMode=story',
cardWithClickToPay: '/iframe.html?args=&id=cards-card--with-click-to-pay&viewMode=story',
fullAvsWithoutPrefilledDataUrl: '/iframe.html?args=componentConfiguration.data:!undefined&globals=&id=cards-card--with-avs&viewMode=story',
fullAvsWithPrefilledDataUrl: '/iframe.html?globals=&args=&id=cards-card--with-avs&viewMode=story',
Expand Down
17 changes: 14 additions & 3 deletions packages/e2e-playwright/mocks/payments/payments.mock.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Page } from '@playwright/test';

const PAYMENTS_URL = 'https://checkoutshopper-*.adyen.com/checkoutshopper/v1/sessions/*/payments?*';

const paymentsMock = async (page: Page, mockedResponse: any): Promise<void> => {
await page.route(PAYMENTS_URL, (route, request) => {
await page.route(PAYMENTS_URL, async (route, request) => {
const requestData = JSON.parse(request.postData() || '');

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

export { paymentsMock };
const paymentSuccessfulMock = async (page: Page) => {
await page.route(PAYMENTS_URL, async route => {
await route.fulfill({
json: {
resultCode: 'Authorised'
}
});
});
};

export { paymentsMock, paymentSuccessfulMock };
27 changes: 23 additions & 4 deletions packages/e2e-playwright/models/card-kcp.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
import { Card } from './card';
import { type Locator, Page } from '@playwright/test';
import { USER_TYPE_DELAY } from '../tests/utils/constants';

class CardWithKCP extends Card {
readonly kcpTaxNumberField: Locator;

constructor(page: Page) {
super(page);
this.kcpTaxNumberField = this.rootElement.locator('.adyen-checkout__field--kcp-taxNumber'); // Holder
}

get taxNumberInput() {
return this.kcpTaxNumberField.getByRole('textbox', { name: /Cardholder birthdate/i });
return this.rootElement.getByRole('textbox', { name: /Cardholder birthdate/i });
}

get taxNumberErrorLocator() {
return this.rootElement.locator('.adyen-checkout__field--kcp-taxNumber .adyen-checkout-contextual-text--error');
}

get passwordInput() {
const passwordIframe = this.rootElement.frameLocator('[title="Iframe for password"]');
return passwordIframe.locator('input[aria-label="First 2 digits of card password"]');
}

get passwordErrorLocator() {
return this.rootElement.locator('.adyen-checkout__field--koreanAuthentication-encryptedPassword .adyen-checkout-contextual-text--error');
}

async typeTaxNumber(taxNumber: string) {
return this.taxNumberInput.pressSequentially(taxNumber, { delay: USER_TYPE_DELAY });
}

async typePassword(password: string) {
return this.passwordInput.pressSequentially(password, { delay: USER_TYPE_DELAY });
}
}

Expand Down
149 changes: 149 additions & 0 deletions packages/e2e-playwright/tests/e2e/card/kcp/card.kcp.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import { expect, test } from '../../../../fixtures/card.fixture';
import { URL_MAP } from '../../../../fixtures/URL_MAP';
import {
KOREAN_TEST_CARD,
PAYMENT_RESULT,
REGULAR_TEST_CARD,
TEST_CVC_VALUE,
TEST_DATE_VALUE,
TEST_PWD_VALUE,
TEST_TAX_NUMBER_VALUE
} from '../../../utils/constants';
import { getStoryUrl } from '../../../utils/getStoryUrl';
import { paymentSuccessfulMock } from '../../../../mocks/payments/payments.mock';

test.describe('Card with KCP fields', () => {
test.describe('Displaying KCP fields by default', () => {
test('should hide KCP fields if Card is not korean and make the payment', async ({ cardWithKCP }) => {
await cardWithKCP.goto(URL_MAP.cardWithKcp);
await cardWithKCP.typeCardNumber(REGULAR_TEST_CARD);

await expect(cardWithKCP.passwordInput).not.toBeVisible();
await expect(cardWithKCP.taxNumberInput).not.toBeVisible();

await cardWithKCP.typeCvc(TEST_CVC_VALUE);
await cardWithKCP.typeExpiryDate(TEST_DATE_VALUE);
await cardWithKCP.pay();

await expect(cardWithKCP.paymentResult).toContainText(PAYMENT_RESULT.authorised);
});

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 ({
cardWithKCP,
page
}) => {
await paymentSuccessfulMock(page);
const paymentsRequestPromise = page.waitForRequest(request => request.url().includes('/payments') && request.method() === 'POST');

await cardWithKCP.goto(URL_MAP.cardWithKcp);
await cardWithKCP.typeCardNumber(REGULAR_TEST_CARD);

await expect(cardWithKCP.passwordInput).not.toBeVisible();
await expect(cardWithKCP.taxNumberInput).not.toBeVisible();

await cardWithKCP.deleteCardNumber();

await cardWithKCP.typeCardNumber(KOREAN_TEST_CARD);
await cardWithKCP.typeCvc(TEST_CVC_VALUE);
await cardWithKCP.typeExpiryDate(TEST_DATE_VALUE);
await cardWithKCP.typeTaxNumber(TEST_TAX_NUMBER_VALUE);
await cardWithKCP.typePassword(TEST_PWD_VALUE);
await cardWithKCP.pay();

// Check that KCP fields are passed in
const request = await paymentsRequestPromise;
const paymentMethod = await request.postDataJSON().paymentMethod;
expect(paymentMethod.encryptedPassword).not.toBeNull();
expect(paymentMethod.taxNumber).not.toBeNull();

await expect(cardWithKCP.paymentResult).toContainText(PAYMENT_RESULT.authorised);
});
test('should fill in KCP fields, then replace with non-korean Card and make a payment', async ({ cardWithKCP }) => {
await cardWithKCP.goto(URL_MAP.cardWithKcp);

await cardWithKCP.typeCardNumber(KOREAN_TEST_CARD);
await cardWithKCP.typeCvc(TEST_CVC_VALUE);
await cardWithKCP.typeExpiryDate(TEST_DATE_VALUE);
await cardWithKCP.typeTaxNumber(TEST_TAX_NUMBER_VALUE);
await cardWithKCP.typePassword(TEST_PWD_VALUE);

await cardWithKCP.deleteCardNumber();
await cardWithKCP.typeCardNumber(REGULAR_TEST_CARD);

await expect(cardWithKCP.passwordInput).not.toBeVisible();
await expect(cardWithKCP.taxNumberInput).not.toBeVisible();

await cardWithKCP.pay();

await expect(cardWithKCP.paymentResult).toContainText(PAYMENT_RESULT.authorised);
});
});

test.describe('Displaying KCP fields once Korean card is detected', () => {
const url = getStoryUrl({
baseUrl: URL_MAP.card,
componentConfig: {
brands: ['mc', 'visa', 'amex', 'korean_local_card'],
configuration: {
koreanAuthenticationRequired: true
}
}
});

test('should display KCP fields once korean card is entered and make the payment', async ({ cardWithKCP, page }) => {
await paymentSuccessfulMock(page);

await cardWithKCP.goto(url);

await expect(cardWithKCP.passwordInput).not.toBeVisible();
await expect(cardWithKCP.taxNumberInput).not.toBeVisible();

await cardWithKCP.typeCardNumber(KOREAN_TEST_CARD);

await expect(cardWithKCP.passwordInput).toBeVisible();
await expect(cardWithKCP.taxNumberInput).toBeVisible();

await cardWithKCP.typeCvc(TEST_CVC_VALUE);
await cardWithKCP.typeExpiryDate(TEST_DATE_VALUE);
await cardWithKCP.typeTaxNumber(TEST_TAX_NUMBER_VALUE);
await cardWithKCP.typePassword(TEST_PWD_VALUE);
await cardWithKCP.pay();

await expect(cardWithKCP.paymentResult).toContainText(PAYMENT_RESULT.authorised);
});

test('should display KCP fields once korean card is entered, then replace by regular Card and make the payment', async ({ cardWithKCP }) => {
await cardWithKCP.goto(url);

await cardWithKCP.typeCardNumber(KOREAN_TEST_CARD);

await expect(cardWithKCP.passwordInput).toBeVisible();
await expect(cardWithKCP.taxNumberInput).toBeVisible();

await cardWithKCP.deleteCardNumber();

await cardWithKCP.typeCardNumber(REGULAR_TEST_CARD);
await cardWithKCP.typeCvc(TEST_CVC_VALUE);
await cardWithKCP.typeExpiryDate(TEST_DATE_VALUE);

await expect(cardWithKCP.passwordInput).not.toBeVisible();
await expect(cardWithKCP.taxNumberInput).not.toBeVisible();

await cardWithKCP.pay();

await expect(cardWithKCP.paymentResult).toContainText(PAYMENT_RESULT.authorised);
});

test('should apply validation to KCP fields', async ({ cardWithKCP }) => {
await cardWithKCP.goto(url);

await cardWithKCP.typeCardNumber(KOREAN_TEST_CARD);
await cardWithKCP.typeCvc(TEST_CVC_VALUE);
await cardWithKCP.typeExpiryDate(TEST_DATE_VALUE);
await cardWithKCP.pay();

await expect(cardWithKCP.taxNumberErrorLocator).toHaveText('Invalid Cardholder birthdate or Corporate registration number');
await expect(cardWithKCP.passwordErrorLocator).toHaveText('Enter the password');
});
});
});

This file was deleted.

This file was deleted.

This file was deleted.

Loading
Loading