### Install Dependencies and Build SharePoint Web Part
Source: https://github.com/microsoft/botframework-webchat/blob/main/samples/01.getting-started/l.sharepoint-web-part/README.md
Install esbuild and botframework-webchat, then copy source files and start the development server using concurrently.
```bash
RUN npm install esbuild@0.12.15
RUN npm install botframework-webchat
ADD --chown=spfx:spfx src/spfx/src/webparts/webChat /usr/app/spfx/src/webparts/webChat
ENTRYPOINT npx concurrently "node proxy" "gulp serve --nobrowser"
```
--------------------------------
### JavaScript Bot Setup
Source: https://github.com/microsoft/botframework-webchat/blob/main/samples/01.getting-started/k.direct-line-token/README.md
Install dependencies and start the JavaScript bot server.
```bash
npm install
npm start
```
--------------------------------
### Initializing Web Chat with useActivities Example
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/hooks/useActivities.setter.html
This example shows a complete setup for using the useActivities hook within a test harness. It initializes a direct line emulator, creates a store, and renders the hook to assert the initial state of activities.
```javascript
import '/test-harness.mjs';
import '/test-page-object.mjs';
import { createStoreWithOptions, testIds } from 'botframework-webchat';
import { useActivities } from 'botframework-webchat/hook.js';
import createRenderHook from '/assets/esm/createRenderHook.js';
const { createDirectLineEmulator } = window.testHelpers;
window.WebChat = {
createStoreWithOptions,
testIds
};
run(async function () {
const {
directLine,
store
} = createDirectLineEmulator();
const renderHook = createRenderHook(document.getElementById('webchat'), {
directLine,
store
});
const activitiesState = await renderHook(() => useActivities());
expect(activitiesState).toEqual([[]]);
});
```
--------------------------------
### Set up Project with npm
Source: https://github.com/microsoft/botframework-webchat/blob/main/samples/06.recomposing-ui/b.speech-ui/README.md
Installs Web Chat and creates a new React app. Navigate to the project directory and install the botframework-webchat package.
```sh
cd C:\Users\You\Documents
npx create-react-app 06.recomposing-ui/b.speech-ui
cd 06.recomposing-ui/b.speech-ui
npm i botframework-webchat
```
--------------------------------
### Create React App and Install Web Chat
Source: https://github.com/microsoft/botframework-webchat/blob/main/samples/06.recomposing-ui/a.minimizable-web-chat/README.md
Set up a new React project and install the botframework-webchat package using npm.
```sh
cd C:\Users\You\Documents
npx create-react-app06.recomposing-ui/a.minimizable-web-chat
cd06.recomposing-ui/a.minimizable-web-chat
npm i botframework-webchat
```
--------------------------------
### Install Dependencies for Development
Source: https://github.com/microsoft/botframework-webchat/blob/main/docs/BUILD_SCRIPTS.md
Use this command to install all necessary dependencies for development. It ensures a clean installation.
```bash
npm clean-install
```
--------------------------------
### Complete App Setup with Custom Web Chat
Source: https://github.com/microsoft/botframework-webchat/blob/main/samples/06.recomposing-ui/e.extending-ui/README.md
This is a simplified `App.js` demonstrating the complete setup, including fetching a Direct Line token and rendering the `CustomWebChat` component within the `Composer`.
```javascript
import { createDirectLine } from 'botframework-webchat';
import { Components } from 'botframework-webchat-component';
import React from 'react';
import CustomWebChat from './CustomWebChat';
// In this demo, we are using Direct Line token from MockBot.
// To talk to your bot, you should use the token exchanged using your Direct Line secret.
// You should never put the Direct Line secret in the browser or client app.
// https://docs.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-direct-line-3-0-authentication
async function getDirectLineToken() {
const res = await fetch('https://hawo-mockbot4-token-app.ambitiousflower-67725bfd.westus.azurecontainerapps.io/api/token/directline', { method: 'POST' });
const { token } = await res.json();
return token;
}
const App = () => {
const [directLine, setDirectLine] = React.useState();
if (!directLine) {
getDirectLineToken().then(token => setDirectLine(createDirectLine({ token })));
}
return (
{!!directLine && (
)}
);
};
export default App;
```
--------------------------------
### Install Node.js Dependencies
Source: https://github.com/microsoft/botframework-webchat/blob/main/samples/07.advanced-web-chat-apps/e.sso-on-behalf-of-authentication/bot/README.md
Install all the necessary npm packages required for the bot to function. This command should be run after navigating to the sample's directory.
```bash
npm install
```
--------------------------------
### Start Development Server with Watch Mode
Source: https://github.com/microsoft/botframework-webchat/blob/main/docs/BUILD_SCRIPTS.md
Starts the development server and continuously builds the packages directory. Serves samples and bits from http://localhost:5000/ with source maps enabled for debugging.
```bash
npm start
```
--------------------------------
### Using useAdaptiveCardsPackage Hook
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/hooks/useAdaptiveCardsPackage.setter.html
Demonstrates how to use the useAdaptiveCardsPackage hook to get the Adaptive Cards package state. Requires setup with createStoreWithOptions and createDirectLineEmulator.
```javascript
import '/test-harness.mjs';
import '/test-page-object.mjs';
import { createStoreWithOptions, testIds } from 'botframework-webchat';
import { useAdaptiveCardsPackage } from 'botframework-webchat/hook.js';
import createRenderHook from '/assets/esm/createRenderHook.js';
const { createDirectLineEmulator } = window.testHelpers;
window.WebChat = {
createStoreWithOptions,
testIds
};
run(async function () {
const {
directLine,
store
} = createDirectLineEmulator();
const renderHook = createRenderHook(document.getElementById('webchat'), {
adaptiveCardsPackage: {
__DUMMY__: 0
},
directLine,
store
});
const adaptiveCardsPackageState = await renderHook(() => useAdaptiveCardsPackage());
expect(adaptiveCardsPackageState).toEqual([
expect.objectContaining({})
]);
});
```
--------------------------------
### C# Bot Setup
Source: https://github.com/microsoft/botframework-webchat/blob/main/samples/01.getting-started/k.direct-line-token/README.md
Build and run the C# bot application.
```bash
dotnet build
dotnet run
```
--------------------------------
### Using useGroupTimestamp Hook
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/hooks/useGroupTimestamp.getter.html
Demonstrates how to use the useGroupTimestamp hook to set a custom group timestamp interval. This example is part of a test harness setup.
```javascript
import '/test-harness.mjs';
import '/test-page-object.mjs';
import { createStoreWithOptions, testIds } from 'botframework-webchat';
import { useGroupTimestamp } from 'botframework-webchat/hook.js';
import createRenderHook from '/assets/esm/createRenderHook.js';
const { createDirectLineEmulator } = window.testHelpers;
window.WebChat = {
createStoreWithOptions,
testIds
};
run(async function () {
const {
directLine,
store
} = createDirectLineEmulator();
const renderHook = createRenderHook(document.getElementById('webchat'), {
directLine,
store,
styleOptions: {
groupTimestamp: 1000
}
});
const [groupTimestamp] = await renderHook(() => useGroupTimestamp());
expect(groupTimestamp).toEqual(1000);
});
```
--------------------------------
### Use useSendBoxSpeechInterimsVisible Hook
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/hooks/useSendBoxSpeechInterimsVisible.setter.html
Demonstrates how to use the useSendBoxSpeechInterimsVisible hook to get the visibility state of speech interims. This example is set up within a test harness environment.
```javascript
import '/test-harness.mjs';
import '/test-page-object.mjs';
import { createStoreWithOptions, testIds } from 'botframework-webchat';
import { useSendBoxSpeechInterimsVisible } from 'botframework-webchat/hook.js';
import createRenderHook from '/assets/esm/createRenderHook.js';
import { actRecognizeOnce, createWebSpeechPonyfill } from '/assets/esm/speech/speechPageObjects.js';
const { createDirectLineEmulator } = window.testHelpers;
window.WebChat = {
createStoreWithOptions,
testIds
};
run(async function () {
const {
directLine,
store
} = createDirectLineEmulator();
const ponyfill = createWebSpeechPonyfill();
const renderHook = createRenderHook(document.getElementById('webchat'), {
directLine,
store,
webSpeechPonyfillFactory: () => ponyfill
}, {
renderWebChat: true
});
const sendBoxSpeechInterimsVisibleState = await renderHook(() => useSendBoxSpeechInterimsVisible());
expect(sendBoxSpeechInterimsVisibleState).toEqual([
expect.anything()
]);
});
```
--------------------------------
### Navigate to the Sample Directory
Source: https://github.com/microsoft/botframework-webchat/blob/main/samples/07.advanced-web-chat-apps/e.sso-on-behalf-of-authentication/bot/README.md
Change your current directory to the specific sample folder within the cloned repository. This ensures you are in the correct location to install dependencies and run the bot.
```bash
cd samples/javascript_nodejs/24.bot-authentication-msgraph
```
--------------------------------
### Setup and Initialization for Speech-to-Speech
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/speechToSpeech/barge.in.html
Initializes mock media devices and audio playback, then sets up the Web Chat component with Direct Line emulator and voice configuration. This prepares the environment for testing speech-to-speech interactions.
```javascript
import { setupMockMediaDevices } from '/assets/esm/speechToSpeech/mockMediaDevices.js';
import { setupMockAudioPlayback } from '/assets/esm/speechToSpeech/mockAudioPlayback.js';
setupMockMediaDevices();
setupMockAudioPlayback();
run(async function () {
const { React, ReactDOM: { render }, WebChat: { FluentThemeProvider, ReactWebChat, testIds } } = window;
const { directLine, store } = testHelpers.createDirectLineEmulator();
// Set voice configuration capability to enable microphone button
directLine.setCapability('getVoiceConfiguration', { sampleRate: 24000, chunkIntervalMs: 100 }, { emitEvent: false });
render(
,
document.getElementById('webchat')
);
await pageConditions.uiConnected();
const micButton = document.querySelector(`[data-testid="${testIds.sendBoxMicrophoneButton}"]`);
const textArea = document.querySelector(`[data-testid="${testIds.sendBoxTextBox}"]`);
expect(micButton).toBeTruthy();
expect(textArea).toBeTruthy();
```
--------------------------------
### Scroll to Top of Transcript
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/hooks/useScrollTo.activityID.html
This example demonstrates how to scroll the Web Chat transcript to the very beginning by setting the scrollTop property to 0. This is useful for navigating to the start of the conversation.
```javascript
await renderWithFunction(() => useScrollTo()({ scrollTop: 0 }));
```
--------------------------------
### Using useAvatarForUser Hook
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/hooks/useAvatarForUser.getter.html
Demonstrates how to use the useAvatarForUser hook to get user avatar details. This example sets a custom avatar image and initials for the user.
```javascript
import '/test-harness.mjs';
import '/test-page-object.mjs';
import { createStoreWithOptions, testIds } from 'botframework-webchat';
import { useAvatarForUser } from 'botframework-webchat/hook.js';
import createRenderHook from '/assets/esm/createRenderHook.js';
const { createDirectLineEmulator } = window.testHelpers;
window.WebChat = {
createStoreWithOptions,
testIds
};
run(async function () {
const { directLine, store } = createDirectLineEmulator();
const renderHook = createRenderHook(document.getElementById('webchat'), {
directLine,
store,
styleOptions: {
userAvatarImage: 'about:blank#user-icon',
userAvatarInitials: 'WW'
}
});
const [userAvatar] = await renderHook(() => useAvatarForUser());
expect(userAvatar).toEqual({
image: 'about:blank#user-icon',
initials: 'WW'
});
});
```
--------------------------------
### Set Locale for Conversation Start Properties
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/conversationStartProperties/sendNonISOFormat.html
When creating a Direct Line client, you can specify `conversationStartProperties` to set initial values for the conversation. This example shows how to set the `locale` property.
```javascript
WebChat.renderWebChat({
directLine: WebChat.createDirectLine({
conversationStartProperties: {
locale: '1a2b3c'
},
token: await testHelpers.token.fetchDirectLineToken()
}),
store: testHelpers.createStore()
}, document.getElementById('webchat'));
```
--------------------------------
### Web Chat Rendering with Custom Middleware
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/transcript/legacyActivityMiddleware.reactionButtons.html
Example of initializing Web Chat with a custom activity middleware and a transcript. This setup ensures that bot messages are rendered with the custom decorator.
```javascript
run(async function () { const now = Date.now(); WebChat.renderWebChat( { activityMiddleware, directLine: await testHelpers.createDirectLineWithTranscript('multiple-lines-multiple-files.json'), store: testHelpers.createStore() }, document.getElementById('webchat') ); await pageConditions.uiConnected(); await host.snapshot('local'); });
```
--------------------------------
### Completed Web Chat implementation with welcome event
Source: https://github.com/microsoft/botframework-webchat/blob/main/samples/04.api/a.welcome-event/README.md
This is the complete HTML file for the sample, including Web Chat initialization, store customization for sending the welcome event, and rendering the chat interface.
```html
Web Chat: Send welcome event
```
--------------------------------
### Setup and Initialization for Activity Rendering Test
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/middleware/activity/hooks/useBuildRenderActivityCallback/renderLegacyActivityMiddleware.html
Sets up the testing environment by importing necessary modules and creating a direct line emulator. This code is essential for running tests related to activity rendering.
```javascript
import React from 'react';
window.React = React;
import { waitFor } from '@testduet/wait-for';
import React, { createElement, memo } from 'react';
import { createRoot } from 'react-dom/client';
run(async function () {
const { testHelpers: { createDirectLineEmulator }, WebChat: { Components: { Composer }, hooks: { useActivities, useBuildRenderActivityCallback } } } = window;
const { directLine, store } = createDirectLineEmulator();
```
--------------------------------
### Bot Response with Python Visualization Code
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/side-by-side/index.html
A bot response that includes a complete Python code example for generating harmonic wave visualizations using Matplotlib. It also provides installation instructions.
```javascript
{ timestamp: timestamp(), from: { role: 'bot' }, entities: [
{
...aiMessageEntity,
isBasedOn: {
'@type': 'SoftwareSourceCode',
'programmingLanguage': 'python',
"text": `import numpy as np
import matplotlib.pyplot as plt
def plot_sine_waves():
"""Create a beautiful visualization of sine waves with different frequencies."""
# Generate time points
t = np.linspace(0, 10, 1000)
# Create waves with different frequencies and phases
wave1 = np.sin(t)
wave2 = 0.5 * np.sin(2 * t + np.pi/4)
wave3 = 0.3 * np.sin(3 * t + np.pi/3)
# Combine waves
combined = wave1 + wave2 + wave3
# Create a stylish plot
plt.style.use('seaborn-darkgrid')
plt.figure(figsize=(12, 8))
# Plot individual waves
plt.plot(t, wave1, label='Primary Wave', alpha=0.5)
plt.plot(t, wave2, label='Second Harmonic', alpha=0.5)
plt.plot(t, wave3, label='Third Harmonic', alpha=0.5)
# Plot combined wave with a thicker line
plt.plot(t, combined, 'r-', label='Combined Wave', linewidth=2)
plt.title('Harmonic Wave Composition', fontsize=14)
plt.xlabel('Time', fontsize=12)
plt.ylabel('Amplitude', fontsize=12)
plt.legend()
plt.grid(True, alpha=0.3)
# Show the plot
plt.tight_layout()
plt.show()
# Generate the visualization
plot_sine_waves()`
}
}
],
id: "a4c0c01d-c06e-4dde-9278-265c607b545b-82",
type: "message",
text: `This example demonstrates creating a visualization of harmonic waves using Python's Matplotlib library. The code generates three sine waves with different frequencies and phases, then combines them to show wave interference patterns.
Use the command to install required dependencies: $ pip install numpy matplotlib`
}
```
--------------------------------
### Using useDisabled Hook
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/hooks/useDisabled.getter.default.html
Demonstrates how to use the useDisabled hook to get the disabled state of the Web Chat. This example sets up a direct line emulator and renders the hook within a test harness.
```javascript
import '/test-harness.mjs';
import '/test-page-object.mjs';
import { createStoreWithOptions, testIds } from 'botframework-webchat';
import { useDisabled } from 'botframework-webchat/hook.js';
import createRenderHook from '/assets/esm/createRenderHook.js';
const { createDirectLineEmulator } = window.testHelpers;
window.WebChat = {
createStoreWithOptions,
testIds
};
run(async function () {
const {
directLine,
store
} = createDirectLineEmulator();
const renderHook = createRenderHook(document.getElementById('webchat'), {
directLine,
store
});
const [disabled] = await renderHook(() => useDisabled());
expect(disabled).toBe(false);
});
```
--------------------------------
### Test Setup and Speech Input Hint Handling
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/speech/inputHint/consecutive/expectingExpecting.html
Sets up the Web Chat environment with a speech ponyfill and tests the handling of consecutive 'expecting' input hints during speech recognition. It verifies that the UI displays the correct feedback to the user.
```javascript
Project: /microsoft/botframework-webchat
Content:
{ "imports": { "@testduet/wait-for": "https://esm.sh/@testduet/wait-for", "jest-mock": "https://esm.sh/jest-mock", "react-dictate-button": "https://esm.sh/react-dictate-button", "react-dictate-button/ப்புகளை": "https://esm.sh/react-dictate-button/"
} }
import { waitFor } from '@testduet/wait-for';
import { fn, spyOn } from 'jest-mock';
import { SpeechGrammarList, SpeechRecognition } from 'react-dictate-button/internal';
import { actRecognizeOnce, actSpeak, createWebSpeechPonyfill, sendMessageViaMicrophone } from '/assets/esm/speech/speechPageObjects.js';
const { testHelpers: { createDirectLineEmulator }, WebChat: { renderWebChat, testIds } } = window;
run( async function () {
const ponyfill = createWebSpeechPonyfill();
spyOn(ponyfill.speechSynthesis, 'cancel');
const { directLine, store } = createDirectLineEmulator();
renderWebChat({
directLine,
store,
webSpeechPonyfillFactory: () => ponyfill
}, document.getElementById('webchat'));
await pageConditions.uiConnected();
const { resolveAll } = await directLine.actPostActivity(async () => {
await sendMessageViaMicrophone(ponyfill, 'input-hint expecting expecting');
});
await resolveAll();
await actSpeak(ponyfill, async () => {
await directLine.emulateIncomingActivity({
inputHint: 'expectingInput',
text: '`{ inputHint: "expectingInput" }`',
type: 'message'
});
await directLine.emulateIncomingActivity({
inputHint: 'expectingInput',
text: '`{ inputHint: "expectingInput" }`',
type: 'message'
});
});
expect(document.querySelector(`[data-testid="${WebChat.testIds.sendBoxSpeechBox}"]`)).toHaveProperty(
'textContent',
'Starting…'
);
}, {
skipCheckAccessibility: true
});
```
--------------------------------
### Using useDisabled Hook
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/hooks/useDisabled.getter.html
Demonstrates how to use the useDisabled hook to get the disabled state of the Web Chat. This example sets up a direct line emulator and renders the hook within a test harness.
```javascript
import '/test-harness.mjs';
import '/test-page-object.mjs';
import { createStoreWithOptions, testIds } from 'botframework-webchat';
import { useDisabled } from 'botframework-webchat/hook.js';
import createRenderHook from '/assets/esm/createRenderHook.js';
const { createDirectLineEmulator } = window.testHelpers;
window.WebChat = {
createStoreWithOptions,
testIds
};
run(async function () {
const {
directLine,
store
} = createDirectLineEmulator();
const renderHook = createRenderHook(document.getElementById('webchat'), {
directLine,
disabled: true,
store
});
const [disabled] = await renderHook(() => useDisabled());
expect(disabled).toBe(true);
});
```
--------------------------------
### Using useUsername Hook
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/hooks/useUsername.getter.default.html
Demonstrates how to use the useUsername hook to retrieve the username from the Web Chat store. This example assumes a test harness setup with a direct line emulator and a renderHook utility.
```javascript
import '/test-harness.mjs';
import '/test-page-object.mjs';
import { createStoreWithOptions, testIds } from 'botframework-webchat';
import { useUsername } from 'botframework-webchat/hook.js';
import createRenderHook from '/assets/esm/createRenderHook.js';
const { createDirectLineEmulator } = window.testHelpers;
window.WebChat = {
createStoreWithOptions,
testIds
};
run(async function () {
const { directLine, store } = createDirectLineEmulator();
const renderHook = createRenderHook(document.getElementById('webchat'), {
directLine,
store
});
const [username] = await renderHook(() => useUsername());
expect(username).toBe('');
});
```
--------------------------------
### Using useTypingIndicatorVisible Hook
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/hooks/useTypingIndicatorVisible/getter.userTyping.html
This example demonstrates how to use the useTypingIndicatorVisible hook to get the typing indicator's visibility state. It's typically used within a React component to react to typing events.
```javascript
run(async function () {
const { ReactDOM: { render }, WebChat: { Components: { BasicWebChat, Composer }, hooks: { useTypingIndicatorVisible } } } = window;
// Imports in UMD fashion.
const directLine = WebChat.createDirectLine({ token: await testHelpers.token.fetchDirectLineToken() });
const store = testHelpers.createStore();
let typingIndicatorVisible;
const RunFunction = () => {
[typingIndicatorVisible] = useTypingIndicatorVisible();
return false;
};
render(
,
document.getElementById('webchat')
);
await pageConditions.uiConnected();
await pageObjects.typeInSendBox('Hello, World!');
expect(typingIndicatorVisible).toBe(false);
});
```
--------------------------------
### Clone the Bot Framework Samples Repository
Source: https://github.com/microsoft/botframework-webchat/blob/main/samples/07.advanced-web-chat-apps/e.sso-on-behalf-of-authentication/bot/README.md
Download the sample code from the official GitHub repository. This is the first step to get the sample running locally.
```bash
git clone https://github.com/microsoft/botbuilder-samples.git
```
--------------------------------
### Using useLocalizer Hook
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/hooks/useLocalizer.yue.html
Demonstrates how to use the useLocalizer hook to get a localized string. This example initializes Web Chat with a specific locale ('yue') and then uses the hook to retrieve the localized text for the 'TEXT_INPUT_SPEAK_BUTTON_ALT' key.
```javascript
import '/test-harness.mjs';
import '/test-page-object.mjs';
import { createStoreWithOptions, testIds } from 'botframework-webchat';
import { useLocalizer } from 'botframework-webchat/hook.js';
import createRenderHook from '/assets/esm/createRenderHook.js';
const { createDirectLineEmulator } = window.testHelpers;
window.WebChat = {
createStoreWithOptions,
testIds
};
run(async function () {
const { directLine, store } = createDirectLineEmulator();
const renderHook = createRenderHook(document.getElementById('webchat'), {
directLine,
locale: 'yue',
store
});
const localize = await renderHook(() => useLocalizer());
expect(localize('TEXT_INPUT_SPEAK_BUTTON_ALT')).toBe('講嘢');
});
```
--------------------------------
### Initialize Web Chat with Suggested Actions
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/suggestedActions/suggestedActions.accessKey.html
Sets up Web Chat with a Direct Line connection and a store. It includes a `SendOnConnect` component that sends a 'suggested-actions' message when the bot connects, triggering the display of suggested actions. Style options are also configured.
```javascript
const { React: { useEffect }, ReactDOM: { render }, WebChat: { Components: { BasicWebChat, Composer }, createDirectLine, hooks: { useConnectivityStatus, useSendMessage } } } = window;
run(async function () {
const directLine = await createDirectLine({ token: await testHelpers.token.fetchDirectLineToken() });
const store = testHelpers.createStore();
const styleOptions = {
internalLiveRegionFadeAfter: 60000,
subtle: 'Black'
};
const SendOnConnect = () => {
const [connectivityStatus] = useConnectivityStatus();
const sendMessage = useSendMessage();
const connected = connectivityStatus === 'connected';
useEffect(() => {
connected && sendMessage('suggested-actions');
}, [connected]);
return false;
};
render(
,
document.getElementById('webchat')
);
await pageConditions.uiConnected();
await pageConditions.minNumActivitiesShown(2);
await pageConditions.allImagesLoaded();
await pageConditions.suggestedActionsShown();
await pageConditions.liveRegionStabilized();
const screenReaderTexts = [].map.call(pageElements.liveRegion().children, child => testHelpers.getAllTextContents(child).join('\n') );
expect(screenReaderTexts).toEqual([
'connecting',
'You said:\nsuggested-actions',
'Bot said:\nPlease select one of the actions below\nIM back as string\nPost back as string\nPost back as JSON\nMessage back as JSON with display text\nMessage back as JSON without display text\nMessage back as string with display text',
'Message has suggested actions. Press Alt Shift A to select them.'
]);
expect(document.querySelector('.webchat__suggested-actions').getAttribute('aria-label')).toBe( 'Suggested actions' );
expect( [].map.call(document.querySelectorAll('[aria-keyshortcuts]'), element => element.getAttribute('aria-keyshortcuts') ) ).toEqual(new Array(6).fill('Alt+Shift+A'));
// Access key only works when the focus is inside Web Chat.
// It will not work when the user is focusing on web page content, to prevent conflict with the hosting page.
await pageObjects.focusTranscript();
await host.snapshot('local');
await host.sendAccessKey('A');
await host.snapshot('local');
await host.sendAccessKey('A');
// We need to wait for flipper button animation to complete.
await testHelpers.sleep(1000);
await host.snapshot('local');
// This will send the focus to a control outside of Web Chat.
await host.sendAccessKey('S');
// We need to wait for flipper button animation to complete.
await testHelpers.sleep(1000);
await host.snapshot('local');
});
```
--------------------------------
### Using useLocalizer Hook
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/hooks/useLocalizer.default.html
Demonstrates how to use the useLocalizer hook to get a localized string. This example sets up a mock direct line and store, then uses a render hook to access the localize function provided by useLocalizer.
```javascript
import '/test-harness.mjs';
import '/test-page-object.mjs';
import { createStoreWithOptions, testIds } from 'botframework-webchat';
import { useLocalizer } from 'botframework-webchat/hook.js';
import createRenderHook from '/assets/esm/createRenderHook.js';
const { createDirectLineEmulator } = window.testHelpers;
window.WebChat = {
createStoreWithOptions,
testIds
};
run(async function () {
const { directLine, store } = createDirectLineEmulator();
const renderHook = createRenderHook(document.getElementById('webchat'), {
directLine,
store
});
const localize = await renderHook(() => useLocalizer());
expect(localize('TEXT_INPUT_SPEAK_BUTTON_ALT')).toBe('Speak');
});
```
--------------------------------
### Initialize Web Chat with Fluent Theme and Feedback Form
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/fluentTheme/feedback.form.markdown.html
This snippet shows how to set up Web Chat using UMD imports, a direct line emulator, and the FluentThemeProvider. It also demonstrates sending an activity with feedback loop data to trigger the feedback form.
```javascript
run(async function () { const { React, ReactDOM: { render }, WebChat: { FluentThemeProvider, ReactWebChat } } = window; // Imports in UMD fashion. const { directLine, store } = testHelpers.createDirectLineEmulator(); const App = () => ; render( , document.getElementById('webchat') ); await pageConditions.uiConnected(); await directLine.emulateIncomingActivity({ type: 'message', id: 'a-00000', timestamp: 0, text: 'This is a test message to show feedback buttons', from: { role: 'bot' }, locale: 'en-US', entities: [], channelData: { feedbackLoop: { type: 'default', disclaimer: 'This is a test disclaimer message with **bold** text and a [link](https://microsoft.com)' } } }); await pageConditions.numActivitiesShown(1); pageElements.byTestId('send box text area').focus(); await host.sendShiftTab(2); await host.sendKeys('ENTER'); await host.sendKeys('SPACE'); await pageConditions.became( 'feedback form is open', () => document.activeElement === pageElements.byTestId('feedback sendbox'), 1000 ); await host.snapshot('local'); });
```
--------------------------------
### Setup Mock Media Devices and CSP Violation Listener
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/speechToSpeech/csp.recording.html
Initializes mock media devices and sets up a listener to capture Content Security Policy (CSP) violations. This is crucial for testing CSP compliance during audio recording.
```javascript
import { setupMockMediaDevices } from '/assets/esm/speechToSpeech/mockMediaDevices.js'; // Setup mock media devices before test starts
setupMockMediaDevices();
run(async function () {
const { React, ReactDOM: { render }, WebChat: { FluentThemeProvider, ReactWebChat, testIds } } = window;
// Track CSP violations
const cspViolations = [];
document.addEventListener('securitypolicyviolation', (e) => {
cspViolations.push({
violatedDirective: e.violatedDirective,
blockedURI: e.blockedURI,
originalPolicy: e.originalPolicy
});
console.error('CSP Violation:', e.violatedDirective, e.blockedURI);
});
```
--------------------------------
### Using useTypingIndicatorVisible Hook
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/hooks/useTypingIndicatorVisible/getter.botTyping.html
This example demonstrates how to use the useTypingIndicatorVisible hook to get the typing indicator's visibility state. It's typically used within a React component to conditionally render UI or trigger actions.
```javascript
run(async function () {
const { ReactDOM: { render }, testHelpers: { createDirectLineEmulator }, WebChat: { Components: { BasicWebChat, Composer }, hooks: { useTypingIndicatorVisible } } } = window;
// Imports in UMD fashion.
const clock = lolex.createClock();
const { directLine, store } = createDirectLineEmulator({ ponyfill: clock });
let typingIndicatorVisible;
const RunFunction = () => {
[typingIndicatorVisible] = useTypingIndicatorVisible();
return false;
};
render(
,
document.getElementById('webchat')
);
await pageConditions.webChatRendered();
clock.tick(600);
await pageConditions.uiConnected();
await ( await directLine.actPostActivity(() => {
pageObjects.sendMessageViaSendBox('typing 1');
}) ).resolveAll();
await directLine.emulateIncomingActivity('Typing indicator should go away after 5 seconds.');
await directLine.emulateIncomingActivity({ from: { id: 'bot', role: 'bot' }, type: 'typing' });
await pageConditions.numActivitiesShown(2);
expect(typingIndicatorVisible).toBe(true);
});
```
--------------------------------
### Test Setup for Speech Input Hint Handling
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/speech/inputHint/consecutive/ignoringAccepting.html
Sets up the Web Chat environment with a speech ponyfill and direct line emulator to test speech input hint functionality. It renders the Web Chat component and simulates user interaction.
```javascript
Project: /microsoft/botframework-webchat
{ "imports": { "@testduet/wait-for": "https://esm.sh/@testduet/wait-for", "jest-mock": "https://esm.sh/jest-mock", "react-dictate-button": "https://esm.sh/react-dictate-button", "react-dictate-button/": "https://esm.sh/react-dictate-button/" } } import { waitFor } from '@testduet/wait-for'; import { fn, spyOn } from 'jest-mock'; import { SpeechGrammarList, SpeechRecognition } from 'react-dictate-button/internal'; import { actRecognizeOnce, actSpeak, createWebSpeechPonyfill, sendMessageViaMicrophone } from '/assets/esm/speech/speechPageObjects.js'; const { testHelpers: { createDirectLineEmulator }, WebChat: { renderWebChat, testIds } } = window;
run( async function () {
const ponyfill = createWebSpeechPonyfill();
spyOn(ponyfill.speechSynthesis, 'cancel');
const { directLine, store } = createDirectLineEmulator();
renderWebChat( {
directLine,
store,
webSpeechPonyfillFactory: () => ponyfill
}, document.getElementById('webchat') );
await pageConditions.uiConnected();
const { resolveAll } = await directLine.actPostActivity(async () => {
await sendMessageViaMicrophone(ponyfill, 'input-hint ignoring accepting');
});
await resolveAll();
await actSpeak(ponyfill, async () => {
await directLine.emulateIncomingActivity({ inputHint: 'ignoringInput', text: '`{ inputHint: "ignoringInput" }`', type: 'message' });
await directLine.emulateIncomingActivity({ inputHint: 'acceptingInput', text: '`{ inputHint: "acceptingInput" }`', type: 'message' });
});
expect(document.querySelector(`[data-testid="${WebChat.testIds.sendBoxSpeechBox}"]`)).toBeFalsy();
}, { skipCheckAccessibility: true } );
```
--------------------------------
### Using useLanguage Hook for Speech
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/hooks/useLanguage.getter.speech.html
Demonstrates how to use the useLanguage hook to get the current language setting for speech. This example sets up a Web Chat store with a specific locale and then uses the hook to verify the speech language.
```javascript
import '/test-harness.mjs';
import '/test-page-object.mjs';
import { createStoreWithOptions, testIds } from 'botframework-webchat';
import { useLanguage } from 'botframework-webchat/hook.js';
import createRenderHook from '/assets/esm/createRenderHook.js';
const { createDirectLineEmulator } = window.testHelpers;
window.WebChat = {
createStoreWithOptions,
testIds
};
run(async function () {
const {
directLine,
store
} = createDirectLineEmulator();
const renderHook = createRenderHook(document.getElementById('webchat'), {
directLine,
locale: 'yue',
store
});
const [language] = await renderHook(() => useLanguage('speech'));
expect(language).toBe('zh-HK');
});
```
--------------------------------
### Using useDictateInterims Hook
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/hooks/useDictateInterims.setter.html
Demonstrates how to use the useDictateInterims hook to get and set interim dictation results. This snippet shows how to initialize the hook and includes an example of expecting an error when the setter is called without proper arguments.
```javascript
import '/test-harness.mjs';
import '/test-page-object.mjs';
import { createStoreWithOptions, testIds } from 'botframework-webchat';
import { useDictateInterims } from 'botframework-webchat/hook.js';
import createRenderHook from '/assets/esm/createRenderHook.js';
import { actRecognizeOnce, createWebSpeechPonyfill } from '/assets/esm/speech/speechPageObjects.js';
const { createDirectLineEmulator } = window.testHelpers;
window.WebChat = {
createStoreWithOptions,
testIds,
};
run(async function () {
const { directLine, store } = createDirectLineEmulator();
const ponyfill = createWebSpeechPonyfill();
const renderHook = createRenderHook(document.getElementById('webchat'), {
directLine,
store,
webSpeechPonyfillFactory: () => ponyfill,
});
const [_, setDictateInterims] = await renderHook(() => useDictateInterims());
expect(() => setDictateInterims()).toThrow();
});
```
--------------------------------
### Complete HTML for Customizing Open URL Behavior
Source: https://github.com/microsoft/botframework-webchat/blob/main/samples/04.api/i.open-url/README.md
This is the complete HTML file for the sample, including Web Chat initialization, Direct Line token retrieval, and the custom cardActionMiddleware for handling 'openUrl' and 'signin' actions.
```html
Web Chat: Customize open URL behavior
```
--------------------------------
### Implement Input with Emoji Support
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/withEmoji/withEmoji.9.html
Use `WebChat.withEmoji` to wrap a React input component, enabling custom emoji mappings. This setup is useful for creating chat interfaces where users can input text that gets transformed into emojis.
```javascript
run(async function () {
const InputWithEmoji = WebChat.withEmoji( React.forwardRef((props, ref) => React.createElement('input', { ...props, ref })) );
const App = () => {
const [value, setValue] = React.useState('');
return React.createElement(
'label',
{},
'Input: ',
React.createElement(InputWithEmoji, {
autoFocus: true,
emojiMap: new Map([
['<3', '❤️'],
['<33', '💓']
]),
onChange: setValue,
value
}),
React.createElement('br'),
React.createElement('div', { 'data-test-id': 'get-value' }, value)
);
};
await new Promise(resolve => ReactDOM.render(React.createElement(App), document.getElementsByTagName('main')[0], resolve));
const [inputElement] = document.getElementsByTagName('input');
const getValueElement = document.querySelector('[data-test-id]');
const getTextWithCaret = () => {
expect(inputElement.value).toBe(getValueElement.textContent);
const tokens = inputElement.value.split('');
if (inputElement.selectionStart === inputElement.selectionEnd) {
tokens.splice(inputElement.selectionStart, 0, '|');
} else {
tokens.splice(inputElement.selectionEnd, 0, ']');
tokens.splice(inputElement.selectionStart, 0, '[');
}
return tokens.join('');
};
await host.sendKeys('<3');
expect(getTextWithCaret()).toBe('❤️|');
await host.sendKeys('+CONTROL', 'Z', '-CONTROL');
expect(getTextWithCaret()).toBe('<3|');
await host.sendKeys('3');
expect(getTextWithCaret()).toBe('💓|');
await host.sendKeys('+CONTROL', 'Z', '-CONTROL');
expect(getTextWithCaret()).toBe('<33|');
await host.sendKeys('LEFT', 'A', 'LEFT', '3');
expect(getTextWithCaret()).toBe('💓|A3');
await host.sendKeys('DELETE', '<');
expect(getTextWithCaret()).toBe('💓<|3');
await host.sendKeys('DELETE', '3');
expect(getTextWithCaret()).toBe('💓❤️|');
await host.sendKeys('+CONTROL', 'Z', '-CONTROL');
expect(getTextWithCaret()).toBe('💓<3|');
await host.sendKeys('+CONTROL', 'Z', '-CONTROL');
expect(inputElement.value).toBe('💓<');
});
```
--------------------------------
### Test Setup and Activity Rendering Logic
Source: https://github.com/microsoft/botframework-webchat/blob/main/__tests__/html2/middleware/activity/hooks/useBuildRenderActivityCallback/extraneousProps.html
Sets up a test environment with Direct Line emulator and Web Chat components. It defines a SystemUnderTest component that uses useActivities and useBuildRenderActivityCallback to render activities. The polymiddleware is configured to use a custom MyActivity component, ensuring only the 'text' prop is passed.
```javascript
import React from 'react';
window.React = React;
import { waitFor } from '@testduet/wait-for';
import React, { createElement, memo } from 'react';
import { createRoot } from 'react-dom/client';
run(async function () {
const {
testHelpers: {
createDirectLineEmulator,
},
WebChat: {
Components: {
Composer,
},
hooks: {
useActivities,
useBuildRenderActivityCallback,
},
middleware: {
activityComponent,
createActivityPolymiddleware,
},
},
} = window;
const { directLine, store } = createDirectLineEmulator();
const SystemUnderTest = memo(function SystemUnderTest() {
const [activities] = useActivities();
const renderActivity = useBuildRenderActivityCallback();
return createElement(
'ol',
{},
activities.map(activity =>
createElement('li', {}, renderActivity({ activity })?.({}))
)
);
});
const MyActivity = memo(function MyActivity({ text }) {
return createElement('div', {}, text);
});
const rootElement = document.getElementsByTagName('main')[0];
const polymiddleware = [
// activityPolymiddleware only has props of { children?: never }, everything is extraneous.
createActivityPolymiddleware(() => ({ activity }) =>
activityComponent(MyActivity, { text: activity.text })
),
];
// WHEN: is being rendered.
createRoot(rootElement).render(
createElement(
Composer,
{
directLine,
polymiddleware,
store,
},
createElement(SystemUnderTest)
)
);
// THEN: Should render no list items.
await waitFor(() =>
expect(rootElement?.getElementsByTagName('ol')[0]?.children).toHaveLength(0)
);
// WHEN: A message "Hello, World!" arrives.
await directLine.emulateIncomingActivity({
text: 'Hello, World!',
type: 'message',
}, {
skipWait: true,
});
// THEN: Should render the message "Hello, World!"
await waitFor(() =>
expect(rootElement?.getElementsByTagName('ol')[0]?.children).toHaveLength(1)
);
await waitFor(() =>
expect(rootElement?.querySelector('ol li')?.textContent.includes('Hello, World!'))
.toBe(true)
);
// THEN: Should match snapshot.
await host.snapshot('local');
});
```