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 { test as base, chromium, BrowserContext, Page } from "@playwright/test";
|
||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
|
import { dismissAllToasts } from "./element-utils";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom test fixture que usa un persistent browser context compartido.
|
* 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
|
* - "Element is open in another window" → click Continue
|
||||||
* - Spinner de carga → esperar
|
|
||||||
* - "Missing session data" → error informativo
|
* - "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("/")
|
* Llamar despues de page.goto("/")
|
||||||
*/
|
*/
|
||||||
@@ -84,11 +87,53 @@ export async function handleElementDialogs(page: Page) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Esperar a que rooms sidebar aparezca (sesion cargada)
|
// 3. Esperar a que la sidebar aparezca (sesion cargada)
|
||||||
console.log("[element] Esperando rooms sidebar...");
|
// Usamos multiples locators porque Element Web cambia la estructura entre versiones
|
||||||
const roomsTree = page.locator('[role="tree"][aria-label="Rooms"]');
|
console.log("[element] Esperando sidebar con rooms...");
|
||||||
await roomsTree.waitFor({ state: "visible", timeout: 30_000 });
|
const sidebarLocators = [
|
||||||
console.log("[element] Rooms sidebar visible");
|
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";
|
export { expect } from "@playwright/test";
|
||||||
|
|||||||
Reference in New Issue
Block a user