Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ Legends:

- Added `styleOptions.richCardTitleOmitHeadingRole` (default `false`) to opt out of `style: 'heading'` on rich card titles, in PR [#5839](https://github.com/microsoft/BotFramework-WebChat/pull/5839), by [@cjennison](https://github.com/cjennison)

### Fixed

- Fixed an error when a failed activity is present when Web Chat mounts, resolving [#5812](https://github.com/microsoft/BotFramework-WebChat/issues/5812), in PR [#5848](https://github.com/microsoft/BotFramework-WebChat/pull/5848), by [@OEvgeny](https://github.com/OEvgeny)


## [4.19.1] - 2026-06-09

Expand Down
86 changes: 86 additions & 0 deletions __tests__/html2/activityStatus/rehydrateSendFailedRetry.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<!doctype html>
<html lang="en-US">
<head>
<link href="/assets/index.css" rel="stylesheet" type="text/css" />
<script crossorigin="anonymous" src="/test-harness.js"></script>
<script crossorigin="anonymous" src="/test-page-object.js"></script>
<script crossorigin="anonymous" src="https://cdn.jsdelivr.net/npm/react@18/umd/react.production.min.js"></script>
<script
crossorigin="anonymous"
src="https://cdn.jsdelivr.net/npm/react-dom@18/umd/react-dom.production.min.js"
></script>
<script crossorigin="anonymous" src="/__dist__/webchat-es5.js"></script>
</head>
<body>
<main id="webchat"></main>
<script type="module">
import { expect } from 'https://esm.sh/expect?standalone';
import { waitFor } from 'https://esm.sh/@testduet/wait-for';

const {
React: { createElement },
ReactDOM: { createRoot },
testHelpers: { createDirectLineEmulator },
WebChat: { createDirectLine, createStoreWithOptions, hooks, ReactWebChat }
} = window;

// This test only fail in 4.18.0.
// After we moved to graph backend in 4.19.0, this test no longer fail.
// This is because the graph backend do not rehydrate activities immediately until after first render.
// Thus, we are not hitting the JavaScript error related to `(undefined).has()`.

run(
async function () {
const { directLine: directLine1, store: store1 } = createDirectLineEmulator();

const root1 = createRoot(document.getElementById('webchat'));

root1.render(createElement(ReactWebChat, { directLine: directLine1, store: store1 }));

await pageConditions.uiConnected();

const sendMessage = await directLine1.emulateOutgoingActivity('Hello, World!');

sendMessage.rejectPostActivity(new Error('artificial error'));

// Initially, the send-status is "sending", we need to wait until it turns into "send failed".
await waitFor(() =>
expect(store1.getState().activities[0].channelData['webchat:send-status']).toBe('send failed')
);

await host.snapshot('local');

const state = store1.getState();

root1.unmount();

const root2 = createRoot(document.getElementById('webchat'));

const { directLine: directLine2, store: store2 } = testHelpers.createDirectLineEmulator({
initialState: state
});

root2.render(
createElement(ReactWebChat, {
directLine: directLine2,
store: store2
})
);

await Promise.race([
pageConditions.uiConnected(),
new Promise((_, reject) =>
setTimeout(
() => reject(new Error('Timed out waiting for chat history to show, possibly JavaScript error')),
500
)
)
]);

await host.snapshot('local');
},
{ ignoreErrors: true }
);
</script>
</body>
</html>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const LiveRegionSendFailed = () => {

/** True, if one or more non-presentational activities start appears as "send failed", otherwise, false. */
const hasNewSendFailed = useMemo<boolean>(() => {
if (activityKeysOfSendFailed === prevActivityKeysOfSendFailed) {
if (!prevActivityKeysOfSendFailed || activityKeysOfSendFailed === prevActivityKeysOfSendFailed) {
Comment thread
compulim marked this conversation as resolved.
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ function uniqueId() {
return random().toString(36).substring(2, 7);
}

export default function createDirectLineEmulator({ autoConnect = true, ponyfill = {} } = {}) {
export default function createDirectLineEmulator({ autoConnect = true, initialState, ponyfill = {} } = {}) {
const { Date = window.Date } = ponyfill;
const store = createStoreWithOptions({ ponyfill });
const store = createStoreWithOptions({ ponyfill }, initialState);

if (!isNativeClock()) {
throw new Error('Fake timer is detected at global-level. You must pass it via the "ponyfill" option.');
Expand Down
Loading