test: add Playwright E2E test suite (30 tests)
Add browser-level end-to-end tests covering public pages, Keycloak OAuth authentication flow, dashboard interactions, providers config, developer section, organization pages, and sidebar navigation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
75
e2e/dashboard.spec.ts
Normal file
75
e2e/dashboard.spec.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import { test, expect } from "@playwright/test";
|
||||
|
||||
test.describe("Dashboard", () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto("/dashboard");
|
||||
// Wait for WASM hydration and auth check to complete
|
||||
await page.waitForSelector(".dashboard-page", { timeout: 15_000 });
|
||||
});
|
||||
|
||||
test("dashboard page loads with page header", async ({ page }) => {
|
||||
await expect(page.locator(".page-header")).toContainText("Dashboard");
|
||||
});
|
||||
|
||||
test("default topic chips are visible", async ({ page }) => {
|
||||
const topics = ["AI", "Technology", "Science", "Finance", "Writing", "Research"];
|
||||
|
||||
for (const topic of topics) {
|
||||
await expect(
|
||||
page.locator(".filter-tab", { hasText: topic })
|
||||
).toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test("clicking a topic chip triggers search", async ({ page }) => {
|
||||
const chip = page.locator(".filter-tab", { hasText: "AI" });
|
||||
await chip.click();
|
||||
|
||||
// Either a loading state or results should appear
|
||||
const searchingOrResults = page
|
||||
.locator(".dashboard-loading, .news-grid, .dashboard-empty");
|
||||
await expect(searchingOrResults.first()).toBeVisible({ timeout: 10_000 });
|
||||
});
|
||||
|
||||
test("news cards render after search completes", async ({ page }) => {
|
||||
// Click a topic to trigger search
|
||||
await page.locator(".filter-tab", { hasText: "Technology" }).click();
|
||||
|
||||
// Wait for loading to finish
|
||||
await page.waitForSelector(".dashboard-loading", {
|
||||
state: "hidden",
|
||||
timeout: 15_000,
|
||||
}).catch(() => {
|
||||
// Loading may already be done
|
||||
});
|
||||
|
||||
// Either news cards or an empty state message should be visible
|
||||
const content = page.locator(".news-grid .news-card, .dashboard-empty");
|
||||
await expect(content.first()).toBeVisible({ timeout: 10_000 });
|
||||
});
|
||||
|
||||
test("clicking a news card opens article detail panel", async ({ page }) => {
|
||||
// Trigger a search and wait for results
|
||||
await page.locator(".filter-tab", { hasText: "AI" }).click();
|
||||
|
||||
await page.waitForSelector(".dashboard-loading", {
|
||||
state: "hidden",
|
||||
timeout: 15_000,
|
||||
}).catch(() => {});
|
||||
|
||||
const firstCard = page.locator(".news-card").first();
|
||||
// Only test if cards are present (search results depend on live data)
|
||||
if (await firstCard.isVisible().catch(() => false)) {
|
||||
await firstCard.click();
|
||||
await expect(page.locator(".dashboard-right, .dashboard-split")).toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test("settings toggle opens settings panel", async ({ page }) => {
|
||||
const settingsBtn = page.locator(".settings-toggle");
|
||||
await settingsBtn.click();
|
||||
|
||||
await expect(page.locator(".settings-panel")).toBeVisible();
|
||||
await expect(page.locator(".settings-panel-title")).toBeVisible();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user