test: tighten workbench scroll and help smoke
Host closeout: reviewed diff, runner validation, and clean merge state. This is SOURCE/local browser smoke hardening for workbench scroll/help behavior only; no deploy, no secret access, and no M3/M4/M5 acceptance claim.
This commit is contained in:
@@ -451,6 +451,22 @@ async function runLiveSmoke(args) {
|
||||
});
|
||||
}
|
||||
|
||||
const help = http.ok ? await inspectLiveHelpRoute(args.url) : { status: "skip", summary: "Browser Markdown help check skipped because HTTP fetch failed.", evidence: [] };
|
||||
addCheck(checks, blockers, "live-help-markdown-route", help.status, help.summary, {
|
||||
blocker: help.status === "pass" ? null : "runtime_blocker",
|
||||
evidence: help.evidence,
|
||||
observations: help.observations
|
||||
});
|
||||
|
||||
if (help.status === "skip") {
|
||||
blockers.push({
|
||||
type: "observability_blocker",
|
||||
scope: "live-help-markdown-route",
|
||||
status: "open",
|
||||
summary: help.summary
|
||||
});
|
||||
}
|
||||
|
||||
const journey = http.ok ? await inspectLiveUserJourney(args.url) : { status: "skip", summary: "Browser Code Agent journey skipped because HTTP fetch failed.", evidence: [] };
|
||||
addCheck(checks, blockers, "live-code-agent-browser-journey", journey.status, journey.summary, {
|
||||
blocker: journey.status === "pass" ? null : "runtime_blocker",
|
||||
@@ -1467,7 +1483,7 @@ async function inspectLiveDom(url) {
|
||||
browser = await chromium.launch({ headless: true });
|
||||
const page = await browser.newPage({ viewport: { width: 1366, height: 768 } });
|
||||
await page.goto(url, { waitUntil: "domcontentloaded", timeout: 8000 });
|
||||
const dom = await page.evaluate(() => {
|
||||
const dom = await page.evaluate(async () => {
|
||||
const workspace = document.querySelector('[data-view="workspace"]');
|
||||
const gate = document.querySelector('[data-view="gate"]');
|
||||
const help = document.querySelector('[data-view="help"]');
|
||||
@@ -1482,6 +1498,15 @@ async function inspectLiveDom(url) {
|
||||
const box = element.getBoundingClientRect();
|
||||
return style.visibility !== "hidden" && style.display !== "none" && box.width > 0 && box.height > 0;
|
||||
};
|
||||
window.scrollTo(0, 240);
|
||||
document.documentElement.scrollTop = 240;
|
||||
document.body.scrollTop = 240;
|
||||
await new Promise((resolve) => requestAnimationFrame(resolve));
|
||||
const rootAfterScrollAttempt = {
|
||||
windowScrollY: window.scrollY,
|
||||
htmlScrollTop: document.documentElement.scrollTop,
|
||||
bodyScrollTop: document.body.scrollTop
|
||||
};
|
||||
return {
|
||||
title: document.title,
|
||||
bodyOverflow: bodyStyle.overflow,
|
||||
@@ -1491,6 +1516,7 @@ async function inspectLiveDom(url) {
|
||||
helpHidden: help ? help.hidden : null,
|
||||
diagnosticsHidden: diagnostics ? diagnostics.hidden : null,
|
||||
outerScrollLocked: document.documentElement.scrollHeight <= document.documentElement.clientHeight + 2,
|
||||
rootAfterScrollAttempt,
|
||||
labelsPresent: ["硬件资源", "Agent 对话", "工作清单", "可信记录", "使用说明"].every((label) => text.includes(label)),
|
||||
coreControlsVisible: {
|
||||
commandInput: visible("#command-input"),
|
||||
@@ -1512,6 +1538,9 @@ async function inspectLiveDom(url) {
|
||||
(dom.helpHidden === true || dom.helpHidden === null) &&
|
||||
(dom.diagnosticsHidden === true || dom.diagnosticsHidden === null) &&
|
||||
dom.outerScrollLocked &&
|
||||
dom.rootAfterScrollAttempt.windowScrollY === 0 &&
|
||||
dom.rootAfterScrollAttempt.htmlScrollTop === 0 &&
|
||||
dom.rootAfterScrollAttempt.bodyScrollTop === 0 &&
|
||||
dom.labelsPresent &&
|
||||
Object.values(dom.coreControlsVisible).every(Boolean);
|
||||
return {
|
||||
@@ -1531,6 +1560,51 @@ async function inspectLiveDom(url) {
|
||||
}
|
||||
}
|
||||
|
||||
async function inspectLiveHelpRoute(url) {
|
||||
let chromium;
|
||||
try {
|
||||
({ chromium } = await import("playwright"));
|
||||
} catch (error) {
|
||||
return {
|
||||
status: "skip",
|
||||
summary: `Browser Markdown help check skipped because Playwright is unavailable: ${error.message}`,
|
||||
evidence: ["playwright import failed"]
|
||||
};
|
||||
}
|
||||
|
||||
let browser;
|
||||
try {
|
||||
browser = await chromium.launch({ headless: true });
|
||||
const page = await browser.newPage({ viewport: { width: 1366, height: 768 } });
|
||||
await page.goto(url, { waitUntil: "domcontentloaded", timeout: 12000 });
|
||||
await page.locator('[data-route="help"]').click();
|
||||
await page.waitForFunction(() => document.querySelector("#help-content")?.dataset.helpState === "ready", null, { timeout: 8000 });
|
||||
const help = await inspectHelpMarkdownRoute(page);
|
||||
const pass = help.nonDefaultMarkdownHelp && help.termsPresent;
|
||||
return {
|
||||
status: pass ? "pass" : "blocked",
|
||||
summary: pass
|
||||
? "Desktop browser help route remains non-default, markdown-rendered, and scrollable."
|
||||
: "Desktop browser help route did not satisfy the markdown workbench contract.",
|
||||
evidence: [
|
||||
`hash=${help.hash ?? "unknown"}`,
|
||||
`heading=${help.heading ?? "unknown"}`,
|
||||
`rootStillLocked=${help.rootStillLocked}`,
|
||||
`helpPanelScrolls=${help.helpPanelScrolls}`
|
||||
],
|
||||
observations: help
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
status: "blocked",
|
||||
summary: `Desktop browser help route failed: ${error.message}`,
|
||||
evidence: ["browser navigation or markdown render failed"]
|
||||
};
|
||||
} finally {
|
||||
if (browser) await browser.close();
|
||||
}
|
||||
}
|
||||
|
||||
async function inspectLiveUserJourney(url) {
|
||||
let chromium;
|
||||
try {
|
||||
|
||||
@@ -60,21 +60,27 @@ const requiredTrustedRecordTerms = Object.freeze([
|
||||
]);
|
||||
const workbenchSmoke = runDevCloudWorkbenchStaticSmoke();
|
||||
const helpSmokeCheck = workbenchSmoke.checks.find((check) => check.id === "help-md-contract");
|
||||
const outerScrollSmokeCheck = workbenchSmoke.checks.find((check) => check.id === "outer-scroll-contract");
|
||||
const mobileLayoutSmokeCheck = workbenchSmoke.checks.find((check) => check.id === "mobile-workbench-layout-contract");
|
||||
const conversationUxSmokeCheck = workbenchSmoke.checks.find((check) => check.id === "code-agent-conversation-ux-states");
|
||||
const mobileWorkbenchSmoke = await runDevCloudWorkbenchMobileSmoke();
|
||||
const mobileOuterScrollSmokeCheck = mobileWorkbenchSmoke.checks.find((check) => check.id === "mobile-outer-scroll-lock");
|
||||
const mobileHelpSmokeCheck = mobileWorkbenchSmoke.checks.find((check) => check.id === "mobile-help-markdown-route");
|
||||
const localAgentFixtureSmoke = await runDevCloudWorkbenchLocalAgentFixtureSmoke();
|
||||
|
||||
assert.equal(workbenchSmoke.status, "pass", JSON.stringify(workbenchSmoke.blockers, null, 2));
|
||||
assert.equal(workbenchSmoke.evidenceLevel, "SOURCE");
|
||||
assert.equal(workbenchSmoke.devLive, false);
|
||||
assert.equal(helpSmokeCheck?.status, "pass", "PR #114 help Markdown route must be present and ready");
|
||||
assert.equal(outerScrollSmokeCheck?.status, "pass", "desktop workbench shell must lock outer page scrolling");
|
||||
assert.equal(mobileLayoutSmokeCheck?.status, "pass", "mobile 390x844 workbench layout contract must be present");
|
||||
assert.equal(conversationUxSmokeCheck?.status, "pass", "Code Agent conversation UX states must remain distinct");
|
||||
assert.equal(workbenchSmoke.help.status, "pass", "smoke report must not leave #114 help contract pending");
|
||||
assert.notEqual(mobileWorkbenchSmoke.status, "blocked", JSON.stringify(mobileWorkbenchSmoke.blockers, null, 2));
|
||||
assert.equal(mobileWorkbenchSmoke.evidenceLevel, "SOURCE");
|
||||
assert.equal(mobileWorkbenchSmoke.devLive, false);
|
||||
assert.equal(mobileOuterScrollSmokeCheck?.status, "pass", "mobile smoke must prove outer page scroll remains locked");
|
||||
assert.equal(mobileHelpSmokeCheck?.status, "pass", "mobile help route must remain non-default Markdown content");
|
||||
assert.equal(localAgentFixtureSmoke.status, "pass", JSON.stringify(localAgentFixtureSmoke.blockers, null, 2));
|
||||
assert.equal(localAgentFixtureSmoke.evidenceLevel, "SOURCE");
|
||||
assert.equal(localAgentFixtureSmoke.devLive, false);
|
||||
|
||||
Reference in New Issue
Block a user