feat: auth fixtures y helpers de interaccion E2E
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>
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
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();
|
||||
}
|
||||
Reference in New Issue
Block a user