import { Page, expect } from "@playwright/test"; export interface LoginOptions { url: string; user: string; password: string; recoveryKey: string; } /** * Ejecuta el flujo completo de login en Element Web: * 1. Navegar a Element Web * 2. Click "Sign in" * 3. Ingresar usuario y contraseña * 4. Manejar verificacion de dispositivo con recovery key * 5. Verificar login exitoso (lista de rooms visible) */ export async function loginToElement(page: Page, opts: LoginOptions) { await page.goto(opts.url); // Esperar a que cargue Element y aparezca el boton de login await page.getByRole("link", { name: "Sign in" }).click(); // Rellenar credenciales await page.getByRole("textbox", { name: "Username" }).fill(opts.user); await page.getByRole("textbox", { name: "Password" }).fill(opts.password); await page.getByRole("button", { name: "Sign in" }).click(); // Manejar cross-signing: verificar con recovery key await handleCrossSigning(page, opts.recoveryKey); // Verificar login exitoso: rooms visibles en el sidebar await expect( page.locator('[role="tree"][aria-label="Rooms"]') ).toBeVisible({ timeout: 30_000 }); } /** * Maneja el prompt de verificacion de dispositivo despues del login. * Element puede mostrar un dialogo pidiendo verificar el dispositivo * via otro dispositivo o via recovery key. */ async function handleCrossSigning(page: Page, recoveryKey: string) { // Element muestra un dialogo de verificacion de dispositivo. // Intentar usar "Verify with Security Key" si aparece. const verifyButton = page.getByRole("button", { name: /verify with security key|use security key/i, }); // El dialogo puede tardar en aparecer tras el login const hasVerifyPrompt = await verifyButton .waitFor({ state: "visible", timeout: 15_000 }) .then(() => true) .catch(() => false); if (!hasVerifyPrompt) { // No hubo prompt de verificacion — login directo (sesion ya verificada) return; } await verifyButton.click(); // Ingresar recovery key en el campo de texto const keyInput = page.getByRole("textbox"); await keyInput.fill(recoveryKey); // Confirmar await page.getByRole("button", { name: /continue/i }).click(); // Esperar a que se complete la verificacion (el dialogo desaparece) await page.getByRole("button", { name: /done/i }).click(); }