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

Refactor API into new api package #3543

Merged
merged 21 commits into from
Oct 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
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(
corinagum marked this conversation as resolved.
Show resolved Hide resolved
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