SPB Git forge

spb/polyllm

Public
15commits 1branches 0releases
2.2 MBsize
maindefault branch
13 days agolast push
TypeScript 97.4% SQL 1% JavaScript 0.9% CSS 0.6%
2.3 KB · 56 lines typescript
Raw Blame History
1import { execSync } from "node:child_process";2import fs from "node:fs";3import type { Page } from "@playwright/test";45export const DB = process.env.E2E_DATABASE_URL ?? "postgres://localhost:5432/polyllm";6export const DEV_LOG = process.env.E2E_DEV_LOG ?? "/tmp/polyllm-dev.log";78export function sql(q: string): string {9  return execSync(`psql "${DB}" -Atc ${JSON.stringify(q)}`, { encoding: "utf8" }).trim();10}1112/** Finds the latest verification / reset URL for an email in the dev log (EMAIL_DRY_RUN_PRINT=1). */13export function lastLinkFromLog(pattern: RegExp): string | null {14  const log = fs.readFileSync(DEV_LOG, "utf8");15  const matches = [...log.matchAll(pattern)];16  return matches.length ? matches[matches.length - 1][0] : null;17}1819export function readEnv(name: string): string | undefined {20  if (process.env[name]) return process.env[name];21  const env = fs.existsSync(".env") ? fs.readFileSync(".env", "utf8") : "";22  const m = env.match(new RegExp(`^${name}=(.*)$`, "m"));23  return m ? m[1].replace(/^"|"$/g, "") : undefined;24}2526export const TEST_EMAIL = process.env.E2E_EMAIL ?? `e2e+${Date.now()}@polyllm.test`;27export const TEST_PASSWORD = "Str0ng-Passw0rd-e2e!";2829export async function login(page: Page, email: string, password: string) {30  await page.goto("/login");31  await page.getByLabel(/email/i).fill(email);32  await page.getByLabel(/^password$/i).fill(password);33  await page.getByRole("button", { name: /sign in/i }).click();34  await page.waitForURL(/\/app/);35}3637export async function noConsoleErrors(page: Page) {38  const errors: string[] = [];39  page.on("console", (msg) => {40    if (msg.type() === "error" && !/favicon|hydration|Download the React DevTools/i.test(msg.text())) errors.push(msg.text());41  });42  page.on("pageerror", (e) => errors.push(e.message));43  return errors;44}4546const STATE_FILE = "qa/.e2e-session.json";47/** Persist the signed-in cookies so later tests don't hit the sign-in rate limit (8/min). */48export async function saveSession(page: Page) {49  fs.mkdirSync("qa", { recursive: true });50  await page.context().storageState({ path: STATE_FILE });51}52export async function restoreSession(page: Page) {53  const state = JSON.parse(fs.readFileSync(STATE_FILE, "utf8")) as { cookies: Parameters<Page["context"]>[0] extends never ? never : import("@playwright/test").Cookie[] };54  await page.context().addCookies(state.cookies);55}56