/** * Shared login helper for Playwright @playwright/test spec files. * Uses the project baseURL (http://localhost:3000) from playwright.config.ts. */ import { type Page, expect } from "@playwright/test"; export interface Credentials { email: string; password: string; } export const USERS = { TECH: { email: "tech@pelagia.local", password: "tech1234" }, MANNING: { email: "manning@pelagia.local", password: "manning1234" }, ACCOUNTS: { email: "accounts@pelagia.local", password: "accounts1234" }, MANAGER: { email: "manager@pelagia.local", password: "manager1234" }, SUPERUSER: { email: "superuser@pelagia.local", password: "super1234" }, AUDITOR: { email: "auditor@pelagia.local", password: "audit1234" }, ADMIN: { email: "admin@pelagia.local", password: "admin1234" }, } satisfies Record; export async function login(page: Page, creds: Credentials): Promise { await page.goto("/login"); await page.getByLabel(/email address/i).fill(creds.email); await page.getByLabel(/password/i).fill(creds.password); await page.getByRole("button", { name: /sign in/i }).click(); await expect(page).not.toHaveURL(/\/login/, { timeout: 20_000 }); console.log(`✓ Logged in as ${creds.email}`); } /** * Create a minimal draft PO and return the absolute PO URL. * Uses name-based selectors since the PO form labels have no htmlFor binding. */ export async function createDraftPo(page: Page, title: string): Promise { await page.goto("/po/new"); // Wait for the form to be ready await page.waitForSelector('input[name="title"]', { timeout: 15_000 }); await page.locator('input[name="title"]').fill(title); await page.locator('select[name="vesselId"]').selectOption({ index: 1 }); await page.locator('select[name="accountId"]').selectOption({ index: 1 }); await page.getByPlaceholder("Item description").fill("Test item"); await page.getByRole("spinbutton").first().fill("1"); await page.locator("input[placeholder='0.00']").first().fill("100"); await page.getByRole("button", { name: /save as draft/i }).click(); await expect(page).toHaveURL(/\/po\//, { timeout: 20_000 }); return page.url(); } /** Create a PO and submit it for approval; returns the PO URL. */ export async function submitPo(page: Page, title: string): Promise { await page.goto("/po/new"); await page.waitForSelector('input[name="title"]', { timeout: 15_000 }); await page.locator('input[name="title"]').fill(title); await page.locator('select[name="vesselId"]').selectOption({ index: 1 }); await page.locator('select[name="accountId"]').selectOption({ index: 1 }); await page.getByPlaceholder("Item description").fill("Engine gasket"); await page.getByRole("spinbutton").first().fill("2"); await page.locator("input[placeholder='0.00']").first().fill("250"); await page.getByRole("button", { name: /submit for approval/i }).click(); await expect(page).toHaveURL(/\/po\//, { timeout: 20_000 }); return page.url(); }