diff --git a/.changeset/perfect-ghosts-mix.md b/.changeset/perfect-ghosts-mix.md new file mode 100644 index 00000000..643ee434 --- /dev/null +++ b/.changeset/perfect-ghosts-mix.md @@ -0,0 +1,5 @@ +--- +"@elasticpath/d2c-schematics": patch +--- + +correct e2e tests for d2c starter diff --git a/examples/algolia/e2e/checkout-flow.spec.ts b/examples/algolia/e2e/checkout-flow.spec.ts index 0fbeee3b..7e865658 100644 --- a/examples/algolia/e2e/checkout-flow.spec.ts +++ b/examples/algolia/e2e/checkout-flow.spec.ts @@ -22,25 +22,18 @@ test.describe("Checkout flow", async () => { /* Enter information */ await checkoutPage.enterInformation({ - Email: { value: "test@tester.com", fieldType: "input" }, + "Email Address": { value: "test@tester.com", fieldType: "input" }, "First Name": { value: "Jim", fieldType: "input" }, "Last Name": { value: "Brown", fieldType: "input" }, - "Street Address": { value: "Main Street", fieldType: "input" }, - "Extended Address": { value: "Extended Address", fieldType: "input" }, + Address: { value: "Main Street", fieldType: "input" }, City: { value: "Brownsville", fieldType: "input" }, - County: { value: "Brownsville County", fieldType: "input" }, Region: { value: "Browns", fieldType: "input" }, Postcode: { value: "ABC 123", fieldType: "input" }, - Country: { value: "Algeria", fieldType: "select" }, + Country: { value: "Algeria", fieldType: "combobox" }, "Phone Number": { value: "01234567891", fieldType: "input" }, - "Additional Instructions": { - value: "This is some extra instructions.", - fieldType: "input", - }, }); await checkoutPage.checkout(); - await checkoutPage.checkOrderComplete; /* Continue Shopping */ await checkoutPage.continueShopping(); diff --git a/examples/algolia/e2e/models/d2c-cart-page.ts b/examples/algolia/e2e/models/d2c-cart-page.ts index f7399cd5..34626aca 100644 --- a/examples/algolia/e2e/models/d2c-cart-page.ts +++ b/examples/algolia/e2e/models/d2c-cart-page.ts @@ -8,7 +8,7 @@ export interface D2CCartPage { } export function createD2CCartPage(page: Page): D2CCartPage { - const checkoutBtn = page.getByRole("button", { name: "Checkout" }); + const checkoutBtn = page.getByRole("link", { name: "Checkout" }); return { page, diff --git a/examples/algolia/e2e/models/d2c-checkout-page.ts b/examples/algolia/e2e/models/d2c-checkout-page.ts index 74f1688f..e1efec42 100644 --- a/examples/algolia/e2e/models/d2c-checkout-page.ts +++ b/examples/algolia/e2e/models/d2c-checkout-page.ts @@ -1,6 +1,5 @@ import type { Locator, Page } from "@playwright/test"; import { fillAllFormFields, FormInput } from "../util/fill-form-field"; -import { expect } from "@playwright/test"; import { enterPaymentInformation as _enterPaymentInformation } from "../util/enter-payment-information"; export interface D2CCheckoutPage { @@ -12,15 +11,14 @@ export interface D2CCheckoutPage { readonly checkout: () => Promise; readonly enterPaymentInformation: (values: FormInput) => Promise; readonly submitPayment: () => Promise; - readonly checkOrderComplete: () => Promise; readonly continueShopping: () => Promise; } export function createD2CCheckoutPage(page: Page): D2CCheckoutPage { - const payNowBtn = page.getByRole("button", { name: "Pay now" }); - const checkoutBtn = page.getByRole("button", { name: "Checkout Now" }); - const continueShoppingBtn = page.getByRole("button", { - name: "Continue Shopping", + const payNowBtn = page.getByRole("button", { name: "Pay $" }); + const checkoutBtn = page.getByRole("button", { name: "Pay $" }); + const continueShoppingBtn = page.getByRole("link", { + name: "Continue shopping", }); return { @@ -42,14 +40,9 @@ export function createD2CCheckoutPage(page: Page): D2CCheckoutPage { async checkout() { await checkoutBtn.click(); }, - async checkOrderComplete() { - await page.getByText("Thank you for your order!"); - }, async continueShopping() { await continueShoppingBtn.click(); - await expect( - page.getByRole("heading", { name: "Your Elastic Path storefront" }), - ).toBeVisible(); + await page.waitForURL("/"); }, }; } diff --git a/examples/algolia/e2e/product-list-page.spec.ts b/examples/algolia/e2e/product-list-page.spec.ts index 0e858ba4..ab300b80 100644 --- a/examples/algolia/e2e/product-list-page.spec.ts +++ b/examples/algolia/e2e/product-list-page.spec.ts @@ -1,5 +1,6 @@ import { test, expect } from "@playwright/test"; import { gateway } from "@moltin/sdk"; +import { buildSiteNavigation } from "../src/lib/build-site-navigation"; const host = process.env.NEXT_PUBLIC_EPCC_ENDPOINT_URL; const client_id = process.env.NEXT_PUBLIC_EPCC_CLIENT_ID; @@ -22,28 +23,24 @@ test("should be able to use quick view to view full product details", async ({ (cookie) => cookie.name === "_store_ep_cart", )?.value; - /* Mobile - open hamburger menu */ - if (isMobile) { - await page.getByRole("button", { name: "Menu" }).click(); + const nav = await buildSiteNavigation(client); + + const firstNavItem = nav[0]; + + if (!firstNavItem) { + test.skip( + true, + "No navigation items found can't test product list page flow", + ); } - /* Select the Men's / T-Shirts menu option */ - await page.getByRole("button", { name: "Men's", exact: true }).click(); - await page.getByRole("menuitem", { name: "T-Shirts", exact: true }).click(); + await page.getByRole("button", {name: "Shop Now"}).click(); /* Check to make sure the page has navigated to the product list page for Men's / T-Shirts */ - await expect(page).toHaveURL("/search/menswear/shirts/t-shirts"); - - await page - .getByTestId("2f435914-03b5-4b9e-80cb-08d3baa4c1d3") - .getByRole("button", { name: "Quick View" }) - .click(); + await expect(page).toHaveURL(`/search`); - await page.getByRole("link", { name: "View full details" }).click(); + await page.locator('[href*="/products/"]').first().click(); /* Check to make sure the page has navigated to the product details page for Simple T-Shirt */ - await page.waitForURL("/products/2f435914-03b5-4b9e-80cb-08d3baa4c1d3"); - await expect(page).toHaveURL( - "/products/2f435914-03b5-4b9e-80cb-08d3baa4c1d3", - ); + await page.waitForURL(/\/products\//); }); diff --git a/examples/algolia/e2e/util/fill-form-field.ts b/examples/algolia/e2e/util/fill-form-field.ts index f2b06696..92c6ce20 100644 --- a/examples/algolia/e2e/util/fill-form-field.ts +++ b/examples/algolia/e2e/util/fill-form-field.ts @@ -1,6 +1,10 @@ import { FrameLocator, Page } from "@playwright/test"; -export type FormInputValue = { value: string; fieldType: "input" | "select" }; +export type FormInputValue = { + value: string; + fieldType: "input" | "select" | "combobox"; + options?: { exact?: boolean }; +}; export type FormInput = Record; export async function fillAllFormFields( @@ -19,9 +23,14 @@ export async function fillAllFormFields( export async function fillFormField( page: Page | FrameLocator, key: string, - { value, fieldType }: FormInputValue, + { value, fieldType, options }: FormInputValue, ): Promise { - const locator = page.getByLabel(key); + let locator; + if (fieldType === "combobox") { + locator = page.getByRole("combobox"); + } else { + locator = page.getByLabel(key, { exact: true, ...options }); + } switch (fieldType) { case "input": @@ -30,5 +39,10 @@ export async function fillFormField( await locator.selectOption(value); return; } + case "combobox": { + await locator.click(); + await page.getByLabel(value).click(); + return; + } } } diff --git a/examples/algolia/src/app/(checkout)/checkout/OrderConfirmation.tsx b/examples/algolia/src/app/(checkout)/checkout/OrderConfirmation.tsx index 0671f6b3..0391da30 100644 --- a/examples/algolia/src/app/(checkout)/checkout/OrderConfirmation.tsx +++ b/examples/algolia/src/app/(checkout)/checkout/OrderConfirmation.tsx @@ -7,6 +7,7 @@ import EpIcon from "../../../components/icons/ep-icon"; import * as React from "react"; import { Separator } from "../../../components/separator/Separator"; import { CheckoutFooter } from "./CheckoutFooter"; +import { Button } from "../../../components/button/Button"; export function OrderConfirmation() { const { confirmationData } = useCheckout(); @@ -44,6 +45,11 @@ export function OrderConfirmation() { Thanks{customerName ? ` ${customerName}` : ""}! +
+ +
Order #{orderId} is confirmed. diff --git a/examples/payments/e2e/checkout-flow.spec.ts b/examples/payments/e2e/checkout-flow.spec.ts index 5a039f00..9808c8c2 100644 --- a/examples/payments/e2e/checkout-flow.spec.ts +++ b/examples/payments/e2e/checkout-flow.spec.ts @@ -32,18 +32,12 @@ test.describe("Checkout flow", async () => { "Email Address": { value: "test@tester.com", fieldType: "input" }, "First Name": { value: "Jim", fieldType: "input" }, "Last Name": { value: "Brown", fieldType: "input" }, - "Street Address": { value: "Main Street", fieldType: "input" }, - "Extended Address": { value: "Extended Address", fieldType: "input" }, + Address: { value: "Main Street", fieldType: "input" }, City: { value: "Brownsville", fieldType: "input" }, - County: { value: "Brownsville County", fieldType: "input" }, Region: { value: "Browns", fieldType: "input" }, Postcode: { value: "ABC 123", fieldType: "input" }, - Country: { value: "Algeria", fieldType: "select" }, + Country: { value: "Algeria", fieldType: "combobox" }, "Phone Number": { value: "01234567891", fieldType: "input" }, - "Additional Instructions": { - value: "This is some extra instructions.", - fieldType: "input", - }, }); /* Move to payment */ @@ -51,14 +45,17 @@ test.describe("Checkout flow", async () => { await checkoutPage.enterPaymentInformation({ "Card number": { value: "4242424242424242", fieldType: "input" }, - Expiration: { value: "1272", fieldType: "input" }, CVC: { value: "123", fieldType: "input" }, Country: { value: "United Kingdom", fieldType: "select" }, - "Postal code": { value: "ABC 123", fieldType: "input" }, + "Postal code": { value: "EC2R 8AH", fieldType: "input" }, + Expiration: { + value: "1272", + fieldType: "input", + options: { exact: false }, + }, }); await checkoutPage.submitPayment(); - await checkoutPage.checkOrderComplete; /* Continue Shopping */ await checkoutPage.continueShopping(); diff --git a/examples/payments/e2e/models/d2c-cart-page.ts b/examples/payments/e2e/models/d2c-cart-page.ts index f7399cd5..34626aca 100644 --- a/examples/payments/e2e/models/d2c-cart-page.ts +++ b/examples/payments/e2e/models/d2c-cart-page.ts @@ -8,7 +8,7 @@ export interface D2CCartPage { } export function createD2CCartPage(page: Page): D2CCartPage { - const checkoutBtn = page.getByRole("button", { name: "Checkout" }); + const checkoutBtn = page.getByRole("link", { name: "Checkout" }); return { page, diff --git a/examples/payments/e2e/models/d2c-checkout-page.ts b/examples/payments/e2e/models/d2c-checkout-page.ts index 74f1688f..e1efec42 100644 --- a/examples/payments/e2e/models/d2c-checkout-page.ts +++ b/examples/payments/e2e/models/d2c-checkout-page.ts @@ -1,6 +1,5 @@ import type { Locator, Page } from "@playwright/test"; import { fillAllFormFields, FormInput } from "../util/fill-form-field"; -import { expect } from "@playwright/test"; import { enterPaymentInformation as _enterPaymentInformation } from "../util/enter-payment-information"; export interface D2CCheckoutPage { @@ -12,15 +11,14 @@ export interface D2CCheckoutPage { readonly checkout: () => Promise; readonly enterPaymentInformation: (values: FormInput) => Promise; readonly submitPayment: () => Promise; - readonly checkOrderComplete: () => Promise; readonly continueShopping: () => Promise; } export function createD2CCheckoutPage(page: Page): D2CCheckoutPage { - const payNowBtn = page.getByRole("button", { name: "Pay now" }); - const checkoutBtn = page.getByRole("button", { name: "Checkout Now" }); - const continueShoppingBtn = page.getByRole("button", { - name: "Continue Shopping", + const payNowBtn = page.getByRole("button", { name: "Pay $" }); + const checkoutBtn = page.getByRole("button", { name: "Pay $" }); + const continueShoppingBtn = page.getByRole("link", { + name: "Continue shopping", }); return { @@ -42,14 +40,9 @@ export function createD2CCheckoutPage(page: Page): D2CCheckoutPage { async checkout() { await checkoutBtn.click(); }, - async checkOrderComplete() { - await page.getByText("Thank you for your order!"); - }, async continueShopping() { await continueShoppingBtn.click(); - await expect( - page.getByRole("heading", { name: "Your Elastic Path storefront" }), - ).toBeVisible(); + await page.waitForURL("/"); }, }; } diff --git a/examples/payments/e2e/product-list-page.spec.ts b/examples/payments/e2e/product-list-page.spec.ts index 0e858ba4..ab300b80 100644 --- a/examples/payments/e2e/product-list-page.spec.ts +++ b/examples/payments/e2e/product-list-page.spec.ts @@ -1,5 +1,6 @@ import { test, expect } from "@playwright/test"; import { gateway } from "@moltin/sdk"; +import { buildSiteNavigation } from "../src/lib/build-site-navigation"; const host = process.env.NEXT_PUBLIC_EPCC_ENDPOINT_URL; const client_id = process.env.NEXT_PUBLIC_EPCC_CLIENT_ID; @@ -22,28 +23,24 @@ test("should be able to use quick view to view full product details", async ({ (cookie) => cookie.name === "_store_ep_cart", )?.value; - /* Mobile - open hamburger menu */ - if (isMobile) { - await page.getByRole("button", { name: "Menu" }).click(); + const nav = await buildSiteNavigation(client); + + const firstNavItem = nav[0]; + + if (!firstNavItem) { + test.skip( + true, + "No navigation items found can't test product list page flow", + ); } - /* Select the Men's / T-Shirts menu option */ - await page.getByRole("button", { name: "Men's", exact: true }).click(); - await page.getByRole("menuitem", { name: "T-Shirts", exact: true }).click(); + await page.getByRole("button", {name: "Shop Now"}).click(); /* Check to make sure the page has navigated to the product list page for Men's / T-Shirts */ - await expect(page).toHaveURL("/search/menswear/shirts/t-shirts"); - - await page - .getByTestId("2f435914-03b5-4b9e-80cb-08d3baa4c1d3") - .getByRole("button", { name: "Quick View" }) - .click(); + await expect(page).toHaveURL(`/search`); - await page.getByRole("link", { name: "View full details" }).click(); + await page.locator('[href*="/products/"]').first().click(); /* Check to make sure the page has navigated to the product details page for Simple T-Shirt */ - await page.waitForURL("/products/2f435914-03b5-4b9e-80cb-08d3baa4c1d3"); - await expect(page).toHaveURL( - "/products/2f435914-03b5-4b9e-80cb-08d3baa4c1d3", - ); + await page.waitForURL(/\/products\//); }); diff --git a/examples/payments/e2e/util/fill-form-field.ts b/examples/payments/e2e/util/fill-form-field.ts index f2b06696..92c6ce20 100644 --- a/examples/payments/e2e/util/fill-form-field.ts +++ b/examples/payments/e2e/util/fill-form-field.ts @@ -1,6 +1,10 @@ import { FrameLocator, Page } from "@playwright/test"; -export type FormInputValue = { value: string; fieldType: "input" | "select" }; +export type FormInputValue = { + value: string; + fieldType: "input" | "select" | "combobox"; + options?: { exact?: boolean }; +}; export type FormInput = Record; export async function fillAllFormFields( @@ -19,9 +23,14 @@ export async function fillAllFormFields( export async function fillFormField( page: Page | FrameLocator, key: string, - { value, fieldType }: FormInputValue, + { value, fieldType, options }: FormInputValue, ): Promise { - const locator = page.getByLabel(key); + let locator; + if (fieldType === "combobox") { + locator = page.getByRole("combobox"); + } else { + locator = page.getByLabel(key, { exact: true, ...options }); + } switch (fieldType) { case "input": @@ -30,5 +39,10 @@ export async function fillFormField( await locator.selectOption(value); return; } + case "combobox": { + await locator.click(); + await page.getByLabel(value).click(); + return; + } } } diff --git a/examples/payments/src/app/(checkout)/checkout/OrderConfirmation.tsx b/examples/payments/src/app/(checkout)/checkout/OrderConfirmation.tsx index 0671f6b3..0391da30 100644 --- a/examples/payments/src/app/(checkout)/checkout/OrderConfirmation.tsx +++ b/examples/payments/src/app/(checkout)/checkout/OrderConfirmation.tsx @@ -7,6 +7,7 @@ import EpIcon from "../../../components/icons/ep-icon"; import * as React from "react"; import { Separator } from "../../../components/separator/Separator"; import { CheckoutFooter } from "./CheckoutFooter"; +import { Button } from "../../../components/button/Button"; export function OrderConfirmation() { const { confirmationData } = useCheckout(); @@ -44,6 +45,11 @@ export function OrderConfirmation() { Thanks{customerName ? ` ${customerName}` : ""}! +
+ +
Order #{orderId} is confirmed. diff --git a/examples/payments/src/app/(checkout)/checkout/PaymentForm.tsx b/examples/payments/src/app/(checkout)/checkout/PaymentForm.tsx index e6715716..15f50d30 100644 --- a/examples/payments/src/app/(checkout)/checkout/PaymentForm.tsx +++ b/examples/payments/src/app/(checkout)/checkout/PaymentForm.tsx @@ -8,7 +8,7 @@ export function PaymentForm() {
Payment
- + ); } diff --git a/examples/simple/e2e/checkout-flow.spec.ts b/examples/simple/e2e/checkout-flow.spec.ts index 0fbeee3b..7e865658 100644 --- a/examples/simple/e2e/checkout-flow.spec.ts +++ b/examples/simple/e2e/checkout-flow.spec.ts @@ -22,25 +22,18 @@ test.describe("Checkout flow", async () => { /* Enter information */ await checkoutPage.enterInformation({ - Email: { value: "test@tester.com", fieldType: "input" }, + "Email Address": { value: "test@tester.com", fieldType: "input" }, "First Name": { value: "Jim", fieldType: "input" }, "Last Name": { value: "Brown", fieldType: "input" }, - "Street Address": { value: "Main Street", fieldType: "input" }, - "Extended Address": { value: "Extended Address", fieldType: "input" }, + Address: { value: "Main Street", fieldType: "input" }, City: { value: "Brownsville", fieldType: "input" }, - County: { value: "Brownsville County", fieldType: "input" }, Region: { value: "Browns", fieldType: "input" }, Postcode: { value: "ABC 123", fieldType: "input" }, - Country: { value: "Algeria", fieldType: "select" }, + Country: { value: "Algeria", fieldType: "combobox" }, "Phone Number": { value: "01234567891", fieldType: "input" }, - "Additional Instructions": { - value: "This is some extra instructions.", - fieldType: "input", - }, }); await checkoutPage.checkout(); - await checkoutPage.checkOrderComplete; /* Continue Shopping */ await checkoutPage.continueShopping(); diff --git a/examples/simple/e2e/models/d2c-cart-page.ts b/examples/simple/e2e/models/d2c-cart-page.ts index f7399cd5..34626aca 100644 --- a/examples/simple/e2e/models/d2c-cart-page.ts +++ b/examples/simple/e2e/models/d2c-cart-page.ts @@ -8,7 +8,7 @@ export interface D2CCartPage { } export function createD2CCartPage(page: Page): D2CCartPage { - const checkoutBtn = page.getByRole("button", { name: "Checkout" }); + const checkoutBtn = page.getByRole("link", { name: "Checkout" }); return { page, diff --git a/examples/simple/e2e/models/d2c-checkout-page.ts b/examples/simple/e2e/models/d2c-checkout-page.ts index 74f1688f..e1efec42 100644 --- a/examples/simple/e2e/models/d2c-checkout-page.ts +++ b/examples/simple/e2e/models/d2c-checkout-page.ts @@ -1,6 +1,5 @@ import type { Locator, Page } from "@playwright/test"; import { fillAllFormFields, FormInput } from "../util/fill-form-field"; -import { expect } from "@playwright/test"; import { enterPaymentInformation as _enterPaymentInformation } from "../util/enter-payment-information"; export interface D2CCheckoutPage { @@ -12,15 +11,14 @@ export interface D2CCheckoutPage { readonly checkout: () => Promise; readonly enterPaymentInformation: (values: FormInput) => Promise; readonly submitPayment: () => Promise; - readonly checkOrderComplete: () => Promise; readonly continueShopping: () => Promise; } export function createD2CCheckoutPage(page: Page): D2CCheckoutPage { - const payNowBtn = page.getByRole("button", { name: "Pay now" }); - const checkoutBtn = page.getByRole("button", { name: "Checkout Now" }); - const continueShoppingBtn = page.getByRole("button", { - name: "Continue Shopping", + const payNowBtn = page.getByRole("button", { name: "Pay $" }); + const checkoutBtn = page.getByRole("button", { name: "Pay $" }); + const continueShoppingBtn = page.getByRole("link", { + name: "Continue shopping", }); return { @@ -42,14 +40,9 @@ export function createD2CCheckoutPage(page: Page): D2CCheckoutPage { async checkout() { await checkoutBtn.click(); }, - async checkOrderComplete() { - await page.getByText("Thank you for your order!"); - }, async continueShopping() { await continueShoppingBtn.click(); - await expect( - page.getByRole("heading", { name: "Your Elastic Path storefront" }), - ).toBeVisible(); + await page.waitForURL("/"); }, }; } diff --git a/examples/simple/e2e/product-list-page.spec.ts b/examples/simple/e2e/product-list-page.spec.ts index 0e858ba4..ab300b80 100644 --- a/examples/simple/e2e/product-list-page.spec.ts +++ b/examples/simple/e2e/product-list-page.spec.ts @@ -1,5 +1,6 @@ import { test, expect } from "@playwright/test"; import { gateway } from "@moltin/sdk"; +import { buildSiteNavigation } from "../src/lib/build-site-navigation"; const host = process.env.NEXT_PUBLIC_EPCC_ENDPOINT_URL; const client_id = process.env.NEXT_PUBLIC_EPCC_CLIENT_ID; @@ -22,28 +23,24 @@ test("should be able to use quick view to view full product details", async ({ (cookie) => cookie.name === "_store_ep_cart", )?.value; - /* Mobile - open hamburger menu */ - if (isMobile) { - await page.getByRole("button", { name: "Menu" }).click(); + const nav = await buildSiteNavigation(client); + + const firstNavItem = nav[0]; + + if (!firstNavItem) { + test.skip( + true, + "No navigation items found can't test product list page flow", + ); } - /* Select the Men's / T-Shirts menu option */ - await page.getByRole("button", { name: "Men's", exact: true }).click(); - await page.getByRole("menuitem", { name: "T-Shirts", exact: true }).click(); + await page.getByRole("button", {name: "Shop Now"}).click(); /* Check to make sure the page has navigated to the product list page for Men's / T-Shirts */ - await expect(page).toHaveURL("/search/menswear/shirts/t-shirts"); - - await page - .getByTestId("2f435914-03b5-4b9e-80cb-08d3baa4c1d3") - .getByRole("button", { name: "Quick View" }) - .click(); + await expect(page).toHaveURL(`/search`); - await page.getByRole("link", { name: "View full details" }).click(); + await page.locator('[href*="/products/"]').first().click(); /* Check to make sure the page has navigated to the product details page for Simple T-Shirt */ - await page.waitForURL("/products/2f435914-03b5-4b9e-80cb-08d3baa4c1d3"); - await expect(page).toHaveURL( - "/products/2f435914-03b5-4b9e-80cb-08d3baa4c1d3", - ); + await page.waitForURL(/\/products\//); }); diff --git a/examples/simple/e2e/util/fill-form-field.ts b/examples/simple/e2e/util/fill-form-field.ts index f2b06696..92c6ce20 100644 --- a/examples/simple/e2e/util/fill-form-field.ts +++ b/examples/simple/e2e/util/fill-form-field.ts @@ -1,6 +1,10 @@ import { FrameLocator, Page } from "@playwright/test"; -export type FormInputValue = { value: string; fieldType: "input" | "select" }; +export type FormInputValue = { + value: string; + fieldType: "input" | "select" | "combobox"; + options?: { exact?: boolean }; +}; export type FormInput = Record; export async function fillAllFormFields( @@ -19,9 +23,14 @@ export async function fillAllFormFields( export async function fillFormField( page: Page | FrameLocator, key: string, - { value, fieldType }: FormInputValue, + { value, fieldType, options }: FormInputValue, ): Promise { - const locator = page.getByLabel(key); + let locator; + if (fieldType === "combobox") { + locator = page.getByRole("combobox"); + } else { + locator = page.getByLabel(key, { exact: true, ...options }); + } switch (fieldType) { case "input": @@ -30,5 +39,10 @@ export async function fillFormField( await locator.selectOption(value); return; } + case "combobox": { + await locator.click(); + await page.getByLabel(value).click(); + return; + } } } diff --git a/examples/simple/src/app/(checkout)/checkout/OrderConfirmation.tsx b/examples/simple/src/app/(checkout)/checkout/OrderConfirmation.tsx index 0671f6b3..0391da30 100644 --- a/examples/simple/src/app/(checkout)/checkout/OrderConfirmation.tsx +++ b/examples/simple/src/app/(checkout)/checkout/OrderConfirmation.tsx @@ -7,6 +7,7 @@ import EpIcon from "../../../components/icons/ep-icon"; import * as React from "react"; import { Separator } from "../../../components/separator/Separator"; import { CheckoutFooter } from "./CheckoutFooter"; +import { Button } from "../../../components/button/Button"; export function OrderConfirmation() { const { confirmationData } = useCheckout(); @@ -44,6 +45,11 @@ export function OrderConfirmation() { Thanks{customerName ? ` ${customerName}` : ""}! +
+ +
Order #{orderId} is confirmed. diff --git a/packages/d2c-schematics/application/files/e2e/util/fill-form-field.ts.template b/packages/d2c-schematics/application/files/e2e/util/fill-form-field.ts.template index f2b06696..92c6ce20 100644 --- a/packages/d2c-schematics/application/files/e2e/util/fill-form-field.ts.template +++ b/packages/d2c-schematics/application/files/e2e/util/fill-form-field.ts.template @@ -1,6 +1,10 @@ import { FrameLocator, Page } from "@playwright/test"; -export type FormInputValue = { value: string; fieldType: "input" | "select" }; +export type FormInputValue = { + value: string; + fieldType: "input" | "select" | "combobox"; + options?: { exact?: boolean }; +}; export type FormInput = Record; export async function fillAllFormFields( @@ -19,9 +23,14 @@ export async function fillAllFormFields( export async function fillFormField( page: Page | FrameLocator, key: string, - { value, fieldType }: FormInputValue, + { value, fieldType, options }: FormInputValue, ): Promise { - const locator = page.getByLabel(key); + let locator; + if (fieldType === "combobox") { + locator = page.getByRole("combobox"); + } else { + locator = page.getByLabel(key, { exact: true, ...options }); + } switch (fieldType) { case "input": @@ -30,5 +39,10 @@ export async function fillFormField( await locator.selectOption(value); return; } + case "combobox": { + await locator.click(); + await page.getByLabel(value).click(); + return; + } } } diff --git a/packages/d2c-schematics/cart/files/e2e/models/d2c-cart-page.ts.template b/packages/d2c-schematics/cart/files/e2e/models/d2c-cart-page.ts.template index f7399cd5..34626aca 100644 --- a/packages/d2c-schematics/cart/files/e2e/models/d2c-cart-page.ts.template +++ b/packages/d2c-schematics/cart/files/e2e/models/d2c-cart-page.ts.template @@ -8,7 +8,7 @@ export interface D2CCartPage { } export function createD2CCartPage(page: Page): D2CCartPage { - const checkoutBtn = page.getByRole("button", { name: "Checkout" }); + const checkoutBtn = page.getByRole("link", { name: "Checkout" }); return { page, diff --git a/packages/d2c-schematics/checkout/files/e2e/models/d2c-checkout-page.ts.template b/packages/d2c-schematics/checkout/files/e2e/models/d2c-checkout-page.ts.template index 74f1688f..e1efec42 100644 --- a/packages/d2c-schematics/checkout/files/e2e/models/d2c-checkout-page.ts.template +++ b/packages/d2c-schematics/checkout/files/e2e/models/d2c-checkout-page.ts.template @@ -1,6 +1,5 @@ import type { Locator, Page } from "@playwright/test"; import { fillAllFormFields, FormInput } from "../util/fill-form-field"; -import { expect } from "@playwright/test"; import { enterPaymentInformation as _enterPaymentInformation } from "../util/enter-payment-information"; export interface D2CCheckoutPage { @@ -12,15 +11,14 @@ export interface D2CCheckoutPage { readonly checkout: () => Promise; readonly enterPaymentInformation: (values: FormInput) => Promise; readonly submitPayment: () => Promise; - readonly checkOrderComplete: () => Promise; readonly continueShopping: () => Promise; } export function createD2CCheckoutPage(page: Page): D2CCheckoutPage { - const payNowBtn = page.getByRole("button", { name: "Pay now" }); - const checkoutBtn = page.getByRole("button", { name: "Checkout Now" }); - const continueShoppingBtn = page.getByRole("button", { - name: "Continue Shopping", + const payNowBtn = page.getByRole("button", { name: "Pay $" }); + const checkoutBtn = page.getByRole("button", { name: "Pay $" }); + const continueShoppingBtn = page.getByRole("link", { + name: "Continue shopping", }); return { @@ -42,14 +40,9 @@ export function createD2CCheckoutPage(page: Page): D2CCheckoutPage { async checkout() { await checkoutBtn.click(); }, - async checkOrderComplete() { - await page.getByText("Thank you for your order!"); - }, async continueShopping() { await continueShoppingBtn.click(); - await expect( - page.getByRole("heading", { name: "Your Elastic Path storefront" }), - ).toBeVisible(); + await page.waitForURL("/"); }, }; } diff --git a/packages/d2c-schematics/checkout/files/src/app/(checkout)/checkout/OrderConfirmation.tsx.template b/packages/d2c-schematics/checkout/files/src/app/(checkout)/checkout/OrderConfirmation.tsx.template index 0671f6b3..0391da30 100644 --- a/packages/d2c-schematics/checkout/files/src/app/(checkout)/checkout/OrderConfirmation.tsx.template +++ b/packages/d2c-schematics/checkout/files/src/app/(checkout)/checkout/OrderConfirmation.tsx.template @@ -7,6 +7,7 @@ import EpIcon from "../../../components/icons/ep-icon"; import * as React from "react"; import { Separator } from "../../../components/separator/Separator"; import { CheckoutFooter } from "./CheckoutFooter"; +import { Button } from "../../../components/button/Button"; export function OrderConfirmation() { const { confirmationData } = useCheckout(); @@ -44,6 +45,11 @@ export function OrderConfirmation() { Thanks{customerName ? ` ${customerName}` : ""}! +
+ +
Order #{orderId} is confirmed. diff --git a/packages/d2c-schematics/ep-payments-payment-gateway/files/e2e/checkout-flow.spec.ts.template b/packages/d2c-schematics/ep-payments-payment-gateway/files/e2e/checkout-flow.spec.ts.template index 5a039f00..9808c8c2 100644 --- a/packages/d2c-schematics/ep-payments-payment-gateway/files/e2e/checkout-flow.spec.ts.template +++ b/packages/d2c-schematics/ep-payments-payment-gateway/files/e2e/checkout-flow.spec.ts.template @@ -32,18 +32,12 @@ test.describe("Checkout flow", async () => { "Email Address": { value: "test@tester.com", fieldType: "input" }, "First Name": { value: "Jim", fieldType: "input" }, "Last Name": { value: "Brown", fieldType: "input" }, - "Street Address": { value: "Main Street", fieldType: "input" }, - "Extended Address": { value: "Extended Address", fieldType: "input" }, + Address: { value: "Main Street", fieldType: "input" }, City: { value: "Brownsville", fieldType: "input" }, - County: { value: "Brownsville County", fieldType: "input" }, Region: { value: "Browns", fieldType: "input" }, Postcode: { value: "ABC 123", fieldType: "input" }, - Country: { value: "Algeria", fieldType: "select" }, + Country: { value: "Algeria", fieldType: "combobox" }, "Phone Number": { value: "01234567891", fieldType: "input" }, - "Additional Instructions": { - value: "This is some extra instructions.", - fieldType: "input", - }, }); /* Move to payment */ @@ -51,14 +45,17 @@ test.describe("Checkout flow", async () => { await checkoutPage.enterPaymentInformation({ "Card number": { value: "4242424242424242", fieldType: "input" }, - Expiration: { value: "1272", fieldType: "input" }, CVC: { value: "123", fieldType: "input" }, Country: { value: "United Kingdom", fieldType: "select" }, - "Postal code": { value: "ABC 123", fieldType: "input" }, + "Postal code": { value: "EC2R 8AH", fieldType: "input" }, + Expiration: { + value: "1272", + fieldType: "input", + options: { exact: false }, + }, }); await checkoutPage.submitPayment(); - await checkoutPage.checkOrderComplete; /* Continue Shopping */ await checkoutPage.continueShopping(); diff --git a/packages/d2c-schematics/ep-payments-payment-gateway/files/src/app/(checkout)/checkout/PaymentForm.tsx.template b/packages/d2c-schematics/ep-payments-payment-gateway/files/src/app/(checkout)/checkout/PaymentForm.tsx.template index e6715716..15f50d30 100644 --- a/packages/d2c-schematics/ep-payments-payment-gateway/files/src/app/(checkout)/checkout/PaymentForm.tsx.template +++ b/packages/d2c-schematics/ep-payments-payment-gateway/files/src/app/(checkout)/checkout/PaymentForm.tsx.template @@ -8,7 +8,7 @@ export function PaymentForm() {
Payment
- + ); } diff --git a/packages/d2c-schematics/manual-payment-gateway/files/e2e/checkout-flow.spec.ts.template b/packages/d2c-schematics/manual-payment-gateway/files/e2e/checkout-flow.spec.ts.template index 0fbeee3b..7e865658 100644 --- a/packages/d2c-schematics/manual-payment-gateway/files/e2e/checkout-flow.spec.ts.template +++ b/packages/d2c-schematics/manual-payment-gateway/files/e2e/checkout-flow.spec.ts.template @@ -22,25 +22,18 @@ test.describe("Checkout flow", async () => { /* Enter information */ await checkoutPage.enterInformation({ - Email: { value: "test@tester.com", fieldType: "input" }, + "Email Address": { value: "test@tester.com", fieldType: "input" }, "First Name": { value: "Jim", fieldType: "input" }, "Last Name": { value: "Brown", fieldType: "input" }, - "Street Address": { value: "Main Street", fieldType: "input" }, - "Extended Address": { value: "Extended Address", fieldType: "input" }, + Address: { value: "Main Street", fieldType: "input" }, City: { value: "Brownsville", fieldType: "input" }, - County: { value: "Brownsville County", fieldType: "input" }, Region: { value: "Browns", fieldType: "input" }, Postcode: { value: "ABC 123", fieldType: "input" }, - Country: { value: "Algeria", fieldType: "select" }, + Country: { value: "Algeria", fieldType: "combobox" }, "Phone Number": { value: "01234567891", fieldType: "input" }, - "Additional Instructions": { - value: "This is some extra instructions.", - fieldType: "input", - }, }); await checkoutPage.checkout(); - await checkoutPage.checkOrderComplete; /* Continue Shopping */ await checkoutPage.continueShopping(); diff --git a/packages/d2c-schematics/product-list-page/files/e2e/product-list-page.spec.ts.template b/packages/d2c-schematics/product-list-page/files/e2e/product-list-page.spec.ts.template index 0e858ba4..ab300b80 100644 --- a/packages/d2c-schematics/product-list-page/files/e2e/product-list-page.spec.ts.template +++ b/packages/d2c-schematics/product-list-page/files/e2e/product-list-page.spec.ts.template @@ -1,5 +1,6 @@ import { test, expect } from "@playwright/test"; import { gateway } from "@moltin/sdk"; +import { buildSiteNavigation } from "../src/lib/build-site-navigation"; const host = process.env.NEXT_PUBLIC_EPCC_ENDPOINT_URL; const client_id = process.env.NEXT_PUBLIC_EPCC_CLIENT_ID; @@ -22,28 +23,24 @@ test("should be able to use quick view to view full product details", async ({ (cookie) => cookie.name === "_store_ep_cart", )?.value; - /* Mobile - open hamburger menu */ - if (isMobile) { - await page.getByRole("button", { name: "Menu" }).click(); + const nav = await buildSiteNavigation(client); + + const firstNavItem = nav[0]; + + if (!firstNavItem) { + test.skip( + true, + "No navigation items found can't test product list page flow", + ); } - /* Select the Men's / T-Shirts menu option */ - await page.getByRole("button", { name: "Men's", exact: true }).click(); - await page.getByRole("menuitem", { name: "T-Shirts", exact: true }).click(); + await page.getByRole("button", {name: "Shop Now"}).click(); /* Check to make sure the page has navigated to the product list page for Men's / T-Shirts */ - await expect(page).toHaveURL("/search/menswear/shirts/t-shirts"); - - await page - .getByTestId("2f435914-03b5-4b9e-80cb-08d3baa4c1d3") - .getByRole("button", { name: "Quick View" }) - .click(); + await expect(page).toHaveURL(`/search`); - await page.getByRole("link", { name: "View full details" }).click(); + await page.locator('[href*="/products/"]').first().click(); /* Check to make sure the page has navigated to the product details page for Simple T-Shirt */ - await page.waitForURL("/products/2f435914-03b5-4b9e-80cb-08d3baa4c1d3"); - await expect(page).toHaveURL( - "/products/2f435914-03b5-4b9e-80cb-08d3baa4c1d3", - ); + await page.waitForURL(/\/products\//); });