From 3e58a437d6f89463b6e25890e8117761f7876f42 Mon Sep 17 00:00:00 2001 From: chidii Date: Thu, 30 Jul 2026 17:47:26 -0700 Subject: [PATCH 1/3] test(e2e): add notification bell mark-as-read flow --- tests/e2e/notifications.spec.ts | 81 +++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 tests/e2e/notifications.spec.ts diff --git a/tests/e2e/notifications.spec.ts b/tests/e2e/notifications.spec.ts new file mode 100644 index 00000000..4e521307 --- /dev/null +++ b/tests/e2e/notifications.spec.ts @@ -0,0 +1,81 @@ +import { test, expect } from "@playwright/test"; + +test.describe("Notification Bell", () => { + test.beforeEach(async ({ page }) => { + page.on("pageerror", (err) => { + if ( + err.message.includes("ChunkLoadError") || + err.message.includes("Load failed") || + err.message.includes("access control checks") + ) { + return; + } + throw new Error(`Uncaught page error: ${err.message}`); + }); + + await page.addInitScript(() => { + localStorage.setItem("onboarding_tour_dismissed", "1"); + }); + + await page.goto("/"); + }); + + test("should open notification dropdown, mark one read, and decrement unread count", async ({ page }) => { + // 1. Connect wallet + const connectButton = page.getByRole("button", { name: /Connect Wallet/i }).first(); + await expect(connectButton).toBeVisible(); + await connectButton.click(); + await expect(page.getByText(/Connected/i).first()).toBeVisible(); + + // 2. Make a contribution to generate a notification + await page.goto("/en/causes/1"); + await expect(page.getByRole("heading", { name: /Clean Water/i })).toBeVisible({ timeout: 10000 }); + + const fundButton = page.getByRole("button", { name: /Fund This Cause/i }).first(); + await expect(fundButton).toBeVisible(); + await fundButton.click(); + + const dialog = page.getByRole("dialog"); + await expect(dialog).toBeVisible(); + + const amountInput = dialog.getByLabel(/Amount/i); + await amountInput.fill("10"); + + const donateButton = dialog.getByRole("button", { name: /Donate 10 XLM/i }); + await expect(donateButton).toBeEnabled(); + await donateButton.click(); + + // Wait for confirmation + await expect(page.getByText(/donated successfully/i)).toBeVisible({ timeout: 15000 }); + await page.getByRole("button", { name: /Close/i }).click(); + + // 3. Open notification bell + const bell = page.getByRole("button", { name: /Notifications/i }); + await expect(bell).toBeVisible(); + + // Get initial unread count + const badge = bell.locator("span").first(); + const initialBadgeText = await badge.textContent().catch(() => "0"); + + await bell.click(); + + // 4. Verify dropdown opened + const dropdown = page.getByRole("dialog", { name: /Notifications/i }); + await expect(dropdown).toBeVisible(); + + // 5. Mark first unread notification as read + const markReadButton = dropdown.getByRole("button", { name: /Mark notification/i }).first(); + if (await markReadButton.isVisible()) { + await markReadButton.click(); + } + + // 6. Close dropdown + await page.keyboard.press("Escape"); + await expect(dropdown).not.toBeVisible(); + + // 7. Verify badge updated (if there were notifications) + if (initialBadgeText && initialBadgeText !== "0") { + await expect(badge).not.toHaveText(initialBadgeText, { timeout: 5000 }); + } + }); +}); \ No newline at end of file From 45c7e2a55258367edbed6353e829cead90bedb36 Mon Sep 17 00:00:00 2001 From: chidii Date: Thu, 6 Aug 2026 00:04:58 -0700 Subject: [PATCH 2/3] test: fix notification e2e test with unconditional assertions --- tests/e2e/notifications.spec.ts | 39 ++++++++++----------------------- 1 file changed, 11 insertions(+), 28 deletions(-) diff --git a/tests/e2e/notifications.spec.ts b/tests/e2e/notifications.spec.ts index 4e521307..711bb078 100644 --- a/tests/e2e/notifications.spec.ts +++ b/tests/e2e/notifications.spec.ts @@ -2,17 +2,6 @@ import { test, expect } from "@playwright/test"; test.describe("Notification Bell", () => { test.beforeEach(async ({ page }) => { - page.on("pageerror", (err) => { - if ( - err.message.includes("ChunkLoadError") || - err.message.includes("Load failed") || - err.message.includes("access control checks") - ) { - return; - } - throw new Error(`Uncaught page error: ${err.message}`); - }); - await page.addInitScript(() => { localStorage.setItem("onboarding_tour_dismissed", "1"); }); @@ -45,37 +34,31 @@ test.describe("Notification Bell", () => { await expect(donateButton).toBeEnabled(); await donateButton.click(); - // Wait for confirmation await expect(page.getByText(/donated successfully/i)).toBeVisible({ timeout: 15000 }); await page.getByRole("button", { name: /Close/i }).click(); - // 3. Open notification bell - const bell = page.getByRole("button", { name: /Notifications/i }); + // 3. Assert unread badge is visible with a count + const bell = page.getByRole("button", { name: /Notifications/ }); await expect(bell).toBeVisible(); - - // Get initial unread count - const badge = bell.locator("span").first(); - const initialBadgeText = await badge.textContent().catch(() => "0"); - - await bell.click(); + const badge = bell.getByText(/\d+/); + await expect(badge).toBeVisible(); + const initialCount = await badge.textContent(); - // 4. Verify dropdown opened + // 4. Open dropdown + await bell.click(); const dropdown = page.getByRole("dialog", { name: /Notifications/i }); await expect(dropdown).toBeVisible(); // 5. Mark first unread notification as read const markReadButton = dropdown.getByRole("button", { name: /Mark notification/i }).first(); - if (await markReadButton.isVisible()) { - await markReadButton.click(); - } + await expect(markReadButton).toBeVisible(); + await markReadButton.click(); // 6. Close dropdown await page.keyboard.press("Escape"); await expect(dropdown).not.toBeVisible(); - // 7. Verify badge updated (if there were notifications) - if (initialBadgeText && initialBadgeText !== "0") { - await expect(badge).not.toHaveText(initialBadgeText, { timeout: 5000 }); - } + // 7. Verify badge decremented + await expect(badge).not.toHaveText(initialCount ?? "", { timeout: 5000 }); }); }); \ No newline at end of file From 559d76c8b4ab56523254cef1901d5631ac039e96 Mon Sep 17 00:00:00 2001 From: chidii Date: Thu, 6 Aug 2026 00:39:16 -0700 Subject: [PATCH 3/3] test: fix duplicate lines in notification e2e --- tests/e2e/notifications.spec.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tests/e2e/notifications.spec.ts b/tests/e2e/notifications.spec.ts index 711bb078..6c2ffd70 100644 --- a/tests/e2e/notifications.spec.ts +++ b/tests/e2e/notifications.spec.ts @@ -10,13 +10,11 @@ test.describe("Notification Bell", () => { }); test("should open notification dropdown, mark one read, and decrement unread count", async ({ page }) => { - // 1. Connect wallet const connectButton = page.getByRole("button", { name: /Connect Wallet/i }).first(); await expect(connectButton).toBeVisible(); await connectButton.click(); await expect(page.getByText(/Connected/i).first()).toBeVisible(); - // 2. Make a contribution to generate a notification await page.goto("/en/causes/1"); await expect(page.getByRole("heading", { name: /Clean Water/i })).toBeVisible({ timeout: 10000 }); @@ -32,33 +30,29 @@ test.describe("Notification Bell", () => { const donateButton = dialog.getByRole("button", { name: /Donate 10 XLM/i }); await expect(donateButton).toBeEnabled(); + await donateButton.scrollIntoViewIfNeeded(); await donateButton.click(); await expect(page.getByText(/donated successfully/i)).toBeVisible({ timeout: 15000 }); await page.getByRole("button", { name: /Close/i }).click(); - // 3. Assert unread badge is visible with a count const bell = page.getByRole("button", { name: /Notifications/ }); await expect(bell).toBeVisible(); const badge = bell.getByText(/\d+/); await expect(badge).toBeVisible(); const initialCount = await badge.textContent(); - // 4. Open dropdown await bell.click(); const dropdown = page.getByRole("dialog", { name: /Notifications/i }); await expect(dropdown).toBeVisible(); - // 5. Mark first unread notification as read const markReadButton = dropdown.getByRole("button", { name: /Mark notification/i }).first(); await expect(markReadButton).toBeVisible(); await markReadButton.click(); - // 6. Close dropdown await page.keyboard.press("Escape"); await expect(dropdown).not.toBeVisible(); - // 7. Verify badge decremented await expect(badge).not.toHaveText(initialCount ?? "", { timeout: 5000 }); }); }); \ No newline at end of file