import { test, expect, type BrowserContext } from "@playwright/test"; import { createEntryViaForm, listSearch, makeContext, openList, setupVault } from "./helpers/vault"; // Real vault creation (Argon2id + recovery confirmation ≈ 12s) plus a form // round-trip per test — the global 30s cap is too tight. test.describe.configure({ timeout: 90_000 }); test.describe("Entry CRUD", () => { let ctx: BrowserContext; test.afterEach(async () => { await ctx.close(); }); test.beforeEach(async () => { ctx = await makeContext("peach-crud"); }); test("EC01 - add entry with all fields", async () => { const { popup } = await setupVault(ctx); await createEntryViaForm(popup, { title: "GitHub", url: "https://github.com", username: "june", password: "secret123!", }); await openList(popup); await expect(popup.locator(".peach-entry-row-name", { hasText: "GitHub" })).toBeVisible({ timeout: 5000 }); }); test("EC02 - add entry with TOTP shows a live code", async () => { const { popup } = await setupVault(ctx); await createEntryViaForm(popup, { title: "GitHub2FA", url: "https://github.com", username: "june", password: "secret123!", totp: "JBSWY3DPEHPK3PXP", }); await openList(popup); await popup.locator(".peach-entry-row", { hasText: "GitHub2FA" }).click(); await expect(popup.locator(".peach-totp-code-text")).toHaveText(/\d{3} \d{3}/, { timeout: 5000 }); }); test("EC03 - edited title persists", async () => { const { popup } = await setupVault(ctx); await createEntryViaForm(popup, { title: "EditTest", url: "https://edit.test", username: "u", password: "oldpass" }); await openList(popup); await popup.locator(".peach-entry-row", { hasText: "EditTest" }).click(); await popup.locator(".peach-entry-name-button").click(); await popup.locator(".peach-inline-title-input").fill("EditedTitle"); await popup.keyboard.press("Enter"); await openList(popup); await expect(popup.locator(".peach-entry-row-name", { hasText: "EditedTitle" })).toBeVisible({ timeout: 5000 }); await expect(popup.locator(".peach-entry-row-name", { hasText: "EditTest" })).toHaveCount(0); }); test("EC04 - delete entry removes it from the vault", async () => { const { popup } = await setupVault(ctx); await createEntryViaForm(popup, { title: "DeleteMe", url: "https://delete.test", username: "u", password: "p" }); await openList(popup); await popup.locator(".peach-entry-row", { hasText: "DeleteMe" }).click(); await popup.locator("[aria-label='Move to trash']").click(); await popup.getByRole("button", { name: /^yes$/i }).click(); await openList(popup); await expect(popup.locator(".peach-entry-row-name", { hasText: "DeleteMe" })).toHaveCount(0, { timeout: 5000 }); }); test("EC05 - search filters entries by title", async () => { const { popup } = await setupVault(ctx); for (const name of ["Apple", "Amazon"]) { await createEntryViaForm(popup, { title: name, url: `https://${name.toLowerCase()}.test`, username: "u", password: "p" }); } await openList(popup); await listSearch(popup).fill("Apple"); await expect(popup.locator(".peach-entry-row-name", { hasText: "Apple" })).toBeVisible(); await expect(popup.locator(".peach-entry-row-name", { hasText: "Amazon" })).toHaveCount(0); }); test("EC06 - a fresh vault shows the empty state", async () => { const { popup } = await setupVault(ctx); await expect(popup.locator(".peach-empty-copy")).toBeVisible({ timeout: 5000 }); }); });