### 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. wave plot 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'); }); ```