From 3643454288bb0277e76e11e71155893e56f425b5 Mon Sep 17 00:00:00 2001 From: Test User Date: Mon, 25 May 2026 14:36:03 +0530 Subject: [PATCH 1/3] feat: custom 404 page --- src/app/not-found.tsx | 49 ++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx index b9aefea7..57e6ba7e 100644 --- a/src/app/not-found.tsx +++ b/src/app/not-found.tsx @@ -2,28 +2,39 @@ import Link from "next/link"; export default function NotFound() { return ( -
-
-
-
- - 🕳️ - -
+
+
+ {/* Branded 404 code */} +

+ 404 +

+
+ Page Not Found
-

404

-

- Oops! Page not found +

+ +
+

+ Lost in space?

-

- The page you're looking for doesn't exist or has been moved. +

+ The page you are looking for might have been removed, had its name changed, or is temporarily unavailable. Let's get you back on track!

- - Return to Dashboard - + +
+ + Go to Dashboard + + + Go Home + +
); From 80e3b370251cdc5a3e4d7432ab200c97eb5b0cb0 Mon Sep 17 00:00:00 2001 From: Test User Date: Mon, 25 May 2026 15:28:07 +0530 Subject: [PATCH 2/3] fix(e2e): use case-insensitive heading match for DASHBOARD h1 The DashboardHeader renders the h1 as 'DASHBOARD' (all-caps via design), but the Playwright selectors used an exact-case match { name: "Dashboard" } which never matched. Changed all three heading assertions to /dashboard/i regex so they match the actual DOM output and unblock every failing E2E test. --- e2e/dashboard-widgets.spec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/e2e/dashboard-widgets.spec.js b/e2e/dashboard-widgets.spec.js index 40ab6562..59aaecc8 100644 --- a/e2e/dashboard-widgets.spec.js +++ b/e2e/dashboard-widgets.spec.js @@ -121,7 +121,7 @@ test.beforeEach(async ({ page }) => { test("dashboard widgets render with mocked metrics", async ({ page }) => { await page.goto("/dashboard", { waitUntil: "load" }); - await expect(page.getByRole("heading", { name: "Dashboard" })).toBeVisible({ timeout: 30000 }); + await expect(page.getByRole("heading", { name: /dashboard/i })).toBeVisible({ timeout: 30000 }); await expect(page.getByRole("heading", { name: "Your Commits" })).toBeVisible({ timeout: 10000 }); await expect(page.getByRole("heading", { name: "PR Analytics" })).toBeVisible({ timeout: 10000 }); await expect(page.getByRole("heading", { name: "Goals" })).toBeVisible({ timeout: 10000 }); @@ -137,7 +137,7 @@ test("contribution graph range buttons request a new range", async ({ page }) => }); await page.goto("/dashboard", { waitUntil: "load" }); - await expect(page.getByRole("heading", { name: "Dashboard" })).toBeVisible({ timeout: 30000 }); + await expect(page.getByRole("heading", { name: /dashboard/i })).toBeVisible({ timeout: 30000 }); await page.getByRole("button", { name: "Show 90-day range" }).click(); await expect.poll(() => contributionRequests.some((url) => url.includes("days=90")), { timeout: 15000 }).toBe(true); @@ -152,7 +152,7 @@ test("goal form posts a new goal", async ({ page }) => { }); await page.goto("/dashboard", { waitUntil: "load" }); - await expect(page.getByRole("heading", { name: "Dashboard" })).toBeVisible({ timeout: 30000 }); + await expect(page.getByRole("heading", { name: /dashboard/i })).toBeVisible({ timeout: 30000 }); await page.getByLabel("Goal title").fill("Ship one PR"); await page.getByLabel("Target").fill("1"); await page.getByLabel("Unit").selectOption("prs"); From 76fffd2fbc87e106b76ed48d1f979d54ab1a2a10 Mon Sep 17 00:00:00 2001 From: Test User Date: Mon, 25 May 2026 15:37:02 +0530 Subject: [PATCH 3/3] fix(e2e): fix all Playwright test failures across 3 spec files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit landing.spec.js: - Remove assertion for 'DevTrack' h1 (hero reads 'YOUR CODE HAS A PULSE') - Add .first() to 'Sign in with GitHub' link selectors (2 links on page, strict mode violation) - Replace 'View on GitHub' link with '★ Star on GitHub' (actual text) auth-bypass.spec.js: - Add .first() to 'Sign in with GitHub' link (strict mode violation) - Change heading assertions from exact 'Dashboard' to /dashboard/i regex dashboard-widgets.spec.js: - Add mock for /api/goals/sync so GoalTracker doesn't hang waiting for a real Supabase call (Goals heading was never rendering in CI) - Add mocks for additional API routes hit on dashboard load --- e2e/auth-bypass.spec.js | 6 +++--- e2e/dashboard-widgets.spec.js | 16 ++++++++++++++++ e2e/landing.spec.js | 18 +++++++++++------- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/e2e/auth-bypass.spec.js b/e2e/auth-bypass.spec.js index 62b26544..46163e81 100644 --- a/e2e/auth-bypass.spec.js +++ b/e2e/auth-bypass.spec.js @@ -19,7 +19,7 @@ test("unauthenticated request to /dashboard redirects to landing page", async ({ await page.goto("/dashboard", { waitUntil: "load" }); await expect(page).toHaveURL(/\/$/, { timeout: 10_000 }); await expect( - page.getByRole("link", { name: "Sign in with GitHub" }) + page.getByRole("link", { name: "Sign in with GitHub" }).first() ).toBeVisible({ timeout: 5_000 }); }); @@ -28,7 +28,7 @@ test("dashboard heading is not visible without a valid session", async ({ }) => { await page.goto("/dashboard", { waitUntil: "load" }); await expect( - page.getByRole("heading", { name: "Dashboard" }) + page.getByRole("heading", { name: /dashboard/i }) ).not.toBeVisible({ timeout: 5_000 }); }); @@ -53,7 +53,7 @@ test("setting playwright-dashboard-auth=1 cookie does not bypass authentication" // The cookie alone must never grant dashboard access. await expect(page).toHaveURL(/\/$/, { timeout: 10_000 }); await expect( - page.getByRole("heading", { name: "Dashboard" }) + page.getByRole("heading", { name: /dashboard/i }) ).not.toBeVisible({ timeout: 5_000 }); }); diff --git a/e2e/dashboard-widgets.spec.js b/e2e/dashboard-widgets.spec.js index 59aaecc8..1cd3c3e1 100644 --- a/e2e/dashboard-widgets.spec.js +++ b/e2e/dashboard-widgets.spec.js @@ -107,6 +107,13 @@ test.beforeEach(async ({ page }) => { "**/api/metrics/ci**", "**/api/streak/freeze**", "**/api/user/github-accounts**", + "**/api/metrics/activity**", + "**/api/metrics/commit-time**", + "**/api/metrics/personal-records**", + "**/api/metrics/discussions**", + "**/api/metrics/pr-review-trend**", + "**/api/metrics/inactive-repos**", + "**/api/notifications**", ]; for (const pattern of metricRoutes) { @@ -117,6 +124,15 @@ test.beforeEach(async ({ page }) => { }); }); } + + // Mock goals/sync so GoalTracker doesn't hang waiting for Supabase + await page.route("**/api/goals/sync**", async (route) => { + await route.fulfill({ + contentType: "application/json", + status: 200, + body: JSON.stringify({ ok: true }), + }); + }); }); test("dashboard widgets render with mocked metrics", async ({ page }) => { diff --git a/e2e/landing.spec.js b/e2e/landing.spec.js index 55a83be5..9a914f71 100644 --- a/e2e/landing.spec.js +++ b/e2e/landing.spec.js @@ -3,19 +3,23 @@ import { expect, test } from "@playwright/test"; test("landing page renders GitHub sign-in entrypoint", async ({ page }) => { await page.goto("/"); - await expect(page.getByRole("heading", { name: "DevTrack", exact: true })).toBeVisible(); + // The hero h1 is "YOUR CODE HAS A PULSE" — verify the page loaded + await expect(page.getByRole("heading", { level: 1 })).toBeVisible(); + + // Two "Sign in with GitHub" links exist (hero + setup section) — check first one await expect( - page.getByRole("link", { name: "Sign in with GitHub" }), + page.getByRole("link", { name: "Sign in with GitHub" }).first(), ).toHaveAttribute("href", /\/api\/auth\/signin\/github\?callbackUrl=\/dashboard/); - await expect(page.getByRole("link", { name: "View on GitHub" })).toHaveAttribute( - "href", - "https://github.com/Priyanshu-byte-coder/devtrack", - ); + + // Verify at least one link to the upstream GitHub repo is present + await expect( + page.getByRole("link", { name: /star on github/i }).first(), + ).toHaveAttribute("href", "https://github.com/Priyanshu-byte-coder/devtrack"); }); test("dashboard stays protected for unauthenticated users", async ({ page }) => { await page.goto("/dashboard"); await expect(page).toHaveURL(/\/$/); - await expect(page.getByRole("link", { name: "Sign in with GitHub" })).toBeVisible(); + await expect(page.getByRole("link", { name: "Sign in with GitHub" }).first()).toBeVisible(); });