JB/web/tests/e2e.spec.ts

95 lines
4.3 KiB
TypeScript

import { test, expect } from "@playwright/test";
test.describe("JobsBoard Core E2E Journeys", () => {
const timestamp = Date.now();
const seekerEmail = `seeker_${timestamp}@example.com`;
const employerEmail = `recruiter_${timestamp}@acmecorp.com`;
test("Layout Check: No duplicate navbar/header elements across pages", async ({ page }) => {
const testPaths = ["/", "/jobs", "/companies", "/login", "/register", "/privacy", "/terms"];
for (const p of testPaths) {
await page.goto(p);
const navs = await page.locator("nav").count();
// Only 1 navigation bar element should exist in DOM
expect(navs, `Page ${p} has unexpected number of <nav> elements: ${navs}`).toBeLessThanOrEqual(1);
}
});
test("Job Seeker E2E Journey: Register, Browse Jobs & View Application Status", async ({ page }) => {
// 1. Visit registration with seeker pre-selection
await page.goto("/register?role=seeker");
await expect(page.getByRole("heading", { name: "Create Job Seeker Account" })).toBeVisible();
// 2. Fill registration details
await page.locator('input[placeholder="Alex Morgan"]').fill("Jane TestSeeker");
await page.locator('input[placeholder="alex@example.com"]').fill(seekerEmail);
await page.locator('input[type="password"]').fill("ValidPass123!");
await page.getByRole("button", { name: "Create Job Seeker Account" }).click();
// 3. Confirm redirected to /jobs
await page.waitForURL("**/jobs", { timeout: 10000 });
expect(page.url()).toContain("/jobs");
// 4. Navigate to /applications
await page.goto("/applications");
await expect(page.locator("body")).toContainText(/Applications/i);
});
test("Employer E2E Journey: Register with Company, Redirect to ATS, Kanban Layout Check", async ({ page }) => {
// 1. Visit registration with employer role
await page.goto("/register?role=employer");
await expect(page.getByRole("heading", { name: "Create Employer Account" })).toBeVisible();
await expect(page.locator("text=Company Information")).toBeVisible();
// 2. Fill employer details
const uniqueCompany = `Apex Inno ${timestamp}`;
await page.locator('input[placeholder="Alex Morgan"]').fill("John Recruiter");
await page.locator('input[placeholder="recruiter@company.com"]').fill(employerEmail);
await page.locator('input[type="password"]').fill("ValidPass123!");
await page.locator('input[placeholder="Acme Corporation"]').fill(uniqueCompany);
await page.locator('input[placeholder="https://acme.com"]').fill("https://apex.test");
await page.locator('input[placeholder="Hartford, CT or Remote"]').fill("Stamford, CT");
// 3. Submit
await page.getByRole("button", { name: /Create Employer Account/ }).click();
// 4. Confirm redirected or login state
await page.waitForTimeout(2000);
const currentUrl = page.url();
expect(currentUrl.includes("/employer/ats") || currentUrl.includes("/login")).toBeTruthy();
});
test("Phase 7 Seeker Journey: Job Discovery & Explainable Match Interface", async ({ page }) => {
// 1. Visit jobs marketplace
await page.goto("/jobs");
await expect(page.locator("h1")).toContainText(/Aggregated Job Postings/i);
await page.waitForTimeout(1000);
// 2. Open first job listing link or direct job card
const jobLink = page.locator('a[href^="/jobs/"]').first();
if (await jobLink.isVisible()) {
await jobLink.click();
await page.waitForTimeout(1000);
await expect(page.locator("h1")).toBeVisible();
await expect(page.locator("text=Job Description & Responsibilities")).toBeVisible();
} else {
// Direct visit to sample job
const res = await page.request.get("/api/jobs?limit=1");
const data = await res.json();
if (data.jobs && data.jobs[0]) {
await page.goto(`/jobs/${data.jobs[0].id}`);
await expect(page.locator("h1")).toBeVisible();
await expect(page.locator("text=Job Description & Responsibilities")).toBeVisible();
}
}
});
test("Phase 7 Employer Journey: Candidate Directory & Job-Context Matching UI", async ({ page }) => {
// 1. Visit employer candidates directory
await page.goto("/employer/candidates");
await page.waitForTimeout(1000);
const bodyText = await page.textContent("body");
expect(bodyText).toBeDefined();
});
});