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

Migrated card's general test and legacyInputMode tests to Playwright … #2332

Merged
merged 2 commits into from
Sep 27, 2023
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
59 changes: 56 additions & 3 deletions packages/e2e-playwright/models/card.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,70 @@
import { Locator, Page } from '@playwright/test';
import { USER_TYPE_DELAY } from '../tests/utils/constants';
import LANG from '../../lib/src/language/locales/en-US.json';

const CARD_IFRAME_TITLE = LANG['creditCard.encryptedCardNumber.aria.iframeTitle'];
const EXPIRY_DATE_IFRAME_TITLE = LANG['creditCard.encryptedExpiryDate.aria.iframeTitle'];
const CVC_IFRAME_TITLE = LANG['creditCard.encryptedSecurityCode.aria.iframeTitle'];

const CARD_IFRAME_LABEL = LANG['creditCard.encryptedCardNumber.aria.label'];
const EXPIRY_DATE_IFRAME_LABEL = LANG['creditCard.encryptedExpiryDate.aria.label'];
const CVC_IFRAME_LABEL = LANG['creditCard.encryptedSecurityCode.aria.label'];

class Card {
readonly rootElement: Locator;
readonly rootElementSelector: string;

readonly cardNumberField: Locator;
readonly cardNumberErrorElement: Locator;
readonly cardNumberInput: Locator;

readonly expiryDateField: Locator;
readonly expiryDateErrorElement: Locator;
readonly expiryDateInput: Locator;

readonly cvcField: Locator;
readonly cvcErrorElement: Locator;
readonly cvcInput: Locator;

constructor(page: Page, rootElementSelector = '.adyen-checkout__card-input') {
this.rootElement = page.locator(rootElementSelector);
this.rootElementSelector = rootElementSelector;

this.cardNumberInput = this.rootElement.frameLocator('[title="Iframe for card number"]').locator('input[aria-label="Card number"]');
this.expiryDateInput = this.rootElement.frameLocator('[title="Iframe for expiry date"]').locator('input[aria-label="Expiry date"]');
this.cvcInput = this.rootElement.frameLocator('[title="Iframe for security code"]').locator('input[aria-label="Security code"]');
/**
* Card Number elements, in Checkout
*/
this.cardNumberField = this.rootElement.locator('.adyen-checkout__field--cardNumber'); // Holder
this.cardNumberErrorElement = this.cardNumberField.locator('.adyen-checkout__error-text');

/**
* Card Number elements, in iframe
*/
const cardNumberIframe = this.rootElement.frameLocator(`[title="${CARD_IFRAME_TITLE}"]`);
this.cardNumberInput = cardNumberIframe.locator(`input[aria-label="${CARD_IFRAME_LABEL}"]`);

/**
* Expiry Date elements, in Checkout
*/
this.expiryDateField = this.rootElement.locator('.adyen-checkout__field--expiryDate'); // Holder
this.expiryDateErrorElement = this.expiryDateField.locator('.adyen-checkout__error-text'); // Related error element

/**
* Expiry Date elements, in iframe
*/
const expiryDateIframe = this.rootElement.frameLocator(`[title="${EXPIRY_DATE_IFRAME_TITLE}"]`);
this.expiryDateInput = expiryDateIframe.locator(`input[aria-label="${EXPIRY_DATE_IFRAME_LABEL}"]`);

/**
* Security code elements, in Checkout
*/
this.cvcField = this.rootElement.locator('.adyen-checkout__field--securityCode'); // Holder
this.cvcErrorElement = this.cvcField.locator('.adyen-checkout__error-text'); // Related error element

/**
* Security code elements, in iframe
*/
const cvcIframe = this.rootElement.frameLocator(`[title="${CVC_IFRAME_TITLE}"]`);
this.cvcInput = cvcIframe.locator(`input[aria-label="${CVC_IFRAME_LABEL}"]`);
}

async isComponentVisible() {
Expand All @@ -28,6 +77,10 @@ class Card {
await this.cardNumberInput.type(cardNumber, { delay: USER_TYPE_DELAY });
}

async deleteCardNumber() {
await this.cardNumberInput.clear();
}

async typeExpiryDate(expiryDate: string) {
await this.expiryDateInput.type(expiryDate, { delay: USER_TYPE_DELAY });
}
Expand Down
11 changes: 11 additions & 0 deletions packages/e2e-playwright/pages/cards/card.fixture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { optionalDateAndCvcMock } from '../../mocks/binLookup/binLookup.data';
type Fixture = {
cardPage: CardPage;
cardAvsPage: CardAvsPage;
cardLegacyInputModePage: CardPage;
};

const test = base.extend<Fixture>({
Expand All @@ -26,6 +27,16 @@ const test = base.extend<Fixture>({
const cardAvsPage = new CardAvsPage(page);
await cardAvsPage.goto();
await use(cardAvsPage);
},

cardLegacyInputModePage: async ({ page }, use) => {
await page.addInitScript({
content: 'window.cardConfig = { legacyInputMode: true}'
});

const cardPage = new CardPage(page);
await cardPage.goto();
await use(cardPage);
}
});

Expand Down
36 changes: 18 additions & 18 deletions packages/e2e-playwright/playwright-report/index.html

Large diffs are not rendered by default.

38 changes: 37 additions & 1 deletion packages/e2e-playwright/tests/card/card.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { test, expect } from '../../pages/cards/card.fixture';
import { REGULAR_TEST_CARD, TEST_CVC_VALUE, TEST_DATE_VALUE } from '../utils/constants';
import LANG from '../../../lib/src/language/locales/en-US.json';

test('should fill in card fields and complete the payment', async ({ cardPage }) => {
const PAN_ERROR_NOT_VALID = LANG['error.va.sf-cc-num.01'];
const PAN_ERROR_EMPTY = LANG['error.va.sf-cc-num.02'];
const PAN_ERROR_NOT_COMPLETE = LANG['error.va.sf-cc-num.04'];

test('#1 Should fill in card fields and complete the payment', async ({ cardPage }) => {
const { card, page } = cardPage;

await card.typeCardNumber(REGULAR_TEST_CARD);
Expand All @@ -12,3 +17,34 @@ test('should fill in card fields and complete the payment', async ({ cardPage })

await expect(page.locator('#result-message')).toHaveText('Authorised');
});

test('#2 PAN that consists of the same digit (but passes luhn) causes an error', async ({ cardPage }) => {
const { card, page } = cardPage;

await card.typeCardNumber('3333 3333 3333 3333 3333');

await cardPage.pay();

await expect(card.cardNumberErrorElement).toBeVisible();
await expect(card.cardNumberErrorElement).toHaveText(PAN_ERROR_NOT_VALID);
});

test('#3 Clicking pay button with an empty PAN causes an "empty" error on the PAN field', async ({ cardPage }) => {
const { card, page } = cardPage;

await cardPage.pay();

await expect(card.cardNumberErrorElement).toBeVisible();
await expect(card.cardNumberErrorElement).toHaveText(PAN_ERROR_EMPTY);
});

test('#4 PAN that consists of only 1 digit causes a "wrong length" error ', async ({ cardPage }) => {
const { card, page } = cardPage;

await card.typeCardNumber('4');

await cardPage.pay();

await expect(card.cardNumberErrorElement).toBeVisible();
await expect(card.cardNumberErrorElement).toHaveText(PAN_ERROR_NOT_COMPLETE);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { test, expect } from '../../../pages/cards/card.fixture';

test('#1 By default expect all securedFields to have inputs with type="text" & inputmode="numeric"', async ({ cardPage }) => {
const { card } = cardPage;

await card.isComponentVisible();

const panInputType = await card.cardNumberInput.getAttribute('type');
await expect(panInputType).toEqual('text');

const panInputMode = await card.cardNumberInput.getAttribute('inputmode');
await expect(panInputMode).toEqual('numeric');

const expiryDateInputType = await card.expiryDateInput.getAttribute('type');
await expect(expiryDateInputType).toEqual('text');

const expiryDateInputMode = await card.expiryDateInput.getAttribute('inputmode');
await expect(expiryDateInputMode).toEqual('numeric');

const cvcInputType = await card.cvcInput.getAttribute('type');
await expect(cvcInputType).toEqual('text');

const cvcInputMode = await card.cvcInput.getAttribute('inputmode');
await expect(cvcInputMode).toEqual('numeric');
});

test('#2 Set legacyInputMode and expect all securedFields to have inputs with type="tel"', async ({ cardLegacyInputModePage }) => {
const { card, page } = cardLegacyInputModePage;

await card.isComponentVisible();

const panInputType = await card.cardNumberInput.getAttribute('type');
await expect(panInputType).toEqual('tel');

const panInputMode = await card.cardNumberInput.getAttribute('inputmode');
await expect(panInputMode).toBeNull();

const expiryDateInputType = await card.expiryDateInput.getAttribute('type');
await expect(expiryDateInputType).toEqual('tel');

const expiryDateInputMode = await card.expiryDateInput.getAttribute('inputmode');
await expect(expiryDateInputMode).toBeNull();

const cvcInputType = await card.cvcInput.getAttribute('type');
await expect(cvcInputType).toEqual('tel');

const cvcInputMode = await card.cvcInput.getAttribute('inputmode');
await expect(cvcInputMode).toBeNull();
});
97 changes: 0 additions & 97 deletions packages/e2e/tests/cards/general/general.test.js

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.