Repository navigation
Expand file tree
/
Copy pathpopupSandboxPaymentCheckout.spec.ts
More file actions
148 lines (127 loc) · 6.5 KB
/
Copy pathpopupSandboxPaymentCheckout.spec.ts
File metadata and controls
148 lines (127 loc) · 6.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import {expect, type Page} from '@playwright/test';
import {test} from './workerContext';
import {preparePopupSandbox} from './popupSandbox.helpers';
import type {PaymentRequestedInfo, PaymentsPaymentForm} from '@layer';
declare global {
interface Window {
paymentResult: string
}
}
/*
* The invoice checkout: what it shows from saved information, what it says when the payment is
* refused, and that a shipping option the bot no longer offers is not paid for.
*/
const CHECKOUT = '.popup-payment:not(.popup-payment-card):not(.popup-payment-shipping):not(.popup-payment-shipping-methods)';
type FormPatch = {
invoiceFlags?: PaymentsPaymentForm.paymentsPaymentForm['invoice']['pFlags'],
savedInfo?: PaymentRequestedInfo | 'fixture',
nativeParams?: object
};
/** Opens the checkout on the sandbox's invoice, changed by `patch`, and records how it finishes. */
async function openCheckout(page: Page, patch: FormPatch = {}) {
await page.evaluate(async(patch) => {
const popupPath = '/src/components/popups/payment.tsx';
const fixturesPath = '/src/components/popupSandbox/fixtures.ts';
const {createPaymentPopup} = await window.e2eImport(popupPath);
const {paymentForm, savedPaymentInfo} = await window.e2eImport(fixturesPath);
const handle = await createPaymentPopup({
paymentForm: {
...paymentForm,
invoice: patch.invoiceFlags ? {...paymentForm.invoice, pFlags: patch.invoiceFlags} : paymentForm.invoice,
saved_info: patch.savedInfo === 'fixture' ? savedPaymentInfo : patch.savedInfo,
native_params: patch.nativeParams ? {_: 'dataJSON', data: JSON.stringify(patch.nativeParams)} : paymentForm.native_params
},
inputInvoice: {_: 'inputInvoiceMessage', peer: {_: 'inputPeerSelf'}, msg_id: 1}
});
handle.addEventListener('finish', (result: string) => window.paymentResult = result);
}, patch);
const checkout = page.locator(`${CHECKOUT}.active`);
await expect(checkout).toBeVisible();
return checkout;
}
async function overrideManagers(page: Page, which: 'refusePayment' | 'dropStandardShipping') {
await page.evaluate(async(which) => {
const path = '/src/components/popupSandbox/environment.ts';
const fixturesPath = '/src/components/popupSandbox/fixtures.ts';
const {getMockManagers} = await window.e2eImport(path);
const {validatedRequestedInfo, shippingOptions} = await window.e2eImport(fixturesPath);
getMockManagers().override({appPaymentsManager: which === 'refusePayment' ? {
sendPaymentForm: () => {
throw {type: 'PAYMENT_FAILED'};
}
} : {
validateRequestedInfo: () => ({
...validatedRequestedInfo,
id: 'sandbox-info-2',
shipping_options: shippingOptions.filter(({id}: {id: string}) => id !== 'standard')
})
}});
}, which);
}
let pageErrors: string[];
test.beforeEach(async({page}) => {
const errors: string[] = pageErrors = [];
page.on('pageerror', (error) => errors.push(error.message));
await preparePopupSandbox(page, false);
});
test.afterEach(() => {
expect(pageErrors).toEqual([]);
});
test('saved information without an address still opens a checkout that asks for one', async({page}) => {
const checkout = await openCheckout(page, {
savedInfo: {_: 'paymentRequestedInfo', name: 'Sandbox Buyer', email: 'buyer@example.com'}
});
await expect(checkout.locator('.payment-item-method-row')).toBeVisible();
await expect(checkout).toContainText('Sandbox Buyer');
});
test('the shipping form opens over a saved address the invoice does not ask for', async({page}) => {
const checkout = await openCheckout(page, {
invoiceFlags: {name_requested: true},
savedInfo: 'fixture'
});
await checkout.locator('.payment-item-row', {hasText: 'Sandbox Buyer'}).click();
const shipping = page.locator('.popup-payment-shipping.active');
await expect(shipping).toBeVisible();
await expect(shipping.locator('[contenteditable="true"]')).toHaveText('Sandbox Buyer');
});
test('a payment the server refuses says so, and finishes as failed', async({page}) => {
await page.route('https://api.stripe.com/**', (route) => route.fulfill({json: {id: 'tok_sandbox', type: 'card'}}));
await overrideManagers(page, 'refusePayment');
const checkout = await openCheckout(page, {invoiceFlags: {}, nativeParams: {publishable_key: 'pk_test_sandbox'}});
// no card yet: Pay asks for one first
await checkout.locator('.popup-footer-button').click();
const card = page.locator('.popup-payment-card.active');
await expect(card).toBeVisible();
await card.locator('input[autocomplete="cc-number"]').pressSequentially('4242424242424242');
await card.locator('input[autocomplete="cc-exp"]').pressSequentially('1230');
await card.locator('input.input-field-input[type="password"]').pressSequentially('123');
await card.locator('.popup-footer-button').click();
await expect(card).toHaveCount(0);
await expect(checkout.locator('.payment-item-method-row')).toContainText('4242');
await checkout.locator('.popup-footer-button').click();
await expect(page.locator('.toast')).toContainText('Sorry, the payment was declined.');
await expect(checkout).toBeVisible();
await page.evaluate(() => window.popupSandbox.closePopups());
await expect.poll(() => page.evaluate(() => window.paymentResult)).toBe('failed');
});
test('a shipping option the bot no longer offers for a new address is not kept', async({page}) => {
const checkout = await openCheckout(page, {savedInfo: 'fixture'});
const prices = checkout.locator('.payment-item-prices');
// the first press validates the saved address and asks for a shipping option
await checkout.locator('.popup-footer-button').click();
const methods = page.locator('.popup-payment-shipping-methods.active');
await expect(methods).toBeVisible();
await methods.locator('.popup-footer-button').click();
await expect(methods).toHaveCount(0);
await expect(checkout.locator('.payment-item-row', {hasText: 'Standard delivery'})).toBeVisible();
await expect(prices).toContainText('Standard');
// the bot answers the same address again, without that option
await overrideManagers(page, 'dropStandardShipping');
await checkout.locator('.payment-item-row', {hasText: 'Sandboxville'}).click();
const shipping = page.locator('.popup-payment-shipping.active');
await expect(shipping).toBeVisible();
await shipping.locator('.popup-footer-button').click();
await expect(shipping).toHaveCount(0);
await expect(checkout.locator('.payment-item-row', {hasText: 'Standard delivery'})).toHaveCount(0);
await expect(prices).not.toContainText('Standard');
});