Skip to content

Commit 8e79392

Browse files
committed
test(qa): accept Matrix progress edits without draft root
1 parent 9b397b4 commit 8e79392

3 files changed

Lines changed: 29 additions & 17 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ Docs: https://docs.openclaw.ai
7676
- Google Meet: keep Chrome realtime transport tests hermetic on Linux prerelease shards while preserving the macOS-only runtime guard. Thanks @vincentkoc.
7777
- QA/Slack: fail the live mention-gating scenario on any unexpected SUT reply, even when the reply does not echo the expected marker. Thanks @vincentkoc.
7878
- QA/Matrix: steer the live tool-progress preview check away from `HEARTBEAT.md` and report final preview candidates when the live marker reply misses the exact token. Thanks @vincentkoc.
79-
- QA/Matrix: let the live tool-progress preview and error checks verify progress replacement events without depending on the preview saying `Working`, `tool: read`, or an unlabelled/pathless `read from`. Thanks @vincentkoc.
79+
- QA/Matrix: let the live tool-progress preview and error checks verify progress replacement events without depending on the preview saying `Working`, `tool: read`, an unlabelled/pathless `read from`, or the original draft root being observed. Thanks @vincentkoc.
8080
- QA/Matrix: wait for live approval reactions to echo before starting the threaded approval decision timeout. Thanks @vincentkoc.
8181
- QA/Matrix: reuse the primed driver sync stream when confirming approval reaction echoes, avoiding missed self-reactions in live release runs. Thanks @vincentkoc.
8282
- Tlon: expose `groupInviteAllowlist` in the channel config schema and clarify that group invite auto-accept fails closed without an invite allowlist. Thanks @vincentkoc.

extensions/qa-matrix/src/runners/contract/scenario-runtime-room.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -812,14 +812,22 @@ async function runMatrixToolProgressScenario(
812812
mentionUserIds: [context.sutUserId],
813813
roomId: context.roomId,
814814
});
815+
const matchesExpectedProgress = (body: string | undefined) =>
816+
params.progressPattern.test(body ?? "") ||
817+
(params.allowGenericProgressLine === true && hasMatrixQaToolProgressPreviewLine(body));
818+
const getPreviewRootEventId = (event: MatrixQaObservedEvent) =>
819+
event.relatesTo?.relType === "m.replace" && event.relatesTo.eventId
820+
? event.relatesTo.eventId
821+
: event.eventId;
815822
const preview = await client
816823
.waitForRoomEvent({
817824
observedEvents: context.observedEvents,
818825
predicate: (event) =>
819826
event.roomId === context.roomId &&
820827
event.sender === context.sutUserId &&
821828
event.kind === params.expectedPreviewKind &&
822-
event.relatesTo === undefined,
829+
(event.relatesTo === undefined ||
830+
(event.relatesTo.relType === "m.replace" && matchesExpectedProgress(event.body))),
823831
roomId: context.roomId,
824832
since: startSince,
825833
timeoutMs: context.timeoutMs,
@@ -837,9 +845,7 @@ async function runMatrixToolProgressScenario(
837845
}),
838846
);
839847
});
840-
const matchesExpectedProgress = (body: string | undefined) =>
841-
params.progressPattern.test(body ?? "") ||
842-
(params.allowGenericProgressLine === true && hasMatrixQaToolProgressPreviewLine(body));
848+
const previewRootEventId = getPreviewRootEventId(preview.event);
843849
const progress = matchesExpectedProgress(preview.event.body)
844850
? preview
845851
: await client
@@ -850,7 +856,7 @@ async function runMatrixToolProgressScenario(
850856
event.sender === context.sutUserId &&
851857
event.kind === params.expectedPreviewKind &&
852858
event.relatesTo?.relType === "m.replace" &&
853-
event.relatesTo.eventId === preview.event.eventId &&
859+
event.relatesTo.eventId === previewRootEventId &&
854860
matchesExpectedProgress(event.body),
855861
roomId: context.roomId,
856862
since: preview.since,
@@ -862,7 +868,7 @@ async function runMatrixToolProgressScenario(
862868
cause: err,
863869
events: context.observedEvents,
864870
expectedPreviewKind: params.expectedPreviewKind,
865-
previewEventId: preview.event.eventId,
871+
previewEventId: previewRootEventId,
866872
roomId: context.roomId,
867873
startIndex: startObservedIndex,
868874
sutUserId: context.sutUserId,
@@ -882,7 +888,7 @@ async function runMatrixToolProgressScenario(
882888
event.sender === context.sutUserId &&
883889
isMatrixQaMessageLikeKind(event.kind) &&
884890
event.relatesTo?.relType === "m.replace" &&
885-
event.relatesTo.eventId === preview.event.eventId &&
891+
event.relatesTo.eventId === previewRootEventId &&
886892
doesMatrixQaReplyBodyMatchToken(event, params.finalText),
887893
roomId: context.roomId,
888894
since: progress.since,
@@ -893,7 +899,7 @@ async function runMatrixToolProgressScenario(
893899
buildMatrixQaToolProgressFinalTimeoutMessage({
894900
cause: err,
895901
events: context.observedEvents,
896-
previewEventId: preview.event.eventId,
902+
previewEventId: previewRootEventId,
897903
roomId: context.roomId,
898904
startIndex: startObservedIndex,
899905
sutUserId: context.sutUserId,
@@ -904,7 +910,7 @@ async function runMatrixToolProgressScenario(
904910
const unexpectedWorkingEvents = findMatrixQaUnexpectedWorkingEvents({
905911
events: context.observedEvents,
906912
finalEventId: finalized.event.eventId,
907-
previewEventId: preview.event.eventId,
913+
previewEventId: previewRootEventId,
908914
startIndex: startObservedIndex,
909915
sutUserId: context.sutUserId,
910916
});
@@ -924,7 +930,7 @@ async function runMatrixToolProgressScenario(
924930
artifacts: {
925931
driverEventId,
926932
previewBodyPreview: progress.event.body?.slice(0, 200),
927-
previewEventId: preview.event.eventId,
933+
previewEventId: previewRootEventId,
928934
previewFormattedBodyPreview: progress.event.formattedBody?.slice(0, 200),
929935
previewMentions: progress.event.mentions,
930936
reply: finalReply,

extensions/qa-matrix/src/runners/contract/scenarios.test.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2858,15 +2858,20 @@ describe("matrix live qa scenarios", () => {
28582858

28592859
it("finalizes Matrix tool progress previews after tool errors", async () => {
28602860
const previewEventId = "$tool-progress-error-preview";
2861-
const { sendTextMessage } = mockMatrixQaRoomClient({
2861+
const progressEvent = matrixQaMessageEvent({
2862+
kind: "notice",
2863+
eventId: "$tool-progress-error-progress",
2864+
body: "Pearling...\n`📖 Read: from /tmp/qa/workspace/missing-matrix-tool-progress-target.txt`",
2865+
relatesTo: {
2866+
relType: "m.replace",
2867+
eventId: previewEventId,
2868+
},
2869+
});
2870+
const { sendTextMessage, waitForRoomEvent } = mockMatrixQaRoomClient({
28622871
driverEventId: "$tool-progress-error-trigger",
28632872
events: [
28642873
{
2865-
event: matrixQaMessageEvent({
2866-
kind: "notice",
2867-
eventId: previewEventId,
2868-
body: "Pearling...\n`📖 Read: from /tmp/qa/workspace/missing-matrix-tool-progress-target.txt`",
2869-
}),
2874+
event: progressEvent,
28702875
since: "driver-sync-preview",
28712876
},
28722877
{
@@ -2909,6 +2914,7 @@ describe("matrix live qa scenarios", () => {
29092914
},
29102915
});
29112916

2917+
expect(waitForRoomEvent.mock.calls[0]?.[0].predicate(progressEvent)).toBe(true);
29122918
expect(sendTextMessage).toHaveBeenCalledWith({
29132919
body: expect.stringContaining("Tool progress error QA check"),
29142920
mentionUserIds: ["@sut:matrix-qa.test"],

0 commit comments

Comments
 (0)