Files
canvas-frontend/qa/_measure_topbar.mjs
canvas-bot 8d85a4c3ea
build-and-publish / test (push) Has been cancelled
build-and-publish / image (push) Has been cancelled
fix(login): do not block login completion on EA2 scenario fetch
If buildLiveScenariosFromApi hangs or errors on any EA2 read,
loginAs would await it forever, leaving the user stuck on
'VERIFYING...' even after auth+identity succeed. Make refreshLive
fire-and-forget after the toast; the Mission scene re-fetches
on mount and surfaces failures via liveError.
2026-06-15 19:13:13 +04:00

66 lines
2.5 KiB
JavaScript

// DOM-introspection — measure topbar item count, sizes, overlap.
import { chromium } from "playwright";
const URL = "https://canvas.flow-master.ai/";
const b = await chromium.launch({ headless: true });
const ctx = await b.newContext({ viewport: { width: 1440, height: 900 } });
const p = await ctx.newPage();
await ctx.addInitScript(() => localStorage.setItem("fm.canvas.tour.seen", String(Date.now())));
await p.goto(URL, { waitUntil: "domcontentloaded" });
await p.waitForTimeout(2500);
console.log("=== LOGIN PAGE ===");
const loginHas = await p.evaluate(() => ({
topbar: !!document.querySelector(".topbar"),
personaChips: document.querySelectorAll(".persona-chip").length,
ssoBtn: !!document.querySelector(".sso-btn"),
emailInput: !!document.querySelector("input[type='email']"),
banner: document.querySelector(".global-banner, .login-banner")?.textContent?.slice(0, 100) || null,
}));
console.log(JSON.stringify(loginHas, null, 2));
console.log("\n=== POST-LOGIN ===");
await p.locator(".persona-chip").filter({ hasText: /Mariana/ }).click();
await p.waitForSelector(".topbar", { timeout: 15000 }).catch(() => {});
await p.waitForTimeout(3000);
const topbar = await p.evaluate(() => {
const tb = document.querySelector(".topbar");
if (!tb) return null;
const items = Array.from(tb.children).map((el) => ({
tag: el.tagName.toLowerCase(),
class: el.className,
text: el.textContent?.trim().slice(0, 50),
width: el.getBoundingClientRect().width,
}));
const tabs = Array.from(tb.querySelectorAll(".tab")).map((el) => el.textContent?.trim());
const actions = Array.from(tb.querySelectorAll(".topbar-actions > *")).map((el) => ({
tag: el.tagName.toLowerCase(),
class: el.className.slice(0, 40),
text: el.textContent?.trim().slice(0, 30),
}));
return {
totalWidth: tb.getBoundingClientRect().width,
children: items,
tabs,
actionsCount: actions.length,
actions,
overflows: tb.scrollWidth > tb.clientWidth,
};
});
console.log(JSON.stringify(topbar, null, 2));
console.log("\n=== USER MENU ===");
await p.locator(".user-avatar").first().click().catch(() => {});
await p.waitForTimeout(800);
const menu = await p.evaluate(() => {
const m = document.querySelector(".user-menu-pop");
if (!m) return { open: false };
const items = Array.from(m.querySelectorAll(".user-menu-item")).map((el) => el.textContent?.trim().slice(0, 50));
return { open: true, items, width: m.getBoundingClientRect().width };
});
console.log(JSON.stringify(menu, null, 2));
await b.close();