From 7bf68be703551200cb201322a0e1578537ad0a28 Mon Sep 17 00:00:00 2001 From: Test User Date: Mon, 25 May 2026 14:41:00 +0530 Subject: [PATCH 1/3] chore(devops): add dependabot configuration for automated weekly updates --- .github/dependabot.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..e8677690 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,14 @@ +version: 2 +updates: + - package-ecosystem: npm + directory: / + schedule: + interval: weekly + day: monday + open-pull-requests-limit: 5 + labels: + - type:devops + - level:beginner + ignore: + - dependency-name: "*" + update-types: ["version-update:semver-major"] From db679114bd1a35d8ca25f9cf5730ad0af8e7322f 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 813c4b1949b7fab3f13c92e7a06b3becede3b2eb 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(); });