--- name: pw_kanban_login kind: function lang: ts domain: browser version: "1.0.0" purity: impure signature: "async (page: Page, opts: PwLoginOptions) => Promise" description: "Authenticates a Playwright Page against the kanban backend via POST /api/login. Sets session cookie and navigates to root. Throws on failure or if login page remains visible." tags: [playwright, e2e, browser, kanban] uses_functions: [] uses_types: [] returns: [] returns_optional: false error_type: "error_go_core" imports: [] params: - name: page desc: "Playwright Page (typically from pw_launch_browser). The page context shares storageState with page.request, so the Set-Cookie response propagates automatically." - name: opts desc: "{username, password, baseUrl?}. baseUrl defaults to the origin derived from page.url() — so the page must already be navigated to the target host before calling this function." output: "void; throws on failed login (HTTP >= 400) or if login page selectors remain visible after navigation. After resolve, page is on root (baseUrl + '/') and the kanban_session cookie is active." tested: true tests: - "happy path" - "rejects 401" - "rejects when login page still visible" test_file_path: "frontend/functions/browser/pw_kanban_login.test.ts" file_path: "frontend/functions/browser/pw_kanban_login.ts" --- ## Ejemplo ```typescript import { pw_launch_browser } from "@fn_library/../browser/pw_launch_browser"; import { pw_kanban_login } from "@fn_library/../browser/pw_kanban_login"; const { page, close } = await pw_launch_browser({ baseUrl: "http://localhost:5180" }); await pw_kanban_login(page, { username: "egutierrez", password: "..." }); // page is now on http://localhost:5180/ with kanban_session cookie active await close(); ``` ## Cuando usarla Usala al inicio de cualquier test Playwright o script e2e contra el kanban. Despues de esta llamada el `page` esta autenticado y puede acceder a rutas protegidas sin redireccion al login. ## Gotchas - `page.url()` debe devolver una URL valida con origin antes de llamar a esta funcion si no se pasa `baseUrl`. Si la pagina no ha navegado todavia (`about:blank`), pasar `baseUrl` explicitamente. - La funcion asume que `page.request` comparte el contexto de cookies con `page` (comportamiento por defecto de Playwright). Si usas un `APIRequestContext` separado, la cookie no se propagara automaticamente. - La comprobacion post-login busca texto literal "Login" o "Iniciar sesion". Si el backend usa otro texto en el boton, la comprobacion pasara aunque la autenticacion haya fallado silenciosamente — en ese caso ampliar los selectores de sanidad. - Espera `networkidle` tras `goto`: si la app lanza requests continuos (polling, WebSocket upgrade), `networkidle` puede tardar o no resolverse. Considerar `page.waitForURL` como alternativa en esos casos.