71d866abde
Implementa el issue 0022b — fixtures de Playwright para autenticacion en Element Web y helpers de interaccion con rooms. - element-auth.ts: flujo completo de login + cross-signing con recovery key, preparado para cachear sesion via storageState - global-setup.ts: ejecuta login una vez antes de todos los tests, reutiliza sesion cacheada si tiene menos de 12 horas - matrix-room.ts: helpers goToRoom, sendMessage, waitForBotReply, getLastMessage, assertNoDecryptionErrors (detecta "Unable to decrypt") - login.spec.ts: 3 smoke tests validando sesion, E2EE y navegacion - playwright.config.ts: configurado storageState para inyectar sesion Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
73 lines
2.3 KiB
TypeScript
73 lines
2.3 KiB
TypeScript
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();
|
|
}
|