QG6 完成QA治理矩阵与报告规范

这个提交包含在:
2026-05-12 17:47:25 +08:00
父节点 4a2e6fc71a
当前提交 bc03e9946c
共修改 10 个文件,包含 535 行新增和 21 行删除
+39 -3
查看文件
@@ -1,3 +1,4 @@
import { execSync } from "node:child_process";
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
import { expect, test, type Browser, type Page } from "@playwright/test";
@@ -30,14 +31,41 @@ type PreparedRoutes = {
const ROOT_DIR = path.resolve(process.cwd(), "..");
const MATRIX_PATH = path.join(ROOT_DIR, "docs/trialrun/project-wide-flow-matrix.csv");
const SCREENSHOT_DIR = path.join(ROOT_DIR, "output/playwright/project-wide-visual");
const ARTIFACT_DIR = path.join(ROOT_DIR, "artifacts/qa-flow/project-wide-visual");
const ISSUE_ID = process.env.QA_ISSUE_ID?.trim() || "project-wide-visual";
const BASE_URL = process.env.E2E_BASE_URL?.trim() || null;
const SCREENSHOT_DIR = resolveRootPath(
process.env.QA_VISUAL_OUTPUT_DIR,
path.join(ROOT_DIR, "output/playwright/project-wide-visual"),
);
const ARTIFACT_DIR = resolveRootPath(
process.env.QA_VISUAL_ARTIFACT_DIR,
path.join(ROOT_DIR, "artifacts/qa-flow/project-wide-visual"),
);
const WECOM_UA =
"Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 wxwork/4.1.20 MicroMessenger/8.0.1 Language/zh_CN";
const UUID_RE = /[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/gi;
const findings: VisualFinding[] = [];
function resolveRootPath(value: string | undefined, fallback: string) {
if (!value?.trim()) {
return fallback;
}
return path.isAbsolute(value) ? value : path.join(ROOT_DIR, value);
}
function currentCommit() {
try {
return execSync("git rev-parse --short HEAD", {
cwd: ROOT_DIR,
encoding: "utf8",
stdio: ["ignore", "pipe", "ignore"],
}).trim();
} catch {
return "unknown";
}
}
function outputPath(dir: string, fileName: string) {
mkdirSync(dir, { recursive: true });
return path.join(dir, fileName);
@@ -357,7 +385,7 @@ async function auditPlans(browser: Browser, plans: Array<{ route: string; domain
for (const { user, plans: userPlans } of plansByUser.values()) {
const context = viewport === "mobile-wecom"
? await newWecomContext(browser)
: await browser.newContext({ viewport: { width: 1366, height: 900 }, serviceWorkers: "block" });
: await browser.newContext({ viewport: { width: 1440, height: 960 }, serviceWorkers: "block" });
try {
const page = await context.newPage();
await loginForVisual(page, user);
@@ -382,7 +410,15 @@ test.describe("项目级全页面视觉巡检", () => {
const reportPath = outputPath(ARTIFACT_DIR, "report.json");
writeFileSync(reportPath, JSON.stringify({
issueId: ISSUE_ID,
baseURL: BASE_URL,
commit: currentCommit(),
checkedAt: new Date().toISOString(),
status: findings.some((finding) => finding.severity === "P1") ? "FAIL" : "PASS",
matrix: {
pc: "1440x960",
mobileWeCom: "390x844",
},
pcRoutes: pcPlans.map((item) => item.route),
mobileRoutes: mobilePlans.map((item) => item.route),
findings,