Adds a Playwright suite (App/tests/staging/) that logs into the running staging instance (ppms-staging, :3200) and verifies each closed portal issue is actually fixed — feature level, driving the real UI, one spec per issue. To make credential login possible against the prod-mirror pelagia_test (which only holds real, mostly SSO-only users), prisma/seed-test-users.ts idempotently seeds one known-password @pelagia.local user per role, and automation/refresh-test-db.sh runs it after every daily refresh so the logins persist on staging. Result against staging: 41 passed, 1 skipped (#10 — no attachment data on staging). Two closed issues were found NOT fixed and are recorded as documented test.fail(): - #13 Accounts "payments completed this month" card is absent. - #24/#40 logout tooltip still reads "Sign out" (pipeline test issues). Docs/TESTING.md documents the suite, the seeded users, how to run it against staging, and the full issue -> script mapping. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
89 lines
3.8 KiB
TypeScript
89 lines
3.8 KiB
TypeScript
/**
|
|
* Seed deterministic, credential-capable TEST USERS into a database.
|
|
*
|
|
* Why this exists
|
|
* ---------------
|
|
* `pelagia_test` (the staging / autofix DB) is a daily mirror of production, so it
|
|
* only contains real `@pelagiamarine.com` users — most are SSO-only (no password)
|
|
* and none have a password we know. That makes it impossible to log into the
|
|
* staging instance (port 3200) with the credentials provider to run end-to-end
|
|
* feature tests.
|
|
*
|
|
* This script upserts one **known-password** user per `Role` (using the throwaway
|
|
* `@pelagia.local` domain, which never exists in prod, so there is zero collision
|
|
* with real accounts). Credentials intentionally mirror
|
|
* `tests/e2e/helpers/login.ts` so the same Playwright specs run locally and against
|
|
* staging unchanged.
|
|
*
|
|
* Safety
|
|
* ------
|
|
* - Idempotent: upsert keyed on the (unique) email; re-running only refreshes the
|
|
* password hash / role / isActive.
|
|
* - `employeeId` uses a `TEST-*` prefix so it can never clash with a real
|
|
* production employee id carried over by the mirror.
|
|
* - Only ever creates the `@pelagia.local` users below — it touches no prod rows.
|
|
*
|
|
* Usage
|
|
* -----
|
|
* DATABASE_URL="postgresql://.../pelagia_test" pnpm tsx prisma/seed-test-users.ts
|
|
*
|
|
* It is wired into `automation/refresh-test-db.sh` so these accounts are recreated
|
|
* automatically after every daily refresh of `pelagia_test`.
|
|
*/
|
|
import { PrismaClient, Role } from "@prisma/client";
|
|
import bcrypt from "bcryptjs";
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
/**
|
|
* One login per role/flow that the closed-issue feature tests exercise.
|
|
* Passwords match tests/e2e/helpers/login.ts (do not change one without the other).
|
|
*/
|
|
const TEST_USERS: Array<{
|
|
employeeId: string;
|
|
email: string;
|
|
name: string;
|
|
password: string;
|
|
role: Role;
|
|
}> = [
|
|
{ employeeId: "TEST-TECH", email: "tech@pelagia.local", name: "Test Technical", password: "tech1234", role: Role.TECHNICAL },
|
|
{ employeeId: "TEST-MANNING",email: "manning@pelagia.local", name: "Test Manning", password: "manning1234", role: Role.MANNING },
|
|
{ employeeId: "TEST-ACCT", email: "accounts@pelagia.local", name: "Test Accounts", password: "accounts1234", role: Role.ACCOUNTS },
|
|
{ employeeId: "TEST-MGR", email: "manager@pelagia.local", name: "Test Manager", password: "manager1234", role: Role.MANAGER },
|
|
{ employeeId: "TEST-SUPER", email: "superuser@pelagia.local", name: "Test Superuser", password: "super1234", role: Role.SUPERUSER },
|
|
{ employeeId: "TEST-AUDIT", email: "auditor@pelagia.local", name: "Test Auditor", password: "audit1234", role: Role.AUDITOR },
|
|
{ employeeId: "TEST-ADMIN", email: "admin@pelagia.local", name: "Test Admin", password: "admin1234", role: Role.ADMIN },
|
|
{ employeeId: "TEST-SITE", email: "site@pelagia.local", name: "Test Site Staff", password: "site1234", role: Role.SITE_STAFF},
|
|
];
|
|
|
|
async function main() {
|
|
console.log(`Seeding ${TEST_USERS.length} test users...`);
|
|
for (const u of TEST_USERS) {
|
|
const passwordHash = await bcrypt.hash(u.password, 12);
|
|
await prisma.user.upsert({
|
|
where: { email: u.email },
|
|
// Keep an existing test account in sync (refresh the hash / role / active flag)
|
|
// but never overwrite its employeeId once created.
|
|
update: { name: u.name, passwordHash, role: u.role, isActive: true },
|
|
create: {
|
|
employeeId: u.employeeId,
|
|
email: u.email,
|
|
name: u.name,
|
|
passwordHash,
|
|
role: u.role,
|
|
isActive: true,
|
|
},
|
|
});
|
|
console.log(` ✓ ${u.email.padEnd(28)} ${u.role}`);
|
|
}
|
|
console.log("Test users ready.");
|
|
}
|
|
|
|
main()
|
|
.catch((e) => {
|
|
console.error("seed-test-users failed:", e);
|
|
process.exit(1);
|
|
})
|
|
.finally(async () => {
|
|
await prisma.$disconnect();
|
|
});
|