From 98e7b213ff387b4497f412f9614ed54714adee58 Mon Sep 17 00:00:00 2001 From: Tony Anziano Date: Mon, 7 Oct 2019 17:37:49 -0700 Subject: [PATCH] Fixed open bot dialog url validation a11y issue. --- CHANGELOG.md | 1 + .../ui/dialogs/openBotDialog/openBotDialog.spec.tsx | 10 ---------- .../src/ui/dialogs/openBotDialog/openBotDialog.tsx | 10 ---------- .../dialogs/openBotDialog/openBotDialogContainer.ts | 4 ---- .../src/widget/autoComplete/autoComplete.spec.tsx | 7 +++++++ .../src/widget/autoComplete/autoComplete.tsx | 13 +++++++++++-- 6 files changed, 19 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ebe7ebbe1..2ea7d81d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [1902](https://github.com/microsoft/BotFramework-Emulator/pull/1902) - [1893](https://github.com/microsoft/BotFramework-Emulator/pull/1893) - [1916](https://github.com/microsoft/BotFramework-Emulator/pull/1916) + - [1918](https://github.com/microsoft/BotFramework-Emulator/pull/1918) - [client] Fixed an issue with the transcripts path input inside of the resource settings dialog in PR [1836](https://github.com/microsoft/BotFramework-Emulator/pull/1836) - [client] Implemented HTML app menu for Windows in PR [1893](https://github.com/microsoft/BotFramework-Emulator/pull/1893) diff --git a/packages/app/client/src/ui/dialogs/openBotDialog/openBotDialog.spec.tsx b/packages/app/client/src/ui/dialogs/openBotDialog/openBotDialog.spec.tsx index bb9a881c5..2264300c9 100644 --- a/packages/app/client/src/ui/dialogs/openBotDialog/openBotDialog.spec.tsx +++ b/packages/app/client/src/ui/dialogs/openBotDialog/openBotDialog.spec.tsx @@ -249,16 +249,6 @@ describe('The OpenBotDialog', () => { expect(instance.state.botUrl).toBe('http://localhost:3978'); }); - it('should announce any validation error messages', () => { - // make sure there are no leftover alerts from previous test(s) - const preExistingAlerts = document.querySelectorAll('body > span#alert-from-service'); - preExistingAlerts.forEach(alert => alert.remove()); - const spy = jest.spyOn(ariaAlertService, 'alert').mockReturnValueOnce(undefined); - instance.announceErrorMessage('Invalid bot url.'); - - expect(spy).toHaveBeenCalledWith('For Bot URL, Invalid bot url.'); - }); - it('should call the appropriate command when onAnchorClick is called', () => { instance.props.onAnchorClick('http://blah'); expect(mockDispatch).toHaveBeenCalledWith( diff --git a/packages/app/client/src/ui/dialogs/openBotDialog/openBotDialog.tsx b/packages/app/client/src/ui/dialogs/openBotDialog/openBotDialog.tsx index ebe4c355e..1d71a10e4 100644 --- a/packages/app/client/src/ui/dialogs/openBotDialog/openBotDialog.tsx +++ b/packages/app/client/src/ui/dialogs/openBotDialog/openBotDialog.tsx @@ -46,12 +46,9 @@ import * as React from 'react'; import { ChangeEvent, Component, MouseEvent, ReactNode } from 'react'; import { EmulatorMode } from '@bfemulator/sdk-shared'; -import { debounce } from '../../../utils'; - import * as openBotStyles from './openBotDialog.scss'; export interface OpenBotDialogProps { - createAriaAlert?: (msg: string) => void; mode?: EmulatorMode; isDebug?: boolean; onAnchorClick?: (url: string) => void; @@ -136,7 +133,6 @@ export class OpenBotDialog extends Component { - // ensure that we aren't spamming aria alerts each time the input is validated - this.props.createAriaAlert(`For Bot URL, ${msg}`); - }, 2000); } diff --git a/packages/app/client/src/ui/dialogs/openBotDialog/openBotDialogContainer.ts b/packages/app/client/src/ui/dialogs/openBotDialog/openBotDialogContainer.ts index 3373d12e5..2ce0929cf 100644 --- a/packages/app/client/src/ui/dialogs/openBotDialog/openBotDialogContainer.ts +++ b/packages/app/client/src/ui/dialogs/openBotDialog/openBotDialogContainer.ts @@ -38,16 +38,12 @@ import { Action } from 'redux'; import { openBotViaFilePathAction, openBotViaUrlAction } from '../../../state/actions/botActions'; import { DialogService } from '../service'; import { RootState } from '../../../state/store'; -import { ariaAlertService } from '../../a11y'; import { executeCommand } from '../../../state/actions/commandActions'; import { OpenBotDialog, OpenBotDialogProps, OpenBotDialogState } from './openBotDialog'; const mapDispatchToProps = (dispatch: (action: Action) => void): OpenBotDialogProps => { return { - createAriaAlert: (msg: string) => { - ariaAlertService.alert(msg); - }, onAnchorClick: (url: string) => { dispatch(executeCommand(true, SharedConstants.Commands.Electron.OpenExternal, null, url)); }, diff --git a/packages/sdk/ui-react/src/widget/autoComplete/autoComplete.spec.tsx b/packages/sdk/ui-react/src/widget/autoComplete/autoComplete.spec.tsx index a84d57f3c..73e7932bb 100644 --- a/packages/sdk/ui-react/src/widget/autoComplete/autoComplete.spec.tsx +++ b/packages/sdk/ui-react/src/widget/autoComplete/autoComplete.spec.tsx @@ -76,6 +76,13 @@ describe('', () => { expect(instance.errorMessage).toBeTruthy(); }); + it('should generate an error message id if there is an error message', () => { + expect(instance.errorMessageId).toBe(undefined); + + wrapper.setProps({ errorMessage: 'something broke :(' }); + expect(instance.errorMessageId).toBe(`auto-complete-err-msg-${wrapper.state().id}`); + }); + it('should generate a label id if a label has been provided', () => { expect(instance.labelId).toBe(undefined); diff --git a/packages/sdk/ui-react/src/widget/autoComplete/autoComplete.tsx b/packages/sdk/ui-react/src/widget/autoComplete/autoComplete.tsx index 4095c65d3..e10fb859d 100644 --- a/packages/sdk/ui-react/src/widget/autoComplete/autoComplete.tsx +++ b/packages/sdk/ui-react/src/widget/autoComplete/autoComplete.tsx @@ -74,7 +74,7 @@ export class AutoComplete extends Component {this.errorMessage} {this.results} @@ -148,11 +149,19 @@ export class AutoComplete extends Component{errorMessage}; + return ( + + {errorMessage} + + ); } return undefined; } + private get errorMessageId(): string { + return this.props.errorMessage ? `auto-complete-err-msg-${this.state.id}` : undefined; + } + private get labelId(): string { // label id is only necessary if we have a label return this.props.label ? `auto-complete-label-${this.state.id}` : undefined;