Skip to content

Commit

Permalink
Refactor API into new api package (#3543)
Browse files Browse the repository at this point in the history
* Add API package

* Continue refactoring

* Continue refactoring

* Fix tests

* Fix DLSpeech

* Fix speech support

* Fix tests

* Fix ESLint

* Fix tests

* Fix ESLint

* Fix all TODOs

* Add back localize

* Clean up

* Add entry

* Apply suggestions from code review

Co-authored-by: Corina <[email protected]>

* Apply PR suggestions

* Fix tests

* Fix tests

* Fix tests

* Fix tests

* Remove eslint-disable

Co-authored-by: Corina <[email protected]>
  • Loading branch information
compulim and corinagum authored Oct 27, 2020
1 parent df4c2ff commit 0cd6b8d
Show file tree
Hide file tree
Showing 334 changed files with 10,319 additions and 2,350 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,19 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

### Breaking changes

### Added

- Resolves [#3316](https://github.com/microsoft/BotFramework-WebChat/issues/3316). Refactored platform-neutral APIs into the new `api` package, to be reused on React Native component, in PR [#3543](https://github.com/microsoft/BotFramework-WebChat/pull/3543) by [@compulim](https://github.com/compulim)
- The new layering is `core` -> `api` -> `component` (HTML-only) -> `bundle`
- Includes composition mode, platform-neutral React hooks, and localization resources
- Most hooks are available in the new `api` package. Some hooks are only available on the existing `component` package, due to their platform dependency or coupling with visual components. For example, Web Worker, 2D canvas, `useMicrophoneButton*` are not available on the `api` package
- Most implementations of middleware are only available in `component` package due to their coupling with visual components or platform features. Some implementations, (e.g. card action middleware and activity grouping middleware) are available on `api` package. For example:
- Carousel layout and stacked layout is only available on `component` package due to their coupling with their respective visual components
- For card action middleware, `imBack`, `messageBack` and `postBack` actions are available on `api` package, but `call`, `openUrl` and other platform-dependent actions are only available on `component` package
- `activityMiddleware`, `attachmentMiddleware`, etc, now support arrays for multiple middleware

### Fixed

- Fixes [#3489](https://github.com/microsoft/BotFramework-WebChat/issues/3489). [Accessibility]: Fix AT saying 'Bot undefined said', by [@corinagum](https://github.com/corinagum) in PR [#3524](https://github.com/microsoft/BotFramework-WebChat/pull/3524)
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.
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.
13 changes: 13 additions & 0 deletions __tests__/adaptiveCards.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,16 @@ test('disable card inputs', async () => {

expect(await driver.takeScreenshot()).toMatchImageSnapshot(imageSnapshotOptions);
});

test('broken card of invalid version', async () => {
const { driver, pageObjects } = await setupWebDriver();

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

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

const base64PNG = await driver.takeScreenshot();

expect(base64PNG).toMatchImageSnapshot(imageSnapshotOptions);
});
6 changes: 4 additions & 2 deletions __tests__/attachmentMiddleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@ test('file upload should show thumbnail and file name', async () => {
attachments: patchedAttachments
});

return React.createElement(React.Fragment, {}, [
return React.createElement(
React.Fragment,
{},
next({ activity, attachment }),
next({ activity: patchedActivity, attachment: patchedAttachment })
]);
);
}

return next({ activity, attachment });
Expand Down
6 changes: 3 additions & 3 deletions __tests__/cardActionMiddleware.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { By } from 'selenium-webdriver';
import { By, logging } from 'selenium-webdriver';

import { imageSnapshotOptions, timeouts } from './constants.json';

Expand Down Expand Up @@ -98,7 +98,7 @@ test('card action "signin" when directLine.getSessionId is falsy', async () => {
props: {
cardActionMiddleware: ({ dispatch }) => next => ({ cardAction, getSignInUrl }) => {
if (cardAction.type === 'signin') {
getSignInUrl().then(url => {
Promise.resolve(getSignInUrl()).then(url => {
dispatch({
type: 'WEB_CHAT/SEND_MESSAGE',
payload: {
Expand Down Expand Up @@ -138,6 +138,6 @@ test('card action "signin" when directLine.getSessionId is falsy', async () => {
expect(base64PNG).toMatchImageSnapshot(imageSnapshotOptions);
expect(await pageObjects.getConsoleErrors()).toEqual([]);
expect(await pageObjects.getConsoleWarnings()).toEqual([
'botframework-webchat: No-magic-code OAuth flow is not supported on this Direct Line adapter.'
'botframework-webchat: OAuth is not supported on this Direct Line adapter.'
]);
});
4 changes: 4 additions & 0 deletions __tests__/hooks/useTrackDimension.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ describe('useTrackDimension', () => {
"data": null,
"dimensions": Object {
"capability:downscaleImage:workerType": "web worker",
"capability:renderer": "html",
"hello": "aloha",
"prop:locale": "en-US",
"prop:speechRecognition": "false",
Expand All @@ -62,6 +63,7 @@ describe('useTrackDimension', () => {
"data": null,
"dimensions": Object {
"capability:downscaleImage:workerType": "web worker",
"capability:renderer": "html",
"prop:locale": "en-US",
"prop:speechRecognition": "false",
"prop:speechSynthesis": "false",
Expand All @@ -85,6 +87,7 @@ describe('useTrackDimension', () => {
"data": null,
"dimensions": Object {
"capability:downscaleImage:workerType": "web worker",
"capability:renderer": "html",
"prop:locale": "en-US",
"prop:speechRecognition": "false",
"prop:speechSynthesis": "false",
Expand All @@ -108,6 +111,7 @@ describe('useTrackDimension', () => {
"data": null,
"dimensions": Object {
"capability:downscaleImage:workerType": "web worker",
"capability:renderer": "html",
"prop:locale": "en-US",
"prop:speechRecognition": "false",
"prop:speechSynthesis": "false",
Expand Down
5 changes: 5 additions & 0 deletions __tests__/hooks/useTrackEvent.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ describe('useTrackEvent', () => {
"data": null,
"dimensions": Object {
"capability:downscaleImage:workerType": "web worker",
"capability:renderer": "html",
"prop:locale": "en-US",
"prop:speechRecognition": "false",
"prop:speechSynthesis": "false",
Expand All @@ -66,6 +67,7 @@ describe('useTrackEvent', () => {
"data": null,
"dimensions": Object {
"capability:downscaleImage:workerType": "web worker",
"capability:renderer": "html",
"prop:locale": "en-US",
"prop:speechRecognition": "false",
"prop:speechSynthesis": "false",
Expand All @@ -89,6 +91,7 @@ describe('useTrackEvent', () => {
"data": 123,
"dimensions": Object {
"capability:downscaleImage:workerType": "web worker",
"capability:renderer": "html",
"prop:locale": "en-US",
"prop:speechRecognition": "false",
"prop:speechSynthesis": "false",
Expand All @@ -112,6 +115,7 @@ describe('useTrackEvent', () => {
"data": "aloha",
"dimensions": Object {
"capability:downscaleImage:workerType": "web worker",
"capability:renderer": "html",
"prop:locale": "en-US",
"prop:speechRecognition": "false",
"prop:speechSynthesis": "false",
Expand All @@ -138,6 +142,7 @@ describe('useTrackEvent', () => {
},
"dimensions": Object {
"capability:downscaleImage:workerType": "web worker",
"capability:renderer": "html",
"prop:locale": "en-US",
"prop:speechRecognition": "false",
"prop:speechSynthesis": "false",
Expand Down
2 changes: 2 additions & 0 deletions __tests__/hooks/useTrackException.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ describe('useTrackException', () => {
"data": null,
"dimensions": Object {
"capability:downscaleImage:workerType": "web worker",
"capability:renderer": "html",
"prop:locale": "en-US",
"prop:speechRecognition": "false",
"prop:speechSynthesis": "false",
Expand All @@ -68,6 +69,7 @@ describe('useTrackException', () => {
"data": null,
"dimensions": Object {
"capability:downscaleImage:workerType": "web worker",
"capability:renderer": "html",
"prop:locale": "en-US",
"prop:speechRecognition": "false",
"prop:speechSynthesis": "false",
Expand Down
4 changes: 4 additions & 0 deletions __tests__/hooks/useTrackTiming.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ describe('useTrackTiming', () => {
"data": null,
"dimensions": Object {
"capability:downscaleImage:workerType": "web worker",
"capability:renderer": "html",
"prop:locale": "en-US",
"prop:speechRecognition": "false",
"prop:speechSynthesis": "false",
Expand All @@ -62,6 +63,7 @@ describe('useTrackTiming', () => {
"data": null,
"dimensions": Object {
"capability:downscaleImage:workerType": "web worker",
"capability:renderer": "html",
"prop:locale": "en-US",
"prop:speechRecognition": "false",
"prop:speechSynthesis": "false",
Expand Down Expand Up @@ -92,6 +94,7 @@ describe('useTrackTiming', () => {
"data": null,
"dimensions": Object {
"capability:downscaleImage:workerType": "web worker",
"capability:renderer": "html",
"prop:locale": "en-US",
"prop:speechRecognition": "false",
"prop:speechSynthesis": "false",
Expand All @@ -105,6 +108,7 @@ describe('useTrackTiming', () => {
"data": null,
"dimensions": Object {
"capability:downscaleImage:workerType": "web worker",
"capability:renderer": "html",
"prop:locale": "en-US",
"prop:speechRecognition": "false",
"prop:speechSynthesis": "false",
Expand Down
51 changes: 51 additions & 0 deletions __tests__/html/deprecated.localize.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<script crossorigin="anonymous" src="/__dist__/testharness.js"></script>
<script crossorigin="anonymous" src="/__dist__/webchat-es5.js"></script>
</head>
<body>
<div id="webchat"></div>
<script type="text/babel" data-presets="env,stage-3,react">
const {
WebChat: {
Components: { Composer, Localize }
},
WebChatTest: {
conditions,
createStore,
expect,
host,
pageObjects,
parseURLParams,
shareObservable,
timeouts,
token: { fetchDirectLineToken },
updateIn
}
} = window;

(async function () {
const token = await fetchDirectLineToken();
const { l: locale } = parseURLParams(window.location.hash);

await new Promise(resolve =>
ReactDOM.render(
<Composer directLine={window.WebChat.createDirectLine({ token })} locale={locale} store={createStore()}>
<Localize text="SPEECH_INPUT_LISTENING" />
</Composer>,
document.getElementById('webchat'),
resolve
)
);

await host.snapshot();
await host.done();
})().catch(async err => {
console.error(err);

await host.error(err);
});
</script>
</body>
</html>
9 changes: 9 additions & 0 deletions __tests__/html/deprecated.localize.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* @jest-environment ./__tests__/html/__jest__/WebChatEnvironment.js
*/

describe('deprecated <Localize>', () => {
test('should localize text in navigator language', () => runHTMLTest('deprecated.localize.html'));
test('should localize text in "en"', () => runHTMLTest('deprecated.localize.html#l=en'));
test('should localize text in "yue"', () => runHTMLTest('deprecated.localize.html#l=yue'));
});
3 changes: 2 additions & 1 deletion __tests__/html/focusManagement.sendFailedRetry.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
*/

describe('focus management', () => {
test('click on retry button should focus on main', () => runHTMLTest('focusManagement.sendFailedRetry.html'));
test('click on retry button should focus on main', () =>
runHTMLTest('focusManagement.sendFailedRetry.html', { ignoreConsoleError: true }));
});
77 changes: 77 additions & 0 deletions __tests__/html/hooks.useRenderAttachment.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<script crossorigin="anonymous" src="/__dist__/testharness.js"></script>
<script crossorigin="anonymous" src="/__dist__/webchat-es5.js"></script>
</head>
<body>
<div id="webchat"></div>
<script type="text/babel" data-presets="env,stage-3,react">
const {
ReactDOM: { render },
WebChat: {
Components: { Composer },
hooks: { useActivities, useRenderAttachment }
},
WebChatTest: { conditions, createDirectLineWithTranscript, createStore, host, pageObjects, timeouts, token }
} = window;

(async function () {
const Test = () => {
const [[activity]] = useActivities();
const renderAttachment = useRenderAttachment();

if (!activity) {
return false;
}

const attachment = renderAttachment({ activity, attachment: activity.attachments[0] });

return (
<React.Fragment>
{attachment}
{!!attachment && <div className="done" />}
</React.Fragment>
);
};

const directLine = await createDirectLineWithTranscript([
{
attachments: [
{
contentType: 'image/png',
contentUrl:
'https://raw.githubusercontent.com/compulim/BotFramework-MockBot/master/public/assets/surface1.jpg'
}
],
from: { role: 'bot' },
id: '1.0',
text: 'Nostrud in dolor Lorem nulla esse anim nisi adipisicing do nisi.',
timestamp: 0,
type: 'message'
}
]);

const store = createStore();

render(
<Composer directLine={directLine} store={store}>
<Test />
</Composer>,
document.getElementById('webchat')
);

await pageObjects.wait(conditions.uiConnected(), timeouts.directLine);
await pageObjects.wait(() => document.querySelector('.done'), timeouts.ui);
await pageObjects.wait(conditions.allImagesLoaded(), timeouts.ui);

await host.snapshot();
await host.done();
})().catch(async err => {
console.error(err);

await host.error(err);
});
</script>
</body>
</html>
7 changes: 7 additions & 0 deletions __tests__/html/hooks.useRenderAttachment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* @jest-environment ./__tests__/html/__jest__/WebChatEnvironment.js
*/

describe('useRenderAttachment', () => {
test('should render attachment', () => runHTMLTest('hooks.useRenderAttachment.html'));
});
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@
const RenderAttachmentForScreenReader = () => {
const createAttachmentForScreenReaderRenderer = useCreateAttachmentForScreenReaderRenderer();

createAttachmentForScreenReaderRenderer({ activity: {}, attachment: {} })();

return false;
return createAttachmentForScreenReaderRenderer({ activity: {}, attachment: {} })();
};

const attachmentForScreenReaderMiddleware = () => next => (...args) => {
Expand Down
2 changes: 1 addition & 1 deletion __tests__/html/offlineUI.sendFailed.noAck.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@

describe('offline UI', () => {
test('should display "Send failed. Retry" when activity is sent but not acknowledged', () =>
runHTMLTest('offlineUI.sendFailed.noAck.html'));
runHTMLTest('offlineUI.sendFailed.noAck.html', { ignoreConsoleError: true }));
});
2 changes: 1 addition & 1 deletion __tests__/html/offlineUI.sendFailed.notSend.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@

describe('offline UI', () => {
test('should display "Send failed. Retry" when activity is not able to send', () =>
runHTMLTest('offlineUI.sendFailed.notSend.html'));
runHTMLTest('offlineUI.sendFailed.notSend.html', { ignoreConsoleError: true }));
});
3 changes: 2 additions & 1 deletion __tests__/html/timestamp.attachmentSendTimeout.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
*/

describe('timestamp', () => {
test('send timeout for attachment should be different', () => runHTMLTest('timestamp.attachmentSendTimeout.html'));
test('send timeout for attachment should be different', () =>
runHTMLTest('timestamp.attachmentSendTimeout.html', { ignoreConsoleError: true }));
});
2 changes: 1 addition & 1 deletion __tests__/richCards.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { By, until } from 'selenium-webdriver';
import { By } from 'selenium-webdriver';
import { imageSnapshotOptions, timeouts } from './constants.json';

import allImagesLoaded from './setup/conditions/allImagesLoaded';
Expand Down
Loading

0 comments on commit 0cd6b8d

Please sign in to comment.