Skip to content

Commit

Permalink
Merge branch 'v6' into poc/component-tree-shaking-new-operator-v2
Browse files Browse the repository at this point in the history
  • Loading branch information
ribeiroguilherme committed Oct 2, 2023
2 parents 9fce638 + 28ae874 commit 3251083
Show file tree
Hide file tree
Showing 265 changed files with 3,532 additions and 3,182 deletions.
13 changes: 13 additions & 0 deletions .changeset/short-dolphins-worry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
'@adyen/adyen-web': major
---

Redesign with Bento design tokens.\
Remove default placeholders, merchants can configure placeholders via the configuration object.\
Add `showContextualElement` and `contextualText` for the form field, merchants can configure them via configuration object.\
New spinner.\
Phone prefix drop down contains flag icons.\
Ideal issuer names align to the right.\
Fix the stored card icon overlapping with the error icon.\
Scss code refactoring.\
Use the same syntax for 'required' error message in the Personal details and Address components.
7 changes: 4 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ dist
coverage
storybook-static

packages/lib/package
packages/lib/package2
# Playwright reports
packages/playground/playwright-report/


*.log*
.env
Expand Down Expand Up @@ -35,4 +36,4 @@ Vagrantfile

# Certifictes
cert
*.pem
*.pem
2 changes: 1 addition & 1 deletion env.default
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
API_VERSION=v68
API_VERSION=v69

CHECKOUT_API_KEY=

Expand Down
66 changes: 63 additions & 3 deletions packages/e2e-playwright/models/card.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,77 @@
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.cardNumber.label'];
const EXPIRY_DATE_IFRAME_LABEL = LANG['creditCard.expiryDate.label'];
const CVC_IFRAME_LABEL = LANG['creditCard.securityCode.label'];

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

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

readonly expiryDateField: Locator;
readonly expiryDateContextualElement: Locator;
readonly expiryDateInput: Locator;
readonly expiryDateIframeContextualElement: Locator;

readonly cvcField: Locator;
readonly cvcErrorElement: Locator;
readonly cvcContextualElement: Locator;
readonly cvcInput: Locator;
readonly cvcIframeContextualElement: 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-contextual-text--error');

/**
* 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.expiryDateContextualElement = this.expiryDateField.locator('.adyen-checkout-contextual-text'); // Related contextual 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}"]`);
this.expiryDateIframeContextualElement = expiryDateIframe.locator('.aria-context');

/**
* Security code elements, in Checkout
*/
this.cvcField = this.rootElement.locator('.adyen-checkout__field--securityCode'); // Holder
this.cvcErrorElement = this.cvcField.locator('.adyen-checkout-contextual-text--error'); // Related erro element
this.cvcContextualElement = this.cvcField.locator('.adyen-checkout-contextual-text'); // Related contextual 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}"]`);
this.cvcIframeContextualElement = cvcIframe.locator('.aria-context');
}

async isComponentVisible() {
Expand All @@ -28,6 +84,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
2 changes: 1 addition & 1 deletion packages/e2e-playwright/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@
"webpack-dev-server": "4.13.3"
},
"dependencies": {
"@adyen/adyen-web": "5.50.1"
"@adyen/adyen-web": "5.51.0"
}
}
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;
cardNoContextualElementPage: 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);
},

cardNoContextualElementPage: async ({ page }, use) => {
await page.addInitScript({
content: 'window.cardConfig = { showContextualElement: false}'
});

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

Expand Down
102 changes: 102 additions & 0 deletions packages/e2e-playwright/tests/card/card.contextualTexts.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { test, expect } from '../../pages/cards/card.fixture';
import { AMEX_CARD } from '../utils/constants';
import LANG from '../../../lib/src/language/locales/en-US.json';

const EXPIRY_DATE_CONTEXTUAL_TEXT = LANG['creditCard.expiryDate.contextualText'];
const CVC_CONTEXTUAL_TEXT_3_DIGITS = LANG['creditCard.securityCode.contextualText.3digits'];
const CVC_CONTEXTUAL_TEXT_4_DIGITS = LANG['creditCard.securityCode.contextualText.4digits'];
const CVC_ERROR = LANG['error.va.sf-cc-cvc.01'];

test('#1 Should inspect the card inputs and see they have contextual elements set', async ({ cardPage }) => {
const { card, page } = cardPage;

await card.isComponentVisible();

// checkout expiryDate element
await expect(card.expiryDateContextualElement).toHaveText(EXPIRY_DATE_CONTEXTUAL_TEXT);
const expiryDateAriaHidden = await card.expiryDateContextualElement.getAttribute('aria-hidden');
await expect(expiryDateAriaHidden).toEqual('true');

// iframe expiryDate element
await expect(card.expiryDateIframeContextualElement).toHaveText(EXPIRY_DATE_CONTEXTUAL_TEXT);

// checkout security code contextual element
await expect(card.cvcContextualElement).toHaveText(CVC_CONTEXTUAL_TEXT_3_DIGITS);
const cvcAriaHidden = await card.cvcContextualElement.getAttribute('aria-hidden');
await expect(cvcAriaHidden).toEqual('true');

// iframe security code element
await expect(card.cvcIframeContextualElement).toHaveText(CVC_CONTEXTUAL_TEXT_3_DIGITS);

// Type amex number and see the contextual element change in the CVC field
await card.typeCardNumber(AMEX_CARD);

await expect(card.cvcContextualElement).toHaveText(CVC_CONTEXTUAL_TEXT_4_DIGITS);
await expect(card.cvcIframeContextualElement).toHaveText(CVC_CONTEXTUAL_TEXT_4_DIGITS);

// Delete the card number and see the contextual element reset in the CVC field
await card.deleteCardNumber();

await expect(card.cvcContextualElement).toHaveText(CVC_CONTEXTUAL_TEXT_3_DIGITS);
await expect(card.cvcIframeContextualElement).toHaveText(CVC_CONTEXTUAL_TEXT_3_DIGITS);
});

test('#2 Should inspect the cvc input for a contextual text set, then it should be replaced by an error, then reset', async ({ cardPage }) => {
const { card, page } = cardPage;

await card.isComponentVisible();

// checkout security code contextual element
await expect(card.cvcContextualElement).toHaveText(CVC_CONTEXTUAL_TEXT_3_DIGITS);
let cvcAriaHidden = await card.cvcContextualElement.getAttribute('aria-hidden');
await expect(cvcAriaHidden).toEqual('true');

// error element hidden
await expect(card.cvcErrorElement).not.toBeVisible();

// iframe security code contextual element
await expect(card.cvcIframeContextualElement).toHaveText(CVC_CONTEXTUAL_TEXT_3_DIGITS);

// press pay to generate errors
await cardPage.pay();

// checkout security code error element
await expect(card.cvcErrorElement).toBeVisible();
await expect(card.cvcErrorElement).toHaveText(CVC_ERROR);
cvcAriaHidden = await card.cvcErrorElement.getAttribute('aria-hidden');
await expect(cvcAriaHidden).toEqual('true');

// contextual element being hidden
await expect(card.cvcContextualElement).not.toBeVisible();

// iframe contextual (error) element
await expect(card.cvcIframeContextualElement).toHaveText(CVC_ERROR);

// Allow default focusing after validation to happen
await page.waitForTimeout(1000);

// type
await card.typeCvc('737');

// reset
await expect(card.cvcContextualElement).toBeVisible();
await expect(card.cvcContextualElement).toHaveText(CVC_CONTEXTUAL_TEXT_3_DIGITS);
// error element hidden
await expect(card.cvcErrorElement).not.toBeVisible();

await expect(card.cvcIframeContextualElement).toHaveText(CVC_CONTEXTUAL_TEXT_3_DIGITS);
});

test('#3 Should find no contextualElements because the config says to not show them', async ({ cardNoContextualElementPage }) => {
const { card, page } = cardNoContextualElementPage;

await card.isComponentVisible();

// checkout contextual elements not present
await expect(card.expiryDateContextualElement).not.toBeVisible();
await expect(card.cvcContextualElement).not.toBeVisible();

// iframe contextual elements - present but without text
await expect(card.expiryDateIframeContextualElement).toHaveText('');
await expect(card.cvcIframeContextualElement).toHaveText('');
});
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ test('should select highlighted issuer and update pay button label', async ({ is
await expect(issuerList.submitButton).toHaveText('Continue to Test Issuer 4');

await expect(issuerList.highlightedIssuerButtonGroup.getByRole('button', { pressed: true })).toHaveText('Test Issuer 4');
await expect(issuerList.selectorCombobox).toHaveValue('Select your bank');
});

test('it should be able to filter and select using the keyboard', async ({ issuerListPage }) => {
Expand Down
1 change: 1 addition & 0 deletions packages/e2e-playwright/tests/utils/constants.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export const BIN_LOOKUP_VERSION = 'v3';

export const REGULAR_TEST_CARD = '5500000000000004';
export const AMEX_CARD = '370000000000002';

export const TEST_DATE_VALUE = '03/30';
export const TEST_CVC_VALUE = '737';
Expand Down
2 changes: 1 addition & 1 deletion packages/e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@
"whatwg-fetch": "^3.6.2"
},
"dependencies": {
"@adyen/adyen-web": "5.50.1"
"@adyen/adyen-web": "5.51.0"
}
}
2 changes: 1 addition & 1 deletion packages/e2e/tests/_models/Address.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default class AddressComponent {

this.postalCodeLabel = this.baseEl.find('.adyen-checkout__field--postalCode .adyen-checkout__label__text');
this.postalCodeInput = this.baseEl.find('.adyen-checkout__input--postalCode');
this.postalCodeInputError = this.baseEl.find('.adyen-checkout__field--postalCode .adyen-checkout__error-text');
this.postalCodeInputError = this.baseEl.find('.adyen-checkout__field--postalCode .adyen-checkout-contextual-text--error');
}

async fillPostalCode(value = '') {
Expand Down
14 changes: 8 additions & 6 deletions packages/e2e/tests/_models/CardComponent.page.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export default class CardPage extends BasePage {
this.numSpan = Selector(`${BASE_EL} .adyen-checkout__card__cardNumber__input`);

// The <span> that holds the error text
this.numErrorText = Selector(`${BASE_EL} .adyen-checkout__field--cardNumber .adyen-checkout__error-text`);
this.numErrorText = Selector(`${BASE_EL} .adyen-checkout__field--cardNumber .adyen-checkout-contextual-text--error`);

// The <img> el that holds the card brand logo (actually a child of this.numSpan)
this.brandingIcon = Selector(`${BASE_EL} .adyen-checkout__card__cardNumber__brandIcon`);
Expand All @@ -60,7 +60,7 @@ export default class CardPage extends BasePage {
this.dateSpan = Selector(`${BASE_EL} .adyen-checkout__card__exp-date__input`);

// The <span> that holds the error text
this.dateErrorText = Selector(`${BASE_EL} .adyen-checkout__field__exp-date .adyen-checkout__error-text`);
this.dateErrorText = Selector(`${BASE_EL} .adyen-checkout__field__exp-date .adyen-checkout-contextual-text--error`);

this.storedCardExpiryDate = Selector(`${BASE_EL} .adyen-checkout__field--storedCard .adyen-checkout__card__exp-date__input--oneclick`);

Expand All @@ -81,7 +81,7 @@ export default class CardPage extends BasePage {
this.cvcSpan = Selector(`${BASE_EL} .adyen-checkout__card__cvc__input`);

// The <span> that holds the error text
this.cvcErrorText = Selector(`${BASE_EL} .adyen-checkout__field__cvc .adyen-checkout__error-text`);
this.cvcErrorText = Selector(`${BASE_EL} .adyen-checkout__field__cvc .adyen-checkout-contextual-text--error`);

/**
* Dual branding
Expand All @@ -96,18 +96,20 @@ export default class CardPage extends BasePage {
this.kcpTaxNumberLabelWithFocus = Selector(`${BASE_EL} .adyen-checkout__field--kcp-taxNumber .adyen-checkout__label--focused`);
this.kcpTaxNumberInput = Selector(`${BASE_EL} .adyen-checkout__field--kcp-taxNumber .adyen-checkout__card__kcp-taxNumber__input`);
this.pwdSpan = Selector(`${BASE_EL} [data-cse="encryptedPassword"]`);
this.pwdErrorText = Selector(`${BASE_EL} .adyen-checkout__field--koreanAuthentication-encryptedPassword .adyen-checkout__error-text`);
this.pwdErrorText = Selector(
`${BASE_EL} .adyen-checkout__field--koreanAuthentication-encryptedPassword .adyen-checkout-contextual-text--error`
);

/**
* AVS
*/
this.addressLabelWithFocus = Selector(`${BASE_EL} .adyen-checkout__field--street .adyen-checkout__label--focused`);
this.addressLabelErrorText = Selector(`${BASE_EL} .adyen-checkout__field--street .adyen-checkout__error-text`);
this.addressLabelErrorText = Selector(`${BASE_EL} .adyen-checkout__field--street .adyen-checkout-contextual-text--error`);
this.addressLabel = Selector(`${BASE_EL} .adyen-checkout__field--street .adyen-checkout__label`);
this.addressInput = Selector(`${BASE_EL} .adyen-checkout__field--street .adyen-checkout__input--street`);

this.postalCodeInput = Selector(`${BASE_EL} .adyen-checkout__field--postalCode .adyen-checkout__input--postalCode`);
this.postalCodeErrorText = Selector(`${BASE_EL} .adyen-checkout__field--postalCode .adyen-checkout__error-text`);
this.postalCodeErrorText = Selector(`${BASE_EL} .adyen-checkout__field--postalCode .adyen-checkout-contextual-text--error`);

this.houseNumberLabelWithFocus = Selector(`${BASE_EL} .adyen-checkout__field--houseNumberOrName .adyen-checkout__label--focused`);

Expand Down
2 changes: 0 additions & 2 deletions packages/e2e/tests/address/address.postalCode.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ test('should show error when switching from country that has valid postal code t
await addressComponent.selectCountry('United States');
await addressComponent.fillPostalCode('12345');

await t.expect(addressComponent.postalCodeInputError.exists).ok(); // error fields should always be in DOM

await addressComponent.selectCountry('Brazil');
await t.expect(addressComponent.postalCodeInputError.innerText).contains('Invalid format. Expected format: 12345678 or 12345-678');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ test('#3 Enter card number, that we mock to co-branded bcmc/visa ' + 'then compl
});

test(
'#4 Enter card number, that we mock to co-branded bcmc/visa ' +
'#4 Enter card number (co-branded bcmc/visa) ' +
'then complete expiryDate and expect comp to be valid' +
'then click Visa logo and expect comp to not be valid' +
'then click BCMC logo and expect comp to be valid again',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const logger = RequestLogger(
}
);

const errorLabel = Selector('.card-field .adyen-checkout__error-text');
const errorLabel = Selector('.card-field .adyen-checkout-contextual-text--error');

const UNSUPPORTED_CARD = LANG['error.va.sf-cc-num.03'];

Expand All @@ -29,10 +29,7 @@ const iframeSelector = getIframeSelector('.card-field iframe');

const cardUtils = cu(iframeSelector);

fixture`Testing binLookup v2 response`
.page(CARDS_URL)
.clientScripts('binLookup.clientScripts.js')
.requestHooks(logger);
fixture`Testing binLookup v2 response`.page(CARDS_URL).clientScripts('binLookup.clientScripts.js').requestHooks(logger);

test('#1 Enter number of known dual branded card, ' + 'then inspect response body for expected properties ', async t => {
// Start, allow time for iframes to load
Expand Down
Loading

0 comments on commit 3251083

Please sign in to comment.