From 89bf7a1fefc1ef353cc8cdb7c836c08c2c42a655 Mon Sep 17 00:00:00 2001 From: nicholas Date: Thu, 19 Dec 2024 10:53:51 +0100 Subject: [PATCH 1/3] Migrating bcmc e2e tests --- .../tests/e2e/card/bcmc/dualBranding.spec.ts | 94 +++++++-- .../ui/card/bcmc/dualBranding.reset.spec.ts | 143 +++++++++++++ .../bancontact.dualbranding.reset.spec.ts | 195 ------------------ .../dropin/bcmc/bancontact.visa.reset.spec.ts | 99 --------- .../tests/ui/dropin/bcmc/config.js | 13 -- 5 files changed, 219 insertions(+), 325 deletions(-) create mode 100644 packages/e2e-playwright/tests/ui/card/bcmc/dualBranding.reset.spec.ts delete mode 100644 packages/e2e-playwright/tests/ui/dropin/bcmc/bancontact.dualbranding.reset.spec.ts delete mode 100644 packages/e2e-playwright/tests/ui/dropin/bcmc/bancontact.visa.reset.spec.ts delete mode 100644 packages/e2e-playwright/tests/ui/dropin/bcmc/config.js diff --git a/packages/e2e-playwright/tests/e2e/card/bcmc/dualBranding.spec.ts b/packages/e2e-playwright/tests/e2e/card/bcmc/dualBranding.spec.ts index c0618993d8..670a3d9f7f 100644 --- a/packages/e2e-playwright/tests/e2e/card/bcmc/dualBranding.spec.ts +++ b/packages/e2e-playwright/tests/e2e/card/bcmc/dualBranding.spec.ts @@ -13,7 +13,9 @@ import { URL_MAP } from '../../../../fixtures/URL_MAP'; test.describe('Bcmc payments with dual branding', () => { test.describe('Bancontact (BCMC) / Maestro brands', () => { test.describe('Selecting the Bancontact brand', () => { - test('should submit the bcmc payment', async ({ bcmc }) => { + test('#1a should submit the bcmc payment', async ({ bcmc, page }) => { + const paymentsRequestPromise = page.waitForRequest(request => request.url().includes('/payments') && request.method() === 'POST'); + await bcmc.goto(URL_MAP.bcmc); await bcmc.isComponentVisible(); @@ -28,12 +30,18 @@ test.describe('Bcmc payments with dual branding', () => { await bcmc.selectBrand('Bancontact card'); await bcmc.pay(); + + // check brand has been set in paymentMethod data + const request = await paymentsRequestPromise; + const paymentMethod = await request.postDataJSON().paymentMethod; + expect(paymentMethod.brand).toEqual('bcmc'); + await bcmc.threeDs2Challenge.fillInPassword(THREEDS2_CHALLENGE_PASSWORD); await bcmc.threeDs2Challenge.submit(); await expect(bcmc.paymentResult).toContainText(PAYMENT_RESULT.authorised); }); - test('should not submit the bcmc payment with incomplete form data', async ({ bcmc }) => { + test('#1b should not submit the bcmc payment with incomplete form data', async ({ bcmc }) => { await bcmc.goto(URL_MAP.bcmc); await bcmc.isComponentVisible(); await bcmc.fillCardNumber(BCMC_CARD); @@ -44,7 +52,7 @@ test.describe('Bcmc payments with dual branding', () => { await expect(bcmc.expiryDateErrorElement).toHaveText('Enter the expiry date'); }); - test('should not submit the bcmc payment with invalid bcmc card number', async ({ bcmc }) => { + test('#1c should not submit the bcmc payment with invalid bcmc card number', async ({ bcmc }) => { await bcmc.goto(URL_MAP.bcmc); await bcmc.isComponentVisible(); await bcmc.fillCardNumber(`${BCMC_CARD}111`); @@ -55,7 +63,9 @@ test.describe('Bcmc payments with dual branding', () => { }); test.describe('Selecting the maestro brand', () => { - test('should submit the maestro payment', async ({ bcmc }) => { + test('#2a should submit the maestro payment', async ({ bcmc, page }) => { + const paymentsRequestPromise = page.waitForRequest(request => request.url().includes('/payments') && request.method() === 'POST'); + await bcmc.goto(URL_MAP.bcmc); await bcmc.isComponentVisible(); @@ -70,10 +80,14 @@ test.describe('Bcmc payments with dual branding', () => { await bcmc.selectBrand('Maestro'); await bcmc.pay(); + const request = await paymentsRequestPromise; + const paymentMethod = await request.postDataJSON().paymentMethod; + expect(paymentMethod.brand).toEqual('maestro'); + await expect(bcmc.paymentResult).toContainText(PAYMENT_RESULT.authorised); }); - test('should not submit the maestro payment with incomplete form data', async ({ bcmc }) => { + test('#2b should not submit the maestro payment with incomplete form data', async ({ bcmc }) => { await bcmc.goto(URL_MAP.bcmc); await bcmc.isComponentVisible(); await bcmc.fillCardNumber(BCMC_CARD); @@ -84,7 +98,7 @@ test.describe('Bcmc payments with dual branding', () => { await expect(bcmc.expiryDateErrorElement).toHaveText('Enter the expiry date'); }); - test('should not submit the maestro payment with invalid maestro card number', async ({ bcmc }) => { + test('#2c should not submit the maestro payment with invalid maestro card number', async ({ bcmc }) => { await bcmc.goto(URL_MAP.bcmc); await bcmc.isComponentVisible(); await bcmc.fillCardNumber(`${BCMC_CARD}111`); @@ -97,7 +111,7 @@ test.describe('Bcmc payments with dual branding', () => { test.describe('Bancontact (BCMC) / Visa Debit brands', () => { test.describe('Selecting the Bancontact brand', () => { - test('should submit the bcmc payment', async ({ bcmc }) => { + test('#3a should submit the bcmc payment (without needing to fill CVC field)', async ({ bcmc }) => { await bcmc.goto(URL_MAP.bcmc); await bcmc.isComponentVisible(); @@ -116,7 +130,7 @@ test.describe('Bcmc payments with dual branding', () => { await expect(bcmc.paymentResult).toContainText(PAYMENT_RESULT.authorised); }); - test('should not submit the bcmc payment with incomplete form data', async ({ bcmc }) => { + test('#3b should not submit the bcmc payment with incomplete form data', async ({ bcmc }) => { await bcmc.goto(URL_MAP.bcmc); await bcmc.isComponentVisible(); await bcmc.fillCardNumber(BCMC_DUAL_BRANDED_VISA); @@ -127,7 +141,7 @@ test.describe('Bcmc payments with dual branding', () => { await expect(bcmc.expiryDateErrorElement).toHaveText('Enter the expiry date'); }); - test('should not submit the bcmc payment with invalid bcmc card number', async ({ bcmc }) => { + test('#3c should not submit the bcmc payment with invalid bcmc card number', async ({ bcmc }) => { await bcmc.goto(URL_MAP.bcmc); await bcmc.isComponentVisible(); await bcmc.fillCardNumber(`${BCMC_DUAL_BRANDED_VISA}111`); @@ -138,7 +152,9 @@ test.describe('Bcmc payments with dual branding', () => { }); test.describe('Selecting the visa brand', () => { - test('should submit the visa payment', async ({ bcmc }) => { + test('#4a should submit the visa payment', async ({ bcmc, page }) => { + const paymentsRequestPromise = page.waitForRequest(request => request.url().includes('/payments') && request.method() === 'POST'); + await bcmc.goto(URL_MAP.bcmc); await bcmc.isComponentVisible(); @@ -154,12 +170,16 @@ test.describe('Bcmc payments with dual branding', () => { await bcmc.fillCvc(TEST_CVC_VALUE); await bcmc.pay(); + const request = await paymentsRequestPromise; + const paymentMethod = await request.postDataJSON().paymentMethod; + expect(paymentMethod.brand).toEqual('visa'); + await bcmc.threeDs2Challenge.fillInPassword(THREEDS2_CHALLENGE_PASSWORD); await bcmc.threeDs2Challenge.submit(); await expect(bcmc.paymentResult).toContainText(PAYMENT_RESULT.authorised); }); - test('should not submit the visa payment with incomplete form data', async ({ bcmc }) => { + test('#4b should not submit the visa payment with incomplete form data', async ({ bcmc }) => { await bcmc.goto(URL_MAP.bcmc); await bcmc.isComponentVisible(); @@ -173,7 +193,7 @@ test.describe('Bcmc payments with dual branding', () => { await expect(bcmc.cvcErrorElement).toHaveText('Enter the security code'); }); - test('should not submit the visa payment with invalid visa card number', async ({ bcmc }) => { + test('#4c should not submit the visa payment with invalid visa card number', async ({ bcmc }) => { await bcmc.goto(URL_MAP.bcmc); await bcmc.isComponentVisible(); await bcmc.fillCardNumber(`${BCMC_DUAL_BRANDED_VISA}111`); @@ -186,7 +206,7 @@ test.describe('Bcmc payments with dual branding', () => { test.describe('Bancontact (BCMC) / MC brands', () => { test.describe('Selecting the Bancontact brand', () => { - test('should submit the bcmc payment', async ({ bcmc }) => { + test('#5a should submit the bcmc payment', async ({ bcmc }) => { await bcmc.goto(URL_MAP.bcmc); await bcmc.isComponentVisible(); @@ -204,7 +224,7 @@ test.describe('Bcmc payments with dual branding', () => { await expect(bcmc.paymentResult).toContainText(PAYMENT_RESULT.authorised); }); - test('should not submit the bcmc payment with incomplete form data', async ({ bcmc }) => { + test('#5b should not submit the bcmc payment with incomplete form data', async ({ bcmc }) => { await bcmc.goto(URL_MAP.bcmc); await bcmc.isComponentVisible(); await bcmc.fillCardNumber(BCMC_DUAL_BRANDED_MC); @@ -215,7 +235,7 @@ test.describe('Bcmc payments with dual branding', () => { await expect(bcmc.expiryDateErrorElement).toHaveText('Enter the expiry date'); }); - test('should not submit the bcmc payment with invalid bcmc card number', async ({ bcmc }) => { + test('#5c should not submit the bcmc payment with invalid bcmc card number', async ({ bcmc }) => { await bcmc.goto(URL_MAP.bcmc); await bcmc.isComponentVisible(); await bcmc.fillCardNumber(`${BCMC_DUAL_BRANDED_MC}111`); @@ -226,7 +246,9 @@ test.describe('Bcmc payments with dual branding', () => { }); test.describe('Selecting the mc brand', () => { - test('should submit the mc payment', async ({ bcmc }) => { + test('#6a should submit the mc payment', async ({ bcmc, page }) => { + const paymentsRequestPromise = page.waitForRequest(request => request.url().includes('/payments') && request.method() === 'POST'); + await bcmc.goto(URL_MAP.bcmc); await bcmc.isComponentVisible(); @@ -242,10 +264,14 @@ test.describe('Bcmc payments with dual branding', () => { await bcmc.fillCvc(TEST_CVC_VALUE); await bcmc.pay(); + const request = await paymentsRequestPromise; + const paymentMethod = await request.postDataJSON().paymentMethod; + expect(paymentMethod.brand).toEqual('mc'); + await expect(bcmc.paymentResult).toContainText(PAYMENT_RESULT.authorised); }); - test('should not submit the mc payment with incomplete form data', async ({ bcmc }) => { + test('#6b should not submit the mc payment with incomplete form data', async ({ bcmc }) => { await bcmc.goto(URL_MAP.bcmc); await bcmc.isComponentVisible(); @@ -259,7 +285,7 @@ test.describe('Bcmc payments with dual branding', () => { await expect(bcmc.cvcErrorElement).toHaveText('Enter the security code'); }); - test('should not submit the mc payment with invalid mc card number', async ({ bcmc }) => { + test('#6c should not submit the mc payment with invalid mc card number', async ({ bcmc }) => { await bcmc.goto(URL_MAP.bcmc); await bcmc.isComponentVisible(); await bcmc.fillCardNumber(`${BCMC_DUAL_BRANDED_MC}111`); @@ -269,4 +295,36 @@ test.describe('Bcmc payments with dual branding', () => { }); }); }); + test.describe('Selecting the mc brand', () => { + test.describe('Then deleting the PAN and retyping it without selecting a brand', () => { + test('#7 should submit a non-branded payment payment', async ({ bcmc, page }) => { + const paymentsRequestPromise = page.waitForRequest(request => request.url().includes('/payments') && request.method() === 'POST'); + + await bcmc.goto(URL_MAP.bcmc); + await bcmc.isComponentVisible(); + + await bcmc.fillCardNumber(BCMC_DUAL_BRANDED_MC); + await bcmc.fillExpiryDate(TEST_DATE_VALUE); + await bcmc.waitForVisibleBrands(); + + const [firstBrand, secondBrand] = await bcmc.brands; + expect(firstBrand).toHaveAttribute('data-value', 'bcmc'); + expect(secondBrand).toHaveAttribute('data-value', 'mc'); + + await bcmc.selectBrand('MasterCard'); + await bcmc.fillCvc(TEST_CVC_VALUE); + + await bcmc.deleteCardNumber(); + await bcmc.fillCardNumber(BCMC_DUAL_BRANDED_MC); + + await bcmc.pay(); + + const request = await paymentsRequestPromise; + const paymentMethod = await request.postDataJSON().paymentMethod; + expect(paymentMethod.brand).toBeUndefined(); + + await expect(bcmc.paymentResult).toContainText(PAYMENT_RESULT.authorised); + }); + }); + }); }); diff --git a/packages/e2e-playwright/tests/ui/card/bcmc/dualBranding.reset.spec.ts b/packages/e2e-playwright/tests/ui/card/bcmc/dualBranding.reset.spec.ts new file mode 100644 index 0000000000..5d8ba4df81 --- /dev/null +++ b/packages/e2e-playwright/tests/ui/card/bcmc/dualBranding.reset.spec.ts @@ -0,0 +1,143 @@ +import { test, expect } from '../../../../fixtures/card.fixture'; +import { URL_MAP } from '../../../../fixtures/URL_MAP'; +import { BCMC_CARD, BCMC_DUAL_BRANDED_VISA, UNKNOWN_VISA_CARD } from '../../../utils/constants'; + +test.describe('Testing Bancontact, with dual branded cards, how UI resets', () => { + test( + '#1 Fill in dual branded card then ' + + 'check that brands have been sorted to place Bcmc first then ' + + 'ensure only bcmc logo shows after deleting digits', + async ({ bcmc }) => { + await bcmc.goto(URL_MAP.bcmc); + + await bcmc.isComponentVisible(); + + await bcmc.fillCardNumber(BCMC_CARD); + + await bcmc.waitForVisibleBrands(); + + let [firstBrand, secondBrand] = await bcmc.brands; + + // Correct order + expect(firstBrand).toHaveAttribute('data-value', 'bcmc'); + expect(secondBrand).toHaveAttribute('data-value', 'maestro'); + + await bcmc.deleteCardNumber(); + + await bcmc.waitForVisibleBrands(1); + + [firstBrand, secondBrand] = await bcmc.brands; + + // Now only a single brand + expect(firstBrand).toHaveAttribute('alt', /bancontact/i); + expect(secondBrand).toBeUndefined(); + } + ); + + test('#2 Fill in dual branded card then ' + 'select maestro & see that cvc field is hidden even though it is maestro ', async ({ bcmc }) => { + await bcmc.goto(URL_MAP.bcmc); + + await bcmc.isComponentVisible(); + + await bcmc.fillCardNumber(BCMC_CARD); + + await bcmc.waitForVisibleBrands(); + + await bcmc.selectBrand('Maestro'); + + // Due to brand sorting and priority being given to the Bcmc brand - cvc should remain hidden + // even tho' maestro has been selected + await bcmc.cvcField.waitFor({ state: 'hidden' }); + }); + + test( + '#3 Fill in dual branded card then ' + + 'paste in number not recognised by binLookup (but that our local regEx will recognise as Visa)' + + 'see that UI stays looking like a BCMC card i.e. bcmc logo remains showing', + async ({ bcmc }) => { + await bcmc.goto(URL_MAP.bcmc); + + await bcmc.isComponentVisible(); + + await bcmc.typeCardNumber(BCMC_CARD); + + // "paste" + await bcmc.fillCardNumber(UNKNOWN_VISA_CARD); + + await bcmc.waitForVisibleBrands(1); + + const [firstBrand, secondBrand] = await bcmc.brands; + + // Remains a single brand + expect(firstBrand).toHaveAttribute('alt', /bancontact/i); + expect(secondBrand).toBeUndefined(); + } + ); + + test( + '#4 Fill in dual branded card then ' + + 'select visa & see that cvc field shows then' + + 'paste in number not recognised by binLookup (but that our local regEx will recognise as Visa) ' + + 'see that UI stays looking like a BCMC card i.e. bcmc logo remains showing and cvc field is hidden again', + async ({ bcmc }) => { + await bcmc.goto(URL_MAP.bcmc); + + await bcmc.isComponentVisible(); + + await bcmc.fillCardNumber(BCMC_DUAL_BRANDED_VISA); + + await bcmc.waitForVisibleBrands(); + + await bcmc.selectBrand('Visa'); + + await bcmc.cvcField.waitFor({ state: 'visible' }); + + // "paste" + await bcmc.fillCardNumber(UNKNOWN_VISA_CARD); + + await bcmc.waitForVisibleBrands(1); + + const [firstBrand, secondBrand] = await bcmc.brands; + + // Returns to a Bcmc + expect(firstBrand).toHaveAttribute('alt', /bancontact/i); + expect(secondBrand).toBeUndefined(); + + // with hidden cvc + await bcmc.cvcField.waitFor({ state: 'hidden' }); + } + ); + + test( + '#5 Fill in dual branded card then ' + + 'select visa & see that cvc field shows then' + + 'delete number and see that bcmc logo remains showing and cvc field is hidden again', + async ({ bcmc }) => { + await bcmc.goto(URL_MAP.bcmc); + + await bcmc.isComponentVisible(); + + await bcmc.fillCardNumber(BCMC_DUAL_BRANDED_VISA); + + await bcmc.waitForVisibleBrands(); + + await bcmc.selectBrand('Visa'); + + await bcmc.cvcField.waitFor({ state: 'visible' }); + + // "paste" + await bcmc.deleteCardNumber(); + + await bcmc.waitForVisibleBrands(1); + + const [firstBrand, secondBrand] = await bcmc.brands; + + // Returns to a Bcmc + expect(firstBrand).toHaveAttribute('alt', /bancontact/i); + expect(secondBrand).toBeUndefined(); + + // with hidden cvc + await bcmc.cvcField.waitFor({ state: 'hidden' }); + } + ); +}); diff --git a/packages/e2e-playwright/tests/ui/dropin/bcmc/bancontact.dualbranding.reset.spec.ts b/packages/e2e-playwright/tests/ui/dropin/bcmc/bancontact.dualbranding.reset.spec.ts deleted file mode 100644 index 0f30e50f58..0000000000 --- a/packages/e2e-playwright/tests/ui/dropin/bcmc/bancontact.dualbranding.reset.spec.ts +++ /dev/null @@ -1,195 +0,0 @@ -import { test } from '@playwright/test'; - -const cvcSpan = '.adyen-checkout__dropin .adyen-checkout__field__cvc'; -const brandingIcon = '.adyen-checkout__dropin .adyen-checkout__card__cardNumber__brandIcon'; -const dualBrandingIconHolderActive = '.adyen-checkout__payment-method--bcmc .adyen-checkout__card__dual-branding__buttons--active'; - -const getPropFromPMData = prop => { - return globalThis.dropin.dropinRef.state.activePaymentMethod.formatData().paymentMethod[prop]; -}; - -const iframe = '.adyen-checkout__payment-method--bcmc iframe'; - -test.describe('Testing Bancontact, with dual branded cards, in Dropin, resetting after failed binLookup', () => { - // todo: create fixture - test.beforeEach(async () => { - // use config bancontact.clientScripts.js to construct the url & countryCode=BE - // await t.navigateTo(url); - // preselect the Bancontact payment method item from the dropin - .adyen-checkout__payment-method--bcmc - }); - test( - '#1 Fill in dual branded card then ' + - 'check that brands have been sorted to place Bcmc first then ' + - 'ensure only bcmc logo shows after deleting digits', - async () => { - // Start, allow time to load - // await start(t, 2000, TEST_SPEED); - // - // await cardUtils.fillCardNumber(t, BCMC_CARD); // dual branded with maestro - // - // // Bcmc first, Maestro second - // await t - // .expect(dualBrandingIconHolderActive.exists) - // .ok() - // .expect(dualBrandingIconHolderActive.find('img').nth(0).getAttribute('data-value')) - // .eql('bcmc') - // .expect(dualBrandingIconHolderActive.find('img').nth(1).getAttribute('data-value')) - // .eql('maestro'); - // - // // TODO delete action fails in Safari - but only if the "Click BCMC brand icon" action takes place!? - // await cardUtils.deleteCardNumber(t); - // - // await t - // .expect(dualBrandingIconHolderActive.exists) - // .notOk() - // // single bcmc card icon - // .expect(brandingIcon.getAttribute('alt')) - // .contains('Bancontact card'); - } - ); - - test( - '#2 Fill in dual branded card then ' + - 'select bcmc, as first item (brand sorting has occurred), then' + - 'ensure only bcmc logo shows after deleting digits and ' + - 'that the brand has been reset on paymentMethod data', - async () => { - // Start, allow time to load - // await start(t, 2000, TEST_SPEED); - // - // await cardUtils.fillCardNumber(t, BCMC_CARD); // dual branded with maestro - // - // await t - // .expect(dualBrandingIconHolderActive.exists) - // .ok() - // .expect(dualBrandingIconHolderActive.find('img').nth(0).getAttribute('data-value')) - // .eql('bcmc') - // .expect(dualBrandingIconHolderActive.find('img').nth(1).getAttribute('data-value')) - // .eql('maestro'); - // - // // Click BCMC brand icon - // await t.click(dualBrandingIconHolderActive.find('img').nth(0)); - // - // // Should be a brand property in the PM data - // await t.expect(getPropFromPMData('brand')).eql('bcmc'); - // - // // TODO delete action fails in Safari - // await cardUtils.deleteCardNumber(t); - // - // await t - // .expect(dualBrandingIconHolderActive.exists) - // .notOk() - // // bcmc card icon - // .expect(brandingIcon.getAttribute('alt')) - // .contains('Bancontact card'); - // - // // Should not be a brand property in the PM data - // await t.expect(getPropFromPMData('brand')).eql(undefined); - } - ); - - test( - '#3 Fill in dual branded card then ' + - 'select maestro then' + - 'ensure cvc field is hidden even though it is maestro (brand sorting has occurred)' + - 'ensure only bcmc logo shows after deleting digits and ' + - 'that the brand has been reset on paymentMethod data', - async () => { - // Start, allow time to load - // await start(t, 2000, TEST_SPEED); - // - // await cardUtils.fillCardNumber(t, BCMC_CARD); // dual branded with maestro - // - // await t - // .expect(dualBrandingIconHolderActive.exists) - // .ok() - // .expect(dualBrandingIconHolderActive.find('img').nth(0).getAttribute('data-value')) - // .eql('bcmc') - // .expect(dualBrandingIconHolderActive.find('img').nth(1).getAttribute('data-value')) - // .eql('maestro'); - // - // // Click Maestro brand icon - // await t.click(dualBrandingIconHolderActive.find('img').nth(1)); - // - // // Should be a brand property in the PM data - // await t.expect(getPropFromPMData('brand')).eql('maestro'); - // - // // Hidden cvc field - // await t.expect(cvcSpan.filterHidden().exists).ok(); - // - // // TODO delete action fails in Safari - but only if the "Click BCMC brand icon" action takes place - // await cardUtils.deleteCardNumber(t); - // - // await t - // // bcmc card icon - // .expect(brandingIcon.getAttribute('alt')) - // .contains('Bancontact card'); - // - // // Should not be a brand property in the PM data - // await t.expect(getPropFromPMData('brand')).eql(undefined); - } - ); - - test( - '#4 Fill in dual branded card then ' + - 'paste in number not recognised by binLookup (but that internally is recognised as Visa)' + - 'ensure that bcmc logo shows', - async () => { - // Start, allow time to load - // await start(t, 2000, TEST_SPEED); - // - // await cardUtils.fillCardNumber(t, BCMC_CARD); // dual branded with maestro - // - // await t - // .expect(dualBrandingIconHolderActive.exists) - // .ok() - // .expect(dualBrandingIconHolderActive.find('img').nth(0).getAttribute('data-value')) - // .eql('bcmc') - // .expect(dualBrandingIconHolderActive.find('img').nth(1).getAttribute('data-value')) - // .eql('maestro'); - // - // await cardUtils.fillCardNumber(t, UNKNOWN_VISA_CARD, 'paste'); // number not recognised by binLookup - // - // await t - // // bcmc card icon - // .expect(brandingIcon.getAttribute('alt')) - // .contains('Bancontact card'); - } - ); - - test( - '#5 Fill in dual branded card then ' + - 'select maestro then' + - 'paste in number not recognised by binLookup (but that internally is recognised as Visa)' + - 'ensure that bcmc logo shows', - async () => { - // Start, allow time to load - // await start(t, 2000, TEST_SPEED); - // - // await cardUtils.fillCardNumber(t, BCMC_CARD); // dual branded with maestro - // - // await t - // .expect(dualBrandingIconHolderActive.exists) - // .ok() - // .expect(dualBrandingIconHolderActive.find('img').nth(0).getAttribute('data-value')) - // .eql('bcmc') - // .expect(dualBrandingIconHolderActive.find('img').nth(1).getAttribute('data-value')) - // .eql('maestro'); - // - // // Click Maestro brand icon - // await t.click(dualBrandingIconHolderActive.find('img').nth(1)); - // - // // Hidden cvc field - // await t.expect(cvcSpan.filterHidden().exists).ok(); - // - // await cardUtils.fillCardNumber(t, UNKNOWN_VISA_CARD, 'paste'); // number not recognised by binLookup - // - // await t - // // bcmc card icon - // .expect(brandingIcon.getAttribute('alt')) - // .contains('Bancontact card'); - // - // await t.wait(2000); - } - ); -}); diff --git a/packages/e2e-playwright/tests/ui/dropin/bcmc/bancontact.visa.reset.spec.ts b/packages/e2e-playwright/tests/ui/dropin/bcmc/bancontact.visa.reset.spec.ts deleted file mode 100644 index 2ced5cfe25..0000000000 --- a/packages/e2e-playwright/tests/ui/dropin/bcmc/bancontact.visa.reset.spec.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { test } from '../../../../fixtures/dropin.fixture'; - -const cvcSpan = '.adyen-checkout__dropin .adyen-checkout__field__cvc'; -const brandingIcon = '.adyen-checkout__dropin .adyen-checkout__card__cardNumber__brandIcon'; -const dualBrandingIconHolderActive = '.adyen-checkout__payment-method--bcmc .adyen-checkout__card__dual-branding__buttons--active'; -const iframe = '.adyen-checkout__payment-method--bcmc iframe'; - -test.describe('Testing Bancontact in Dropin', () => { - // todo: create fixture - test.beforeEach(async () => { - // Navigate to drop in page, with correct dropin config from bancontact.clientScripts.js to construct the URL - // await t.navigateTo(`${dropinPage.pageUrl}?countryCode=BE`); - // preselect the Bancontact payment method item from the dropin - selector .adyen-checkout__payment-method--bcmc - }); - test( - '#1 Enter card number, that we mock to co-branded bcmc/visa ' + - 'then click Visa logo and expect CVC field to show, then' + - 'paste in number not recognised by binLookup (but that internally is recognised as Visa)' + - 'ensure that bcmc logo shows & CVC field is hidden', - async () => { - // await start(t, 2000, TEST_SPEED); - // - // await cardUtils.fillCardNumber(t, BCMC_DUAL_BRANDED_VISA); - // - // await t - // .expect(dualBrandingIconHolderActive.exists) - // .ok() - // .expect(dualBrandingIconHolderActive.find('img').nth(0).getAttribute('data-value')) - // .eql('bcmc') - // .expect(dualBrandingIconHolderActive.find('img').nth(1).getAttribute('data-value')) - // .eql('visa'); - // - // // Click Visa brand icon - // await t.click(dualBrandingIconHolderActive.find('img').nth(1)); - // - // // Visible CVC field - // await t.expect(cvcSpan.filterVisible().exists).ok(); - // - // // Expect iframe to exist in CVC field and with aria-required set to true - // await t - // .switchToIframe(iframe.nth(2)) - // .expect('[data-fieldtype="encryptedSecurityCode"]'.getAttribute('aria-required')) - // .eql('true') - // .switchToMainWindow(); - // - // await cardUtils.fillCardNumber(t, UNKNOWN_VISA_CARD, 'paste'); // number not recognised by binLookup - // - // // Hidden CVC field - // await t.expect(cvcSpan.filterHidden().exists).ok(); - // - // await t - // // bcmc card icon - // .expect(brandingIcon.getAttribute('alt')) - // .contains('Bancontact card'); - } - ); - test( - '#2 Enter card number, that we mock to co-branded bcmc/visa ' + - 'then click Visa logo and expect CVC field to show, then' + - 'delete card number and ' + - 'ensure that bcmc logo shows & CVC field is hidden', - async () => { - // await start(t, 2000, TEST_SPEED); - // - // await cardUtils.fillCardNumber(t, BCMC_DUAL_BRANDED_VISA); - // - // await t - // .expect(dualBrandingIconHolderActive.exists) - // .ok() - // .expect(dualBrandingIconHolderActive.find('img').nth(0).getAttribute('data-value')) - // .eql('bcmc') - // .expect(dualBrandingIconHolderActive.find('img').nth(1).getAttribute('data-value')) - // .eql('visa'); - // - // // Click Visa brand icon - // await t.click(dualBrandingIconHolderActive.find('img').nth(1)); - // - // // Visible CVC field - // await t.expect(cvcSpan.filterVisible().exists).ok(); - // - // // Expect iframe to exist in CVC field and with aria-required set to true - // await t - // .switchToIframe(iframe.nth(2)) - // .expect('[data-fieldtype="encryptedSecurityCode"]'.getAttribute('aria-required')) - // .eql('true') - // .switchToMainWindow(); - // - // await cardUtils.deleteCardNumber(t); - // - // // Hidden CVC field - // await t.expect(cvcSpan.filterHidden().exists).ok(); - // - // await t - // // bcmc card icon - // .expect(brandingIcon.getAttribute('alt')) - // .contains('Bancontact card'); - } - ); -}); diff --git a/packages/e2e-playwright/tests/ui/dropin/bcmc/config.js b/packages/e2e-playwright/tests/ui/dropin/bcmc/config.js deleted file mode 100644 index 23e63e59bb..0000000000 --- a/packages/e2e-playwright/tests/ui/dropin/bcmc/config.js +++ /dev/null @@ -1,13 +0,0 @@ -window.dropinConfig = { - showStoredPaymentMethods: false // hide stored PMs -}; - -window.mainConfiguration = { - removePaymentMethods: ['paywithgoogle', 'applepay'], - allowPaymentMethods: ['bcmc'], - paymentMethodsConfiguration: { - bcmc: { - _disableClickToPay: true - } - } -}; From 0891b0b4ef14f867f316ca82dc35f895425509b4 Mon Sep 17 00:00:00 2001 From: nicholas Date: Thu, 19 Dec 2024 12:31:52 +0100 Subject: [PATCH 2/3] Added test checking BCMC's UI when in the Dropin --- packages/e2e-playwright/fixtures/URL_MAP.ts | 1 + packages/e2e-playwright/models/bcmc.ts | 16 +++++++++ .../ui/dropin/bcmc/bancontact.dropin.spec.ts | 34 +++++++++++++++++++ .../ui/dropin/bcmc/dropinWithBcmc.fixture.ts | 28 +++++++++++++++ 4 files changed, 79 insertions(+) create mode 100644 packages/e2e-playwright/tests/ui/dropin/bcmc/bancontact.dropin.spec.ts create mode 100644 packages/e2e-playwright/tests/ui/dropin/bcmc/dropinWithBcmc.fixture.ts diff --git a/packages/e2e-playwright/fixtures/URL_MAP.ts b/packages/e2e-playwright/fixtures/URL_MAP.ts index 564323a858..8fa9b23d63 100644 --- a/packages/e2e-playwright/fixtures/URL_MAP.ts +++ b/packages/e2e-playwright/fixtures/URL_MAP.ts @@ -6,6 +6,7 @@ export const URL_MAP = { '/iframe.html?globals=&args=amount:0;sessionData.recurringProcessingModel:CardOnFile;sessionData.storePaymentMethodMode:askForConsent&id=dropin-default--auto&viewMode=story', dropinSessions_zeroAuthCard_fail: '/iframe.html?globals=&args=amount:0;sessionData.recurringProcessingModel:CardOnFile;sessionData.storePaymentMethodMode:askForConsent;sessionData.enableOneClick:!true&id=dropin-default--auto&viewMode=story', + dropinWithSession_BCMC_noStoredPms: '/iframe.html?args=countryCode:BE&globals=&id=dropin-default--auto&viewMode=story', /** * Card diff --git a/packages/e2e-playwright/models/bcmc.ts b/packages/e2e-playwright/models/bcmc.ts index 774e65a613..917bc4551c 100644 --- a/packages/e2e-playwright/models/bcmc.ts +++ b/packages/e2e-playwright/models/bcmc.ts @@ -1,4 +1,8 @@ import { Card } from './card'; +import LANG from '../../server/translations/en-US.json'; + +const CVC_IFRAME_TITLE = LANG['creditCard.encryptedSecurityCode.aria.iframeTitle']; +const CVC_IFRAME_LABEL = LANG['creditCard.securityCode.label']; class BCMC extends Card { get brands() { @@ -24,6 +28,18 @@ class BCMC extends Card { ) { await this.cardNumberField.getByAltText(text, options).click(); } + + /** + * When in the context of the Dropin, if storedPMs are not hidden - the cvcInput locator will find 2 CVC inputs + * - the hidden, storedPM, one, and the one in the BCMC comp + */ + get getCVCInputInDropin() { + const rootEl = this.rootElement.locator('.adyen-checkout__payment-method--bcmc'); + const cvcIframe = rootEl.frameLocator(`[title="${CVC_IFRAME_TITLE}"]`); + return cvcIframe.locator(`input[aria-label="${CVC_IFRAME_LABEL}"]`); + } } export { BCMC }; + +// adyen-checkout__payment-method--bcmc diff --git a/packages/e2e-playwright/tests/ui/dropin/bcmc/bancontact.dropin.spec.ts b/packages/e2e-playwright/tests/ui/dropin/bcmc/bancontact.dropin.spec.ts new file mode 100644 index 0000000000..371f612e7d --- /dev/null +++ b/packages/e2e-playwright/tests/ui/dropin/bcmc/bancontact.dropin.spec.ts @@ -0,0 +1,34 @@ +import { test, expect } from './dropinWithBcmc.fixture'; +import { URL_MAP } from '../../../../fixtures/URL_MAP'; + +test.describe('Bcmc in dropin', () => { + test('UI looks as expected with no user interaction', async ({ dropinWithBcmc, bcmc }) => { + const expectedAltAttributes = ['Bancontact card', 'MasterCard', 'VISA', 'Maestro']; + + await dropinWithBcmc.goto(URL_MAP.dropinWithSession_BCMC_noStoredPms); + + // Check shown card brands in Dropin + expect(await dropinWithBcmc.visibleCardBrands).toHaveLength(4); + + // Check list of brands + const visibleBrands = await dropinWithBcmc.visibleCardBrands; + + visibleBrands.forEach((img, index) => { + expect(img).toHaveAttribute('alt', expectedAltAttributes[index]); + }); + + await dropinWithBcmc.selectPaymentMethod('bcmc'); + + await bcmc.isComponentVisible(); + + await bcmc.waitForVisibleBrands(1); + + const [firstBrand, secondBrand] = await bcmc.brands; + + // Only a single brand in the PAN input + expect(firstBrand).toHaveAttribute('alt', /bancontact/i); + + // Hidden Cvc + await bcmc.getCVCInputInDropin.waitFor({ state: 'hidden' }); + }); +}); diff --git a/packages/e2e-playwright/tests/ui/dropin/bcmc/dropinWithBcmc.fixture.ts b/packages/e2e-playwright/tests/ui/dropin/bcmc/dropinWithBcmc.fixture.ts new file mode 100644 index 0000000000..14e6c47d21 --- /dev/null +++ b/packages/e2e-playwright/tests/ui/dropin/bcmc/dropinWithBcmc.fixture.ts @@ -0,0 +1,28 @@ +import { test as base, mergeTests, expect } from '@playwright/test'; +import { DropinWithSession } from '../../../../models/dropinWithSession'; +import { test as card } from '../../../../fixtures/card.fixture'; + +class DropinWithBcmc extends DropinWithSession { + get bcmc() { + return super.getPaymentMethodLabelByType('bcmc'); + } + + get visibleCardBrands() { + return this.bcmc.locator('.adyen-checkout__payment-method__brands').getByRole('img').all(); + } +} + +type Fixture = { + dropinWithBcmc: DropinWithBcmc; +}; + +const dropin = base.extend({ + dropinWithBcmc: async ({ page }, use) => { + const dropin = new DropinWithBcmc(page); + await use(dropin); + } +}); + +const test = mergeTests(card, dropin); + +export { test, expect }; From b079444956dd8ebb57a814a6d19a2d2601bbbe91 Mon Sep 17 00:00:00 2001 From: nicholas Date: Fri, 20 Dec 2024 13:03:16 +0100 Subject: [PATCH 3/3] Deleted redundant file: bancontact.visa.a11y.spec.ts --- .../a11y/bcmc/bancontact.visa.a11y.spec.ts | 2 +- .../ui/dropin/bcmc/bancontact.visa.spec.ts | 70 ------------------- 2 files changed, 1 insertion(+), 71 deletions(-) delete mode 100644 packages/e2e-playwright/tests/ui/dropin/bcmc/bancontact.visa.spec.ts diff --git a/packages/e2e-playwright/tests/a11y/bcmc/bancontact.visa.a11y.spec.ts b/packages/e2e-playwright/tests/a11y/bcmc/bancontact.visa.a11y.spec.ts index 1ddeb91f3c..4a0c585595 100644 --- a/packages/e2e-playwright/tests/a11y/bcmc/bancontact.visa.a11y.spec.ts +++ b/packages/e2e-playwright/tests/a11y/bcmc/bancontact.visa.a11y.spec.ts @@ -41,7 +41,7 @@ test( ); test( - '#5 Enter card number, that we mock to co-branded bcmc/visa ' + + '#5 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 enter CVC and expect comp to be valid', diff --git a/packages/e2e-playwright/tests/ui/dropin/bcmc/bancontact.visa.spec.ts b/packages/e2e-playwright/tests/ui/dropin/bcmc/bancontact.visa.spec.ts deleted file mode 100644 index 1ff75c1f64..0000000000 --- a/packages/e2e-playwright/tests/ui/dropin/bcmc/bancontact.visa.spec.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { test } from '../../../../fixtures/dropin.fixture'; - -test.describe('Testing Bancontact in Dropin', () => { - // todo: create fixture - test.beforeEach(async () => { - // Navigate to drop in page, with correct dropin config from bancontact.clientScripts.js to construct the URL - // await t.navigateTo(`${dropinPage.pageUrl}?countryCode=BE`); - // preselect the Bancontact payment method item from the dropin - selector .adyen-checkout__payment-method--bcmc - }); - - test('#1 Check Bancontact comp is correctly presented at startup', async () => { - // Wait for field to appear in DOM - // await t.wait(1000); - // - // const brandsInsidePaymentMethod = Selector('.adyen-checkout__card__brands'); - // const images = brandsInsidePaymentMethod.find('img'); - // - // // Expect 4 card brand logos to be displayed (not concerned about order) - // await t.expect(images.count).eql(4); - // await t - // .expect(images.nth(0).getAttribute('src')) - // .contains('bcmc.svg') - // .expect(images.nth(1).getAttribute('src')) - // .contains('mc.svg') - // .expect(images.nth(2).getAttribute('src')) - // .contains('visa.svg') - // .expect(images.nth(3).getAttribute('src')) - // .contains('maestro.svg'); - // - // // Hidden cvc field - // await t.expect(dropinPage.cc.cvcHolder.filterHidden().exists).ok(); - // - // // BCMC logo in number field - // await t.expect(dropinPage.cc.numSpan.exists).ok().expect(dropinPage.cc.brandingIcon.withAttribute('alt', 'Bancontact card').exists).ok(); - }); - - test('#2 Entering digits that our local regEx will recognise as Visa does not affect the UI', async () => { - // await dropinPage.cc.numSpan(); - // - // await dropinPage.cc.cardUtils.fillCardNumber(t, '41'); - // - // // BCMC logo still in number field - // await t.expect(dropinPage.cc.brandingIcon.withAttribute('alt', 'Bancontact card').exists).ok(); - // - // // Hidden cvc field - // await t.expect(dropinPage.cc.cvcHolder.filterHidden().exists).ok(); - }); - - test('#3 Enter card number, that we mock to co-branded bcmc/visa ' + 'then complete expiryDate and expect comp to be valid', async () => { - // await dropinPage.cc.numSpan(); - // - // await dropinPage.cc.cardUtils.fillCardNumber(t, BCMC_DUAL_BRANDED_VISA); - // - // // Dual branded with bcmc logo shown first - // await t - // .expect(dropinPage.dualBrandingIconHolderActive.exists) - // .ok() - // .expect(dropinPage.dualBrandingImages.nth(0).withAttribute('data-value', 'bcmc').exists) - // .ok() - // .expect(dropinPage.dualBrandingImages.nth(1).withAttribute('data-value', 'visa').exists) - // .ok(); - // - // await dropinPage.cc.cardUtils.fillDate(t, TEST_DATE_VALUE); - // - // // Expect comp to now be valid - // await t.expect(dropinPage.getFromWindow('dropin.isValid')).eql(true, { timeout: 3000 }); - }); - - /** #4, #5, #6 in a11y/bcmc/bancontact.visa.a11y.spec.ts */ -});