


























@@ -119,6 +119,15 @@ function expectWriteContains(mock: unknown, fragment: string): void {
119119).toBe(true);
120120}
121121122+function makeQaEvidence(entries: unknown[] = []) {
123+return {
124+kind: "openclaw.qa.evidence-summary",
125+schemaVersion: 2,
126+generatedAt: "2026-06-14T00:00:00.000Z",
127+ entries,
128+};
129+}
130+122131function flowSuiteRuntimeResult(params: {
123132evidencePath?: string;
124133reportPath: string;
@@ -178,7 +187,7 @@ describe("qa cli runtime", () => {
178187telegramArtifactsDir = await fs.mkdtemp(path.join(os.tmpdir(), "qa-telegram-runtime-"));
179188telegramSummaryPath = path.join(telegramArtifactsDir, QA_EVIDENCE_FILENAME);
180189await fs.writeFile(suiteReportPath, "# QA Suite Report\n", "utf8");
181-await fs.writeFile(suiteEvidencePath, JSON.stringify({ entries: [] }), "utf8");
190+await fs.writeFile(suiteEvidencePath, JSON.stringify(makeQaEvidence()), "utf8");
182191await fs.writeFile(
183192suiteSummaryPath,
184193JSON.stringify({
@@ -301,7 +310,7 @@ describe("qa cli runtime", () => {
301310302311it("runs selected Playwright scenarios through the suite command", async () => {
303312const evidencePath = path.join(suiteArtifactsDir, "qa-evidence.json");
304-await fs.writeFile(evidencePath, JSON.stringify({ entries: [] }), "utf8");
313+await fs.writeFile(evidencePath, JSON.stringify(makeQaEvidence()), "utf8");
305314runQaSuite.mockResolvedValueOnce(
306315unifiedSuiteRuntimeResult({
307316outputDir: suiteArtifactsDir,
@@ -349,6 +358,63 @@ describe("qa cli runtime", () => {
349358try {
350359runQaSuite.mockImplementationOnce(async () => {
351360expect(process.env.OPENCLAW_QA_PROFILE).toBe("smoke-ci");
361+await fs.writeFile(
362+suiteEvidencePath,
363+JSON.stringify(
364+makeQaEvidence([
365+{
366+test: {
367+kind: "qa-scenario",
368+id: "dm-chat-baseline",
369+title: "DM baseline conversation",
370+source: {
371+path: "qa/scenarios/channels/dm-chat-baseline.yaml",
372+},
373+},
374+mapping: {
375+profile: "smoke-ci",
376+coverage: [
377+{
378+id: "channels.dm",
379+role: "primary",
380+surfaceIds: ["dm"],
381+categoryIds: ["agent-runtime-and-provider-execution.agent-turn-execution"],
382+},
383+],
384+},
385+execution: {
386+runner: "host",
387+environment: {
388+ref: null,
389+os: process.platform,
390+nodeVersion: process.version,
391+},
392+provider: {
393+id: "openai",
394+live: false,
395+model: {
396+name: "gpt-5.5",
397+ref: "mock-openai/gpt-5.5",
398+},
399+fixture: "mock-openai",
400+},
401+channel: {
402+id: "qa-channel",
403+live: false,
404+},
405+packageSource: {
406+kind: "source-checkout",
407+},
408+artifacts: [],
409+},
410+result: {
411+status: "pass",
412+},
413+},
414+]),
415+),
416+"utf8",
417+);
352418return flowSuiteRuntimeResult({
353419reportPath: suiteReportPath,
354420summaryPath: suiteSummaryPath,
@@ -379,7 +445,34 @@ describe("qa cli runtime", () => {
379445expect(suiteArgs.scenarioIds).toEqual(expect.arrayContaining(["dm-chat-baseline"]));
380446expect(suiteArgs.scenarioIds).not.toContain("thinking-slash-model-remap");
381447expect(process.env.OPENCLAW_QA_PROFILE).toBe("release");
448+const evidence = JSON.parse(await fs.readFile(suiteEvidencePath, "utf8")) as {
449+scorecard?: {
450+profile?: unknown;
451+run?: { evidenceEntryCount?: unknown };
452+features?: { fulfilled?: unknown };
453+categoryReports?: Array<{
454+id?: unknown;
455+features?: { fulfilled?: unknown };
456+missingCoverageIds?: unknown;
457+}>;
458+};
459+};
460+expect(evidence.scorecard).toMatchObject({
461+profile: "smoke-ci",
462+run: {
463+evidenceEntryCount: 1,
464+},
465+});
466+expect(evidence.scorecard?.features?.fulfilled).toBe(1);
467+expect(evidence.scorecard?.categoryReports?.[0]).toMatchObject({
468+id: "agent-runtime-and-provider-execution.agent-turn-execution",
469+features: {
470+fulfilled: 1,
471+},
472+});
473+expect(JSON.stringify(evidence.scorecard)).not.toContain("dm-chat-baseline");
382474expectWriteContains(stdoutWrite, "QA run profile: smoke-ci; categories: 1; scenarios:");
475+expectWriteContains(stdoutWrite, `QA profile scorecard: ${suiteEvidencePath}`);
383476} finally {
384477if (previousProfile === undefined) {
385478delete process.env.OPENCLAW_QA_PROFILE;
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。