import { expect, test } from "@playwright/test"; const generatorUrl = "**/PasswordGeneratorDialog.tsx*"; for (const language of ["en", "de"]) { test(`password generation loads only when opened and preserves cancel/use/focus (${language})`, async ({ page }) => { const generateLabel = language === "de" ? "Passwort generieren" : "Generate password"; const cancelLabel = language === "de" ? "Abbrechen" : "Cancel"; const useLabel = language === "de" ? "Passwort verwenden" : "Use password"; const requests: string[] = []; page.on("request", (request) => { if (request.url().includes("/PasswordGeneratorDialog.tsx")) requests.push(request.url()); }); await page.goto(`/password-field.html?language=${language}`); const trigger = page.getByRole("button", { name: generateLabel, exact: true }); await expect(trigger).toHaveCount(1); await expect(page.getByTestId("editable-password")).toHaveValue("fixture-unchanged-password"); expect(requests).toHaveLength(0); await trigger.click(); const dialog = page.getByRole("dialog", { name: generateLabel, exact: true }); await expect(dialog).toBeVisible(); await expect.poll(() => requests.length).toBe(1); await expect(dialog.locator(".password-generator-result input")).toHaveValue(/^.{24}$/); await expect(page.getByTestId("password-changes")).toHaveText("0"); await dialog.getByRole("button", { name: cancelLabel, exact: true }).click(); await expect(dialog).toBeHidden(); await expect(trigger).toBeFocused(); await expect(page.getByTestId("editable-password")).toHaveValue("fixture-unchanged-password"); await trigger.click(); await expect(dialog.locator(".password-generator-result input")).toHaveValue(/^.{24}$/); const candidate = await dialog.locator(".password-generator-result input").inputValue(); await dialog.getByRole("button", { name: useLabel, exact: true }).click(); await expect(dialog).toBeHidden(); await expect(page.getByTestId("editable-password")).toHaveValue(candidate); await expect(page.getByTestId("editable-password")).toHaveAttribute("type", "password"); await expect(page.getByTestId("password-changes")).toHaveText("1"); await expect(trigger).toBeFocused(); expect(requests).toHaveLength(1); }); } test("a pending generator load cannot reopen after generation becomes unavailable", async ({ page }) => { let releaseLoad!: () => void; const pending = new Promise((resolve) => { releaseLoad = resolve; }); await page.route(generatorUrl, async (route) => { await pending; await route.continue(); }); await page.goto("/password-field.html?language=en"); await page.getByRole("button", { name: "Generate password", exact: true }).click(); await expect(page.locator(".module-load-progress")).toBeVisible(); await page.getByTestId("toggle-generator-access").click(); releaseLoad(); await expect(page.getByTestId("editable-password")).toBeDisabled(); await expect(page.locator(".module-load-progress")).toBeHidden(); await expect(page.getByRole("dialog")).toHaveCount(0); await page.getByTestId("toggle-generator-access").click(); await expect(page.getByRole("dialog")).toHaveCount(0); await expect(page.getByTestId("password-changes")).toHaveText("0"); await page.getByRole("button", { name: "Generate password", exact: true }).click(); await expect(page.getByRole("dialog", { name: "Generate password", exact: true })).toBeVisible(); }); test("generator chunk failure leaves ordinary password entry and reveal usable", async ({ page }) => { await page.route(generatorUrl, (route) => route.abort("failed")); await page.goto("/password-field.html?language=en"); await page.getByRole("button", { name: "Generate password", exact: true }).click(); await expect(page.locator(".module-load-error")).toBeVisible(); await expect(page.getByTestId("editable-password")).toBeEnabled(); await page.getByTestId("editable-password").fill("fixture-edited-password"); await page.getByRole("button", { name: "Show password", exact: true }).first().click(); await expect(page.getByTestId("editable-password")).toHaveAttribute("type", "text"); await expect(page.getByTestId("editable-password")).toHaveValue("fixture-edited-password"); await expect(page.getByRole("dialog")).toHaveCount(0); });