entry-crud.spec.ts

3.4 KB · raw

1import { test, expect, type BrowserContext } from "@playwright/test";2import { createEntryViaForm, makeContext, 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 expect(popup.locator(".peach-entry-row-name", { hasText: "GitHub" })).toBeVisible({ timeout: 5000 });22  });2324  test("EC02 - add entry with TOTP shows a live code", async () => {25    const { popup } = await setupVault(ctx);26    await createEntryViaForm(popup, {27      title: "GitHub2FA",28      url: "https://github.com",29      username: "june",30      password: "secret123!",31      totp: "JBSWY3DPEHPK3PXP",32    });33    await popup.locator(".peach-entry-row", { hasText: "GitHub2FA" }).click();34    await expect(popup.locator(".peach-totp-code-text")).toHaveText(/\d{3} \d{3}/, { timeout: 5000 });35  });3637  test("EC03 - edited title persists", async () => {38    const { popup } = await setupVault(ctx);39    await createEntryViaForm(popup, { title: "EditTest", url: "https://edit.test", username: "u", password: "oldpass" });40    await popup.locator(".peach-entry-row", { hasText: "EditTest" }).click();41    await popup.locator(".peach-entry-name-button").click();42    await popup.locator(".peach-inline-title-input").fill("EditedTitle");43    await popup.keyboard.press("Enter");44    await expect(popup.locator(".peach-entry-row-name", { hasText: "EditedTitle" })).toBeVisible({ timeout: 5000 });45    await expect(popup.locator(".peach-entry-row-name", { hasText: "EditTest" })).toHaveCount(0);46  });4748  test("EC04 - delete entry removes it from the vault", async () => {49    const { popup } = await setupVault(ctx);50    await createEntryViaForm(popup, { title: "DeleteMe", url: "https://delete.test", username: "u", password: "p" });51    await popup.locator(".peach-entry-row", { hasText: "DeleteMe" }).click();52    await popup.locator("[aria-label='Move to trash']").click();53    await popup.getByRole("button", { name: /^yes$/i }).click();54    await expect(popup.locator(".peach-entry-row-name", { hasText: "DeleteMe" })).toHaveCount(0, { timeout: 5000 });55  });5657  test("EC05 - search filters entries by title", async () => {58    const { popup } = await setupVault(ctx);59    for (const name of ["Apple", "Amazon"]) {60      await createEntryViaForm(popup, { title: name, url: `https://${name.toLowerCase()}.test`, username: "u", password: "p" });61    }62    await popup.locator('input[placeholder="search vault..."]').fill("Apple");63    await expect(popup.locator(".peach-entry-row-name", { hasText: "Apple" })).toBeVisible();64    await expect(popup.locator(".peach-entry-row-name", { hasText: "Amazon" })).toHaveCount(0);65  });6667  test("EC06 - a fresh vault shows the empty state", async () => {68    const { popup } = await setupVault(ctx);69    await expect(popup.locator(".peach-empty-copy")).toBeVisible({ timeout: 5000 });70  });71});