diff --git a/CHANGELOG.md b/CHANGELOG.md index 71293c90fe..35de4bd6c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -75,6 +75,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Fix [#1515](https://github.com/microsoft/BotFramework-WebChat/issues/1515). Added dynamic phrases when using Cognitive Services Speech Services, by [@compulim](https://github.com/compulim) in PR [#2246](https://github.com/microsoft/BotFramework-WebChat/pull/2246) - Fix [#2273](https://github.com/microsoft/BotFramework-WebChat/issues/2273). Add `ScreenReaderText` component, by [@corinagum](https://github.com/corinagum) in PR [#2278](https://github.com/microsoft/BotFramework-WebChat/pull/2278) - Fix [#2231](https://github.com/microsoft/BotFramework-WebChat/issues/2231). Fallback to English (US) if date time formatting failed, by [@compulim](https://github.com/compulim) in PR [#2286](https://github.com/microsoft/BotFramework-WebChat/pull/2286) +- Fix [#2298](https://github.com/microsoft/BotFramework-WebChat/issues/2298). Speech synthesize errors to be ignored, by [@compulim](https://github.com/compulim) in PR [#2300](https://github.com/microsoft/BotFramework-WebChat/issues/2300) ### Added diff --git a/__tests__/inputHint.js b/__tests__/inputHint.js index cdb54e89d5..e0474eae05 100644 --- a/__tests__/inputHint.js +++ b/__tests__/inputHint.js @@ -21,7 +21,7 @@ describe('input hint', () => { await driver.wait(uiConnected(), timeouts.directLine); - await pageObjects.sendMessageViaMicrophone('hint expecting input'); + await pageObjects.sendMessageViaMicrophone('hint expecting'); await driver.wait(minNumActivitiesShown(2), timeouts.directLine); @@ -41,7 +41,7 @@ describe('input hint', () => { await driver.wait(uiConnected(), timeouts.directLine); - await pageObjects.sendMessageViaMicrophone('hint expecting input'); + await pageObjects.sendMessageViaMicrophone('hint expecting'); await driver.wait(minNumActivitiesShown(2), timeouts.directLine); @@ -59,7 +59,7 @@ describe('input hint', () => { await driver.wait(uiConnected(), timeouts.directLine); - await pageObjects.sendMessageViaMicrophone('hint accepting input'); + await pageObjects.sendMessageViaMicrophone('hint accepting'); await driver.wait(minNumActivitiesShown(2), timeouts.directLine); @@ -79,7 +79,7 @@ describe('input hint', () => { await driver.wait(uiConnected(), timeouts.directLine); - await pageObjects.sendMessageViaSendBox('hint accepting input'); + await pageObjects.sendMessageViaSendBox('hint accepting'); await driver.wait(minNumActivitiesShown(2), timeouts.directLine); @@ -97,7 +97,7 @@ describe('input hint', () => { await driver.wait(uiConnected(), timeouts.directLine); - await pageObjects.sendMessageViaMicrophone('hint ignoring input'); + await pageObjects.sendMessageViaMicrophone('hint ignoring'); await driver.wait(minNumActivitiesShown(2), timeouts.directLine); @@ -117,7 +117,7 @@ describe('input hint', () => { await driver.wait(uiConnected(), timeouts.directLine); - await pageObjects.sendMessageViaSendBox('hint ignoring input'); + await pageObjects.sendMessageViaSendBox('hint ignoring'); await driver.wait(minNumActivitiesShown(2), timeouts.directLine); diff --git a/__tests__/setup/pageObjects/errorSpeechSynthesize.js b/__tests__/setup/pageObjects/errorSpeechSynthesize.js new file mode 100644 index 0000000000..6a2647380f --- /dev/null +++ b/__tests__/setup/pageObjects/errorSpeechSynthesize.js @@ -0,0 +1,5 @@ +import executePromiseScript from './executePromiseScript'; + +export default async function errorSpeechSynthesize(driver, reason) { + return await executePromiseScript(driver, reason => window.WebSpeechMock.mockErrorSynthesize(reason), reason); +} diff --git a/__tests__/setup/pageObjects/index.js b/__tests__/setup/pageObjects/index.js index 32fc37a4e2..a6ed69a808 100644 --- a/__tests__/setup/pageObjects/index.js +++ b/__tests__/setup/pageObjects/index.js @@ -3,6 +3,7 @@ import clickSendButton from './clickSendButton'; import clickSuggestedActionButton from './clickSuggestedActionButton'; import dispatchAction from './dispatchAction'; import endSpeechSynthesize from './endSpeechSynthesize'; +import errorSpeechSynthesize from './errorSpeechSynthesize'; import executePromiseScript from './executePromiseScript'; import getNumActivitiesShown from './getNumActivitiesShown'; import getSendBoxText from './getSendBoxText'; @@ -32,6 +33,7 @@ export default function pageObjects(driver) { clickSuggestedActionButton, dispatchAction, endSpeechSynthesize, + errorSpeechSynthesize, executePromiseScript, getNumActivitiesShown, getSendBoxText, diff --git a/__tests__/setup/web/mockWebSpeech.js b/__tests__/setup/web/mockWebSpeech.js index 08a7aeebf4..568590edf0 100644 --- a/__tests__/setup/web/mockWebSpeech.js +++ b/__tests__/setup/web/mockWebSpeech.js @@ -309,6 +309,18 @@ window.WebSpeechMock = { }); }, + mockErrorSynthesize(error = 'artificial-error') { + return new Promise(resolve => { + speechSynthesisBroker.consume(utterance => { + utterance.dispatchEvent({ error, type: 'error' }); + + const { lang, pitch, rate, text, voice, volume } = utterance; + + resolve({ lang, pitch, rate, text, voice, volume }); + }); + }); + }, + mockRecognize(...args) { speechRecognitionBroker.produce(...args); }, diff --git a/__tests__/speech.recognition.js b/__tests__/speech.recognition.js index cac47cd6d6..c004135a20 100644 --- a/__tests__/speech.recognition.js +++ b/__tests__/speech.recognition.js @@ -17,7 +17,7 @@ describe('speech recognition', () => { } }); - await pageObjects.sendMessageViaMicrophone('hint expecting input'); + await pageObjects.sendMessageViaMicrophone('hint expecting'); await driver.wait(minNumActivitiesShown(2), timeouts.directLine); await driver.wait(speechSynthesisUtterancePended(), timeouts.ui); diff --git a/__tests__/speech.synthesis.js b/__tests__/speech.synthesis.js index a56bc91156..c4312b3799 100644 --- a/__tests__/speech.synthesis.js +++ b/__tests__/speech.synthesis.js @@ -1,6 +1,7 @@ import { timeouts } from './constants.json'; import minNumActivitiesShown from './setup/conditions/minNumActivitiesShown'; +import speechRecognitionStartCalled from './setup/conditions/speechRecognitionStartCalled'; import speechSynthesisUtterancePended from './setup/conditions/speechSynthesisUtterancePended'; // selenium-webdriver API doc: @@ -54,4 +55,23 @@ describe('speech synthesis', () => { await pageObjects.endSpeechSynthesize(); }); + + test('should start recognition after failing on speech synthesis with activity of expecting input', async () => { + const { driver, pageObjects } = await setupWebDriver({ + props: { + webSpeechPonyfillFactory: () => window.WebSpeechMock + } + }); + + await pageObjects.sendMessageViaMicrophone('hint expecting'); + + await expect(speechRecognitionStartCalled().fn(driver)).resolves.toBeFalsy(); + await driver.wait(minNumActivitiesShown(2), timeouts.directLine); + await driver.wait(speechSynthesisUtterancePended(), timeouts.ui); + + await pageObjects.startSpeechSynthesize(); + await pageObjects.errorSpeechSynthesize(); + + await expect(speechRecognitionStartCalled().fn(driver)).resolves.toBeTruthy(); + }); }); diff --git a/packages/bundle/package-lock.json b/packages/bundle/package-lock.json index 4dce684406..a62dd98910 100644 --- a/packages/bundle/package-lock.json +++ b/packages/bundle/package-lock.json @@ -7106,9 +7106,9 @@ } }, "web-speech-cognitive-services": { - "version": "4.0.1-master.ad6e780", - "resolved": "https://registry.npmjs.org/web-speech-cognitive-services/-/web-speech-cognitive-services-4.0.1-master.ad6e780.tgz", - "integrity": "sha512-YZw88M+yUcHtbl5li5fxLVBcu5fs2Vx6PKaxBR+oOTi1yAfCXlZM/JEueYFLf5ayu4uH6BFNVgn4sHiQVfOotw==", + "version": "4.0.1-master.d9fc5d3", + "resolved": "https://registry.npmjs.org/web-speech-cognitive-services/-/web-speech-cognitive-services-4.0.1-master.d9fc5d3.tgz", + "integrity": "sha512-mZOKH9E1g1qDQmmIvbnmjN/zBzJjJBGv+0LOw1kNIfgim2WEgTlzgb364o08cPIaokJhzD+FBMQ583Si8mmDkw==", "requires": { "@babel/runtime": "^7.5.5", "base64-arraybuffer": "^0.2.0", diff --git a/packages/bundle/package.json b/packages/bundle/package.json index ee8fd5fd43..5a03b69d21 100644 --- a/packages/bundle/package.json +++ b/packages/bundle/package.json @@ -46,7 +46,7 @@ "prop-types": "^15.7.2", "sanitize-html": "^1.19.0", "url-search-params-polyfill": "^5.0.0", - "web-speech-cognitive-services": "4.0.1-master.ad6e780", + "web-speech-cognitive-services": "4.0.1-master.d9fc5d3", "whatwg-fetch": "^3.0.0" }, "devDependencies": { diff --git a/packages/component/src/Activity/Speak.js b/packages/component/src/Activity/Speak.js index 2149d1bfe3..e98d5e82f5 100644 --- a/packages/component/src/Activity/Speak.js +++ b/packages/component/src/Activity/Speak.js @@ -48,7 +48,7 @@ const Speak = ({ activity, markAsSpoken, selectVoice, styleSet }) => { return ( - + {!!styleSet.options.showSpokenText && } );