Skip to content

Commit

Permalink
Add "send failed retry" prompt to live region (#4362)
Browse files Browse the repository at this point in the history
* Adds ActivitySendStatus provider

* Use ActivitySendStatus provider

* Fix test

* Fix test

* Fix test

* Add new field

* Add IMPEDED action

* Fix build

* Fix types for deleteKey

* Clean up console.log

* Fix tests

* Update comment

* Fix test

* Fix test

* Add tests for impeded/rejected

* Fix tests

* Fix test

* Fix tests

* Fix test

* Add tests

* Fix test

* Clean up

* Fix path

* Clean up

* Fix test

* Add new DirectLineEmulator

* Fix test

* Clean up

* Fix tests

* Clean up

* Clean up

* Add tests

* Fix test

* Clean up comments

* Clean up

* Clean up

* Add comments

* Rename isDiffMap to isMapEqual

* Add comments

* Add comments

* Add send failed to live region and active descendant

* Commentary clean up

* Update description

* Typo

* Update doc

* Verbiage

* Apply suggestions from code review

Co-authored-by: TJ Durnford <[email protected]>

* Constant-ize SendStatus

* Optionalize hideTimestamp

* Use reduce

* Use reduce

* Update CHANGELOG.md

Co-authored-by: TJ Durnford <[email protected]>

Co-authored-by: TJ Durnford <[email protected]>
  • Loading branch information
compulim and tdurnford authored Aug 3, 2022
1 parent 008aa26 commit 347ef80
Show file tree
Hide file tree
Showing 120 changed files with 9,058 additions and 7,399 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,20 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Suggested actions container is not longer a live region. The suggested action buttons will now be narrated by the chat history live region
- Published NPM packages will now include `/dist`, `/lib`, and `/src` folders
- The `/dist` folder was previously missing from our NPM packages
- The `activity.channelData.state` property is being deprecated in favor of the updated [`activity.channelData['webchat:send-status']`](https://github.com/microsoft/BotFramework-WebChat/blob/main/packages/core/src/types/WebChatActivity.ts) property. Main differences include:
- Previously, we would set the `state` property to `"send failed"` when the chat adapter failed to send the activity, or after passing a timeout as defined in `styleOptions.sendTimeout`
- The new `'webchat:send-status'` property will be set to `"send failed"` when the chat adapter fails to send the activity or after passing a hardcoded timeout of 5 minutes
- See PR [#4362](https://github.com/microsoft/BotFramework-WebChat/pull/4362) for details

### Changed

- Resolves [#4301](https://github.com/microsoft/BotFramework-WebChat/issues/4301). Updated `Dockerfile` to support secure container supply chain, by [@compulim](https://github.com/compulim) in PR [#4303](https://github.com/microsoft/BotFramework-WebChat/pull/4303)
- Resolves [#4317](https://github.com/microsoft/BotFramework-WebChat/issues/4317). Updated `package.json` to allowlist `/dist`, `/lib`, `/src`, by [@compulim](https://github.com/compulim) in PR [#4318](https://github.com/microsoft/BotFramework-WebChat/pull/4318)
- Resolves [#4322](https://github.com/microsoft/BotFramework-WebChat/issues/4322). Improved error messages for sending activities, by [@compulim](https://github.com/compulim) in PR [#4362](https://github.com/microsoft/BotFramework-WebChat/pull/4362)
- Resolves [#4211](https://github.com/microsoft/BotFramework-WebChat/issues/4211). Added new `useSendStatusByActivityKey` hook to check the UI send status of an outgoing activity, by [@compulim](https://github.com/compulim) in PR [#4362](https://github.com/microsoft/BotFramework-WebChat/pull/4362)
- The send status returned by this hook is designed to display different UIs that reflect the "sending", "send failed" or "sent" status of the activity
- When modifying `styleOptions.sendTimeout` prop, the send status returned by this hook may transition from `"send failed"` to `"sending"`, and vice versa
- This is different from the send status provided by the chat adapter, namely `activity.channelData['webchat:send-status']`

### Fixed

Expand All @@ -51,6 +60,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Fixes [#4325](https://github.com/microsoft/BotFramework-WebChat/issues/4325). `aria-keyshortcuts` should use modifier keys according to `KeyboardEvent` key values spec, by [@compulim](https://github.com/compulim), in PR [#4323](https://github.com/microsoft/BotFramework-WebChat/issues/4323)
- Fixes [#4327](https://github.com/microsoft/BotFramework-WebChat/issues/4327). In Adaptive Cards, `TextBlock` with `style="heading"` should have `aria-level` set, by [@compulim](https://github.com/compulim), in PR [#4329](https://github.com/microsoft/BotFramework-WebChat/issues/4329)
- Fixes [#3949](https://github.com/microsoft/BotFramework-WebChat/issues/3949). For accessibility reasons, buttons in Adaptive Cards should be `role="button"` instead of `role="menubar"`/`role="menuitem"`, by [@compulim](https://github.com/compulim), in PR [#4263](https://github.com/microsoft/BotFramework-WebChat/issues/4263)
- Fixes [#4211](https://github.com/microsoft/BotFramework-WebChat/issues/4211). Screen reader should read when an activity was failed to send, by [@compulim](https://github.com/compulim), in PR [#4326](https://github.com/microsoft/BotFramework-WebChat/issues/4326), also fixed:
- The "send failed" status on the activity should show up as soon as the chat adapter failed to send the activity

## Changes

Expand Down
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.
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.
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.
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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<!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="/__dist__/webchat-es5.js"></script>
</head>
<body>
<div id="webchat"></div>
<script>
run(
async function () {
const store = testHelpers.createStore();

const directLine = testHelpers.createDirectLineEmulator(store);

WebChat.renderWebChat(
{
directLine,
store,
styleOptions: {
groupTimestamp: 60000,
sendTimeout: 5000
}
},
document.getElementById('webchat')
);

await pageConditions.uiConnected();

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

await directLine.emulateIncomingActivity('Aloha!');

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

await pageConditions.became(
'failed to send message',
() => pageElements.activityStatuses()[0]?.innerText === 'Send failed. Retry.',
1000
);

expect(pageElements.activityActiveDescendantLabels().map(({ innerText }) => innerText)).toEqual([
'You said: Hello, World! Send failed. Click to interact.',
'Bot said: Aloha!'
]);
},
{ ignoreErrors: true }
);
</script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */

describe('accessibility requirement', () => {
test('active descendant accessible name should contains "Send failed" for failing activities', () =>
runHTML('accessibility.accessibleName.activityStatus.sendFailed'));
});
47 changes: 47 additions & 0 deletions __tests__/html/accessibility.accessibleName.simple.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<!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="/__dist__/webchat-es5.js"></script>
</head>
<body>
<div id="webchat"></div>
<script>
run(
async function () {
const store = testHelpers.createStore();

const directLine = testHelpers.createDirectLineEmulator(store);

WebChat.renderWebChat(
{
directLine,
store,
styleOptions: {
groupTimestamp: 60000,
sendTimeout: 5000
}
},
document.getElementById('webchat')
);

await pageConditions.uiConnected();

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

await sendMessage.resolveAll();

await directLine.emulateIncomingActivity('Aloha!');

expect(pageElements.activityActiveDescendantLabels().map(({ innerText }) => innerText)).toEqual([
'You said: Hello, World!',
'Bot said: Aloha!'
]);
},
{ ignoreErrors: true }
);
</script>
</body>
</html>
6 changes: 6 additions & 0 deletions __tests__/html/accessibility.accessibleName.simple.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */

describe('accessibility requirement', () => {
test('active descendant accessible name should contains simple message content', () =>
runHTML('accessibility.accessibleName.simple'));
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<!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="/__dist__/webchat-es5.js"></script>
</head>
<body>
<div id="webchat"></div>
<script>
run(
async function () {
const store = testHelpers.createStore();

const directLine = testHelpers.createDirectLineEmulator(store);

WebChat.renderWebChat(
{
directLine,
store,
styleOptions: {
groupTimestamp: 60000,
sendTimeout: 5000
}
},
document.getElementById('webchat')
);

await pageConditions.uiConnected();

const { flush } = pageObjects.observeLiveRegion();

const sendMessage = await directLine.emulateOutgoingActivity({ name: 'hello', type: 'event', value: 'aloha' });

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

await directLine.emulateIncomingActivity('Aloha!');

expect(flush()).toEqual(['Bot said:\nAloha!']);
},
{ ignoreErrors: true }
);
</script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */

describe('live region', () => {
test('should not narrate "failed to send message" through live region for event activity', () =>
runHTML('accessibility.liveRegion.activityStatus.sendFailed.event.html'));
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<!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="/__dist__/webchat-es5.js"></script>
</head>
<body>
<div id="webchat"></div>
<script>
run(
async function () {
const store = testHelpers.createStore();

const directLine = testHelpers.createDirectLineEmulator(store);

WebChat.renderWebChat(
{
directLine,
store,
styleOptions: {
groupTimestamp: 60000,
sendTimeout: 5000
}
},
document.getElementById('webchat')
);

await pageConditions.uiConnected();

const { flush } = pageObjects.observeLiveRegion();

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

await directLine.emulateIncomingActivity('Aloha!');

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

await pageConditions.became(
'failed to send message',
() => pageElements.activityStatuses()[0]?.innerText === 'Send failed. Retry.',
1000
);

expect(flush()).toEqual(['You said:\nHello, World!', 'Bot said:\nAloha!', 'Failed to send message.']);
},
{ ignoreErrors: true }
);
</script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */

describe('live region', () => {
test('should narrate "failed to send message" through live region', () =>
runHTML('accessibility.liveRegion.activityStatus.sendFailed.html'));
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<!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="/__dist__/webchat-es5.js"></script>
</head>
<body>
<div id="webchat"></div>
<script>
run(
async function () {
const store = testHelpers.createStore();

const directLine = testHelpers.createDirectLineEmulator(store);

WebChat.renderWebChat(
{
directLine,
store,
styleOptions: {
groupTimestamp: 60000,
sendTimeout: 5000
}
},
document.getElementById('webchat')
);

await pageConditions.uiConnected();

const { flush } = pageObjects.observeLiveRegion();

const sendMessage = await directLine.emulateOutgoingActivity({ type: 'typing' });

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

await directLine.emulateIncomingActivity('Aloha!');

expect(flush()).toEqual(['Bot said:\nAloha!']);
},
{ ignoreErrors: true }
);
</script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */

describe('live region', () => {
test('should not narrate "failed to send message" through live region for typing activity', () =>
runHTML('accessibility.liveRegion.activityStatus.sendFailed.typing.html'));
});
Loading

0 comments on commit 347ef80

Please sign in to comment.