fix: 修复工作区状态构建明细浮层
This commit is contained in:
@@ -1140,6 +1140,12 @@ export async function runDevCloudWorkbenchLayoutSmoke(args = {}) {
|
||||
summary: "#352 default workbench has no aside#resource-explorer, #explorer-resize, resource tree/capability copy, or reclaimed left panel across desktop and mobile.",
|
||||
observations: summarizeResourceExplorerRemovalCoverage(viewportResults)
|
||||
},
|
||||
{
|
||||
id: "layout-feedback-437-live-build-overlay",
|
||||
status: allViewportCoverage(viewportResults, "liveBuildOverlayStable") ? "pass" : "blocked",
|
||||
summary: "#437 workbench status build details open as an overlay without changing the topbar, workspace, or conversation geometry across desktop and mobile.",
|
||||
observations: summarizeCoverageGap(viewportResults, "liveBuildOverlay")
|
||||
},
|
||||
{
|
||||
id: "layout-left-sidebar-collapse",
|
||||
status: Object.values(viewportResults).every((result) => result.leftCollapse?.pass) ? "pass" : "blocked",
|
||||
@@ -1271,7 +1277,7 @@ export async function runDevCloudWorkbenchLayoutSmoke(args = {}) {
|
||||
summary: useLiveUrl
|
||||
? "Live browser layout smoke verifies workbench layout, hit targets, overflow, /gate usability, and the two-column wiring panel only; it is not M3 hardware acceptance."
|
||||
: "Static local browser layout smoke verifies workbench layout, hit targets, overflow, /gate usability, and the two-column wiring panel only; deployment still requires DEV live verification.",
|
||||
refs: ["pikasTech/HWLAB#273", "pikasTech/HWLAB#276", "pikasTech/HWLAB#278", "pikasTech/HWLAB#287", "pikasTech/HWLAB#288", "pikasTech/HWLAB#352", "pikasTech/HWLAB#99", "pikasTech/HWLAB#227"],
|
||||
refs: ["pikasTech/HWLAB#273", "pikasTech/HWLAB#276", "pikasTech/HWLAB#278", "pikasTech/HWLAB#287", "pikasTech/HWLAB#288", "pikasTech/HWLAB#352", "pikasTech/HWLAB#437", "pikasTech/HWLAB#239", "pikasTech/HWLAB#99", "pikasTech/HWLAB#227"],
|
||||
viewports: layoutViewports.map(({ id, width, height }) => ({ id, width, height })),
|
||||
checks,
|
||||
blockers,
|
||||
@@ -3171,22 +3177,26 @@ async function inspectLiveDom(url, options = {}) {
|
||||
liveBuildListVisibleWhenClosed: visible("#live-build-list"),
|
||||
liveBuildDetailWhenOpen: (() => {
|
||||
const details = document.querySelector("#live-build-summary");
|
||||
const popover = document.querySelector("#live-build-popover");
|
||||
const list = document.querySelector("#live-build-list");
|
||||
if (!details || !list) {
|
||||
if (!details || !popover || !list) {
|
||||
return {
|
||||
visible: false,
|
||||
rows: 0,
|
||||
scrollContained: false,
|
||||
overlay: false,
|
||||
text: "",
|
||||
overflowX: 0
|
||||
};
|
||||
}
|
||||
details.open = true;
|
||||
const popoverStyle = getComputedStyle(popover);
|
||||
const rows = [...list.querySelectorAll(".live-build-row")];
|
||||
return {
|
||||
visible: visible("#live-build-list"),
|
||||
rows: rows.length,
|
||||
scrollContained: list.clientHeight <= Math.ceil(window.innerHeight * 0.42) + 4,
|
||||
scrollContained: list.clientHeight <= Math.ceil(window.innerHeight * 0.58) + 4,
|
||||
overlay: popoverStyle.position === "absolute",
|
||||
text: list.textContent?.replace(/\s+/gu, " ").trim() ?? "",
|
||||
overflowX: Math.max(0, ...rows.map((row) => row.scrollWidth - row.clientWidth), list.scrollWidth - list.clientWidth)
|
||||
};
|
||||
@@ -7830,36 +7840,103 @@ async function inspectLayoutState(page, { mode, viewport, compareTo }) {
|
||||
const inspectLiveBuildLayout = async () => {
|
||||
const details = document.querySelector("#live-build-summary");
|
||||
const label = document.querySelector("#live-build-latest");
|
||||
const toggle = document.querySelector("#live-build-toggle");
|
||||
const popover = document.querySelector("#live-build-popover");
|
||||
const list = document.querySelector("#live-build-list");
|
||||
if (!details || !label || !list) {
|
||||
const topbar = document.querySelector(".topbar");
|
||||
const workspace = document.querySelector('[data-view="workspace"]');
|
||||
const conversation = document.querySelector(".conversation-column");
|
||||
const boxSnapshot = () => ({
|
||||
topbar: boxForElement(topbar),
|
||||
workspace: boxForElement(workspace),
|
||||
conversation: boxForElement(conversation)
|
||||
});
|
||||
if (!details || !label || !toggle || !popover || !list || !topbar || !workspace || !conversation) {
|
||||
return { ok: false, exists: false, summaryOverflowX: null, listOverflowX: null, maxRowOverflowX: null, rows: 0 };
|
||||
}
|
||||
const wasOpen = details.open;
|
||||
const labelBox = boxForElement(label);
|
||||
const detailsBox = boxForElement(details);
|
||||
const labelStyle = getComputedStyle(label);
|
||||
const summaryOverflowX = Math.max(0, label.scrollWidth - label.clientWidth);
|
||||
const summaryContained =
|
||||
Boolean(labelBox && detailsBox) &&
|
||||
labelBox.left >= detailsBox.left - 1 &&
|
||||
labelBox.right <= detailsBox.right + 1 &&
|
||||
labelStyle.overflow === "hidden" &&
|
||||
labelStyle.textOverflow === "ellipsis" &&
|
||||
labelStyle.whiteSpace === "nowrap";
|
||||
details.open = false;
|
||||
await new Promise((resolve) => requestAnimationFrame(resolve));
|
||||
const before = boxSnapshot();
|
||||
details.open = true;
|
||||
await new Promise((resolve) => requestAnimationFrame(resolve));
|
||||
const rows = [...list.querySelectorAll(".live-build-row")];
|
||||
const rowOverflows = rows.map((row) => Math.max(0, row.scrollWidth - row.clientWidth));
|
||||
const maxRowOverflowX = Math.max(0, ...rowOverflows);
|
||||
const listOverflowX = Math.max(0, list.scrollWidth - list.clientWidth);
|
||||
const scrollContained = list.clientHeight <= Math.ceil(window.innerHeight * 0.42) + 4;
|
||||
const popoverBox = boxForElement(popover);
|
||||
const popoverStyle = getComputedStyle(popover);
|
||||
const toggleExpanded = toggle.getAttribute("aria-expanded") === "true";
|
||||
const popoverVisible = popoverBox && popoverBox.width > 0 && popoverBox.height > 0 && popoverStyle.display !== "none";
|
||||
const popoverViewportContained =
|
||||
Boolean(popoverBox) &&
|
||||
popoverBox.left >= -1 &&
|
||||
popoverBox.right <= window.innerWidth + 1 &&
|
||||
popoverBox.top >= -1 &&
|
||||
popoverBox.bottom <= window.innerHeight + 1;
|
||||
const overlayPositioned = popoverStyle.position === "absolute";
|
||||
const scrollContained = list.clientHeight <= Math.ceil(window.innerHeight * 0.58) + 4;
|
||||
const text = list.textContent?.replace(/\s+/gu, " ").trim() ?? "";
|
||||
const expectedRows = rows.length >= 4;
|
||||
const expectedText = /构建时间不可用/u.test(text) && /外部镜像或非 HWLAB 构建产物/u.test(text);
|
||||
const afterOpen = boxSnapshot();
|
||||
const stableGeometry = ["topbar", "workspace", "conversation"].every((key) => {
|
||||
const a = before[key];
|
||||
const b = afterOpen[key];
|
||||
return a && b && Math.abs(a.top - b.top) <= 1 && Math.abs(a.height - b.height) <= 1;
|
||||
});
|
||||
document.querySelector("#live-build-close")?.click();
|
||||
await new Promise((resolve) => requestAnimationFrame(resolve));
|
||||
const closedByButton = details.open === false && toggle.getAttribute("aria-expanded") === "false";
|
||||
details.open = wasOpen;
|
||||
await new Promise((resolve) => requestAnimationFrame(resolve));
|
||||
return {
|
||||
ok: summaryOverflowX <= 1 && listOverflowX <= 1 && maxRowOverflowX <= 1 && scrollContained && expectedRows && expectedText,
|
||||
ok:
|
||||
summaryContained &&
|
||||
listOverflowX <= 1 &&
|
||||
maxRowOverflowX <= 1 &&
|
||||
scrollContained &&
|
||||
expectedRows &&
|
||||
expectedText &&
|
||||
overlayPositioned &&
|
||||
popoverVisible &&
|
||||
popoverViewportContained &&
|
||||
toggleExpanded &&
|
||||
stableGeometry &&
|
||||
closedByButton,
|
||||
exists: true,
|
||||
openStateRestored: details.open === wasOpen,
|
||||
summaryContained,
|
||||
summaryOverflowX,
|
||||
labelBox,
|
||||
detailsBox,
|
||||
listOverflowX,
|
||||
maxRowOverflowX,
|
||||
rowOverflows,
|
||||
rows: rows.length,
|
||||
expectedRows,
|
||||
expectedText,
|
||||
overlayPositioned,
|
||||
popoverVisible,
|
||||
popoverViewportContained,
|
||||
toggleExpanded,
|
||||
scrollContained,
|
||||
stableGeometry,
|
||||
closedByButton,
|
||||
before,
|
||||
afterOpen,
|
||||
popoverBox,
|
||||
textSample: text.slice(0, 240)
|
||||
};
|
||||
};
|
||||
@@ -8231,6 +8308,7 @@ async function inspectLayoutState(page, { mode, viewport, compareTo }) {
|
||||
rightResizeHandle,
|
||||
sidePanelScroll,
|
||||
sidePanelOverflowUsable,
|
||||
liveBuildOverlayStable: liveBuildLayout.ok,
|
||||
hardwareTabsCenterHit,
|
||||
wiring: {
|
||||
longTableOk: wiringLongTableOk,
|
||||
@@ -8640,7 +8718,8 @@ function summarizeCoverageGap(viewportResults, issueKey) {
|
||||
issue288: "issue288SingleTableReady",
|
||||
issue287: "issue287HardwareTabsReady",
|
||||
hardwareTabs: "hardwareTabsCenterHit",
|
||||
wiring: "wiringReadableTwoColumn"
|
||||
wiring: "wiringReadableTwoColumn",
|
||||
liveBuildOverlay: "liveBuildOverlayStable"
|
||||
}[issueKey] ?? "issue287HardwareTabsReady";
|
||||
return {
|
||||
status: allViewportCoverage(viewportResults, fieldName) ? "pass" : "skip",
|
||||
|
||||
Reference in New Issue
Block a user