-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Card, Stored Card, Paypal E2E tests for huva-default checkout (#113)
* Hyva 6#: CC without 3ds * Hyva 6#: CC 3ds variations * Hyva 6#: Vault with and without 3ds * Hyva 6#: Move to directory hyva-default * Hyva 6#: Paypal
- Loading branch information
1 parent
561f213
commit d1de7ca
Showing
17 changed files
with
747 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
## Tests scope: Hyva Default | ||
|
||
These tests are based on the `Hyva Default` theme. | ||
|
||
More importantly, they are based on the Checkout option/variation called `Hyva Default`. | ||
|
||
This checkout option splits the checkout processes into two steps: shipping and billing. | ||
This means, somewhere in the tests, after filling in shipping info, we are expecting to locate and click a button that roughly suggests that we need to proceed to the next page. | ||
|
||
For comparison, selecting `Hyva One Page` yield a view where there both shipping and billing segments appear, as the name suggests, on one page. | ||
This view will render these tests invalid. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { PaymentDetailsPage } from "../pageObjects/plugin/PaymentDetails.page.js"; | ||
import { placeOrder } from "./ScenarioHelper.js"; | ||
|
||
export async function makeCreditCardPayment( | ||
page, | ||
user, | ||
creditCardNumber, | ||
expDate, | ||
cvc | ||
) { | ||
const paymentDetailPage = new PaymentDetailsPage(page); | ||
const creditCardSection = await paymentDetailPage.selectCreditCard(); | ||
await creditCardSection.fillCreditCardInfo( | ||
user.firstName, | ||
user.lastName, | ||
creditCardNumber, | ||
expDate, | ||
cvc | ||
); | ||
|
||
await placeOrder(page); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { expect } from "@playwright/test"; | ||
import { ProductDetailsPage } from "../pageObjects/plugin/ProductDetail.page.js"; | ||
import { ShippingDetails } from "../pageObjects/plugin/ShippingDetails.page.js"; | ||
import { SuccessfulCheckoutPage } from "../pageObjects/checkout/SuccessfulCheckout.page.js"; | ||
import { ShoppingCartPage } from "../pageObjects/plugin/ShoppingCart.page.js"; | ||
import { LoginPage } from "../pageObjects/plugin/Login.page.js"; | ||
|
||
export async function goToShippingWithFullCart(page, additionalItemCount = 0, itemURL="joust-duffle-bag.html") { | ||
const productDetailsPage = new ProductDetailsPage(page); | ||
await productDetailsPage.addItemToCart(itemURL); | ||
|
||
if (additionalItemCount >= 1) { | ||
await productDetailsPage.addItemWithOptionsToCart( | ||
"breathe-easy-tank.html", | ||
"M", | ||
additionalItemCount | ||
); | ||
} | ||
|
||
await page.waitForLoadState("networkidle", { timeout: 20000 }); | ||
} | ||
|
||
export async function loginAs(page, user) { | ||
const loginPage = new LoginPage(page); | ||
await loginPage.goTo(); | ||
await loginPage.login(user); | ||
} | ||
|
||
export async function proceedToPaymentAs(page, user, isGuest = true) { | ||
const shippingDetailsPage = new ShippingDetails(page); | ||
await shippingDetailsPage.goTo(); | ||
|
||
isGuest?await shippingDetailsPage.fillShippingDetailsAndProceedToPayment(user) | ||
:await shippingDetailsPage.proceedToPaymentWithSavedAddress(); | ||
} | ||
|
||
/* This method should only be used for cases where the user should fill the billing | ||
details only on payment page; e.g. For virtual products */ | ||
export async function fillBillingAddress(page, user){ | ||
await new ShippingDetails(page, page.locator(".payment-method._active")) | ||
.fillShippingDetails(user, false); | ||
await page.getByRole('button', { name: 'Update' }).click(); | ||
} | ||
|
||
export async function verifySuccessfulPayment(page, redirect = true, timeout) { | ||
const successfulCheckoutPage = new SuccessfulCheckoutPage(page); | ||
if (redirect !== false) { | ||
await successfulCheckoutPage.waitForRedirection(timeout); | ||
} | ||
expect(await successfulCheckoutPage.pageTitle.innerText()).toContain( | ||
"Thank you for your purchase!" | ||
); | ||
} | ||
|
||
export async function getOrderNumber(page){ | ||
return (await new SuccessfulCheckoutPage(page).orderNumber()); | ||
} | ||
|
||
|
||
export async function verifyVoucherCouponGeneration(page) { | ||
const successfulCheckoutPage = new SuccessfulCheckoutPage(page); | ||
await expect(successfulCheckoutPage.voucherCodeContainer).toBeVisible(); | ||
} | ||
|
||
export async function verifyFailedPayment(page) { | ||
const errorMessage = await new ShoppingCartPage( | ||
page | ||
).errorMessage.innerText(); | ||
expect(errorMessage).toContain( | ||
"Your payment failed, Please try again later" | ||
); | ||
} | ||
|
||
export async function placeOrder(page) { | ||
const placeOrderButton = page.locator("button[x-bind='buttonPlaceOrder()']").last(); | ||
|
||
await placeOrderButton.click({timeout: 10000}); | ||
} | ||
|
||
export async function proceedToPaymentWithoutShipping(page) { | ||
await page.goto("/checkout#payment"); | ||
await new AnimationHelper(page).waitForAnimation(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// @ts-check | ||
const { devices } = require("@playwright/test"); | ||
const dotenv = require('dotenv'); | ||
const VIEWPORT_WIDTH = 1600; | ||
const VIEWPORT_HEIGHT = 900; | ||
|
||
dotenv.config(); | ||
/** | ||
* @see https://playwright.dev/docs/test-configuration | ||
* @type {import('@playwright/test').PlaywrightTestConfig} | ||
*/ | ||
const config = { | ||
testDir: "./tests/", | ||
|
||
/* Maximum time one test can run for. */ | ||
timeout: 120 * 1000, | ||
|
||
expect: { | ||
/** | ||
* Maximum time expect() should wait for the condition to be met. | ||
* For example in `await expect(locator).toHaveText();` | ||
*/ | ||
timeout: 20000, | ||
}, | ||
|
||
/* Fail the build on CI if you accidentally left test.only in the source code. */ | ||
forbidOnly: !!process.env.CI, | ||
|
||
/* Retry on CI only */ | ||
retries: 0, | ||
|
||
/* Opt out of parallel tests on CI. */ | ||
workers: 3, | ||
|
||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */ | ||
reporter: "html", | ||
|
||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ | ||
use: { | ||
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */ | ||
actionTimeout: 20000, | ||
|
||
/* Base URL to use in actions like `await page.goto('/')`. */ | ||
baseURL: process.env.MAGENTO_BASE_URL, | ||
ignoreHTTPSErrors: true, | ||
|
||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ | ||
}, | ||
|
||
/* Configure projects for major browsers */ | ||
projects: [ | ||
|
||
{ | ||
name: "userHyva", | ||
testDir: "./tests/", | ||
testIgnore: [], | ||
use: { | ||
browserName: "chromium", | ||
trace: "retain-on-failure", | ||
viewport: { | ||
width: VIEWPORT_WIDTH, | ||
height: VIEWPORT_HEIGHT, | ||
}, | ||
} | ||
}, | ||
], | ||
|
||
/* Folder for test artifacts such as screenshots, videos, traces, etc. */ | ||
outputDir: "test-results/", | ||
|
||
/* Run your local dev server before starting the tests */ | ||
// webServer: { | ||
// command: 'npm run start', | ||
// port: 3000, | ||
// }, | ||
}; | ||
module.exports = config; |
22 changes: 22 additions & 0 deletions
22
projects/hyva-default/pageObjects/checkout/CreditCardComponentsMagento.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { expect } from "@playwright/test"; | ||
import { CreditCardComponents } from "../../../common/checkoutComponents/CreditCardComponents.js"; | ||
export class CreditCardComponentsMagento extends CreditCardComponents { | ||
constructor(page) { | ||
super(page); | ||
this.page = page; | ||
|
||
this.errorMessage = page.locator("#CreditCardActionContainerMessageContainer"); | ||
} | ||
|
||
async verifyPaymentRefusal() { | ||
expect(await this.errorMessage.innerText()).toContain( | ||
"The Payment is Refused" | ||
); | ||
} | ||
|
||
async verifyPaymentCancellation() { | ||
expect(await this.errorMessage.innerText()).toContain( | ||
"Payment has been cancelled" | ||
); | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
projects/hyva-default/pageObjects/checkout/SuccessfulCheckout.page.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
export class SuccessfulCheckoutPage { | ||
constructor(page) { | ||
this.page = page; | ||
this.pageTitle = page.locator("span[data-ui-id='page-title-wrapper']"); | ||
} | ||
|
||
async waitForRedirection(timeout = 15000) { | ||
await this.page.waitForNavigation({ | ||
url: / *\/onepage\/success/, | ||
timeout: timeout, | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { TopBar } from "./TopBar.page.js"; | ||
|
||
export class BasePage extends TopBar { | ||
constructor(page) { | ||
super(page); | ||
this.page = page; | ||
this.storeLogo = page.locator(".logo img"); | ||
this.searchInput = page.locator(".control #search"); | ||
this.cartIcon = page.locator(".showcart"); | ||
this.cartItemCount = page.locator(".qty .counter-number"); | ||
this.shoppingCartLoaderMask = page.locator(".showcart .loading-mask"); | ||
|
||
this.miniCartWrapper = page.locator(".block-minicart"); | ||
this.buyWithGoogleViaCartButton = this.miniCartWrapper.locator(".adyen-checkout__paywithgoogle"); | ||
this.buyWithGoogleViaCartButtonAnimation = this.miniCartWrapper.locator(".gpay-card-info-animated-progress-bar"); | ||
} | ||
|
||
async currentCartItemCount() { | ||
await this.shoppingCartLoaderMask.waitFor({ | ||
state: "detached", | ||
timeout: 10000, | ||
}); | ||
return this.cartItemCount.innerText(); | ||
} | ||
|
||
async clickbuyWithGPayViaMiniCart(){ | ||
await this.shoppingCartLoaderMask.waitFor({ | ||
state: "detached", | ||
timeout: 10000, | ||
}); | ||
await this.cartIcon.click(); | ||
|
||
await (this.buyWithGoogleViaCartButtonAnimation).waitFor({state: "visible"}); | ||
await (this.buyWithGoogleViaCartButton).waitFor({state: "visible"}); | ||
await this.page.waitForLoadState("networkidle", { timeout: 10000 }); | ||
await this.buyWithGoogleViaCartButton.click(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { TopBar } from "./TopBar.page.js"; | ||
|
||
export class LoginPage extends TopBar { | ||
constructor(page) { | ||
super(page); | ||
this.page = page; | ||
this.loginFormContainer = page.locator(".login-container"); | ||
this.loginForm = this.loginFormContainer.locator(".fieldset.login"); | ||
this.emailInput = this.loginForm.locator("#email"); | ||
this.passwordInput = this.loginForm.locator("#pass"); | ||
this.loginButton = this.loginForm.locator("button[type='submit']"); | ||
} | ||
|
||
async goTo() { | ||
await this.page.goto("/customer/account/login"); | ||
} | ||
|
||
async login(user) { | ||
await this.emailInput.fill(user.email); | ||
await this.passwordInput.fill(user.password); | ||
await this.loginButton.click(); | ||
} | ||
} |
64 changes: 64 additions & 0 deletions
64
projects/hyva-default/pageObjects/plugin/PaymentDetails.page.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import { CreditCardComponentsMagento } from "../checkout/CreditCardComponentsMagento.js"; | ||
import { PayPalComponents } from "../../../common/checkoutComponents/PayPalComponents.js" | ||
import PaymentResources from "../../../data/PaymentResources.js"; | ||
|
||
const paymentResources = new PaymentResources(); | ||
|
||
export class PaymentDetailsPage { | ||
constructor(page) { | ||
this.page = page; | ||
|
||
this.emailField = page.locator("#customer-email"); | ||
|
||
this.creditCardRadioButton = page.locator("input[id='payment-method-adyen_cc']"); | ||
this.without3dsVaultButton = page.locator("input#payment-method-adyen_vault_1"); | ||
this.with3dsVaultButton = page.locator("input#payment-method-adyen_vault_2"); | ||
this.cvcInput = page | ||
.frameLocator(".adyen-checkout__card__cvc__input iframe") | ||
.locator(".input-field"); | ||
this.payPalRadioButton = page.locator("input#payment-method-adyen_paypal"); | ||
|
||
this.paymentSummaryLoadingSpinner = page.locator( | ||
".opc-sidebar .loading-mask" | ||
); | ||
this.activePaymentMethod = page.locator("div[id='CreditCardActionContainer']"); | ||
this.paymentMethodSaveCheckBox = this.activePaymentMethod.locator( | ||
".adyen-checkout__checkbox__label" | ||
); | ||
} | ||
|
||
async fillEmailAddress(user){ | ||
this.emailField.fill(user.email); | ||
} | ||
|
||
async savePaymentMethod() { | ||
await this.paymentMethodSaveCheckBox.click(); | ||
} | ||
|
||
async selectVaultAndInsertCVC(creditCardNumber, cvc) { | ||
if (creditCardNumber == paymentResources.masterCard3DS2) { | ||
await this.with3dsVaultButton.click(); | ||
} else { | ||
await this.without3dsVaultButton.click(); | ||
} | ||
|
||
await this.cvcInput.type(cvc, { delay: 50 }); | ||
} | ||
|
||
async selectCreditCard() { | ||
await this.creditCardRadioButton.click(); | ||
await this.waitForPaymentMethodReady(); | ||
return new CreditCardComponentsMagento(this.page.locator("div[id='CreditCardActionContainer']")); | ||
} | ||
|
||
async selectPayPal() { | ||
await this.payPalRadioButton.click(); | ||
this.activePaymentMethod = this.page.locator("div[id='PaypalActionContainer']"); | ||
await this.waitForPaymentMethodReady(); | ||
return new PayPalComponents(this.page); | ||
} | ||
|
||
async waitForPaymentMethodReady() { | ||
await this.activePaymentMethod.scrollIntoViewIfNeeded(); | ||
} | ||
} |
Oops, something went wrong.