diff --git a/scripts/src/hwlab-node-web-sentinel-cicd.ts b/scripts/src/hwlab-node-web-sentinel-cicd.ts index 7f351a20..ee55e34a 100644 --- a/scripts/src/hwlab-node-web-sentinel-cicd.ts +++ b/scripts/src/hwlab-node-web-sentinel-cicd.ts @@ -2240,6 +2240,28 @@ const dom = await page.evaluate(() => { const panes = Array.from(document.querySelectorAll(".workspace-grid .pane")); const detailPane = document.querySelector(".workspace-grid .pane-detail"); const detailHeader = document.querySelector("#monitor-web-root > div > section.workspace-grid > main > div.pane-header"); + const internalTextPattern = /水合|投影|Trace|trace|Shell|API|DOM|Console|console|Runner|runner|JSONL|steer|facts|分页|HTTP|http|requestfailed|pageerror|Final Response|Code Agent|web-probe|observe|analyzer|终态/u; + const cards = Array.from(document.querySelectorAll(".finding-card")).slice(0, 8).map((card) => ({ + code: String(card.querySelector(".check-code")?.textContent || "").trim(), + title: String(card.querySelector("strong")?.textContent || "").trim(), + body: String(card.textContent || "").replace(/\s+/g, " ").trim().slice(0, 180), + })); + const badCardTitles = cards.filter((card) => internalTextPattern.test(card.title)); + const badCardBodies = cards.filter((card) => internalTextPattern.test(card.body)); + const legendTexts = Array.from(document.querySelectorAll(".trend-legend .legend-item")).map((item) => String(item.textContent || "").replace(/\s+/g, " ").trim()); + const legendNumber = (label) => { + const row = legendTexts.find((item) => item.includes(label)) || ""; + const match = /(\d+)/u.exec(row); + return match ? Number(match[1]) : null; + }; + const chartCounts = { + error: legendNumber("错误"), + warning: legendNumber("警告"), + total: legendNumber("错误+警告合计"), + }; + chartCounts.ok = typeof chartCounts.error === "number" && typeof chartCounts.warning === "number" && typeof chartCounts.total === "number" + ? chartCounts.total === chartCounts.error + chartCounts.warning + : false; const doc = document.documentElement; const body = document.body; const viewport = { width: window.innerWidth, height: window.innerHeight }; @@ -2287,10 +2309,17 @@ const dom = await page.evaluate(() => { summaryText: text(".status-strip"), runRows: document.querySelectorAll(".run-list .run-row").length, findingItems: document.querySelectorAll(".finding-list .finding-card").length, + firstCards: cards, + badCardTitleCount: badCardTitles.length, + badCardBodyCount: badCardBodies.length, + badCardTitles, + badCardBodies, trendCurve: Boolean(trend), trendDotCount: document.querySelectorAll(".trend-dot-hit").length, trendTooltip: tooltipSummary(trendTooltip), trendPanelText: text("#trend-heading"), + legendTexts, + chartCounts, timelineItems: document.querySelectorAll(".timeline-list .timeline-item").length, timelineVisible: Boolean(timeline), errorVisible: visible(error), @@ -2332,7 +2361,7 @@ const dom = await page.evaluate(() => { return { visible: Boolean(element && body.length > 0), text: body.slice(0, 240), - hasValues: /红色\s+\d+/u.test(body) && /警告\s+\d+/u.test(body) && /总量\s+\d+/u.test(body), + hasValues: /错误\s+\d+/u.test(body) && /警告\s+\d+/u.test(body) && /合计\s+\d+/u.test(body), hasTime: /UTC/u.test(body) || /\d{4}-\d{2}-\d{2}/u.test(body), }; } @@ -2377,7 +2406,10 @@ const ok = !navigationError && dom.ready === true && dom.errorVisible !== true && dom.trendCurve === true + && dom.chartCounts?.ok === true && (dom.trendDotCount === 0 || (dom.trendTooltip?.visible === true && dom.trendTooltip?.hasValues === true && dom.trendTooltip?.hasTime === true)) + && dom.badCardTitleCount === 0 + && dom.badCardBodyCount === 0 && dom.timelineVisible === true && dom.scrollModel?.independentScroll === true && dom.scrollModel?.stickyHeader?.present === true @@ -4670,6 +4702,7 @@ function renderDashboardResult(result: Record): string { const dom = record(page.dom); const dataset = record(dom.dataset); const layout = record(dom.layout); + const chartCounts = record(dom.chartCounts); const screenshot = record(result.screenshot); const remote = record(result.remote); const transport = record(result.transport); @@ -4692,6 +4725,15 @@ function renderDashboardResult(result: Record): string { "", table(["TITLE", "STATUS_TEXT", "CONTRACT", "BASE_PATH"], [[dom.title, dom.statusText, dataset.contractVersion, dataset.basePath ?? "-"]]), "", + table(["TREND_ERROR", "TREND_WARNING", "TREND_TOTAL", "TREND_EXACT", "BAD_TITLE", "BAD_BODY"], [[ + chartCounts.error ?? "-", + chartCounts.warning ?? "-", + chartCounts.total ?? "-", + chartCounts.ok ?? "-", + dom.badCardTitleCount ?? "-", + dom.badCardBodyCount ?? "-", + ]]), + "", table(["VIEWPORT", "DOC", "H_OVERFLOW", "OVERFLOW_COUNT"], [[ result.viewport, `${record(layout.documentSize).width ?? "-"}x${record(layout.documentSize).height ?? "-"}`,