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 more tests #2293

Merged
merged 11 commits into from
Aug 10, 2019
Merged
Show file tree
Hide file tree
Changes from 6 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: 2 additions & 2 deletions __tests__/clockSkew.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ describe('Clock skew', () => {

// Make sure the clock skew is set correctly.
// If it is not set, the result could be false-positive.
expect(pageObjects.getStore()).resolves.toHaveProperty('clockSkewAdjustment', 120000);
await expect(pageObjects.getStore()).resolves.toHaveProperty('clockSkewAdjustment', 120000);

await pageObjects.sendMessageViaSendBox('echo This outgoing activity should be the last in the list.', {
waitForSend: false
Expand All @@ -94,7 +94,7 @@ describe('Clock skew', () => {

const lastActivity = await driver.findElement(By.css('[role="list"] > li:last-child p'));

expect(lastActivity.getText()).resolves.toBe('echo This outgoing activity should be the last in the list.');
await expect(lastActivity.getText()).resolves.toBe('echo This outgoing activity should be the last in the list.');

// Skip the echoback for 2nd user-originated activity, so we don't apply server timestamp to it. It will be visually appear as "sending".
// Even the 2nd user-originated activity didn't apply server timestamp, the insertion-sort algorithm should put bot-originated activity below it.
Expand Down
47 changes: 47 additions & 0 deletions __tests__/focus.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Key } from 'selenium-webdriver';
import { timeouts } from './constants.json';

import uiConnected from './setup/conditions/uiConnected';
import suggestedActionsShowed from './setup/conditions/suggestedActionsShowed';

// selenium-webdriver API doc:
// https://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebDriver.html

jest.setTimeout(timeouts.test);

// Verification of fix of #1971
compulim marked this conversation as resolved.
Show resolved Hide resolved
test('should not focus send box after clicking on send button', async () => {
const { driver, pageObjects } = await setupWebDriver();

await driver.wait(uiConnected(), timeouts.directLine);

await pageObjects.setSendBoxText('echo 123');
await pageObjects.clickSendButton();

await expect(pageObjects.hasFocusOnSendBoxTextBox()).resolves.toBeFalsy();
});

// Verification of fix of #1971
compulim marked this conversation as resolved.
Show resolved Hide resolved
test('should not focus send box after clicking on suggested actions', async () => {
const { driver, pageObjects } = await setupWebDriver();

await driver.wait(uiConnected(), timeouts.directLine);
await pageObjects.sendMessageViaSendBox('suggested-actions');

await driver.wait(suggestedActionsShowed(), timeouts.directLine);

await pageObjects.clickSuggestedActionButton(0);

await expect(pageObjects.hasFocusOnSendBoxTextBox()).resolves.toBeFalsy();
});

// Verification of fix of #1971
compulim marked this conversation as resolved.
Show resolved Hide resolved
test('should focus send box after pressing ENTER to send message', async () => {
const { driver, pageObjects } = await setupWebDriver();

await driver.wait(uiConnected(), timeouts.directLine);

await pageObjects.setSendBoxText('echo 123', Key.RETURN);

await expect(pageObjects.hasFocusOnSendBoxTextBox()).resolves.toBeTruthy();
});
27 changes: 13 additions & 14 deletions __tests__/inputHint.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { timeouts } from './constants.json';

import isRecognizingSpeech from './setup/pageObjects/isRecognizingSpeech';
import hasSpeechRecognitionStartCalled from './setup/pageObjects/hasSpeechRecognitionStartCalled';
compulim marked this conversation as resolved.
Show resolved Hide resolved
import minNumActivitiesShown from './setup/conditions/minNumActivitiesShown';
import speechSynthesisPending from './setup/conditions/speechSynthesisPending';
import uiConnected from './setup/conditions/uiConnected';

// selenium-webdriver API doc:
Expand All @@ -25,11 +24,11 @@ describe('input hint', () => {

await driver.wait(minNumActivitiesShown(2), timeouts.directLine);

await driver.wait(speechSynthesisPending(), timeouts.ui);
await driver.wait(pageObjects.hasPendingSpeechSynthesisUtterance(), timeouts.ui);
compulim marked this conversation as resolved.
Show resolved Hide resolved
await pageObjects.startSpeechSynthesize();
await pageObjects.endSpeechSynthesize();

expect(isRecognizingSpeech(driver)).resolves.toBeTruthy();
await expect(hasSpeechRecognitionStartCalled(driver)).resolves.toBeTruthy();
});

test('should not turn on microphone if initiated via typing', async () => {
Expand All @@ -45,7 +44,7 @@ describe('input hint', () => {

await driver.wait(minNumActivitiesShown(2), timeouts.directLine);

expect(isRecognizingSpeech(driver)).resolves.toBeFalsy();
await expect(hasSpeechRecognitionStartCalled(driver)).resolves.toBeFalsy();
});
});

Expand All @@ -63,11 +62,11 @@ describe('input hint', () => {

await driver.wait(minNumActivitiesShown(2), timeouts.directLine);

await driver.wait(speechSynthesisPending(), timeouts.ui);
await driver.wait(pageObjects.hasPendingSpeechSynthesisUtterance(), timeouts.ui);
await pageObjects.startSpeechSynthesize();
await pageObjects.endSpeechSynthesize();

expect(isRecognizingSpeech(driver)).resolves.toBeFalsy();
await expect(hasSpeechRecognitionStartCalled(driver)).resolves.toBeFalsy();
});

test('should not turn on microphone if initiated via typing', async () => {
Expand All @@ -83,7 +82,7 @@ describe('input hint', () => {

await driver.wait(minNumActivitiesShown(2), timeouts.directLine);

expect(isRecognizingSpeech(driver)).resolves.toBeFalsy();
await expect(hasSpeechRecognitionStartCalled(driver)).resolves.toBeFalsy();
});
});

Expand All @@ -101,11 +100,11 @@ describe('input hint', () => {

await driver.wait(minNumActivitiesShown(2), timeouts.directLine);

await driver.wait(speechSynthesisPending(), timeouts.ui);
await driver.wait(pageObjects.hasPendingSpeechSynthesisUtterance(), timeouts.ui);
await pageObjects.startSpeechSynthesize();
await pageObjects.endSpeechSynthesize();

expect(isRecognizingSpeech(driver)).resolves.toBeFalsy();
await expect(hasSpeechRecognitionStartCalled(driver)).resolves.toBeFalsy();
});

test('should turn off microphone if initiated via typing', async () => {
Expand All @@ -121,7 +120,7 @@ describe('input hint', () => {

await driver.wait(minNumActivitiesShown(2), timeouts.directLine);

expect(isRecognizingSpeech(driver)).resolves.toBeFalsy();
await expect(hasSpeechRecognitionStartCalled(driver)).resolves.toBeFalsy();
});
});

Expand All @@ -139,11 +138,11 @@ describe('input hint', () => {

await driver.wait(minNumActivitiesShown(2), timeouts.directLine);

await driver.wait(speechSynthesisPending(), timeouts.ui);
await driver.wait(pageObjects.hasPendingSpeechSynthesisUtterance(), timeouts.ui);
await pageObjects.startSpeechSynthesize();
await pageObjects.endSpeechSynthesize();

expect(isRecognizingSpeech(driver)).resolves.toBeFalsy();
await expect(hasSpeechRecognitionStartCalled(driver)).resolves.toBeFalsy();
});

test('should not turn on microphone if initiated via typing', async () => {
Expand All @@ -159,7 +158,7 @@ describe('input hint', () => {

await driver.wait(minNumActivitiesShown(2), timeouts.directLine);

expect(isRecognizingSpeech(driver)).resolves.toBeFalsy();
await expect(hasSpeechRecognitionStartCalled(driver)).resolves.toBeFalsy();
});
});
});
15 changes: 0 additions & 15 deletions __tests__/setup/conditions/speechRecognitionStarted.js

This file was deleted.

15 changes: 0 additions & 15 deletions __tests__/setup/conditions/speechSynthesisPending.js

This file was deleted.

7 changes: 7 additions & 0 deletions __tests__/setup/pageObjects/clickMicrophoneButton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import getMicrophoneButton from './elements/getMicrophoneButton';

export default async function clickMicrophoneButton(driver) {
const microphoneButton = await getMicrophoneButton(driver);

await microphoneButton.click();
}
5 changes: 5 additions & 0 deletions __tests__/setup/pageObjects/clickSendButton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import getSendButton from './elements/getSendButton';

export default async function clickSendButton(driver) {
(await getSendButton(driver)).click();
}
7 changes: 7 additions & 0 deletions __tests__/setup/pageObjects/clickSuggestedActionButton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import getSuggestedActionButtons from './elements/getSuggestedActionButtons';

export default async function clickSuggestedActionButton(driver, index) {
const suggestedActions = await getSuggestedActionButtons(driver);

await suggestedActions[index].click();
}
9 changes: 9 additions & 0 deletions __tests__/setup/pageObjects/elements/getSendBoxTextBox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { By } from 'selenium-webdriver';

const CSS_SELECTOR = '[role="form"] > * > form > input[type="text"]';

export default async function getSendBoxTextBox(driver) {
return await driver.findElement(By.css(CSS_SELECTOR));
}

export { CSS_SELECTOR };
5 changes: 5 additions & 0 deletions __tests__/setup/pageObjects/elements/getSendButton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { By } from 'selenium-webdriver';

export default async function getSendButton(driver) {
return await driver.findElement(By.css('[role="form"] button[title="Send"]'));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { By } from 'selenium-webdriver';

export default async function getSuggestedActionButtons(driver) {
return await driver.findElements(By.css('[role="form"] > :nth-child(2) ul > li button'));
}
5 changes: 5 additions & 0 deletions __tests__/setup/pageObjects/getNumActivitiesShown.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { By } from 'selenium-webdriver';

export default async function getNumActivitiesShown(driver) {
return (await driver.findElements(By.css(`[role="listitem"]`))).length;
}
7 changes: 7 additions & 0 deletions __tests__/setup/pageObjects/getSendBoxText.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import getSendBoxTextBox from './elements/getSendBoxTextBox';

export default async function getSendBoxText(driver) {
const textBox = await getSendBoxTextBox(driver);

return await textBox.getAttribute('value');
}
5 changes: 0 additions & 5 deletions __tests__/setup/pageObjects/getSendBoxTextBox.js

This file was deleted.

19 changes: 19 additions & 0 deletions __tests__/setup/pageObjects/hasFocusOnSendBoxTextBox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { By } from 'selenium-webdriver';
import getSendBoxTextBox, { CSS_SELECTOR } from './elements/getSendBoxTextBox';

export default async function hasFocusOnSendBoxTextBox(driver) {
// Make sure the send box text box is visible
await getSendBoxTextBox(driver);

try {
await driver.findElement(By.css(CSS_SELECTOR + ':focus'));

return true;
} catch (err) {
if (err.name === 'NoSuchElementError') {
return false;
}

throw err;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default async function hasSpeechRecognitionStartCalled(driver) {
return await driver.executeScript(() => window.WebSpeechMock.hasSpeechRecognitionStartCalled());
}
31 changes: 21 additions & 10 deletions __tests__/setup/pageObjects/index.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import clickMicrophoneButton from './clickMicrophoneButton';
import clickSendButton from './clickSendButton';
import clickSuggestedActionButton from './clickSuggestedActionButton';
import dispatchAction from './dispatchAction';
import endSpeechSynthesize from './endSpeechSynthesize';
import executePromiseScript from './executePromiseScript';
import getActivityElements from './getActivityElements';
import getMicrophoneButton from './getMicrophoneButton';
import getSendBoxTextBox from './getSendBoxTextBox';
import getNumActivitiesShown from './getNumActivitiesShown';
import getSendBoxText from './getSendBoxText';
import getStore from './getStore';
import getUploadButton from './getUploadButton';
import hasFocusOnSendBoxTextBox from './hasFocusOnSendBoxTextBox';
import hasPendingSpeechSynthesisUtterance from './hasPendingSpeechSynthesisUtterance';
import isRecognizingSpeech from './isRecognizingSpeech';
import hasSpeechRecognitionStartCalled from './hasSpeechRecognitionStartCalled';
import isDictating from './isDictating';
import pingBot from './pingBot';
import putSpeechRecognitionResult from './putSpeechRecognitionResult';
import sendFile from './sendFile';
import sendMessageViaMicrophone from './sendMessageViaMicrophone';
import sendMessageViaSendBox from './sendMessageViaSendBox';
import setSendBoxText from './setSendBoxText';
import startSpeechSynthesize from './startSpeechSynthesize';

function mapMap(map, mapper) {
Expand All @@ -24,23 +28,30 @@ function mapMap(map, mapper) {
}

export default function pageObjects(driver) {
// We will not export page objects under /elements/ folder
// The /elements/ folder is designed to hold "get elements" function internal to page objects
compulim marked this conversation as resolved.
Show resolved Hide resolved

return mapMap(
{
clickMicrophoneButton,
clickSendButton,
clickSuggestedActionButton,
dispatchAction,
endSpeechSynthesize,
executePromiseScript,
getActivityElements,
getMicrophoneButton,
getSendBoxTextBox,
getNumActivitiesShown,
getSendBoxText,
getStore,
getUploadButton,
hasFocusOnSendBoxTextBox,
hasPendingSpeechSynthesisUtterance,
isRecognizingSpeech,
hasSpeechRecognitionStartCalled,
isDictating,
pingBot,
putSpeechRecognitionResult,
sendFile,
sendMessageViaMicrophone,
sendMessageViaSendBox,
setSendBoxText,
startSpeechSynthesize
},
fn => fn.bind(null, driver)
Expand Down
10 changes: 10 additions & 0 deletions __tests__/setup/pageObjects/isDictating.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { By } from 'selenium-webdriver';

export default async function isDictating(driver) {
const microphoneButtonContainer = await driver.findElement(
By.css('[aria-controls="webchatSendBoxMicrophoneButton"]')
);
const microphoneButtonClassName = await microphoneButtonContainer.getAttribute('class');

return microphoneButtonClassName.split(' ').includes('dictating');
}
3 changes: 0 additions & 3 deletions __tests__/setup/pageObjects/isRecognizingSpeech.js

This file was deleted.

5 changes: 3 additions & 2 deletions __tests__/setup/pageObjects/sendFile.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { join, posix } from 'path';

import { timeouts } from '../../constants.json';
import allOutgoingActivitiesSent from '../conditions/allOutgoingActivitiesSent';
import getActivityElements from './getActivityElements';
import getUploadButton from './getUploadButton';
import getActivityElements from './elements/getActivityElements';
import getUploadButton from './elements/getUploadButton';
import minNumActivitiesShown from '../conditions/minNumActivitiesShown.js';

function resolveDockerFile(filename) {
Expand Down
9 changes: 4 additions & 5 deletions __tests__/setup/pageObjects/sendMessageViaMicrophone.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { timeouts } from '../../constants.json';
import allOutgoingActivitiesSent from '../conditions/allOutgoingActivitiesSent';
import getMicrophoneButton from './getMicrophoneButton';
import clickMicrophoneButton from './clickMicrophoneButton';
import hasSpeechRecognitionStartCalled from './hasSpeechRecognitionStartCalled';
import putSpeechRecognitionResult from './putSpeechRecognitionResult';
import speechRecognitionStarted from '../conditions/speechRecognitionStarted';

export default async function sendMessageViaMicrophone(driver, text, { waitForSend = true } = {}) {
const microphoneButton = await getMicrophoneButton(driver);
await clickMicrophoneButton(driver);

await microphoneButton.click();
await driver.wait(hasSpeechRecognitionStartCalled(driver), timeouts.ui);

await driver.wait(speechRecognitionStarted(), timeouts.ui);
await putSpeechRecognitionResult(driver, 'recognize', text);

waitForSend && (await driver.wait(allOutgoingActivitiesSent(), timeouts.directLine));
Expand Down
Loading