Skip to content

Commit 8add591

Browse files
authored
Fix retry button not working but show "Render error" (#5838)
* Fix resend should remove local ID * Add PR number * Add snapshots * Typo * Remove position
1 parent f673783 commit 8add591

8 files changed

Lines changed: 140 additions & 1 deletion

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ Legends:
6060
- [`webpack@5.107.2`](https://npmjs.com/package/webpack/v/5.107.2)
6161
- [`yaml@2.9.0`](https://npmjs.com/package/yaml/v/2.9.0)
6262

63+
### Fixed
64+
65+
- Fixed the "Retry" button to resend the message after it fails to send, instead of showing "Render error", by [@compulim](https://github.com/compulim) in PR [#5838](https://github.com/microsoft/BotFramework-WebChat/pull/5838)
66+
6367
## [4.19.0] - 2026-05-25
6468

6569
Breaking changes in this release:
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
<!doctype html>
2+
<html lang="en-US">
3+
<head>
4+
<link href="/assets/index.css" rel="stylesheet" type="text/css" />
5+
<script crossorigin="anonymous" src="/test-harness.js"></script>
6+
<script crossorigin="anonymous" src="/test-page-object.js"></script>
7+
<script crossorigin="anonymous" src="/__dist__/webchat-es5.js"></script>
8+
</head>
9+
<body>
10+
<main id="webchat"></main>
11+
<script>
12+
function activityStatusInnerTextContained(expectedInnerTextPattern, index = 0) {
13+
return pageConditions.became(
14+
`Activity status should contains "${expectedInnerTextPattern}"`,
15+
() => pageElements.activityStatuses()[index].innerText.includes(expectedInnerTextPattern),
16+
1000
17+
);
18+
}
19+
20+
function activityChannelDataStateBecame(expectedState, index = 0) {
21+
if (typeof expectedState === 'undefined') {
22+
return pageConditions.became(
23+
`Activity "channelData.state" should be undefined`,
24+
() => !('state' in pageObjects.getActivities()[index].channelData),
25+
1000
26+
);
27+
}
28+
29+
return pageConditions.became(
30+
`Activity "channelData.state" should be "${expectedState}"`,
31+
() => pageObjects.getActivities()[index].channelData?.state === expectedState,
32+
1000
33+
);
34+
}
35+
36+
function activityChannelDataWebChatSendStatusBecame(expectedSendStatus, index = 0) {
37+
return pageConditions.became(
38+
`Activity "channelData['webchat:send-status']" should be "${expectedSendStatus}"`,
39+
() => pageObjects.getActivities()[index].channelData?.['webchat:send-status'] === expectedSendStatus,
40+
1000
41+
);
42+
}
43+
44+
run(
45+
async function () {
46+
const clock = lolex.createClock();
47+
48+
const { directLine, store } = testHelpers.createDirectLineEmulator({ ponyfill: clock });
49+
50+
WebChat.renderWebChat(
51+
{
52+
directLine,
53+
ponyfill: clock,
54+
store,
55+
styleOptions: { spinnerAnimationBackgroundImage: 'url(/assets/staticspinner.png)' }
56+
},
57+
document.getElementById('webchat')
58+
);
59+
60+
await pageConditions.webChatRendered();
61+
62+
clock.tick(400);
63+
64+
// SETUP: Send a message and resolve the call to `postActivity()`.
65+
await pageConditions.uiConnected();
66+
67+
const sendMessage = await directLine.actPostActivity(
68+
() => pageObjects.sendMessageViaSendBox('Hello, World!', { waitForSend: false }),
69+
{ id: 'a00001' }
70+
);
71+
72+
// THEN: `channelData.state` should be "sending".
73+
await activityChannelDataStateBecame('sending');
74+
75+
// THEN: `channelData['webchat:send-status']` should be "sending".
76+
await activityChannelDataWebChatSendStatusBecame('sending');
77+
78+
// THEN: The message should have status of "Sending".
79+
await activityStatusInnerTextContained('Sending');
80+
81+
// THEN: It should match snapshot.
82+
await host.snapshot('local');
83+
84+
// WHEN: After 20 seconds.
85+
clock.tick(20000);
86+
87+
// THEN: `channelData.state` should be "send failed".
88+
await activityChannelDataStateBecame('send failed');
89+
90+
// THEN: `channelData['webchat:send-status']` should be "sending".
91+
await activityChannelDataWebChatSendStatusBecame('sending');
92+
93+
// THEN: The message should have status of "Send failed. Retry."
94+
// This is because the message passed 20s as defined in `styleOptions.sendTimeout`.
95+
await activityStatusInnerTextContained('Send failed. Retry.');
96+
97+
// THEN: It should match snapshot.
98+
await host.snapshot('local');
99+
100+
// WHEN: The retry button is clicked.
101+
const sendMessageRetry = await directLine.actPostActivity(() =>
102+
host.click(pageElements.activityStatuses()[0].querySelector('button'))
103+
);
104+
105+
// THEN: It should show 2 outgoing messages.
106+
await pageConditions.numActivitiesShown(2);
107+
108+
// THEN: It should match snapshot.
109+
await host.snapshot('local');
110+
111+
// WHEN: The first outgoing message is sent.
112+
await sendMessage.resolveAll();
113+
114+
// THEN: The activity status of the first message should be "Just now."
115+
await activityStatusInnerTextContained('Just now', 0);
116+
await activityStatusInnerTextContained('Sending', 1);
117+
118+
// THEN: It should match snapshot.
119+
await host.snapshot('local');
120+
121+
// WHEN: The second outgoing message is sent.
122+
await sendMessageRetry.resolveAll();
123+
124+
// THEN: The activity status of the second message should be "Just now."
125+
await activityStatusInnerTextContained('Just now', 0);
126+
await activityStatusInnerTextContained('Just now', 1);
127+
128+
// THEN: It should match snapshot.
129+
await host.snapshot('local');
130+
},
131+
{ ignoreErrors: true }
132+
);
133+
</script>
134+
</body>
135+
</html>
7.11 KB
Loading
7.87 KB
Loading
10 KB
Loading
9.26 KB
Loading
8.53 KB
Loading

packages/core/src/sagas/postActivitySaga.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ function* postActivity(
5858
channelData: {
5959
// `channelData.state` is being deprecated in favor of `channelData['webchat:send-status']`.
6060
// Please refer to #4362 for details. Remove on or after 2024-07-31.
61-
...deleteKey(activity.channelData, 'state'),
61+
...deleteKey(activity.channelData, 'state', 'webchat:internal:local-id', 'webchat:internal:position'),
6262
clientActivityID
6363
},
6464
channelId: 'webchat',

0 commit comments

Comments
 (0)