190 行
6.4 KiB
JavaScript
190 行
6.4 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
import { verifyLocalCandidateResults } from "../verify-local-candidate-results.mjs";
|
|
|
|
const bundles = [
|
|
"login-logout",
|
|
"reimbursement",
|
|
"approval",
|
|
"invoice",
|
|
"procurement",
|
|
"project-contract",
|
|
"payment-ap",
|
|
"people-audit",
|
|
"attendance-archive",
|
|
"mobile-workspace",
|
|
];
|
|
|
|
function manifest() {
|
|
return {
|
|
localCandidateFlows: bundles.map((bundle) => ({
|
|
bundle,
|
|
witnessTag: `@local-candidate:${bundle}`,
|
|
witnessSpec: "client/tests/e2e/synthetic-local-candidate.spec.ts",
|
|
})),
|
|
};
|
|
}
|
|
|
|
function spec(tag, status = "passed", overrides = {}) {
|
|
return {
|
|
title: tag,
|
|
file: "client/tests/e2e/synthetic-local-candidate.spec.ts",
|
|
line: 12,
|
|
tags: [],
|
|
tests: [
|
|
{
|
|
expectedStatus: "passed",
|
|
results: [{ status }],
|
|
},
|
|
],
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
function results(specs, overrides = {}) {
|
|
return {
|
|
suites: [{ title: "local candidate", specs }],
|
|
errors: [],
|
|
stats: { expected: specs.length, skipped: 0, unexpected: 0 },
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
test("10 个唯一 witness tag 全部 passed 时通过", () => {
|
|
const summary = verifyLocalCandidateResults(
|
|
manifest(),
|
|
results(bundles.map((bundle) => spec(`@local-candidate:${bundle}`))),
|
|
);
|
|
assert.equal(summary.ok, true);
|
|
assert.equal(summary.passedTagCount, 10);
|
|
assert.equal(summary.skippedTagCount, 0);
|
|
});
|
|
|
|
test("结果缺失 tag 必须阻断", () => {
|
|
const summary = verifyLocalCandidateResults(
|
|
manifest(),
|
|
results(bundles.slice(1).map((bundle) => spec(`@local-candidate:${bundle}`))),
|
|
);
|
|
assert.equal(summary.ok, false);
|
|
assert.deepEqual(summary.missingTags, ["@local-candidate:login-logout"]);
|
|
assert.ok(summary.issues.includes("missing_tag_result"));
|
|
});
|
|
|
|
test("重复 tag 结果必须阻断", () => {
|
|
const specs = bundles.map((bundle) => spec(`@local-candidate:${bundle}`));
|
|
specs.push(spec("@local-candidate:login-logout"));
|
|
const summary = verifyLocalCandidateResults(manifest(), results(specs));
|
|
assert.equal(summary.ok, false);
|
|
assert.deepEqual(summary.duplicateTags, ["@local-candidate:login-logout"]);
|
|
});
|
|
|
|
test("未知 tag 结果必须阻断", () => {
|
|
const specs = bundles.map((bundle) => spec(`@local-candidate:${bundle}`));
|
|
specs.push(spec("@local-candidate:unknown"));
|
|
const summary = verifyLocalCandidateResults(manifest(), results(specs));
|
|
assert.equal(summary.ok, false);
|
|
assert.deepEqual(summary.unknownTags, ["@local-candidate:unknown"]);
|
|
});
|
|
|
|
test("全部 witness skipped 必须阻断", () => {
|
|
const summary = verifyLocalCandidateResults(
|
|
manifest(),
|
|
results(bundles.map((bundle) => spec(`@local-candidate:${bundle}`, "skipped"))),
|
|
);
|
|
assert.equal(summary.ok, false);
|
|
assert.equal(summary.skippedTagCount, 10);
|
|
assert.equal(summary.passedTagCount, 0);
|
|
assert.ok(summary.issues.includes("skipped_tag_result"));
|
|
});
|
|
|
|
test("任一 witness 或整体 Playwright suite 失败必须阻断", () => {
|
|
const specs = bundles.map((bundle) =>
|
|
spec(`@local-candidate:${bundle}`, bundle === "payment-ap" ? "failed" : "passed"),
|
|
);
|
|
const summary = verifyLocalCandidateResults(
|
|
manifest(),
|
|
results(specs, { errors: [{}], stats: { expected: 9, skipped: 0, unexpected: 1 } }),
|
|
);
|
|
assert.equal(summary.ok, false);
|
|
assert.deepEqual(summary.failedTags, ["@local-candidate:payment-ap"]);
|
|
assert.ok(summary.issues.includes("playwright_suite_failed"));
|
|
assert.deepEqual(summary.failedTests, [{
|
|
file: "synthetic-local-candidate.spec.ts",
|
|
line: 12,
|
|
title: "@local-candidate:payment-ap",
|
|
status: "failed",
|
|
}]);
|
|
});
|
|
|
|
test("非 witness acceptance 用例 skipped 也必须阻断且诊断不泄露绝对路径", () => {
|
|
const specs = bundles.map((bundle) => spec(`@local-candidate:${bundle}`));
|
|
specs.push(spec("本地附加验收", "skipped", {
|
|
file: "/private/workspace/client/tests/e2e/acceptance.spec.ts",
|
|
line: 27,
|
|
}));
|
|
const summary = verifyLocalCandidateResults(
|
|
manifest(),
|
|
results(specs, { stats: { expected: 10, skipped: 1, unexpected: 0 } }),
|
|
);
|
|
assert.equal(summary.ok, false);
|
|
assert.ok(summary.issues.includes("playwright_suite_skipped"));
|
|
assert.equal(summary.suiteSkippedTestCount, 1);
|
|
assert.deepEqual(summary.skippedTests, [{
|
|
file: "acceptance.spec.ts",
|
|
line: 27,
|
|
title: "本地附加验收",
|
|
status: "skipped",
|
|
}]);
|
|
});
|
|
|
|
test("单一测试合并多个 witness tag 不能冒充十个独立流程", () => {
|
|
const mergedTitle = bundles.map((bundle) => `@local-candidate:${bundle}`).join(" ");
|
|
const summary = verifyLocalCandidateResults(manifest(), results([spec(mergedTitle)]));
|
|
assert.equal(summary.ok, false);
|
|
assert.equal(summary.totalTestResultCount, 1);
|
|
assert.ok(summary.issues.includes("multi_tag_test_result"));
|
|
assert.equal(summary.multiTagTests.length, 1);
|
|
});
|
|
|
|
test("witness tag 必须来自 manifest 指定的测试文件", () => {
|
|
const specs = bundles.map((bundle) => spec(`@local-candidate:${bundle}`));
|
|
specs[0] = spec("@local-candidate:login-logout", "passed", {
|
|
file: "/private/workspace/client/tests/e2e/unrelated.spec.ts",
|
|
});
|
|
const summary = verifyLocalCandidateResults(manifest(), results(specs));
|
|
assert.equal(summary.ok, false);
|
|
assert.ok(summary.issues.includes("wrong_witness_spec_result"));
|
|
assert.deepEqual(summary.wrongWitnessSpecs, [{
|
|
tag: "@local-candidate:login-logout",
|
|
expectedFile: "synthetic-local-candidate.spec.ts",
|
|
observedFile: "unrelated.spec.ts",
|
|
}]);
|
|
});
|
|
|
|
test("Playwright JSON 将 file 放在父 suite 时仍能核对 witness 来源", () => {
|
|
const specs = bundles.map((bundle) => {
|
|
const item = spec(`@local-candidate:${bundle}`);
|
|
delete item.file;
|
|
return item;
|
|
});
|
|
const report = results([], {
|
|
suites: [{
|
|
title: "local candidate witnesses",
|
|
file: "tests/e2e/synthetic-local-candidate.spec.ts",
|
|
specs,
|
|
}],
|
|
});
|
|
const summary = verifyLocalCandidateResults(manifest(), report);
|
|
assert.equal(summary.ok, true);
|
|
assert.deepEqual(summary.wrongWitnessSpecs, []);
|
|
});
|
|
|
|
test("Playwright JSON 只提供 spec basename 时按 manifest 唯一 basename 核对", () => {
|
|
const specs = bundles.map((bundle) => spec(`@local-candidate:${bundle}`, "passed", {
|
|
file: "synthetic-local-candidate.spec.ts",
|
|
}));
|
|
const summary = verifyLocalCandidateResults(manifest(), results(specs));
|
|
assert.equal(summary.ok, true);
|
|
assert.deepEqual(summary.wrongWitnessSpecs, []);
|
|
});
|