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

Support Drop-in v6 #106

Merged
merged 6 commits into from
Dec 23, 2024
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
1 change: 1 addition & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nodejs 20.10.0
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM mcr.microsoft.com/playwright:v1.30.0-focal

# Sets argument as environmental variable
ENV PLAYWRIGHT_FOLDERNAME=checkout
# Sets argument as environmental variable (default value)
gcatanese marked this conversation as resolved.
Show resolved Hide resolved
ENV PLAYWRIGHT_FOLDERNAME=checkout/v5

# Copy from current directory to `/e2e`
COPY . /e2e
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ It can be executed in 2 ways:
- Install and run Playwright tests on Node
- Run the `ghcr.io/adyen-examples/adyen-testing-suite` Docker image

**Note:** The E2E Testing Suite supports Checkout testing with both Adyen Drop-in v5 and v6.

## Run in Node

### Pre-requisites

* Node 17+
* Node 20+
* Start sample application on `localhost:8080`
* Make sure the sample application uses English language

Expand Down
6 changes: 3 additions & 3 deletions playwright.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const config = {
testDir: './tests',

/* Maximum time one test can run for. */
timeout: 5 * 60 * 1000,
timeout: process.env.CI ? 5 * 60 * 1000: 1 * 60 * 1000,

expect: {
/**
Expand All @@ -19,7 +19,7 @@ const config = {
*
* note: waiting longer on CI
*/
timeout: process.env.CI ? 40 * 1000 : 20 * 1000
timeout: process.env.CI ? 40 * 1000 : 10 * 1000
},

/* Run tests in files in parallel */
Expand All @@ -42,7 +42,7 @@ const config = {
baseURL: process.env.URL || 'http://localhost:8080',

/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
actionTimeout: 240 * 1000,
actionTimeout: process.env.CI ? 240 * 1000 : 10 * 1000,

/* Base URL to use in actions like `await page.goto('/')`. */
// baseURL: 'http://localhost:3000',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @ts-check
const { test, expect } = require('@playwright/test');
const utilities = require('../utilities');
const utilities = require('../../utilities');

test('Card', async ({ page }) => {
await page.goto('/');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @ts-check
const { test, expect } = require('@playwright/test');
const utilities = require('../utilities');
const utilities = require('../../utilities');

test('Dropin Card', async ({ page }) => {
await page.goto('/');
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @ts-check
const { test, expect } = require('@playwright/test');
const utilities = require('../utilities');
const utilities = require('../../utilities');

// test webhook is successfully delivered
test('Webhook Notification', async ({ request }) => {
Expand Down
33 changes: 33 additions & 0 deletions tests/checkout/v6/card.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// @ts-check
const { test, expect } = require('@playwright/test');
const utilities = require('../../utilities');

test('Card', async ({ page }) => {
await page.goto('/');

await expect(page).toHaveTitle(/Checkout Demo/);
await expect(page.locator('text="Select a demo"')).toBeVisible();

// Select "Card"
await page.getByRole('link', { name: 'Card', exact: true }).click();
await expect(page.locator('text="Cart"')).toBeVisible();

// Click "Continue to checkout"
await page.getByRole('link', { name: 'Continue to checkout' }).click();

// Wait for load event
await page.waitForLoadState('load');

// Assert that "Card number" is visible within iframe
await expect(page.locator('text="Card number"')).toBeVisible();

// Fill card details
await utilities.fillComponentCardDetailsV6(page);

// Click "Pay" button
const payButton = page.locator('.adyen-checkout__button__text >> visible=true');
await expect(payButton).toBeVisible();
await payButton.click();

await expect(page.locator('text="Return Home"')).toBeVisible();
});
40 changes: 40 additions & 0 deletions tests/checkout/v6/dropin-card.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// @ts-check
const { test, expect } = require('@playwright/test');
const utilities = require('../../utilities');

test('Dropin Card', async ({ page }) => {
await page.goto('/');

await expect(page).toHaveTitle(/Checkout Demo/);
await expect(page.locator('text="Select a demo"')).toBeVisible();

// Select "Drop-in"
await page.getByRole('link', { name: 'Drop-in' }).click();
await expect(page.locator('text="Cart"')).toBeVisible();

// Click "Continue to checkout"
await page.getByRole('link', { name: 'Continue to checkout' }).click();

// Wait for load event
await page.waitForLoadState('load');

// Assert that "Cards" is visible
await expect(page.locator('text="Cards"')).toBeVisible();

// Click "Cards"
const radioButton = await page.getByRole('radio', { name: 'Cards' });
await radioButton.click();

// Wait for load event
await page.waitForLoadState('load');

// Fill card details
await utilities.fillDropinCardDetailsV6(page);

// Click "Pay" button
const payButton = page.locator('.adyen-checkout__button__text >> visible=true');
await expect(payButton).toBeVisible();
await payButton.click();

await expect(page.locator('text="Return Home"')).toBeVisible();
});
34 changes: 34 additions & 0 deletions tests/checkout/v6/dropin-sepa.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// @ts-check
const { test, expect } = require('@playwright/test');

test('Dropin SEPA', async ({ page }) => {
await page.goto('/');

await expect(page).toHaveTitle(/Checkout Demo/);
await expect(page.locator('text="Select a demo"')).toBeVisible();

// Select "Drop-in"
await page.getByRole('link', { name: 'Drop-in' }).click();
await expect(page.locator('text="Cart"')).toBeVisible();

// Click "Continue to checkout"
await page.getByRole('link', { name: 'Continue to checkout' }).click();

// Wait for load event
await page.waitForLoadState('load');

// Assert that "SEPA Direct Debit" is visible
await expect(page.locator('text="SEPA Direct Debit"')).toBeVisible();

// Select "SEPA"
await page.locator('button[id^="button-sepadirectdebit"]').click();
await page.fill('input[name="ownerName"]', "A. Klaassen");
await page.fill('input[name="ibanNumber"]', "NL13TEST0123456789");

// Click "Pay" button
const payButton = page.locator('.adyen-checkout__button.adyen-checkout__button--pay >> visible=true');
await expect(payButton).toBeVisible();
await payButton.click();

await expect(page.locator('text="Return Home"')).toBeVisible();
});
21 changes: 21 additions & 0 deletions tests/checkout/v6/googlepay.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @ts-check
const { test, expect } = require('@playwright/test');

test('GooglePay', async ({ page }) => {
await page.goto('/');

await expect(page).toHaveTitle(/Checkout Demo/);
await expect(page.locator('text="Select a demo"')).toBeVisible();

// Select "Google Pay"
await page.getByRole('link', { name: 'Google Pay' }).click();
await expect(page.locator('text="Cart"')).toBeVisible();

// Click "Continue to checkout"
await page.getByRole('link', { name: 'Continue to checkout' }).click();

// Check Google Pay button is visible
const googlePayButton = await page.locator('button[aria-label="Buy with GPay"]');
await expect(googlePayButton).toBeVisible();

});
36 changes: 36 additions & 0 deletions tests/checkout/v6/ideal.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// @ts-check
const { test, expect } = require('@playwright/test');

// test for iDEAL2
test('iDEAL', async ({ page }) => {
await page.goto('/');

await expect(page).toHaveTitle(/Checkout Demo/);
await expect(page.locator('text="Select a demo"')).toBeVisible();

// Select "iDEAL"
await page.getByRole('link', { name: 'iDEAL' }).click();
await expect(page.locator('text="Cart"')).toBeVisible();

// Click "Continue to checkout"
await page.getByRole('link', { name: 'Continue to checkout' }).click();

// Click "Continue to iDEAL"
await page.getByRole('button', { name: 'Continue to iDEAL' }).click();
await expect(page.locator('text="Scan with your banking app to pay"')).toBeVisible();

// Click "Select your bank"
await page.getByRole('button', { name: 'Select your bank' }).click();

// Click "TESTNL2A"
await page.getByRole('button', { name: 'TESTNL2A' }).click();
await expect(page.locator('text="Which test simulation to run?"')).toBeVisible();

// Click "Success"
await page.getByRole('button', { name: 'Success' }).click();

// Click "Continue"
await page.getByRole('link', { name: 'Return Home' }).click();

});

21 changes: 21 additions & 0 deletions tests/checkout/v6/klarna-paynow.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @ts-check
const { test, expect } = require('@playwright/test');

test('Klarna Pay Now', async ({ page }) => {
await page.goto('/');

await expect(page).toHaveTitle(/Checkout Demo/);
await expect(page.locator('text="Select a demo"')).toBeVisible();

// Select "Klarna Pay Now"
await page.getByRole('link', { name: 'Klarna - Pay now' }).click();
await expect(page.locator('text="Cart"')).toBeVisible();

// Click "Continue to checkout"
await page.getByRole('link', { name: 'Continue to checkout' }).click();
await expect(page.locator('text="Continue to Pay now with Klarna."')).toBeVisible();

// Click "Continue to Klarna"
await page.locator('text="Continue to Pay now with Klarna."').click();
await expect(page).toHaveTitle("Complete your purchase");
});
42 changes: 42 additions & 0 deletions tests/checkout/v6/webhook-failure.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// @ts-check
const { test, expect } = require('@playwright/test');

// test webhook is rejected (invalid HMAC signature)
test('Webhook Notification', async ({ request }) => {
const notifications = await request.post(`/api/webhooks/notifications`, {
data: {
"live": "false",
"notificationItems":[
{
"NotificationRequestItem":{
"additionalData":{
"hmacSignature":"INVALID_HMAC_SIGNATURE"
},
"eventCode":"AUTHORISATION",
"success":"true",
"eventDate":"2019-06-28T18:03:50+01:00",
"merchantAccountCode":"YOUR_MERCHANT_ACCOUNT",
"pspReference": "7914073381342284",
"merchantReference": "YOUR_REFERENCE",
"amount": {
"value":24999,
"currency":"EUR"
}
}
}
]
}
});

/// Verify notification is not accepted (invalid HMAC)

// Status code not 404 (verify webhook is found)
expect(notifications.status()).not.toEqual(404);

// Status code not 200 (verify webhook does not accept the notification ie HMAC invalid)
expect(notifications.status()).not.toEqual(200);

// Body response does not contain [accepted]
notifications.text()
.then(value => {expect(value).not.toEqual("[accepted]");} );
});
56 changes: 56 additions & 0 deletions tests/checkout/v6/webhook.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// @ts-check
const { test, expect } = require('@playwright/test');
const utilities = require('../../utilities');

// test webhook is successfully delivered
test('Webhook Notification', async ({ request }) => {

var notificationRequestItem = {
"eventCode":"AUTHORISATION",
"success":"true",
"eventDate":"2019-06-28T18:03:50+01:00",
"merchantAccountCode":"YOUR_MERCHANT_ACCOUNT",
"pspReference": "7914073381342284",
"merchantReference": "YOUR_REFERENCE",
"amount": {
"value":1130,
"currency":"EUR"
}
};

// calculate signature from payload
const hmacSignature = await utilities.calculateHmacSignature(notificationRequestItem);
// add hmacSignature to 'additionalData'
notificationRequestItem["additionalData"] = {"hmacSignature" : ""+hmacSignature+""}

// POST webhook
const notifications = await request.post(`/api/webhooks/notifications`, {
data: {
"live": "false",
"notificationItems":[
{
"NotificationRequestItem": notificationRequestItem
}
]
}
});

var notifications_status = notifications.status();

if (notifications_status === 202) {
// Verify status code 202
expect(notifications.status()).toEqual(202);

// Verify empty response body
notifications.text()
.then(value => { expect(value).toEqual(""); });
} else {
// Verify legacy webhook acknowledgment (status code 200)
expect(notifications.status()).toEqual(200);

// Verify legacy webhook acknowledgment (response body `[accepted]`)
notifications.text()
.then(value => { expect(value).toEqual("[accepted]"); });
}
});

Loading
Loading