Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
 into fix-2620
  • Loading branch information
spyip committed Nov 25, 2019
2 parents 0cfbb93 + 8ef360c commit b475a90
Show file tree
Hide file tree
Showing 23 changed files with 339 additions and 45 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- PR [#2547](https://github.com/microsoft/BotFramework-WebChat/pull/2547): `useEmitTypingIndicator`, `usePeformCardAction`, `usePostActivity`, `useSendEvent`, `useSendFiles`, `useSendMessage`, `useSendMessageBack`, `useSendPostBack`
- PR [#2548](https://github.com/microsoft/BotFramework-WebChat/pull/2548): `useDisabled`
- PR [#2549](https://github.com/microsoft/BotFramework-WebChat/pull/2549): `useSuggestedActions`
- PR [#2550](https://github.com/microsoft/BotFramework-WebChat/pull/2550): `useConnectivityStatus`, `useGroupTimestamp`, `useTimeoutForSend`, `useUserID`, `useUsername`
- PR [#2551](https://github.com/microsoft/BotFramework-WebChat/pull/2551): `useLastTypingAt`, `useSendTypingIndicator`, `useTypingIndicator`
- PR [#2552](https://github.com/microsoft/BotFramework-WebChat/pull/2552): `useFocusSendBox`, `useScrollToEnd`, `useSendBoxValue`, `useSubmitSendBox`, `useTextBoxSubmit`, `useTextBoxValue`
- Bring your own Adaptive Cards package by specifying `adaptiveCardsPackage` prop, by [@compulim](https://github.com/compulim) in PR [#2543](https://github.com/microsoft/BotFramework-WebChat/pull/2543)
- Fixes [#2597](https://github.com/microsoft/BotFramework-WebChat/issues/2597). Modify `watch` script to `start` and add `tableflip` script for throwing `node_modules`, by [@corinagum](https://github.com/corinagum) in PR [#2598](https://github.com/microsoft/BotFramework-WebChat/pull/2598)
- `component`: Fixes [#2331](https://github.com/microsoft/BotFramework-WebChat/issues/2331). Updated timer to use React Hooks, by [@spyip](https://github.com/spyip) in PR [#2546](https://github.com/microsoft/BotFramework-WebChat/pull/2546)
- Resolves [#2620](https://github.com/Microsoft/BotFramework-WebChat/issues/2620), update Chinese localization files, by [@spyip](https://github.com/spyip) in PR [#2631](https://github.com/microsoft/BotFramework-WebChat/pull/2631)
- Resolves [#2597](https://github.com/microsoft/BotFramework-WebChat/issues/2597). Modify `watch` script to `start` and add `tableflip` script for throwing `node_modules`, by [@corinagum](https://github.com/corinagum) in PR [#2598](https://github.com/microsoft/BotFramework-WebChat/pull/2598)
- Adds `suggestedActionLayout` to `defaultStyleOptions`, by [@spyip](https://github.com/spyip), in PR [#2596](https://github.com/microsoft/BotFramework-WebChat/pull/2596)
- Resolves [#2331](https://github.com/microsoft/BotFramework-WebChat/issues/2331). Updated timer to use React Hooks, by [@spyip](https://github.com/spyip) in PR [#2546](https://github.com/microsoft/BotFramework-WebChat/pull/2546)
- Resolves [#2620](https://github.com/microsoft/BotFramework-WebChat/issues/2620), update Chinese localization files, by [@spyip](https://github.com/spyip) in PR [#2631](https://github.com/microsoft/BotFramework-WebChat/pull/2631)

### 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.
24 changes: 24 additions & 0 deletions __tests__/hooks/useConnectivityStatus.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { timeouts } from '../constants.json';
import uiConnected from '../setup/conditions/uiConnected';

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

jest.setTimeout(timeouts.test);

test('getter should return online', async () => {
const { driver, pageObjects } = await setupWebDriver();

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

const [connectivityStatus] = await pageObjects.runHook('useConnectivityStatus');

expect(connectivityStatus).toMatchInlineSnapshot(`"connected"`);
});

test('setter should be falsy', async () => {
const { pageObjects } = await setupWebDriver();
const [_, setConnectivityStatus] = await pageObjects.runHook('useConnectivityStatus');

expect(setConnectivityStatus).toBeFalsy();
});
43 changes: 43 additions & 0 deletions __tests__/hooks/useGroupTimestamp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { timeouts } from '../constants.json';

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

jest.setTimeout(timeouts.test);

test('getter should return group timestamp set in props', async () => {
const { pageObjects } = await setupWebDriver({
props: {
groupTimestamp: 1000
}
});

const [groupTimestamp] = await pageObjects.runHook('useGroupTimestamp');

expect(groupTimestamp).toMatchInlineSnapshot(`1000`);
});

test('getter should return default group timestamp if not set in props', async () => {
const { pageObjects } = await setupWebDriver();

const [groupTimestamp] = await pageObjects.runHook('useGroupTimestamp');

expect(groupTimestamp).toMatchInlineSnapshot(`true`);
});

test('getter should return false if group timestamp is disabled', async () => {
const { pageObjects } = await setupWebDriver({
props: { groupTimestamp: false }
});

const [groupTimestamp] = await pageObjects.runHook('useGroupTimestamp');

expect(groupTimestamp).toMatchInlineSnapshot(`false`);
});

test('setter should be falsy', async () => {
const { pageObjects } = await setupWebDriver();
const [_, setGroupTimestamp] = await pageObjects.runHook('useGroupTimestamp');

expect(setGroupTimestamp).toBeFalsy();
});
36 changes: 36 additions & 0 deletions __tests__/hooks/useTimeoutForSend.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { timeouts } from '../constants.json';

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

jest.setTimeout(timeouts.test);

test('getter should return timeout for sending activity', async () => {
const { pageObjects } = await setupWebDriver({
props: {
sendTimeout: 1000
}
});

const [timeoutForSend] = await pageObjects.runHook('useTimeoutForSend');

expect(timeoutForSend).toMatchInlineSnapshot(`1000`);
});

test('getter should return default timeout for sending activity if not set in props', async () => {
const { pageObjects } = await setupWebDriver();

const [timeoutForSend] = await pageObjects.runHook('useTimeoutForSend');

expect(timeoutForSend).toMatchInlineSnapshot(`20000`);
});

test('setter should set the timeout for sending activity', async () => {
const { pageObjects } = await setupWebDriver();

await pageObjects.runHook('useTimeoutForSend', [], result => result[1](1000));

const [timeoutForSend] = await pageObjects.runHook('useTimeoutForSend');

expect(timeoutForSend).toMatchInlineSnapshot(`1000`);
});
33 changes: 33 additions & 0 deletions __tests__/hooks/useUserID.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { timeouts } from '../constants.json';

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

jest.setTimeout(timeouts.test);

test('getter should return user ID set in props', async () => {
const { pageObjects } = await setupWebDriver({
props: {
userID: 'u-12345'
}
});

const [userID] = await pageObjects.runHook('useUserID');

expect(userID).toMatchInlineSnapshot(`"u-12345"`);
});

test('getter should return empty string if not set in props', async () => {
const { pageObjects } = await setupWebDriver();

const [userID] = await pageObjects.runHook('useUserID');

expect(userID).toMatchInlineSnapshot(`""`);
});

test('setter should be falsy', async () => {
const { pageObjects } = await setupWebDriver();
const [_, setUserID] = await pageObjects.runHook('useUserID');

expect(setUserID).toBeFalsy();
});
33 changes: 33 additions & 0 deletions __tests__/hooks/useUsername.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { timeouts } from '../constants.json';

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

jest.setTimeout(timeouts.test);

test('getter should return username set in props', async () => {
const { pageObjects } = await setupWebDriver({
props: {
username: 'u-12345'
}
});

const [username] = await pageObjects.runHook('useUsername');

expect(username).toMatchInlineSnapshot(`"u-12345"`);
});

test('getter should return undefined if not set in props', async () => {
const { pageObjects } = await setupWebDriver();

const [username] = await pageObjects.runHook('useUsername');

expect(username).toMatchInlineSnapshot(`"Happy Web Chat user"`);
});

test('setter should be falsy', async () => {
const { pageObjects } = await setupWebDriver();
const [_, setUsername] = await pageObjects.runHook('useUsername');

expect(setUsername).toBeFalsy();
});
2 changes: 1 addition & 1 deletion __tests__/setup/conditions/suggestedActionsShown.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { By, until } from 'selenium-webdriver';

export default function suggestedActionsShown() {
return until.elementLocated(By.css('[role="form"] ul'));
return until.elementLocated(By.css('[role="form"] > :not(.main) button'));
}
35 changes: 35 additions & 0 deletions __tests__/suggestedActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,22 @@ describe('suggested-actions command', () => {
expect(base64PNG).toMatchImageSnapshot(imageSnapshotOptions);
});

test('should show correctly formatted buttons when suggested actions are displayed as stacked', async () => {
const { driver, pageObjects } = await setupWebDriver({
props: { styleOptions: { suggestedActionLayout: 'stacked' } }
});

await driver.wait(uiConnected(), timeouts.directLine);
await pageObjects.sendMessageViaSendBox('suggested-actions', { waitForSend: true });

await driver.wait(suggestedActionsShown(), timeouts.directLine);
await driver.wait(allImagesLoaded(), 2000);

const base64PNG = await driver.takeScreenshot();

expect(base64PNG).toMatchImageSnapshot(imageSnapshotOptions);
});

test('should show response from bot and no text from user on imback', async () => {
const { driver, pageObjects } = await setupWebDriver();

Expand Down Expand Up @@ -174,4 +190,23 @@ describe('suggested-actions command', () => {

expect(base64PNG).toMatchImageSnapshot(imageSnapshotOptions);
});

test('should show suggested actions with larger images as stacked', async () => {
const styleOptions = {
suggestedActionHeight: 80,
suggestedActionImageHeight: 60,
suggestedActionLayout: 'stacked'
};
const { driver, pageObjects } = await setupWebDriver({ props: { styleOptions } });

await driver.wait(uiConnected(), timeouts.directLine);
await pageObjects.sendMessageViaSendBox('emptycard', { waitForSend: true });

await driver.wait(suggestedActionsShown(), timeouts.directLine);
await driver.wait(allImagesLoaded(), 2000);

const base64PNG = await driver.takeScreenshot();

expect(base64PNG).toMatchImageSnapshot(imageSnapshotOptions);
});
});
11 changes: 5 additions & 6 deletions packages/component/src/BasicTranscript.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import connectToWebChat from './connectToWebChat';
import ScrollToEndButton from './Activity/ScrollToEndButton';
import SpeakActivity from './Activity/Speak';
import useActivities from './hooks/useActivities';
import useGroupTimestamp from './hooks/useGroupTimestamp';
import useStyleOptions from './hooks/useStyleOptions';
import useStyleSet from './hooks/useStyleSet';

Expand Down Expand Up @@ -59,10 +60,11 @@ function sameTimestampGroup(activityX, activityY, groupTimestamp) {
return false;
}

const BasicTranscript = ({ activityRenderer, attachmentRenderer, className, groupTimestamp, webSpeechPonyfill }) => {
const [activities] = useActivities();
const BasicTranscript = ({ activityRenderer, attachmentRenderer, className, webSpeechPonyfill }) => {
const [{ activities: activitiesStyleSet, activity: activityStyleSet }] = useStyleSet();
const [{ hideScrollToEndButton }] = useStyleOptions();
const [activities] = useActivities();
const [groupTimestamp] = useGroupTimestamp();

const { speechSynthesis, SpeechSynthesisUtterance } = webSpeechPonyfill || {};

Expand Down Expand Up @@ -131,24 +133,21 @@ const BasicTranscript = ({ activityRenderer, attachmentRenderer, className, grou

BasicTranscript.defaultProps = {
className: '',
groupTimestamp: true,
webSpeechPonyfill: undefined
};

BasicTranscript.propTypes = {
activityRenderer: PropTypes.func.isRequired,
attachmentRenderer: PropTypes.func.isRequired,
className: PropTypes.string,
groupTimestamp: PropTypes.oneOfType([PropTypes.bool.isRequired, PropTypes.number.isRequired]),
webSpeechPonyfill: PropTypes.shape({
speechSynthesis: PropTypes.any,
SpeechSynthesisUtterance: PropTypes.any
})
};

export default connectToWebChat(({ activityRenderer, attachmentRenderer, groupTimestamp, webSpeechPonyfill }) => ({
export default connectToWebChat(({ activityRenderer, attachmentRenderer, webSpeechPonyfill }) => ({
activityRenderer,
attachmentRenderer,
groupTimestamp,
webSpeechPonyfill
}))(BasicTranscript);
10 changes: 5 additions & 5 deletions packages/component/src/SendBox/ConnectivityStatus.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import connectToWebChat from '../connectToWebChat';
import ErrorNotificationIcon from '../Attachment/Assets/ErrorNotificationIcon';
import ScreenReaderText from '../ScreenReaderText';
import SpinnerAnimation from '../Attachment/Assets/SpinnerAnimation';
import useConnectivityStatus from '../hooks/useConnectivityStatus';
import useLocalize from '../hooks/useLocalize';
import useStyleSet from '../hooks/useStyleSet';
import WarningNotificationIcon from '../Attachment/Assets/WarningNotificationIcon';
Expand Down Expand Up @@ -51,7 +52,8 @@ DebouncedConnectivityStatus.propTypes = {
const connectConnectivityStatus = (...selectors) =>
connectToWebChat(({ connectivityStatus, language }) => ({ connectivityStatus, language }), ...selectors);

const ConnectivityStatus = ({ connectivityStatus }) => {
const ConnectivityStatus = () => {
const [connectivityStatus] = useConnectivityStatus();
const [
{
connectivityNotification: connectivityNotificationStyleSet,
Expand Down Expand Up @@ -175,8 +177,6 @@ const ConnectivityStatus = ({ connectivityStatus }) => {
);
};

ConnectivityStatus.propTypes = {
connectivityStatus: PropTypes.string.isRequired
};
export default ConnectivityStatus;

export default connectConnectivityStatus()(ConnectivityStatus);
export { connectConnectivityStatus };
6 changes: 4 additions & 2 deletions packages/component/src/SendBox/SuggestedAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ import useStyleSet from '../hooks/useStyleSet';
import useSuggestedActions from '../hooks/useSuggestedActions';

const SUGGESTED_ACTION_CSS = css({
display: 'inline-block',
display: 'flex',
flexDirection: 'column',
whiteSpace: 'initial',

'& > button': {
display: 'flex'
display: 'flex',
overflow: 'hidden'
}
});

Expand Down
Loading

0 comments on commit b475a90

Please sign in to comment.