diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2a94ae9..a51ba8e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -131,6 +131,9 @@ jobs: - name: Seed admin account run: npx tsx prisma/seed.ts + - name: Seed e2e fixtures + run: npx tsx e2e/seed.ts + - name: Build run: npm run build diff --git a/e2e/seed.ts b/e2e/seed.ts new file mode 100644 index 0000000..33168ba --- /dev/null +++ b/e2e/seed.ts @@ -0,0 +1,36 @@ +import { PrismaClient } from "@prisma/client" +import { PrismaPg } from "@prisma/adapter-pg" + +// E2E fixture: one employee so a fresh instance counts as set up +// (the dashboard redirects empty workspaces to /setup). Run after +// prisma/seed.ts; used by the CI e2e job only. +const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL! }) +const prisma = new PrismaClient({ adapter }) + +async function main() { + const company = await prisma.company.findUniqueOrThrow({ + where: { domain: "datashield.dev" }, + }) + + await prisma.employee.upsert({ + where: { + email_companyId: { email: "jane.doe@datashield.dev", companyId: company.id }, + }, + update: {}, + create: { + email: "jane.doe@datashield.dev", + firstName: "Jane", + lastName: "Doe", + department: "Engineering", + companyId: company.id, + }, + }) + +} + +main() + .then(() => prisma.$disconnect()) + .catch((e) => { + console.error(e) + process.exit(1) + }) diff --git a/e2e/smoke.spec.ts b/e2e/smoke.spec.ts index b49961f..e53b6a9 100644 --- a/e2e/smoke.spec.ts +++ b/e2e/smoke.spec.ts @@ -1,19 +1,25 @@ import { test, expect } from "@playwright/test" let cspViolations: string[] +let pageErrors: string[] test.beforeEach(({ page }) => { cspViolations = [] + pageErrors = [] page.on("console", (msg) => { const text = msg.text() if (text.includes("Content Security Policy") || text.includes("Refused to")) { cspViolations.push(text) } }) + page.on("pageerror", (err) => { + pageErrors.push(err.message) + }) }) test.afterEach(() => { expect(cspViolations).toEqual([]) + expect(pageErrors).toEqual([]) }) test("admin signs in, sees dashboard and alerts", async ({ page }) => { @@ -27,4 +33,8 @@ test("admin signs in, sees dashboard and alerts", async ({ page }) => { await page.goto("/alerts") await expect(page.getByRole("main")).toBeVisible() + + await page.goto("/dashboard/widgets") + await expect(page.getByRole("heading", { name: "Widget Library" })).toBeVisible() + await expect(page.getByRole("heading", { name: "Alert Severity" })).toBeVisible() }) diff --git a/src/app/(dashboard)/dashboard/widgets/page.tsx b/src/app/(dashboard)/dashboard/widgets/page.tsx index d548ce8..40be2ba 100644 --- a/src/app/(dashboard)/dashboard/widgets/page.tsx +++ b/src/app/(dashboard)/dashboard/widgets/page.tsx @@ -3,6 +3,7 @@ import { getDashboardData } from "@/lib/dashboard" import { prisma } from "@/lib/prisma" import { WIDGETS } from "@/lib/widgetRegistry" import { WidgetLibrary } from "@/components/dashboard/WidgetLibrary" +import { DetailDrawerProvider } from "@/contexts/DetailDrawerContext" import { StatsRow } from "@/components/dashboard/StatsRow" import { TrendChart } from "@/components/dashboard/TrendChart" import { DataTypeBreakdown } from "@/components/dashboard/DataTypeBreakdown" @@ -86,10 +87,12 @@ export default async function WidgetsPage() { } return ( - + + + ) }