fix: 修复DOCX独立封面视觉门禁
统一 Chromium 与 DOCX 的受限高度封面布局,补齐可编辑边框、装饰边和 Office 页面舍入适配。 按四套独立封面主题、纵横方向及五组页边距执行 40 个 Word/WPS 真实视觉场景,严格失败为 0,并保留正文诊断供 D4 修复。
This commit is contained in:
@@ -58,9 +58,13 @@ const matrixDefinition = summarizeDocxLayoutVisualMatrix(
|
||||
|
||||
const selectedCaseId =
|
||||
process.env.MD_TO_PDF_LAYOUT_VISUAL_CASE?.trim() || undefined;
|
||||
const selectedScope =
|
||||
process.env.MD_TO_PDF_LAYOUT_VISUAL_SCOPE?.trim() || "full";
|
||||
const selectedCases = selectedCaseId
|
||||
? cases.filter((entry) => entry.id === selectedCaseId)
|
||||
: cases;
|
||||
: selectedScope === "cover"
|
||||
? cases.filter((entry) => entry.coverPageCount > 0)
|
||||
: cases;
|
||||
|
||||
function assert(condition, message) {
|
||||
if (!condition) {
|
||||
@@ -287,6 +291,17 @@ function reportGateFailures(report, label) {
|
||||
return failures;
|
||||
}
|
||||
|
||||
function reportCoverGateFailures(report, label) {
|
||||
return getBlockingVisualDiffIssues(report)
|
||||
.filter(
|
||||
(issue) =>
|
||||
issue.code === "COVER_LAYOUT_MISMATCH" ||
|
||||
issue.baselinePageNumber === 1 ||
|
||||
issue.candidatePageNumber === 1
|
||||
)
|
||||
.map((issue) => `${label}: ${issue.code} - ${issue.message}`);
|
||||
}
|
||||
|
||||
function reportSummary(report) {
|
||||
const paragraphIssues = report.basic.paragraphLayouts?.flatMap(
|
||||
(paragraph) => paragraph.issues
|
||||
@@ -462,6 +477,10 @@ assert(
|
||||
selectedCases.length > 0,
|
||||
`视觉矩阵用例不存在:${selectedCaseId}`
|
||||
);
|
||||
assert(
|
||||
selectedScope === "full" || selectedScope === "cover",
|
||||
`不支持的视觉矩阵作用域:${selectedScope}`
|
||||
);
|
||||
const wordAdapter = createWordPdfAdapter({ timeoutMs: 240_000 });
|
||||
const wpsAdapter = createWpsPdfAdapter({ timeoutMs: 240_000 });
|
||||
const wordCapability = await wordAdapter.probe();
|
||||
@@ -471,6 +490,7 @@ assert(wpsCapability.available, `WPS Writer 不可用:${wpsCapability.detail}`
|
||||
|
||||
const summaries = [];
|
||||
const gateFailures = [];
|
||||
const diagnosticFailures = [];
|
||||
for (const caseDefinition of selectedCases) {
|
||||
process.stderr.write(`[layout visual matrix] ${caseDefinition.id}\n`);
|
||||
const { caseDirectory, result } = await generateCase(caseDefinition);
|
||||
@@ -569,7 +589,7 @@ for (const caseDefinition of selectedCases) {
|
||||
writeReportArtifacts(rasterDirectory, "wps", wpsReport);
|
||||
writeReportArtifacts(rasterDirectory, "office", officeReport);
|
||||
|
||||
const currentFailures = [...new Set([
|
||||
const allCurrentFailures = [...new Set([
|
||||
...pageGeometryFailures(chromium, caseDefinition, "Chromium"),
|
||||
...pageGeometryFailures(word, caseDefinition, "Microsoft Word"),
|
||||
...pageGeometryFailures(wps, caseDefinition, "WPS Writer"),
|
||||
@@ -589,9 +609,19 @@ for (const caseDefinition of selectedCases) {
|
||||
...reportGateFailures(wpsReport, "Chromium/WPS"),
|
||||
...reportGateFailures(officeReport, "Word/WPS")
|
||||
])];
|
||||
const currentFailures = selectedScope === "cover"
|
||||
? [...new Set([
|
||||
...reportCoverGateFailures(wordReport, "Chromium/Word"),
|
||||
...reportCoverGateFailures(wpsReport, "Chromium/WPS"),
|
||||
...reportCoverGateFailures(officeReport, "Word/WPS")
|
||||
])]
|
||||
: allCurrentFailures;
|
||||
gateFailures.push(
|
||||
...currentFailures.map((failure) => `${caseDefinition.id}: ${failure}`)
|
||||
);
|
||||
diagnosticFailures.push(
|
||||
...allCurrentFailures.map((failure) => `${caseDefinition.id}: ${failure}`)
|
||||
);
|
||||
summaries.push({
|
||||
id: caseDefinition.id,
|
||||
themeId: caseDefinition.themeId,
|
||||
@@ -623,6 +653,7 @@ for (const caseDefinition of selectedCases) {
|
||||
office: reportSummary(officeReport)
|
||||
},
|
||||
gateFailures: currentFailures,
|
||||
diagnosticFailures: allCurrentFailures,
|
||||
files: {
|
||||
chromiumPdf: path.relative(repositoryDirectory, chromiumPdfPath),
|
||||
docx: path.relative(repositoryDirectory, docxPath),
|
||||
@@ -638,8 +669,13 @@ const summary = {
|
||||
generatedAt: new Date().toISOString(),
|
||||
matrixDefinition,
|
||||
selectedCaseId,
|
||||
selectedScope,
|
||||
execution: {
|
||||
mode: selectedCaseId ? "single-case" : "full-matrix",
|
||||
mode: selectedCaseId
|
||||
? "single-case"
|
||||
: selectedScope === "cover"
|
||||
? "cover-matrix"
|
||||
: "full-matrix",
|
||||
executedCaseCount: summaries.length,
|
||||
expectedFullMatrixCaseCount: matrixDefinition.expectedCaseCount,
|
||||
complete: !selectedCaseId && summaries.length === matrixDefinition.expectedCaseCount
|
||||
@@ -650,15 +686,24 @@ const summary = {
|
||||
caseCount: summaries.length,
|
||||
gatePassed: gateFailures.length === 0,
|
||||
gateFailures,
|
||||
diagnosticFailures,
|
||||
cases: summaries
|
||||
};
|
||||
const summaryPath = path.join(
|
||||
outputDirectory,
|
||||
selectedCaseId ? `summary-${selectedCaseId}.json` : "summary.json"
|
||||
selectedCaseId
|
||||
? `summary-${selectedCaseId}.json`
|
||||
: selectedScope === "cover"
|
||||
? "summary-cover.json"
|
||||
: "summary.json"
|
||||
);
|
||||
const matrixHtmlPath = path.join(
|
||||
outputDirectory,
|
||||
selectedCaseId ? `matrix-${selectedCaseId}.html` : "matrix.html"
|
||||
selectedCaseId
|
||||
? `matrix-${selectedCaseId}.html`
|
||||
: selectedScope === "cover"
|
||||
? "matrix-cover.html"
|
||||
: "matrix.html"
|
||||
);
|
||||
fs.writeFileSync(summaryPath, `${JSON.stringify(summary, null, 2)}\n`, "utf8");
|
||||
fs.writeFileSync(matrixHtmlPath, renderMatrixSummaryHtml(summary), "utf8");
|
||||
|
||||
Reference in New Issue
Block a user