Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic test for speech recognition and synthesis #2153

Merged
merged 25 commits into from
Jul 9, 2019
Merged
Show file tree
Hide file tree
Changes from 18 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Added documentation for using Web Chat dev build, by [@corinagum](https://github.com/corinagum), in PR [#2074](https://github.com/Microsoft/BotFramework-WebChat/pull/2074)
- Added the Web Chat version to DirectLine's botAgent option, by [@tdurnford](https://github.com/tdurnford), in PR [#2101](https://github.com/Microsoft/BotFramework-WebChat/pull/2101)
- Added `richCardWrapTitle` to `defaultStyleOptions`, by [@tdurnford](https://github.com/tdurnford), in PR [#2115](https://github.com/Microsoft/BotFramework-WebChat/pull/2115)
- Added test harness for speech recognition and synthesis for [#2122](https://github.com/microsoft/BotFramework-WebChat/issues/2122), by [@compulim](https://github.com/compulim), in PR [#2153](https://github.com/Microsoft/BotFramework-WebChat/pull/2153)

### Changed

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.
3 changes: 2 additions & 1 deletion __tests__/constants.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"navigation": 10000,
"postActivity": 30000,
"scrollToBottom": 1000,
"test": 60000
"test": 60000,
"ui": 1000
}
}
7 changes: 7 additions & 0 deletions __tests__/setup/conditions/speechRecognitionStarted.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Condition } from 'selenium-webdriver';

import isRecognizingSpeech from '../pageObjects/isRecognizingSpeech';

export default function speechRecognitionStarted() {
return new Condition('Speech recognition to start', async driver => await isRecognizingSpeech(driver));
}
15 changes: 15 additions & 0 deletions __tests__/setup/conditions/speechSynthesisPending.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Condition } from 'selenium-webdriver';

import isPendingSpeechSynthesis from '../pageObjects/isPendingSpeechSynthesis';

export default function speechRecognitionStarted() {
return new Condition('Speech synthesis is pending', async driver => await isPendingSpeechSynthesis(driver));
}

function negate() {
const condition = speechRecognitionStarted();

return new Condition('Speech synthesis is not pending', async driver => !(await condition.fn(driver)));
}

export { negate };
25 changes: 25 additions & 0 deletions __tests__/setup/pageObjects/executePromiseScript.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// executeAsyncScript is not running a Promise function and is not able to deal with errors.
// https://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebDriver.html#executeAsyncScript
// This function will use executeAsyncScript to run a Promise function in an async fashion.

export default async function executePromiseScript(driver, fn, ...args) {
const { error, result } = await driver.executeAsyncScript(
(fn, args, callback) => {
eval(`(${fn})`)
.apply(null, args)
.then(result => callback({ result }), error => callback({ error }));
},
fn + '',
args
);

if (error) {
const err = new Error(error.message);

err.stack = error.stack;

throw err;
} else {
return result;
}
}
5 changes: 5 additions & 0 deletions __tests__/setup/pageObjects/getMicrophoneButton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { By } from 'selenium-webdriver';

export default async function getMicrophoneButton(driver) {
return await driver.findElement(By.css('[aria-controls="webchatSendBoxMicrophoneButton"] > button'));
}
5 changes: 5 additions & 0 deletions __tests__/setup/pageObjects/getSendBoxTextBox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { By } from 'selenium-webdriver';

export default async function isRecognizingSpeech(driver) {
return await driver.findElement(By.css('[role="form"] > * > form > input[type="text"]'));
}
18 changes: 17 additions & 1 deletion __tests__/setup/pageObjects/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import dispatchAction from './dispatchAction';
import executePromiseScript from './executePromiseScript';
import getMicrophoneButton from './getMicrophoneButton';
import getSendBoxTextBox from './getSendBoxTextBox';
import isPendingSpeechSynthesis from './isPendingSpeechSynthesis';
import isRecognizingSpeech from './isRecognizingSpeech';
import peekSpeechSynthesisUtterance from './peekSpeechSynthesisUtterance';
import pingBot from './pingBot';
import putSpeechRecognitionResult from './putSpeechRecognitionResult';
import sendMessageViaSendBox from './sendMessageViaSendBox';
import takeSpeechSynthesisUtterance from './takeSpeechSynthesisUtterance';

function mapMap(map, mapper) {
return Object.keys(map).reduce((final, key) => {
Expand All @@ -14,8 +22,16 @@ export default function pageObjects(driver) {
return mapMap(
{
dispatchAction,
executePromiseScript,
getMicrophoneButton,
getSendBoxTextBox,
isPendingSpeechSynthesis,
isRecognizingSpeech,
peekSpeechSynthesisUtterance,
pingBot,
sendMessageViaSendBox
putSpeechRecognitionResult,
sendMessageViaSendBox,
takeSpeechSynthesisUtterance
},
fn => fn.bind(null, driver)
);
Expand Down
3 changes: 3 additions & 0 deletions __tests__/setup/pageObjects/isPendingSpeechSynthesis.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default async function isPendingSpeechSynthesis(driver) {
return await driver.executeScript(() => !!window.WebSpeechMock.peekSynthesize());
}
3 changes: 3 additions & 0 deletions __tests__/setup/pageObjects/isRecognizingSpeech.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default async function isRecognizingSpeech(driver) {
return await driver.executeScript(() => window.WebSpeechMock.isRecognizing());
}
3 changes: 3 additions & 0 deletions __tests__/setup/pageObjects/peekSpeechSynthesisUtterance.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default async function peekSynthesizeUtterance(driver) {
return await driver.executeScript(() => window.WebSpeechMock.peekSynthesize());
}
3 changes: 3 additions & 0 deletions __tests__/setup/pageObjects/putSpeechRecognitionResult.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default async function putSpeechRecognitionResult(driver, ...args) {
await driver.executeScript((...args) => window.WebSpeechMock.mockRecognize(...args), ...args);
}
5 changes: 3 additions & 2 deletions __tests__/setup/pageObjects/sendMessageViaSendBox.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { By, Key } from 'selenium-webdriver';
import { Key } from 'selenium-webdriver';

import { timeouts } from '../../constants.json';
import allOutgoingActivitiesSent from '../conditions/allOutgoingActivitiesSent';
import getSendBoxTextBox from './getSendBoxTextBox';

export default async function sendMessageViaSendBox(driver, text, { waitForSend = true }) {
const input = await driver.findElement(By.css('[role="form"] > * > form > input[type="text"]'));
const input = await getSendBoxTextBox(driver);

await input.sendKeys(text, Key.RETURN);

Expand Down
5 changes: 5 additions & 0 deletions __tests__/setup/pageObjects/takeSpeechSynthesisUtterance.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import executePromiseScript from './executePromiseScript';

export default async function takeSpeechSynthesisUtterance(driver) {
return await executePromiseScript(driver, () => window.WebSpeechMock.mockSynthesize());
}
4 changes: 3 additions & 1 deletion __tests__/setup/web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
width: 100%;
}
</style>
<script src="https://unpkg.com/event-target-shim@5.0.1/dist/event-target-shim.umd.js"></script>
<script src="/mockWebSpeech.js"></script>
</head>
<body>
<div id="webchat" role="main"></div>
Expand Down Expand Up @@ -143,4 +145,4 @@
};
</script>
</body>
</html>
</html>
Loading