// «Reproducir demo»: revelado paso a paso, detener, velocidad y autoPulsar. import { test, expect, estado, filasChat, cargarEstado, rapido } from "./fixtures.mjs"; const btn = (page) => page.locator("#btn-reproducir"); const GUION_CORTO = { version: 1, tema: "claro", cuenta: { nombre: "Demo corta", verificado: false }, mensajes: [ { id: "m1", dir: "in", tipo: "text", hora: "10:00", texto: "Hola" }, { id: "m2", dir: "out", tipo: "text", hora: "10:01", texto: "Buenas", estado: "read" }, { id: "m3", dir: "in", tipo: "buttons", hora: "10:02", body: "¿Qué quieres?", autoPulsar: 1, botones: [ { texto: "Precios", respuestas: [] }, { texto: "Horario", respuestas: [{ id: "m4", dir: "in", tipo: "text", hora: "10:02", texto: "Abrimos a las 9" }] }, ], }, ], }; test.describe("Reproducir demo", () => { test("vacía el chat, revela los mensajes uno a uno y termina sola", async ({ app }) => { await cargarEstado(app, GUION_CORTO); await rapido(app); // al arrancar el chat se vacía al instante (solo quedan los avisos de sistema) const filasTrasClic = await app.evaluate(() => { document.getElementById("btn-reproducir").click(); return document.querySelectorAll("#chat-cuerpo > li.wa-row").length; }); expect(filasTrasClic).toBe(0); await expect(btn(app)).toHaveAttribute("aria-pressed", "true"); await expect(btn(app)).toContainText("Detener"); // «escribiendo…» antes del primer IN await expect(app.locator("#chat-escribiendo")).toBeVisible(); await expect(filasChat(app)).toHaveCount(1, { timeout: 3000 }); await expect(filasChat(app).nth(0)).toContainText("Hola"); await expect(filasChat(app)).toHaveCount(3, { timeout: 5000 }); // autoPulsar: pulsa sola «Horario» y llega su respuesta await expect(app.locator('#chat-cuerpo li.out[data-id^="s"]')).toContainText("Horario", { timeout: 5000 }); await expect(app.locator('#chat-cuerpo li.in[data-id^="s"]')).toContainText("Abrimos a las 9", { timeout: 6000 }); await expect.poll(() => app.evaluate(() => WAM.demoActiva()), { timeout: 10000 }).toBe(false); await expect(btn(app)).toContainText("Reproducir demo"); await expect(btn(app)).toHaveAttribute("aria-pressed", "false"); }); test("pulsar de nuevo la detiene y vuelve al guion completo", async ({ app }) => { const n = (await estado(app)).mensajes.length; await btn(app).click(); await expect.poll(() => filasChat(app).count(), { timeout: 4000 }).toBeGreaterThan(0); await app.waitForTimeout(400); // evita el antirrebote de doble clic await btn(app).click(); await expect(btn(app)).toContainText("Reproducir demo"); await expect(filasChat(app)).toHaveCount(n); expect(await app.evaluate(() => WAM.demoActiva())).toBe(false); // nada sigue apareciendo después de detener await app.waitForTimeout(1500); await expect(filasChat(app)).toHaveCount(n); }); test("un doble clic no arranca y detiene en el mismo gesto", async ({ app }) => { await btn(app).dblclick(); expect(await app.evaluate(() => WAM.demoActiva())).toBe(true); await app.waitForTimeout(400); await btn(app).click(); }); test("la barra espaciadora (fuera de campos) alterna la demo", async ({ app }) => { await app.locator("#iphone").click({ position: { x: 5, y: 400 } }); await app.keyboard.press("Space"); await expect.poll(() => app.evaluate(() => WAM.demoActiva())).toBe(true); await app.waitForTimeout(400); await app.keyboard.press("Space"); await expect.poll(() => app.evaluate(() => WAM.demoActiva())).toBe(false); }); test("la velocidad se elige en el selector y persiste", async ({ app }) => { await app.locator("#sel-velocidad").selectOption("2"); expect(await app.evaluate(() => WAM.getVelocidad())).toBe(2); await app.reload(); await expect(app.locator("#sel-velocidad")).toHaveValue("2"); await app.locator("#sel-velocidad").selectOption("0.5"); expect(await app.evaluate(() => WAM.getVelocidad())).toBe(0.5); }); test("a 2x la demo es más rápida que a 0,5x", async ({ app }) => { await cargarEstado(app, { ...GUION_CORTO, mensajes: GUION_CORTO.mensajes.slice(0, 2) }); const medir = async (v) => { await app.evaluate((x) => WAM.setVelocidad(x), v); const t0 = Date.now(); await btn(app).click(); await expect.poll(() => app.evaluate(() => WAM.demoActiva()), { timeout: 15000, intervals: [50] }).toBe(false); await app.waitForTimeout(400); return Date.now() - t0; }; const lenta = await medir(0.5); const rapida = await medir(2); expect(rapida).toBeLessThan(lenta); }); test("editar el guion durante la demo la cancela sin errores", async ({ app }) => { await btn(app).click(); await expect.poll(() => filasChat(app).count(), { timeout: 4000 }).toBeGreaterThan(0); await app.locator('#nuevo-tipo [data-tipo="text"]').click(); await expect.poll(() => app.evaluate(() => WAM.demoActiva())).toBe(false); const n = (await estado(app)).mensajes.length; await expect(filasChat(app)).toHaveCount(n); await expect(btn(app)).toContainText("Reproducir demo"); }); });