eb1c13d82c
CardForm: drop pre-fill of requester from logged user; Enter inside the Autocomplete no longer submits the form (Mantine handles dropdown selection; arrows + Enter pick option without closing modal). Submit remains via "Crear" button or Ctrl+Enter from description. Adds data-field="requester" and data-test="add-card" selectors for stable e2e queries. Tests: - vitest component test (CardForm.test.tsx): empty input, Enter does not submit, submit only via button. Dropdown arrow nav covered by e2e (jsdom portal handling is brittle). - Playwright e2e (requester-input.spec.ts) using new browser capability group (pw_kanban_login, pw_keyboard_sequence) from registry. - seed_e2e_user CLI to create deterministic test user against operations.db (bcrypt via standard backend hash). Setup additions (frontend/): - vitest + @testing-library + jsdom devDeps - @playwright/test devDep + playwright.config.ts - src/test/setup.ts polyfills jsdom for Mantine (matchMedia, visualViewport, document.fonts, ResizeObserver) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
69 lines
2.7 KiB
TypeScript
69 lines
2.7 KiB
TypeScript
import { test, expect } from "@playwright/test";
|
|
import { pw_kanban_login } from "../../../../frontend/functions/browser/pw_kanban_login";
|
|
import { pw_keyboard_sequence } from "../../../../frontend/functions/browser/pw_keyboard_sequence";
|
|
import { pw_wait_predicate } from "../../../../frontend/functions/browser/pw_wait_predicate";
|
|
|
|
const USER = process.env.KANBAN_USER || "egutierrez";
|
|
const PWD = process.env.KANBAN_PWD || "egutierrez";
|
|
|
|
test.describe("Issue 0088 — requester input vacio + nav teclado", () => {
|
|
test("input solicitante entra vacio y ArrowDown+Enter no cierra modal", async ({ page }) => {
|
|
await page.goto("/");
|
|
await pw_kanban_login(page, { username: USER, password: PWD });
|
|
|
|
// Abrir Nueva tarjeta del primer "+" disponible en alguna columna del board.
|
|
const addBtn = page.locator('[data-test="add-card"]').first();
|
|
await addBtn.dispatchEvent("click");
|
|
|
|
// Modal de Mantine abierto.
|
|
const dialog = page.locator("[role=dialog]");
|
|
await expect(dialog).toBeVisible();
|
|
|
|
// Solicitante vacio.
|
|
const requester = dialog.locator('input[data-field="requester"]');
|
|
await expect(requester).toHaveValue("");
|
|
|
|
// Necesario titulo para que un eventual submit no se descarte por el guard.
|
|
await dialog.locator("textarea").first().fill("e2e test card");
|
|
|
|
// Tipear + navegar dropdown + Enter.
|
|
await requester.focus();
|
|
await pw_keyboard_sequence(page, [
|
|
{ kind: "type", text: "a", delayMs: 50 },
|
|
{ kind: "wait", ms: 300 },
|
|
{ kind: "press", key: "ArrowDown" },
|
|
{ kind: "press", key: "Enter" },
|
|
]);
|
|
|
|
// Modal sigue visible: Enter no ha cerrado el form.
|
|
await page.waitForTimeout(300);
|
|
await expect(dialog).toBeVisible();
|
|
|
|
// Cancelar para limpiar estado.
|
|
await dialog.locator("button:has-text('Cancelar')").click();
|
|
await expect(dialog).toBeHidden();
|
|
});
|
|
|
|
test("Enter en requester con dropdown cerrado NO cierra modal", async ({ page }) => {
|
|
await page.goto("/");
|
|
await pw_kanban_login(page, { username: USER, password: PWD });
|
|
|
|
const addBtn = page.locator('[data-test="add-card"]').first();
|
|
await addBtn.dispatchEvent("click");
|
|
const dialog = page.locator("[role=dialog]");
|
|
await expect(dialog).toBeVisible();
|
|
|
|
await dialog.locator("textarea").first().fill("e2e test card 2");
|
|
const requester = dialog.locator('input[data-field="requester"]');
|
|
await requester.focus();
|
|
// Press Escape para asegurar dropdown cerrado, luego Enter.
|
|
await page.keyboard.press("Escape");
|
|
await page.keyboard.press("Enter");
|
|
await page.waitForTimeout(200);
|
|
await expect(dialog).toBeVisible();
|
|
|
|
await dialog.locator("button:has-text('Cancelar')").click();
|
|
await expect(dialog).toBeHidden();
|
|
});
|
|
});
|