Repository navigation
Fix the Fluent theme IIFE on React 19 and follow up on renderWebChat() #5971
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
Merged
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
874ab96
Split renderWebChat()'s render schema into legacyReactDOMSchema and r…
d82b8c0
Use the React DOM of the page in the IIFE build of the Fluent theme
e2ddf19
Add a React 19 test for the IIFE build of the Fluent theme
48fa368
Remove react-dom/client from the baseline import map in HOSTING.md
fa51b91
Test that renderWebChat() throws an error from root.render() synchron…
a52527b
Add a React 19 test for the copy button of code blocks with the IIFE …
46e59d5
Name ReactDOM.createRoot() in the error of renderWebChat() for an inv…
e7b64d7
Say what keeps the ESM renderWebChat() test on emulated React 19: rea…
69ed9a9
Expect the version of ReactDOM in the React 19 tests
c1693e7
Spy on root.render() with jest-mock in the React 18 renderWebChat() test
329fd4d
Add the changelog fragment
2957991
Merge branch 'main' into OEvgeny/fix-react-19-follow-ups
OEvgeny File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| ### Fixed | ||
|
|
||
| - Fixed the IIFE build of the Fluent theme crashing on load with React 19, in PR [#5971](https://github.com/microsoft/BotFramework-WebChat/pull/5971), by [@OEvgeny](https://github.com/OEvgeny) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| <!doctype html> | ||
| <html lang="en-US"> | ||
| <head> | ||
| <title>React 19: renders the copy button of code blocks</title> | ||
| <link href="/assets/index.css" rel="stylesheet" type="text/css" /> | ||
| <script type="importmap"> | ||
| { | ||
| "imports": { | ||
| "@testduet/wait-for": "https://esm.sh/@testduet/wait-for", | ||
| "react": "https://esm.sh/react@19.3.1?dev", | ||
| "react-dom": "https://esm.sh/react-dom@19.3.1?dev", | ||
| "react-dom/client": "https://esm.sh/react-dom@19.3.1/client?dev" | ||
| } | ||
| } | ||
| </script> | ||
| <script crossorigin="anonymous" src="/test-harness.js"></script> | ||
| <script crossorigin="anonymous" src="/test-page-object.js"></script> | ||
| <script type="module"> | ||
| // React 19 has no UMD build: the IIFE build of Web Chat uses `window.React` and `window.ReactDOM` when they are set. | ||
| import React from 'react'; | ||
| import ReactDOM from 'react-dom'; | ||
|
|
||
| window.React = React; | ||
| window.ReactDOM = ReactDOM; | ||
| </script> | ||
| <script crossorigin="anonymous" defer src="/__dist__/webchat-es5.js"></script> | ||
| </head> | ||
| <body> | ||
| <main id="webchat"></main> | ||
| <script type="module"> | ||
| import { waitFor } from '@testduet/wait-for'; | ||
| import { createElement, version } from 'react'; | ||
| import ReactDOM from 'react-dom'; | ||
| import { createRoot } from 'react-dom/client'; | ||
|
|
||
| run(async function () { | ||
| await host.sendDevToolsCommand('Browser.setPermission', { | ||
| permission: { name: 'clipboard-write' }, | ||
| setting: 'granted' | ||
| }); | ||
|
|
||
| const { | ||
| WebChat: { ReactWebChat, testIds } | ||
| } = window; // Imports in UMD fashion. | ||
|
|
||
| const { directLine, store } = testHelpers.createDirectLineEmulator(); | ||
|
|
||
| // GIVEN: Web Chat rendered with React 19, which no longer has `ReactDOM.render()`. | ||
| expect(version).toBe('19.3.1'); | ||
| expect(ReactDOM.version).toEqual(expect.stringMatching(/^19\./u)); | ||
| expect(ReactDOM.render).toBeUndefined(); | ||
|
|
||
| createRoot(document.getElementById('webchat')).render( | ||
| createElement(ReactWebChat, { directLine, store, styleOptions: { hideSendBox: true } }) | ||
| ); | ||
|
|
||
| await pageConditions.uiConnected(); | ||
|
|
||
| // WHEN: The bot sends a code block. | ||
| await directLine.emulateIncomingActivity({ | ||
| text: 'Here is the code:\n\n```\nconsole.log("Hello, World!");\n```', | ||
| type: 'message' | ||
| }); | ||
|
|
||
| await pageConditions.numActivitiesShown(1); | ||
|
|
||
| // THEN: The code block should have a "Copy" button. | ||
| const copyButton = await waitFor(() => { | ||
| const element = document.querySelector(`[data-testid="${testIds.codeBlockCopyButton}"]`); | ||
|
|
||
| expect(element).toBeTruthy(); | ||
|
|
||
| return element; | ||
| }); | ||
|
|
||
| const { name, role } = await testHelpers.getAccessibilityNode(copyButton); | ||
|
|
||
| expect(name.value).toBe('Copy'); | ||
| expect(role.value).toBe('button'); | ||
|
|
||
| // WHEN: The "Copy" button is clicked. | ||
| await host.click(copyButton); | ||
|
|
||
| // THEN: The button should change to "Copied". | ||
| await waitFor(async () => expect(await testHelpers.getAccessibleName(copyButton)).toBe('Copied')); | ||
|
|
||
| // THEN: The code block shows the copy button with a check mark. | ||
| await host.snapshot('local'); | ||
| }); | ||
| </script> | ||
| </body> | ||
| </html> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| <!doctype html> | ||
| <html lang="en-US"> | ||
| <head> | ||
| <title>React 19: the IIFE build of the Fluent theme sends a message and shows the reply</title> | ||
| <link href="/assets/index.css" rel="stylesheet" type="text/css" /> | ||
| <script type="importmap"> | ||
| { | ||
| "imports": { | ||
| "react": "https://esm.sh/react@19.3.1?dev", | ||
| "react-dom": "https://esm.sh/react-dom@19.3.1?dev", | ||
| "react-dom/client": "https://esm.sh/react-dom@19.3.1/client?dev" | ||
| } | ||
| } | ||
| </script> | ||
| <script crossorigin="anonymous" src="/test-harness.js"></script> | ||
| <script crossorigin="anonymous" src="/test-page-object.js"></script> | ||
| <script type="module"> | ||
| // React 19 has no UMD build: the IIFE builds of Web Chat and the Fluent theme use `window.React` and `window.ReactDOM`. | ||
| import React from 'react'; | ||
| import ReactDOM from 'react-dom'; | ||
|
|
||
| window.React = React; | ||
| window.ReactDOM = ReactDOM; | ||
| </script> | ||
| <script crossorigin="anonymous" defer src="/__dist__/webchat-es5.js"></script> | ||
| <script crossorigin="anonymous" defer src="/__dist__/botframework-webchat-fluent-theme.development.js"></script> | ||
| </head> | ||
| <body> | ||
| <main id="webchat"></main> | ||
| <script type="module"> | ||
| import { createElement, version } from 'react'; | ||
| import ReactDOM from 'react-dom'; | ||
| import { createRoot } from 'react-dom/client'; | ||
|
|
||
| run(async function () { | ||
| const { | ||
| WebChat: { FluentThemeProvider, ReactWebChat } | ||
| } = window; // Imports in UMD fashion. | ||
|
|
||
| const { directLine, store } = testHelpers.createDirectLineEmulator(); | ||
|
|
||
| // GIVEN: The Fluent theme rendered with React 19, which no longer has `ReactDOM.render()`. | ||
| expect(version).toBe('19.3.1'); | ||
| expect(ReactDOM.version).toEqual(expect.stringMatching(/^19\./u)); | ||
| expect(ReactDOM.render).toBeUndefined(); | ||
|
|
||
| createRoot(document.getElementById('webchat')).render( | ||
| createElement(FluentThemeProvider, {}, createElement(ReactWebChat, { directLine, store })) | ||
| ); | ||
|
|
||
| await pageConditions.uiConnected(); | ||
|
|
||
| // WHEN: A message is sent through the send box. | ||
| const sendMessage = await directLine.actPostActivity(() => | ||
| pageObjects.sendMessageViaSendBox('Aloha!', { waitForSend: false }) | ||
| ); | ||
|
|
||
| await sendMessage.resolveAll(); | ||
|
|
||
| // WHEN: The bot replies. | ||
| await directLine.emulateIncomingActivity({ | ||
| from: { id: 'bot', role: 'bot' }, | ||
| text: 'Aloha! How can I help?', | ||
| type: 'message' | ||
| }); | ||
|
|
||
| // THEN: The transcript shows the message and the reply. | ||
| await pageConditions.numActivitiesShown(2); | ||
|
|
||
| const [sent, reply] = pageElements.activities(); | ||
|
|
||
| expect(sent.textContent).toContain('Aloha!'); | ||
| expect(reply.textContent).toContain('Aloha! How can I help?'); | ||
|
|
||
| // THEN: The Fluent theme shows the message, the reply and its send box. | ||
| await host.snapshot('local'); | ||
| }); | ||
| </script> | ||
| </body> | ||
| </html> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| /// <reference types="node" /> | ||
|
|
||
| // The React DOM of the page, as with "react": a bundled React DOM cannot initialize with another React, such as React 19. | ||
| module.exports = (globalThis as any).ReactDOM; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.