entry-crud.spec.ts

3.5 KB · raw

1import { test, expect, type BrowserContext } from "@playwright/test";2import { createEntryViaForm, listSearch, makeContext, openList, setupVault } from "./helpers/vault";34// Real vault creation (Argon2id + recovery confirmation ≈ 12s) plus a form5// round-trip per test — the global 30s cap is too tight.6test.describe.configure({ timeout: 90_000 });78test.describe("Entry CRUD", () => {9  let ctx: BrowserContext;10  test.afterEach(async () => { await ctx.close(); });11  test.beforeEach(async () => { ctx = await makeContext("peach-crud"); });1213  test("EC01 - add entry with all fields", async () => {14    const { popup } = await setupVault(ctx);15    await createEntryViaForm(popup, {16      title: "GitHub",17      url: "https://github.com",18      username: "june",19      password: "secret123!",20    });21    await openList(popup);22    await expect(popup.locator(".peach-entry-row-name", { hasText: "GitHub" })).toBeVisible({ timeout: 5000 });23  });2425  test("EC02 - add entry with TOTP shows a live code", async () => {26    const { popup } = await setupVault(ctx);27    await createEntryViaForm(popup, {28      title: "GitHub2FA",29      url: "https://github.com",30      username: "june",31      password: "secret123!",32      totp: "JBSWY3DPEHPK3PXP",33    });34    await openList(popup);35    await popup.locator(".peach-entry-row", { hasText: "GitHub2FA" }).click();36    await expect(popup.locator(".peach-totp-code-text")).toHaveText(/\d{3} \d{3}/, { timeout: 5000 });37  });3839  test("EC03 - edited title persists", async () => {40    const { popup } = await setupVault(ctx);41    await createEntryViaForm(popup, { title: "EditTest", url: "https://edit.test", username: "u", password: "oldpass" });42    await openList(popup);43    await popup.locator(".peach-entry-row", { hasText: "EditTest" }).click();44    await popup.locator(".peach-entry-name-button").click();45    await popup.locator(".peach-inline-title-input").fill("EditedTitle");46    await popup.keyboard.press("Enter");47    await openList(popup);48    await expect(popup.locator(".peach-entry-row-name", { hasText: "EditedTitle" })).toBeVisible({ timeout: 5000 });49    await expect(popup.locator(".peach-entry-row-name", { hasText: "EditTest" })).toHaveCount(0);50  });5152  test("EC04 - delete entry removes it from the vault", async () => {53    const { popup } = await setupVault(ctx);54    await createEntryViaForm(popup, { title: "DeleteMe", url: "https://delete.test", username: "u", password: "p" });55    await openList(popup);56    await popup.locator(".peach-entry-row", { hasText: "DeleteMe" }).click();57    await popup.locator("[aria-label='Move to trash']").click();58    await popup.getByRole("button", { name: /^yes$/i }).click();59    await openList(popup);60    await expect(popup.locator(".peach-entry-row-name", { hasText: "DeleteMe" })).toHaveCount(0, { timeout: 5000 });61  });6263  test("EC05 - search filters entries by title", async () => {64    const { popup } = await setupVault(ctx);65    for (const name of ["Apple", "Amazon"]) {66      await createEntryViaForm(popup, { title: name, url: `https://${name.toLowerCase()}.test`, username: "u", password: "p" });67    }68    await openList(popup);69    await listSearch(popup).fill("Apple");70    await expect(popup.locator(".peach-entry-row-name", { hasText: "Apple" })).toBeVisible();71    await expect(popup.locator(".peach-entry-row-name", { hasText: "Amazon" })).toHaveCount(0);72  });7374  test("EC06 - a fresh vault shows the empty state", async () => {75    const { popup } = await setupVault(ctx);76    await expect(popup.locator(".peach-empty-copy")).toBeVisible({ timeout: 5000 });77  });78});