























@@ -265,175 +265,155 @@ describe("matrix live qa runtime", () => {
265265});
266266267267it("records default and per-scenario Matrix config snapshots in the summary", () => {
268-expect(
269-liveTesting.buildMatrixQaSummary({
270-artifactPaths: {
271-observedEvents: "/tmp/observed.json",
272-report: "/tmp/report.md",
273-summary: "/tmp/summary.json",
274-},
275-checks: [{ name: "Matrix harness ready", status: "pass" }],
276-config: {
277-default: liveTesting.buildMatrixQaConfigSnapshot({
278-driverUserId: "@driver:matrix-qa.test",
279-observerUserId: "@observer:matrix-qa.test",
280-sutUserId: "@sut:matrix-qa.test",
281-topology: {
282-defaultRoomId: "!room:matrix-qa.test",
283-defaultRoomKey: "main",
284-rooms: [
285-{
286-key: "main",
287-kind: "group",
288-memberRoles: ["driver", "observer", "sut"],
289-memberUserIds: [
290-"@driver:matrix-qa.test",
291-"@observer:matrix-qa.test",
292-"@sut:matrix-qa.test",
293-],
294-name: "Matrix QA",
295-requireMention: true,
296-roomId: "!room:matrix-qa.test",
297-},
298-],
299-},
300-}),
301-scenarios: [
302-{
303-id: "matrix-room-thread-reply-override",
304-title: "Matrix threadReplies always keeps room replies threaded",
305-config: liveTesting.buildMatrixQaConfigSnapshot({
306-driverUserId: "@driver:matrix-qa.test",
307-observerUserId: "@observer:matrix-qa.test",
308-overrides: {
309-threadReplies: "always",
310-},
311-sutUserId: "@sut:matrix-qa.test",
312-topology: {
313-defaultRoomId: "!room:matrix-qa.test",
314-defaultRoomKey: "main",
315-rooms: [
316-{
317-key: "main",
318-kind: "group",
319-memberRoles: ["driver", "observer", "sut"],
320-memberUserIds: [
321-"@driver:matrix-qa.test",
322-"@observer:matrix-qa.test",
323-"@sut:matrix-qa.test",
324-],
325-name: "Matrix QA",
326-requireMention: true,
327-roomId: "!room:matrix-qa.test",
328-},
329-],
330-},
331-}),
332-},
333-],
334-},
335-finishedAt: "2026-04-10T10:05:00.000Z",
336-harness: {
337-baseUrl: "http://127.0.0.1:28008/",
338-composeFile: "/tmp/docker-compose.yml",
339-dmRoomIds: [],
340-image: "ghcr.io/matrix-construct/tuwunel:v1.5.1",
341-roomId: "!room:matrix-qa.test",
342-roomIds: ["!room:matrix-qa.test"],
343-serverName: "matrix-qa.test",
344-},
345-observedEventCount: 0,
346-scenarios: [],
347-startedAt: "2026-04-10T10:00:00.000Z",
348-sutAccountId: "sut",
349-timings: {
350-artifactWriteMs: 5,
351-canaryMs: 40,
352-harnessBootMs: 100,
353-initialGatewayBootMs: 200,
354-provisioningMs: 300,
355-scenarioGatewayBootMs: 50,
356-scenarioRestartGatewayMs: 60,
357-scenarioTransportInterruptMs: 70,
358-scenarios: [],
359-totalMs: 825,
360-},
361-userIds: {
362-driver: "@driver:matrix-qa.test",
363-observer: "@observer:matrix-qa.test",
364-sut: "@sut:matrix-qa.test",
365-},
366-}).config,
367-).toMatchObject({
368-default: {
369-replyToMode: "off",
370-threadReplies: "inbound",
268+const summary = liveTesting.buildMatrixQaSummary({
269+artifactPaths: {
270+observedEvents: "/tmp/observed.json",
271+report: "/tmp/report.md",
272+summary: "/tmp/summary.json",
371273},
372-scenarios: [
373-{
374-id: "matrix-room-thread-reply-override",
375-config: {
376-threadReplies: "always",
274+checks: [{ name: "Matrix harness ready", status: "pass" }],
275+config: {
276+default: liveTesting.buildMatrixQaConfigSnapshot({
277+driverUserId: "@driver:matrix-qa.test",
278+observerUserId: "@observer:matrix-qa.test",
279+sutUserId: "@sut:matrix-qa.test",
280+topology: {
281+defaultRoomId: "!room:matrix-qa.test",
282+defaultRoomKey: "main",
283+rooms: [
284+{
285+key: "main",
286+kind: "group",
287+memberRoles: ["driver", "observer", "sut"],
288+memberUserIds: [
289+"@driver:matrix-qa.test",
290+"@observer:matrix-qa.test",
291+"@sut:matrix-qa.test",
292+],
293+name: "Matrix QA",
294+requireMention: true,
295+roomId: "!room:matrix-qa.test",
296+},
297+],
377298},
378-},
379-],
299+}),
300+scenarios: [
301+{
302+id: "matrix-room-thread-reply-override",
303+title: "Matrix threadReplies always keeps room replies threaded",
304+config: liveTesting.buildMatrixQaConfigSnapshot({
305+driverUserId: "@driver:matrix-qa.test",
306+observerUserId: "@observer:matrix-qa.test",
307+overrides: {
308+threadReplies: "always",
309+},
310+sutUserId: "@sut:matrix-qa.test",
311+topology: {
312+defaultRoomId: "!room:matrix-qa.test",
313+defaultRoomKey: "main",
314+rooms: [
315+{
316+key: "main",
317+kind: "group",
318+memberRoles: ["driver", "observer", "sut"],
319+memberUserIds: [
320+"@driver:matrix-qa.test",
321+"@observer:matrix-qa.test",
322+"@sut:matrix-qa.test",
323+],
324+name: "Matrix QA",
325+requireMention: true,
326+roomId: "!room:matrix-qa.test",
327+},
328+],
329+},
330+}),
331+},
332+],
333+},
334+finishedAt: "2026-04-10T10:05:00.000Z",
335+harness: {
336+baseUrl: "http://127.0.0.1:28008/",
337+composeFile: "/tmp/docker-compose.yml",
338+dmRoomIds: [],
339+image: "ghcr.io/matrix-construct/tuwunel:v1.5.1",
340+roomId: "!room:matrix-qa.test",
341+roomIds: ["!room:matrix-qa.test"],
342+serverName: "matrix-qa.test",
343+},
344+observedEventCount: 0,
345+scenarios: [],
346+startedAt: "2026-04-10T10:00:00.000Z",
347+sutAccountId: "sut",
348+timings: {
349+artifactWriteMs: 5,
350+canaryMs: 40,
351+harnessBootMs: 100,
352+initialGatewayBootMs: 200,
353+provisioningMs: 300,
354+scenarioGatewayBootMs: 50,
355+scenarioRestartGatewayMs: 60,
356+scenarioTransportInterruptMs: 70,
357+scenarios: [],
358+totalMs: 825,
359+},
360+userIds: {
361+driver: "@driver:matrix-qa.test",
362+observer: "@observer:matrix-qa.test",
363+sut: "@sut:matrix-qa.test",
364+},
380365});
366+const config = summary.config;
367+expect(config.default.replyToMode).toBe("off");
368+expect(config.default.threadReplies).toBe("inbound");
369+expect(config.scenarios).toHaveLength(1);
370+expect(config.scenarios[0]?.id).toBe("matrix-room-thread-reply-override");
371+expect(config.scenarios[0]?.config.threadReplies).toBe("always");
381372});
382373383374it("preserves negative-scenario artifacts in the Matrix summary", () => {
384-expect(
385-liveTesting.buildMatrixQaSummary(
386-buildMatrixQaSummaryInput({
375+const summary = liveTesting.buildMatrixQaSummary(
376+buildMatrixQaSummaryInput({
377+scenarios: [
378+{
379+id: "matrix-mention-gating",
380+title: "Matrix room message without mention does not trigger",
381+status: "pass",
382+details: "no reply",
383+artifacts: {
384+actorUserId: "@driver:matrix-qa.test",
385+driverEventId: "$driver",
386+expectedNoReplyWindowMs: 8_000,
387+token: "MATRIX_QA_NOMENTION_TOKEN",
388+triggerBody: "reply with only this exact marker: MATRIX_QA_NOMENTION_TOKEN",
389+},
390+},
391+],
392+timings: {
387393scenarios: [
388394{
395+durationMs: 80,
396+gatewayBootMs: 0,
397+gatewayRestartMs: 0,
389398id: "matrix-mention-gating",
390399title: "Matrix room message without mention does not trigger",
391-status: "pass",
392-details: "no reply",
393-artifacts: {
394-actorUserId: "@driver:matrix-qa.test",
395-driverEventId: "$driver",
396-expectedNoReplyWindowMs: 8_000,
397-token: "MATRIX_QA_NOMENTION_TOKEN",
398-triggerBody: "reply with only this exact marker: MATRIX_QA_NOMENTION_TOKEN",
399-},
400+transportInterruptMs: 0,
400401},
401402],
402-timings: {
403-scenarios: [
404-{
405-durationMs: 80,
406-gatewayBootMs: 0,
407-gatewayRestartMs: 0,
408-id: "matrix-mention-gating",
409-title: "Matrix room message without mention does not trigger",
410-transportInterruptMs: 0,
411-},
412-],
413-totalMs: 905,
414-},
415-}),
416-),
417-).toMatchObject({
418-counts: {
419-total: 2,
420-passed: 2,
421-failed: 0,
422-},
423-scenarios: [
424-{
425-id: "matrix-mention-gating",
426-artifacts: {
427-actorUserId: "@driver:matrix-qa.test",
428-expectedNoReplyWindowMs: 8_000,
429-triggerBody: "reply with only this exact marker: MATRIX_QA_NOMENTION_TOKEN",
430-},
403+totalMs: 905,
431404},
432-],
433-timings: {
434-totalMs: 905,
435-},
436-});
405+}),
406+);
407+expect(summary.counts.total).toBe(2);
408+expect(summary.counts.passed).toBe(2);
409+expect(summary.counts.failed).toBe(0);
410+expect(summary.scenarios[0]?.id).toBe("matrix-mention-gating");
411+expect(summary.scenarios[0]?.artifacts?.actorUserId).toBe("@driver:matrix-qa.test");
412+expect(summary.scenarios[0]?.artifacts?.expectedNoReplyWindowMs).toBe(8_000);
413+expect(summary.scenarios[0]?.artifacts?.triggerBody).toBe(
414+"reply with only this exact marker: MATRIX_QA_NOMENTION_TOKEN",
415+);
416+expect(summary.timings.totalMs).toBe(905);
437417});
438418439419it("keeps failing Matrix scenario details and timings complete in summary + report output", () => {
@@ -468,28 +448,14 @@ describe("matrix live qa runtime", () => {
468448}),
469449);
470450471-expect(summary).toMatchObject({
472-counts: {
473-total: 2,
474-passed: 1,
475-failed: 1,
476-},
477-scenarios: [
478-{
479-id: "matrix-reaction-not-a-reply",
480-status: "fail",
481-details: expect.stringContaining("reaction event: $reaction"),
482-},
483-],
484-timings: {
485-scenarios: [
486-{
487-id: "matrix-reaction-not-a-reply",
488-durationMs: 8_000,
489-},
490-],
491-},
492-});
451+expect(summary.counts.total).toBe(2);
452+expect(summary.counts.passed).toBe(1);
453+expect(summary.counts.failed).toBe(1);
454+expect(summary.scenarios[0]?.id).toBe("matrix-reaction-not-a-reply");
455+expect(summary.scenarios[0]?.status).toBe("fail");
456+expect(summary.scenarios[0]?.details).toContain("reaction event: $reaction");
457+expect(summary.timings.scenarios[0]?.id).toBe("matrix-reaction-not-a-reply");
458+expect(summary.timings.scenarios[0]?.durationMs).toBe(8_000);
493459494460const report = renderQaMarkdownReport({
495461title: "Matrix QA Report",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。