const { chromium } = require(process.argv[2] || "playwright"); const assert = require("node:assert/strict"); const fs = require("node:fs"); const path = require("node:path"); (async () => { const browser = await chromium.launch({ channel: "msedge", headless: true }); const page = await browser.newPage({ viewport: { width: 1440, height: 1000 } }); const errors = []; page.on("pageerror", error => errors.push(error.stack || error.message)); const artifacts = path.join(__dirname, "../artifacts/zones-check"); fs.mkdirSync(artifacts, { recursive: true }); try { await page.goto("http://127.0.0.1:5199", { waitUntil: "domcontentloaded" }); await page.waitForFunction(() => !!window.rt?._dotNetHelper && !!window.__rtLeafletMap); const initialErrors = errors.slice(); await page.keyboard.press("Control+Shift+KeyE"); await page.locator(".zones-panel").waitFor(); await page.waitForTimeout(1000); await page.getByRole("button", { name: "Polígono", exact: true }).click(); await page.getByRole("button", { name: "Añadir zona", exact: true }).click(); for (const [x, y] of [[600, 420], [850, 430], [760, 640]]) { await page.mouse.click(x, y); await page.waitForTimeout(250); } await page.getByRole("button", { name: "Cerrar zona", exact: true }).click(); await page.getByRole("button", { name: "Añadir zona", exact: true }).waitFor(); assert.equal(await page.locator(".zones-panel__item").count(), 1); assert.equal(await page.locator(".rt-exclusion-vertex").count(), 3); assert.equal(Math.round((await page.locator(".rt-exclusion-vertex").first().boundingBox()).width), 10); const polygon = page.locator('path[stroke="#e879f9"]'); const previousShape = await polygon.getAttribute("d"); const marker = await page.locator(".rt-exclusion-vertex").first().boundingBox(); await page.mouse.move(marker.x + marker.width / 2, marker.y + marker.height / 2); await page.mouse.down(); await page.mouse.move(marker.x - 55, marker.y + 65, { steps: 10 }); assert.notEqual(await polygon.getAttribute("d"), previousShape, "Poligono se mueve durante el arrastre"); await page.mouse.up(); await page.waitForTimeout(250); await page.getByRole("button", { name: "Añadir zona", exact: true }).click(); for (const [x, y] of [[920, 460], [1090, 460], [1020, 640]]) { await page.mouse.click(x, y); await page.waitForTimeout(250); } await page.getByRole("button", { name: "Cerrar zona", exact: true }).click(); await page.getByRole("button", { name: "Añadir zona", exact: true }).waitFor(); assert.equal(await page.locator(".zones-panel__item").count(), 2); await page.screenshot({ path: path.join(artifacts, "desktop.png") }); const heights = await page.locator(".zones-panel__actions .btn-ghost").evaluateAll( buttons => buttons.map(button => button.getBoundingClientRect().height)); assert.equal(new Set(heights).size, 1, "Botones de igual altura"); await page.getByRole("button", { name: "Cerrar herramienta", exact: true }).click(); await page.locator(".zones-panel").waitFor({ state: "detached" }); assert.equal(await page.locator(".rt-exclusion-vertex").count(), 0); assert.equal(await page.locator('path[stroke="#e879f9"], path[stroke="#f97316"]').count(), 0); await page.keyboard.press("Control+Shift+KeyE"); await page.locator(".zones-panel").waitFor(); assert.equal(await page.locator(".zones-panel__item").count(), 2, "Reabrir conserva zonas editables"); await page.getByRole("checkbox", { name: "Activar zona", exact: true }).first().uncheck(); await page.waitForFunction(() => JSON.parse(localStorage.getItem("rutasdbus.zonas.v1"))[0].Activa === false); await page.reload(); await page.waitForFunction(() => !!window.rt?._dotNetHelper && !!window.__rtLeafletMap); await page.waitForTimeout(1000); await page.keyboard.press("Control+Shift+KeyE"); await page.locator(".zones-panel__item").first().waitFor(); assert.equal(await page.locator(".zones-panel__item").count(), 2, "F5 conserva zonas"); assert.equal(await page.getByRole("checkbox", { name: "Activar zona", exact: true }).first().isChecked(), false); const panelBefore = await page.locator(".zones-panel").boundingBox(); const header = await page.locator(".zones-panel .draggable-popup-handle").boundingBox(); await page.mouse.move(header.x + 40, header.y + 15); await page.mouse.down(); await page.mouse.move(header.x + 190, header.y + 65, { steps: 10 }); await page.mouse.up(); const panelAfter = await page.locator(".zones-panel").boundingBox(); assert.ok(Math.abs(panelAfter.x - panelBefore.x) > 50, "El modal se arrastra"); await page.screenshot({ path: path.join(artifacts, "persistencia-arrastre.png") }); await page.keyboard.press("Control+Shift+KeyF"); await page.getByRole("dialog", { name: "Guardar valores predeterminados" }).waitFor(); assert.ok(await page.getByRole("button", { name: "Guardar y sustituir", exact: true }).isVisible()); await page.screenshot({ path: path.join(artifacts, "confirmacion-fabrica.png") }); await page.getByRole("button", { name: "Cancelar", exact: true }).click(); await page.getByRole("button", { name: "Eliminar zona", exact: true }).first().click(); await page.waitForFunction(() => document.querySelectorAll(".zones-panel__item").length === 1); assert.equal(await page.locator(".zones-panel__item").count(), 1); await page.getByRole("button", { name: "Punto", exact: true }).click(); await page.getByRole("button", { name: "Añadir punto", exact: true }).click(); await page.mouse.click(1050, 720); await page.waitForFunction(() => document.querySelectorAll(".zones-panel__item").length === 2); assert.match(await page.locator(".zones-panel__item").last().innerText(), /Punto/); assert.equal(await page.locator(".zones-panel__item").last().innerText().then(text => text.includes("abierta")), false, "Un clic cierra la exclusion puntual"); const puntoGuardado = await page.evaluate(() => JSON.parse(localStorage.getItem("rutasdbus.zonas.v1")).at(-1)); assert.equal(puntoGuardado.EsPunto, true); assert.equal(puntoGuardado.Vertices.length, 1, "El punto se guarda con un solo vertice"); await page.getByRole("button", { name: "Borrar todas", exact: true }).click(); await page.waitForFunction(() => document.querySelectorAll(".zones-panel__item").length === 0); assert.equal(await page.locator(".zones-panel__item").count(), 0); await page.setViewportSize({ width: 390, height: 844 }); await page.screenshot({ path: path.join(artifacts, "mobile.png") }); const box = await page.locator(".zones-panel").boundingBox(); assert.ok(box.x >= 0 && box.x + box.width <= 390 && box.y + box.height <= 844, "Panel dentro del movil"); await page.getByRole("button", { name: "Polígono", exact: true }).click(); await page.getByRole("button", { name: "Añadir zona", exact: true }).click(); await page.getByRole("button", { name: "Cerrar herramienta", exact: true }).click(); await page.setViewportSize({ width: 1440, height: 1000 }); await page.getByTitle("Configuración", { exact: true }).click(); assert.equal(await page.locator(".config-more-menu").count(), 0, "No hay opcion para guardar valores de fabrica"); const externalErrors = errors.filter(error => error.includes("esri-leaflet-geocoder@3.1.4/dist/esri-leaflet-geocoder.js") && error.includes("reading 'extend'")); const newErrors = errors.filter(error => !initialErrors.includes(error) && !externalErrors.includes(error)); assert.equal(newErrors.length, 0, newErrors.join("\n")); if (externalErrors.length) console.log("Aviso del complemento externo de geocodificacion: " + externalErrors[0]); console.log("OK poligonos y puntos, arrastre en vivo, cierre, reapertura, borrado, alturas de botones y movil"); } finally { await browser.close(); } })().catch(error => { console.error(error); process.exitCode = 1; });