add reward card feature with barcodes
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
import { expect } from "@playwright/test";
|
||||
import { test } from "../fixtures";
|
||||
import { registerAndLogin } from "../helpers";
|
||||
|
||||
/** Navigates to the rewards cards page. */
|
||||
async function gotoRewards(page: import("@playwright/test").Page) {
|
||||
await page.goto("/rewards");
|
||||
await expect(page.locator("h1")).toContainText("Rewards cards");
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a rewards card and lands back on the /rewards page with it rendered.
|
||||
*/
|
||||
async function addCard(
|
||||
page: import("@playwright/test").Page,
|
||||
storeName: string,
|
||||
number: string,
|
||||
symbology?: string,
|
||||
) {
|
||||
await page.fill("#store-name", storeName);
|
||||
await page.fill("#card-number", number);
|
||||
if (symbology) {
|
||||
await page.selectOption("#symbology", symbology);
|
||||
}
|
||||
await page.click('button:has-text("Add card")');
|
||||
await expect(page).toHaveURL(/\/rewards$/);
|
||||
const card = page.locator(".rewards-card").filter({ hasText: storeName });
|
||||
await expect(card).toBeVisible();
|
||||
return card;
|
||||
}
|
||||
|
||||
test("the rewards page shows an empty state before any cards are added", async ({
|
||||
page,
|
||||
}) => {
|
||||
await registerAndLogin(page, "alice@example.com");
|
||||
await gotoRewards(page);
|
||||
await expect(page.locator(".empty-state")).toContainText("No rewards cards yet");
|
||||
await expect(page.locator(".rewards-card")).toHaveCount(0);
|
||||
});
|
||||
|
||||
test("the Rewards link is available in the site navigation", async ({ page }) => {
|
||||
await registerAndLogin(page, "alice@example.com");
|
||||
const nav = page.locator(".site-nav");
|
||||
await expect(nav.locator('a[href="/rewards"]')).toHaveText("Rewards");
|
||||
});
|
||||
|
||||
test("a user can add a rewards card and see its barcode", async ({ page }) => {
|
||||
await registerAndLogin(page, "alice@example.com");
|
||||
await gotoRewards(page);
|
||||
|
||||
const card = await addCard(page, "Kroger", "606171584511340224537");
|
||||
|
||||
// The card renders an inline SVG barcode and the store's card number.
|
||||
await expect(card.locator(".rewards-barcode svg")).toBeVisible();
|
||||
await expect(card.locator(".rewards-number")).toHaveText("606171584511340224537");
|
||||
|
||||
// The barcode should be included via the embedded SVG (Code 128 set B→C mix),
|
||||
// not rendered client-side from scratch by an image.
|
||||
const svg = card.locator(".rewards-barcode svg");
|
||||
await expect(svg).toHaveAttribute("viewBox", /\d+ \d+/);
|
||||
});
|
||||
|
||||
test("a user can add a card as Code 39 and see its barcode", async ({ page }) => {
|
||||
await registerAndLogin(page, "alice@example.com");
|
||||
await gotoRewards(page);
|
||||
|
||||
const card = await addCard(page, "Safeway", "ABC123", "code39");
|
||||
await expect(card.locator(".rewards-barcode svg")).toBeVisible();
|
||||
});
|
||||
|
||||
test("multiple rewards cards are each rendered with their own barcode", async ({
|
||||
page,
|
||||
}) => {
|
||||
await registerAndLogin(page, "alice@example.com");
|
||||
await gotoRewards(page);
|
||||
|
||||
await addCard(page, "Kroger", "606171584511340224537");
|
||||
await addCard(page, "Safeway", "012345678901");
|
||||
|
||||
await expect(page.locator(".rewards-card")).toHaveCount(2);
|
||||
await expect(page.locator(".rewards-card").filter({ hasText: "Kroger" })).toBeVisible();
|
||||
await expect(page.locator(".rewards-card").filter({ hasText: "Safeway" })).toBeVisible();
|
||||
});
|
||||
|
||||
test("removing a rewards card prompts for confirmation and deletes on accept", async ({
|
||||
page,
|
||||
}) => {
|
||||
await registerAndLogin(page, "alice@example.com");
|
||||
await gotoRewards(page);
|
||||
await addCard(page, "Kroger", "606171584511340224537");
|
||||
|
||||
await expect(page).toHaveURL(/\/rewards$/);
|
||||
await expect(page.locator(".rewards-card")).toHaveCount(1);
|
||||
|
||||
page.on("dialog", (dialog) => dialog.accept());
|
||||
await page.click('button:has-text("Remove")');
|
||||
|
||||
// The card is deleted and the empty state returns.
|
||||
await expect(page.locator(".rewards-card")).toHaveCount(0);
|
||||
await expect(page.locator(".empty-state")).toContainText("No rewards cards yet");
|
||||
});
|
||||
|
||||
test("cancelling the remove confirmation keeps the rewards card", async ({
|
||||
page,
|
||||
}) => {
|
||||
await registerAndLogin(page, "alice@example.com");
|
||||
await gotoRewards(page);
|
||||
await addCard(page, "Kroger", "606171584511340224537");
|
||||
|
||||
await expect(page.locator(".rewards-card")).toHaveCount(1);
|
||||
|
||||
page.on("dialog", (dialog) => dialog.dismiss());
|
||||
await page.click('button:has-text("Remove")');
|
||||
|
||||
// The card must remain after cancelling.
|
||||
await expect(page.locator(".rewards-card")).toHaveCount(1);
|
||||
await expect(page.locator(".rewards-card").filter({ hasText: "Kroger" })).toBeVisible();
|
||||
});
|
||||
Reference in New Issue
Block a user