feat: extraer dismissAllToasts a element-utils.ts
Mueve la logica de cierre de toasts a un modulo compartido (element-utils.ts) para evitar duplicacion. persistent-context.ts importa dismissAllToasts desde ahi y la invoca despues de verificar el sidebar. Se mejora tambien la deteccion del sidebar usando multiples locators alternativos (mx_RoomList, mx_LeftPanel_roomListContainer, mx_RoomTile) para mayor compatibilidad con distintas versiones de Element Web.
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
import { Page } from "@playwright/test";
|
||||
|
||||
/**
|
||||
* Cierra todos los toasts/notificaciones de Element que bloquean clicks.
|
||||
* Incluye: Notifications, Threads Activity Centre, y cualquier toast generico.
|
||||
*/
|
||||
export async function dismissAllToasts(page: Page) {
|
||||
// Dar un momento para que los toasts aparezcan
|
||||
await page.waitForTimeout(1_500);
|
||||
|
||||
// Estrategia directa: buscar botones conocidos de toasts de Element
|
||||
const knownDismissButtons = [
|
||||
page.getByRole("button", { name: "Dismiss" }),
|
||||
page.locator("button").filter({ hasText: /^OK$/ }),
|
||||
page.getByRole("button", { name: "Close" }),
|
||||
page.getByRole("button", { name: "Not now" }),
|
||||
page.getByRole("button", { name: "Got it" }),
|
||||
page.getByRole("button", { name: "Skip" }),
|
||||
];
|
||||
|
||||
for (const btn of knownDismissButtons) {
|
||||
try {
|
||||
if (await btn.first().isVisible()) {
|
||||
const text = await btn.first().textContent().catch(() => "?");
|
||||
console.log(`[element] Dismissing toast: clicking "${text}"`);
|
||||
await btn.first().click({ force: true });
|
||||
await page.waitForTimeout(500);
|
||||
}
|
||||
} catch {
|
||||
// Ignorar errores — el boton pudo desaparecer entre check y click
|
||||
}
|
||||
}
|
||||
|
||||
// Segunda pasada: verificar si queda algun toast con boton visible
|
||||
const remainingToastBtns = page.locator(
|
||||
'.mx_ToastContainer button, .mx_Toast_buttons button'
|
||||
);
|
||||
const remaining = await remainingToastBtns.count();
|
||||
if (remaining > 0) {
|
||||
for (let i = 0; i < remaining; i++) {
|
||||
try {
|
||||
if (await remainingToastBtns.nth(i).isVisible()) {
|
||||
const text = await remainingToastBtns.nth(i).textContent();
|
||||
console.log(`[element] Closing remaining toast button: "${text}"`);
|
||||
await remainingToastBtns.nth(i).click({ force: true });
|
||||
await page.waitForTimeout(300);
|
||||
}
|
||||
} catch {
|
||||
// Ignorar
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { test as base, chromium, BrowserContext, Page } from "@playwright/test";
|
||||
import * as path from "path";
|
||||
import { dismissAllToasts } from "./element-utils";
|
||||
|
||||
/**
|
||||
* Custom test fixture que usa un persistent browser context compartido.
|
||||
@@ -50,10 +51,12 @@ export const test = base.extend<
|
||||
});
|
||||
|
||||
/**
|
||||
* Maneja dialogos de Element que bloquean la carga:
|
||||
* Maneja dialogos y toasts de Element que bloquean la carga:
|
||||
* - "Element is open in another window" → click Continue
|
||||
* - Spinner de carga → esperar
|
||||
* - "Missing session data" → error informativo
|
||||
* - "Notifications" toast → click Dismiss
|
||||
* - "Threads Activity Centre" toast → click OK
|
||||
* - Cualquier otro toast → intentar cerrarlo
|
||||
*
|
||||
* Llamar despues de page.goto("/")
|
||||
*/
|
||||
@@ -84,11 +87,53 @@ export async function handleElementDialogs(page: Page) {
|
||||
);
|
||||
}
|
||||
|
||||
// 3. Esperar a que rooms sidebar aparezca (sesion cargada)
|
||||
console.log("[element] Esperando rooms sidebar...");
|
||||
const roomsTree = page.locator('[role="tree"][aria-label="Rooms"]');
|
||||
await roomsTree.waitFor({ state: "visible", timeout: 30_000 });
|
||||
console.log("[element] Rooms sidebar visible");
|
||||
// 3. Esperar a que la sidebar aparezca (sesion cargada)
|
||||
// Usamos multiples locators porque Element Web cambia la estructura entre versiones
|
||||
console.log("[element] Esperando sidebar con rooms...");
|
||||
const sidebarLocators = [
|
||||
page.locator('[role="tree"][aria-label="Rooms"]'),
|
||||
page.locator(".mx_RoomList"),
|
||||
page.locator(".mx_LeftPanel_roomListContainer"),
|
||||
page.locator('[role="treeitem"]'),
|
||||
// Rooms visibles como items en el sidebar
|
||||
page.locator(".mx_RoomTile"),
|
||||
];
|
||||
|
||||
let sidebarFound = false;
|
||||
for (const locator of sidebarLocators) {
|
||||
const visible = await locator.first()
|
||||
.waitFor({ state: "visible", timeout: 30_000 })
|
||||
.then(() => true)
|
||||
.catch(() => false);
|
||||
if (visible) {
|
||||
console.log("[element] Sidebar visible");
|
||||
sidebarFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sidebarFound) {
|
||||
// Verificar si estamos en la pagina de login
|
||||
const onLoginPage = await page.locator('text="Welcome to Element!"').isVisible().catch(() => false)
|
||||
|| await page.getByRole("link", { name: "Sign in" }).isVisible().catch(() => false);
|
||||
|
||||
if (onLoginPage) {
|
||||
throw new Error(
|
||||
"Sesion no cargada: se muestra la pagina de login. " +
|
||||
"Borrar .auth/ y re-ejecutar: rm -rf e2e/.auth && ./dev-scripts/e2e/run.sh"
|
||||
);
|
||||
}
|
||||
|
||||
await page.screenshot({
|
||||
path: "test-results/ERROR-no-sidebar.png",
|
||||
fullPage: true,
|
||||
});
|
||||
throw new Error("Sidebar de rooms no encontrado despues de 30s");
|
||||
}
|
||||
|
||||
// 4. Cerrar TODOS los toasts que bloquean interacciones
|
||||
await dismissAllToasts(page);
|
||||
}
|
||||
|
||||
export { dismissAllToasts } from "./element-utils";
|
||||
export { expect } from "@playwright/test";
|
||||
|
||||
Reference in New Issue
Block a user