Skip to content

Commit 4dd1582

Browse files
authored
Fix/stored card selection in storybook (#3395)
* Change how Dropin story selects a storedCard, after changes to the API response * Change how we set the alt attr on a storedCard image * Ensure pmLabel is matched to the display name (which is the value for the alt attr) * Ensure brand is mapped to display name for the alt attr * In e2e tests - find storedCard based on brand name * Added comment
1 parent 508ad99 commit 4dd1582

File tree

6 files changed

+45
-9
lines changed

6 files changed

+45
-9
lines changed

.changeset/breezy-fans-make.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@adyen/adyen-web': patch
3+
---
4+
5+
Change how Dropin story selects a storedCard, and how we set the alt attr on a storedCard image, after changes to the API response.

packages/e2e-playwright/models/dropin.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Locator, Page } from '@playwright/test';
22
import { Base } from './base';
3+
import { getFullBrandName } from '../../lib/src/components/Card/components/CardInput/utils';
34

45
class PaymentMethodHeader {
56
readonly rootElement: Locator;
@@ -32,6 +33,7 @@ class Dropin extends Base {
3233
readonly payButton: Locator;
3334

3435
protected _paymentMethods: Array<{ name: string; type: string }>;
36+
protected _storedPaymentMethods: Array<{ name: string; type: string; brand: string }>;
3537

3638
constructor(
3739
public readonly page: Page,
@@ -55,7 +57,17 @@ class Dropin extends Base {
5557
// Wait for payment methods from the payments call
5658
const responsePromise = this.page.waitForResponse(response => response.url().includes('paymentMethods') && response.status() === 200);
5759
const response = await responsePromise;
58-
this._paymentMethods = (await response.json()).paymentMethods.map(({ name, type }: { name: string; type: string }) => ({ name, type }));
60+
this._paymentMethods = (await response.json()).paymentMethods.map(({ name, type }: { name: string; type: string }) => ({
61+
name,
62+
type
63+
}));
64+
this._storedPaymentMethods = (await response.json()).storedPaymentMethods.map(
65+
({ name, type, brand }: { name: string; type: string; brand: string }) => ({
66+
name,
67+
type,
68+
brand
69+
})
70+
);
5971
await this.isComponentVisible();
6072
}
6173

@@ -96,7 +108,12 @@ class Dropin extends Base {
96108

97109
// Stored payment methods
98110
async selectFirstStoredPaymentMethod(pmType: string, lastFour?: string): Promise<{ paymentMethodDetailsLocator: Locator }> {
99-
const pmLabel = this.paymentMethods.find((pm: { type: string }) => pm.type === pmType)?.name;
111+
/**
112+
* Find storedPM based on brand/txvariant, and then map this to the "display name", which is what will have been used for the image's alt attr.
113+
* (It is the image's alt attr that we use below, to locate the element)
114+
*/
115+
let pmLabel = this.storedPaymentMethods.find((pm: { brand: string }) => pm.brand === pmType)?.brand;
116+
pmLabel = getFullBrandName(pmLabel);
100117

101118
const paymentMethodHeaderLocator = await this.page
102119
.locator('.adyen-checkout__payment-method')
@@ -122,6 +139,10 @@ class Dropin extends Base {
122139
return this._paymentMethods;
123140
}
124141

142+
get storedPaymentMethods() {
143+
return this._storedPaymentMethods;
144+
}
145+
125146
get paymentResult() {
126147
return this.page.locator('.adyen-checkout__status');
127148
}

packages/e2e-playwright/models/dropinWithSession.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,20 @@ class DropinWithSession extends Dropin {
77
const regex = /\/checkoutshopper\/.*\/sessions/;
88
const responsePromise = this.page.waitForResponse(response => regex.test(response.url()) && response.status() === 200);
99
const response = await responsePromise;
10+
1011
this._paymentMethods = (await response.json()).paymentMethods.paymentMethods.map(({ name, type }: { name: string; type: string }) => ({
1112
name,
1213
type
1314
}));
1415

16+
this._storedPaymentMethods = (await response.json()).paymentMethods.storedPaymentMethods.map(
17+
({ name, type, brand }: { name: string; type: string; brand: string }) => ({
18+
name,
19+
type,
20+
brand
21+
})
22+
);
23+
1524
await this.isComponentVisible();
1625
}
1726
}

packages/e2e-playwright/tests/e2e/dropin/storedCard/stored-card-amex.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { Card } from '../../../../models/card';
77
test.describe('Stored Amex card - cvc required', () => {
88
test('#1 Can fill out the cvc fields in the stored card and make a successful payment', async ({ dropinWithSession, page }) => {
99
await dropinWithSession.goto(URL_MAP.dropinWithSession);
10-
const { paymentMethodDetailsLocator } = await dropinWithSession.selectFirstStoredPaymentMethod('American Express', '0002');
10+
const { paymentMethodDetailsLocator } = await dropinWithSession.selectFirstStoredPaymentMethod('amex', '0002');
1111

1212
const card = new Card(page, paymentMethodDetailsLocator);
1313

@@ -19,7 +19,7 @@ test.describe('Stored Amex card - cvc required', () => {
1919

2020
test('#2 Pressing pay without filling the cvc should generate a translated error ("empty")', async ({ dropinWithSession, page }) => {
2121
await dropinWithSession.goto(URL_MAP.dropinWithSession);
22-
const { paymentMethodDetailsLocator } = await dropinWithSession.selectFirstStoredPaymentMethod('American Express', '0002');
22+
const { paymentMethodDetailsLocator } = await dropinWithSession.selectFirstStoredPaymentMethod('amex', '0002');
2323

2424
const card = new Card(page, paymentMethodDetailsLocator);
2525

@@ -38,7 +38,7 @@ test.describe('Stored Amex card - cvc required', () => {
3838
}
3939
});
4040
await dropinWithSession.goto(url);
41-
const { paymentMethodDetailsLocator } = await dropinWithSession.selectFirstStoredPaymentMethod('American Express', '0002');
41+
const { paymentMethodDetailsLocator } = await dropinWithSession.selectFirstStoredPaymentMethod('amex', '0002');
4242

4343
const card = new Card(page, paymentMethodDetailsLocator);
4444

packages/e2e-playwright/tests/e2e/dropin/storedCard/stored-card-mc.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { Card } from '../../../../models/card';
77
test.describe('Stored master card - cvc required', () => {
88
test('#1 Can fill out the cvc fields in the stored card and make a successful payment', async ({ dropinWithSession, page }) => {
99
await dropinWithSession.goto(URL_MAP.dropinWithSession);
10-
const { paymentMethodDetailsLocator } = await dropinWithSession.selectFirstStoredPaymentMethod('MasterCard', '4444');
10+
const { paymentMethodDetailsLocator } = await dropinWithSession.selectFirstStoredPaymentMethod('mc', '4444');
1111

1212
const card = new Card(page, paymentMethodDetailsLocator);
1313

@@ -19,7 +19,7 @@ test.describe('Stored master card - cvc required', () => {
1919

2020
test('#2 Pressing pay without filling the cvc should generate a translated error ("empty")', async ({ dropinWithSession, page }) => {
2121
await dropinWithSession.goto(URL_MAP.dropinWithSession);
22-
const { paymentMethodDetailsLocator } = await dropinWithSession.selectFirstStoredPaymentMethod('MasterCard', '4444');
22+
const { paymentMethodDetailsLocator } = await dropinWithSession.selectFirstStoredPaymentMethod('mc', '4444');
2323

2424
const card = new Card(page, paymentMethodDetailsLocator);
2525

@@ -38,7 +38,7 @@ test.describe('Stored master card - cvc required', () => {
3838
}
3939
});
4040
await dropinWithSession.goto(url);
41-
const { paymentMethodDetailsLocator } = await dropinWithSession.selectFirstStoredPaymentMethod('MasterCard', '4444');
41+
const { paymentMethodDetailsLocator } = await dropinWithSession.selectFirstStoredPaymentMethod('mc', '4444');
4242

4343
const card = new Card(page, paymentMethodDetailsLocator);
4444

packages/lib/src/components/Dropin/components/PaymentMethod/PaymentMethodItem/PaymentMethodItem.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { BRAND_ICON_UI_EXCLUSION_LIST } from '../../../../internal/SecuredFields
1010
import PaymentMethodName from '../PaymentMethodName';
1111
import { useCoreContext } from '../../../../../core/Context/CoreProvider';
1212
import ExpandButton from '../../../../internal/ExpandButton';
13+
import { getFullBrandName } from '../../../../Card/components/CardInput/utils';
1314

1415
export interface PaymentMethodItemProps {
1516
paymentMethod: UIElement;
@@ -96,7 +97,7 @@ class PaymentMethodItem extends Component<PaymentMethodItemProps> {
9697
>
9798
<PaymentMethodIcon
9899
// Only add alt attribute to storedPaymentMethods (to avoid SR reading the PM name twice)
99-
{...(paymentMethod.props.oneClick && { altDescription: paymentMethod.props.name })}
100+
{...(paymentMethod.props.oneClick && { altDescription: getFullBrandName(paymentMethod.props.brand) })}
100101
type={paymentMethod.type}
101102
src={paymentMethod.icon}
102103
/>

0 commit comments

Comments
 (0)