Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Support HTML-in-Markdown #5161

Merged
merged 29 commits into from
May 3, 2024
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
07cccd1
Added betterLinkDocumentMod
compulim May 2, 2024
f20e166
add markdownRenderHTML to styleOptions
beyackle May 2, 2024
575758b
Use new betterLinkDocumentMod and add a test
OEvgeny May 2, 2024
7e24c54
Fix asButton with aria-label and className
compulim May 2, 2024
04e1e5e
Update snapshots
OEvgeny May 2, 2024
cb6e572
Merge branch 'main' into feat-better-link-html-mod
beyackle2 May 2, 2024
269ccf5
Update entry
compulim May 2, 2024
f75d816
Use DOMParser + XMLSerializer
compulim May 2, 2024
ab7ff57
Revert red box
compulim May 2, 2024
66d4ffa
Update CHANGELOG.md
beyackle2 May 2, 2024
8b46ef6
Update CHANGELOG.md
beyackle2 May 2, 2024
6240fb3
Add breaking changes
compulim May 2, 2024
1d91eda
Run in JSDOM and remove empty "title" attribute
compulim May 3, 2024
163c9f0
More explanation
compulim May 3, 2024
20dbad6
Add HTML-in-Markdown for Adaptive Cards
compulim May 3, 2024
5a0ed74
Style HTML-in-Markdown for Adaptive Cards
compulim May 3, 2024
add152c
Fix tests
compulim May 3, 2024
6bf7c68
Revert containerClassName
compulim May 3, 2024
336d6aa
Move container to useRenderMarkdownAsHTML
compulim May 3, 2024
62023a3
Fix tests
compulim May 3, 2024
8de5b68
Fix tests
compulim May 3, 2024
99e2134
Clean up
compulim May 3, 2024
a12cf94
Add comment
compulim May 3, 2024
ffb74fe
Update entry
compulim May 3, 2024
1af6958
Fix tests
compulim May 3, 2024
8d1aad1
Added open in external icon
compulim May 3, 2024
e8eaafb
Add newline to end of XML serialization
compulim May 3, 2024
4d5f686
Better test
compulim May 3, 2024
bbc00be
Add HTML-in-Markdown
compulim May 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Removed deprecated code: `connect*`, `useRenderActivity`, `useRenderActivityStatus`, `useRenderAvatar`, in PR [#5148](https://github.com/microsoft/BotFramework-WebChat/pull/5148), by [@compulim](https://github.com/compulim)
- Added named exports in both CommonJS and ES Modules module format, in PR [#5148](https://github.com/microsoft/BotFramework-WebChat/pull/5148), by [@compulim](https://github.com/compulim)
- Removed deprecated `useFocusSendBox()` hook, please use `useFocus('sendBox')` instead, in PR [#5150](https://github.com/microsoft/BotFramework-WebChat/pull/5150), by [@OEvgeny](https://github.com/OEvgeny)
- HTML-in-Markdown is now supported. To disable this feature, set `styleOptions.markdownRenderHTML` to `false`

### Added

Expand Down Expand Up @@ -65,6 +66,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Added `<ThemeProvider>` component to apply theme pack to Web Chat, by [@compulim](https://github.com/compulim), in PR [#5120](https://github.com/microsoft/BotFramework-WebChat/pull/5120)
- Added `useMakeThumbnail` hook option to create a thumbnail from the file given, by [@compulim](https://github.com/compulim), in PR [#5123](https://github.com/microsoft/BotFramework-WebChat/pull/5123) and [#5122](https://github.com/microsoft/BotFramework-WebChat/pull/5122)
- Added `moduleFormat` and `transpiler` build info to `<meta>` tag, in PR [#5148](https://github.com/microsoft/BotFramework-WebChat/pull/5148), by [@compulim](https://github.com/compulim)
- Added support of rendering HTML-in-Markdown in citation modal, in PR [#5161](https://github.com/microsoft/BotFramework-WebChat/pull/5161), by [@compulim](https://github.com/compulim), [@beyackle2](https://github.com/beyackle2), and [@OEvgeny](https://github.com/OEvgeny)

### Fixed

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
OEvgeny marked this conversation as resolved.
Show resolved Hide resolved
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
compulim marked this conversation as resolved.
Show resolved Hide resolved
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 12 additions & 14 deletions __tests__/hooks/useRenderMarkdownAsHTML.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,21 @@ jest.setTimeout(timeouts.test);
test('renderMarkdown should use Markdown-It if not set in props', async () => {
const { pageObjects } = await setupWebDriver();

await expect(pageObjects.runHook('useRenderMarkdownAsHTML', [], fn => fn('Hello, World!'))).resolves.toBe(
'<p>Hello, World!</p>\n'
await expect(pageObjects.runHook('useRenderMarkdownAsHTML', [], fn => fn('Hello, World!'))).resolves.toContain(
compulim marked this conversation as resolved.
Show resolved Hide resolved
'<p>Hello, World!</p>'
);
});

test('renderMarkdown should use custom Markdown transform function from props', async () => {
const { pageObjects } = await setupWebDriver({
props: {
renderMarkdown: text => text.toUpperCase()
renderMarkdown: text => `<p>${text.toUpperCase()}</p>`
OEvgeny marked this conversation as resolved.
Show resolved Hide resolved
}
});

await expect(
pageObjects.runHook('useRenderMarkdownAsHTML', [], fn => fn('Hello, World!'))
).resolves.toMatchInlineSnapshot(`"HELLO, WORLD!"`);
await expect(pageObjects.runHook('useRenderMarkdownAsHTML', [], fn => fn('Hello, World!'))).resolves.toContain(
'<p>HELLO, WORLD!</p>'
);
});

test('renderMarkdown should return falsy if the custom Markdown transform function is null', async () => {
Expand All @@ -40,19 +40,17 @@ test('renderMarkdown should add accessibility text for external links', async ()

await expect(
pageObjects.runHook('useRenderMarkdownAsHTML', [], fn => fn('Click [here](https://aka.ms/) to find out more.'))
).resolves.toMatchInlineSnapshot(`
"<p>Click \u200B<a href=\\"https://aka.ms/\\" aria-label=\\"here Opens in a new window; external.\\" rel=\\"noopener noreferrer\\" target=\\"_blank\\">here<img src=\\"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\\" alt class=\\"webchat__render-markdown__external-link-icon\\" title=\\"Opens in a new window; external.\\" /></a>\u200B to find out more.</p>
"
`);
).resolves.toContain(
`<p>Click \u200B<a href="https://aka.ms/" aria-label="here Opens in a new window; external." rel="noopener noreferrer" target="_blank">here<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="" class="webchat__render-markdown__external-link-icon" title="Opens in a new window; external." /></a>\u200B to find out more.</p>`
);
});

test('renderMarkdown should add accessibility text for external links with yue', async () => {
const { pageObjects } = await setupWebDriver({ props: { locale: 'yue' } });

await expect(
pageObjects.runHook('useRenderMarkdownAsHTML', [], fn => fn('Click [here](https://aka.ms/) to find out more.'))
).resolves.toMatchInlineSnapshot(`
"<p>Click \u200B<a href=\\"https://aka.ms/\\" aria-label=\\"here 喺新嘅視窗開啟外部連結。\\" rel=\\"noopener noreferrer\\" target=\\"_blank\\">here<img src=\\"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\\" alt class=\\"webchat__render-markdown__external-link-icon\\" title=\\"喺新嘅視窗開啟外部連結。\\" /></a>\u200B to find out more.</p>
"
`);
).resolves.toContain(
`<p>Click \u200B<a href="https://aka.ms/" aria-label="here 喺新嘅視窗開啟外部連結。" rel="noopener noreferrer" target="_blank">here<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="" class="webchat__render-markdown__external-link-icon" title="喺新嘅視窗開啟外部連結。" /></a>\u200B to find out more.</p>`
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

await pageConditions.numActivitiesShown(1);

expect(pageElements.activityContents()[0]).toHaveProperty('textContent', 'Hello, World!\n');
expect(pageElements.activityContents()[0]).toHaveProperty('textContent', '\nHello, World!');

const pushButton1 = document.querySelector('.ac-pushButton');

Expand All @@ -53,7 +53,7 @@
type: 'message'
});

expect(pageElements.activityContents()[0]).toHaveProperty('textContent', 'Aloha!\n');
expect(pageElements.activityContents()[0]).toHaveProperty('textContent', '\nAloha!');

const pushButton2 = document.querySelector('.ac-pushButton');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@

await pageConditions.numActivitiesShown(1);

expect(pageElements.activityContents()[0]).toHaveProperty('textContent', 'Hello, World!\n');
expect(pageElements.activityContents()[0]).toHaveProperty('textContent', '\nHello, World!');

const textInput1 = document.querySelector('.ac-textInput');

Expand All @@ -62,7 +62,7 @@
type: 'message'
});

expect(pageElements.activityContents()[0]).toHaveProperty('textContent', 'Aloha!\n');
expect(pageElements.activityContents()[0]).toHaveProperty('textContent', '\nAloha!');

const textInput2 = document.querySelector('.ac-textInput');

Expand Down
69 changes: 69 additions & 0 deletions __tests__/html/markdownRenderHTML/default.adaptiveCards.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<!doctype html>
<html lang="en-US">
<head>
<link href="/assets/index.css" rel="stylesheet" type="text/css" />
<script crossorigin="anonymous" src="/test-harness.js"></script>
<script crossorigin="anonymous" src="/test-page-object.js"></script>
<script crossorigin="anonymous" src="/__dist__/webchat-es5.js"></script>
</head>
<body>
<main id="webchat"></main>
<script>
run(async function () {
const { directLine, store } = testHelpers.createDirectLineEmulator();

WebChat.renderWebChat({ directLine, store }, document.getElementById('webchat'));

await pageConditions.uiConnected();

await directLine.emulateIncomingActivity({
attachments: [
{
content: {
type: 'AdaptiveCard',
$schema: 'http://adaptivecards.io/schemas/adaptive-card.json',
version: '1.5',
body: [
{
style: 'heading',
type: 'TextBlock',
text: 'This is an Adaptive Card'
},
{
type: 'TextBlock',
text: atob(
'IyMgSGVhZGVyCjxwPlRoaXMgaXMgc29tZSB0ZXh0IHdpdGggYSA8YSBocmVmPSJodHRwOi8vZXhhbXBsZS5jb20iIHRpdGxlPSJldmVuIGhhY2tlcnMgcmVzcGVjdCBhMTF5Ij5saW5rIGluIGl0PC9hPi4gQWxzbyA8c3Ryb25nPnNvbWUgdGV4dDwvc3Ryb25nPiA8ZW0+d2l0aCBmb3JtYXR0aW5nPC9lbT4uPC9wPgo8dWw+CjxsaT5Vbm9yZGVyZWQ8L2xpPgo8bGk+bGlzdDwvbGk+CjxsaT5pdGVtczwvbGk+CjwvdWw+CjxvbD4KPGxpPk9yZGVyZWQ8L2xpPgo8bGk+bGlzdDwvbGk+CjxsaT5pdGVtczwvbGk+Cjwvb2w+Cjx1bD4KPGxpPkJlbG93IGFyZSBzb21lIHVuc2FmZSB0aGluZ3MgdGhhdCBzaG91bGQgZ2V0IHNhbml0aXplZDoKPGxpPjxzY3JpcHQ+VGhpcyBpc24ndCBhbGxvd2VkITwvc2NyaXB0Pgo8bGk+PGltZyBzcmM9IiIgYWx0PSJJIGFtIGEgZHVtbXkgaW1hZ2UgdHJ5aW5nIHRvIGhhY2sgeW91IiBvbmVycm9yPWFsZXJ0KDEpIC8+CjxsaT48c3ZnIGFyaWEtbGFiZWw9Im1hbGljaW91cyBzdmcgaGVyZSI+PGcvb25sb2FkPWFsZXJ0KDIpLy88cD4KPGxpPjxwPmFiYzxpZnJhbWUvL3NyYz1qQXZhJlRhYjtzY3JpcHQ6YWxlcnQoMyk+ZGVmPC9wPgo8bGk+PG1hdGg+PG1pLy94bGluazpocmVmPSJkYXRhOngsPHNjcmlwdD5hbGVydCg0KTwvc2NyaXB0Pgo8bGk+CjwvdWw+'
),
wrap: true
}
],
actions: [
{
type: 'Action.Submit',
title: 'Submit card'
}
]
},
contentType: 'application/vnd.microsoft.card.adaptive'
}
],
type: 'message'
});

await pageConditions.numActivitiesShown(1);

const [firstActivityElement] = pageElements.activities();

const link = firstActivityElement.querySelector('[href="http://example.com"]');
const linkImage = link.querySelector('.webchat__render-markdown__external-link-icon');

expect(link.getAttribute('aria-label')).toBe('link in it Opens in a new window; external.');
expect(link.getAttribute('target')).toBe('_blank');
expect(link.getAttribute('rel')).toBe('noopener noreferrer');
expect(linkImage.title).toBe('Opens in a new window; external.');

await host.snapshot();
});
</script>
</body>
</html>
5 changes: 5 additions & 0 deletions __tests__/html/markdownRenderHTML/default.adaptiveCards.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */

describe('markdownRenderHTML when unset', () => {
test('should render sanitized HTML in Adaptive Cards', () => runHTML('markdownRenderHTML/default.adaptiveCards'));
});
105 changes: 105 additions & 0 deletions __tests__/html/markdownRenderHTML/default.citationModal.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<!doctype html>
<html lang="en-US">
<head>
<link href="/assets/index.css" rel="stylesheet" type="text/css" />
<script crossorigin="anonymous" src="/test-harness.js"></script>
<script crossorigin="anonymous" src="/test-page-object.js"></script>
<script crossorigin="anonymous" src="/__dist__/webchat-es5.js"></script>
</head>
<body>
<main id="webchat"></main>
<script>
run(async function () {
const { directLine, store } = testHelpers.createDirectLineEmulator();

WebChat.renderWebChat({ directLine, store }, document.getElementById('webchat'));

await pageConditions.uiConnected();

await directLine.emulateIncomingActivity({
entities: [
{
'@context': 'https://schema.org',
'@id': '',
'@type': 'Message',
citation: [
{
'@type': 'Claim',
appearance: {
'@type': 'DigitalDocument',
url: 'https://example.com/1/',
usageInfo: {
'@id': '_:1',
'@type': 'CreativeWork',
description:
'Nisi quis ut sint elit est nulla enim eiusmod. Deserunt commodo pariatur nostrud culpa aliquip esse pariatur exercitation nulla do proident. Est qui eiusmod aliquip deserunt labore consequat fugiat. Ullamco reprehenderit nostrud eiusmod nisi nulla esse id. Reprehenderit aliqua quis consectetur sit cupidatat fugiat Lorem ex labore. Eiusmod velit laborum quis tempor incididunt excepteur culpa esse nulla.',
keywords: ['encrypted-content'],
name: 'Sit veniam do irure velit est et quis ut Lorem reprehenderit commodo cillum occaecat',
pattern: {
'@type': 'DefinedTerm',
inDefinedTermSet: 'https://www.w3.org/TR/css-color-4/',
name: 'color',
termCode: 'orange'
}
}
},
position: 1
},
{
'@type': 'Claim',
appearance: {
'@type': 'DigitalDocument',
text: 'Incididunt amet dolore anim commodo fugiat occaecat elit nulla do consequat. Quis incididunt occaecat labore adipisicing. Cillum sunt velit consequat irure ipsum ullamco sint ea aute. Sunt et eu ut enim aliqua cupidatat non adipisicing dolore commodo dolor magna enim. Commodo reprehenderit excepteur ad nostrud ex id aliquip deserunt eiusmod. Esse non labore nulla voluptate.',
usageInfo: {
'@type': 'CreativeWork',
name: 'Velit exercitation',
pattern: {
'@type': 'DefinedTerm',
inDefinedTermSet: 'https://www.w3.org/TR/css-color-4/',
name: 'color',
termCode: 'Yellow'
}
}
},
position: 3
},
{
'@type': 'Claim',
appearance: {
'@type': 'DigitalDocument',
text: atob(
'IyMgSGVhZGVyCjxwPlRoaXMgaXMgc29tZSB0ZXh0IHdpdGggYSA8YSBocmVmPSJodHRwOi8vZXhhbXBsZS5jb20iIHRpdGxlPSJldmVuIGhhY2tlcnMgcmVzcGVjdCBhMTF5Ij5saW5rIGluIGl0PC9hPi4gQWxzbyA8c3Ryb25nPnNvbWUgdGV4dDwvc3Ryb25nPiA8ZW0+d2l0aCBmb3JtYXR0aW5nPC9lbT4uPC9wPgo8dWw+CjxsaT5Vbm9yZGVyZWQ8L2xpPgo8bGk+bGlzdDwvbGk+CjxsaT5pdGVtczwvbGk+CjwvdWw+CjxvbD4KPGxpPk9yZGVyZWQ8L2xpPgo8bGk+bGlzdDwvbGk+CjxsaT5pdGVtczwvbGk+Cjwvb2w+Cjx1bD4KPGxpPkJlbG93IGFyZSBzb21lIHVuc2FmZSB0aGluZ3MgdGhhdCBzaG91bGQgZ2V0IHNhbml0aXplZDoKPGxpPjxzY3JpcHQ+VGhpcyBpc24ndCBhbGxvd2VkITwvc2NyaXB0Pgo8bGk+PGltZyBzcmM9IiIgYWx0PSJJIGFtIGEgZHVtbXkgaW1hZ2UgdHJ5aW5nIHRvIGhhY2sgeW91IiBvbmVycm9yPWFsZXJ0KDEpIC8+CjxsaT48c3ZnIGFyaWEtbGFiZWw9Im1hbGljaW91cyBzdmcgaGVyZSI+PGcvb25sb2FkPWFsZXJ0KDIpLy88cD4KPGxpPjxwPmFiYzxpZnJhbWUvL3NyYz1qQXZhJlRhYjtzY3JpcHQ6YWxlcnQoMyk+ZGVmPC9wPgo8bGk+PG1hdGg+PG1pLy94bGluazpocmVmPSJkYXRhOngsPHNjcmlwdD5hbGVydCg0KTwvc2NyaXB0Pgo8bGk+CjwvdWw+'
)
},
position: 4
}
],
type: 'https://schema.org/Message',
usageInfo: { '@id': '_:1' }
}
],
text: 'Ipsum[1] dolore[2] cupidatat[3] magna[4] consectetur[5] do tempor est excepteur.\n\n[1]: https://example.com/1/ "Sint amet id officia dolor ex eiusmod ipsum ipsum magna fugiat"\n[2]: https://example.com/2/ "Laboris cupidatat voluptate"\n[3]: _:3 "Velit nulla culpa eu ea consectetur consectetur dolore velit"\n[4]: _:4 "Adipisicing enim nulla"\n[5]: https://example.com/5',
type: 'message'
});

const [firstActivityElement] = pageElements.activities();

const linkDefinitions = firstActivityElement.querySelectorAll('.webchat__link-definitions__list-item');

expect(linkDefinitions).toHaveProperty('length', 5);

linkDefinitions[3].querySelector('button').click();

const link = document.querySelector('dialog [href="http://example.com"]');
const linkImage = link.querySelector('.webchat__render-markdown__external-link-icon');

expect(link.getAttribute('aria-label')).toBe('link in it Opens in a new window; external.');
expect(link.getAttribute('target')).toBe('_blank');
expect(link.getAttribute('rel')).toBe('noopener noreferrer');
expect(linkImage.title).toBe('Opens in a new window; external.');

await host.snapshot();
});
</script>
</body>
</html>
5 changes: 5 additions & 0 deletions __tests__/html/markdownRenderHTML/default.citationModal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */

describe('markdownRenderHTML when unset', () => {
test('should render sanitized HTML in citation modal', () => runHTML('markdownRenderHTML/default.citationModal'));
});
42 changes: 42 additions & 0 deletions __tests__/html/markdownRenderHTML/default.messageActivity.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<!doctype html>
<html lang="en-US">
<head>
<link href="/assets/index.css" rel="stylesheet" type="text/css" />
<script crossorigin="anonymous" src="/test-harness.js"></script>
<script crossorigin="anonymous" src="/test-page-object.js"></script>
<script crossorigin="anonymous" src="/__dist__/webchat-es5.js"></script>
</head>
<body>
<main id="webchat"></main>
<script>
run(async function () {
const { directLine, store } = testHelpers.createDirectLineEmulator();

WebChat.renderWebChat({ directLine, store }, document.getElementById('webchat'));

await pageConditions.uiConnected();

await directLine.emulateIncomingActivity({
text: atob(
'IyMgSGVhZGVyCjxwPlRoaXMgaXMgc29tZSB0ZXh0IHdpdGggYSA8YSBocmVmPSJodHRwOi8vZXhhbXBsZS5jb20iIHRpdGxlPSJldmVuIGhhY2tlcnMgcmVzcGVjdCBhMTF5Ij5saW5rIGluIGl0PC9hPi4gQWxzbyA8c3Ryb25nPnNvbWUgdGV4dDwvc3Ryb25nPiA8ZW0+d2l0aCBmb3JtYXR0aW5nPC9lbT4uPC9wPgo8dWw+CjxsaT5Vbm9yZGVyZWQ8L2xpPgo8bGk+bGlzdDwvbGk+CjxsaT5pdGVtczwvbGk+CjwvdWw+CjxvbD4KPGxpPk9yZGVyZWQ8L2xpPgo8bGk+bGlzdDwvbGk+CjxsaT5pdGVtczwvbGk+Cjwvb2w+Cjx1bD4KPGxpPkJlbG93IGFyZSBzb21lIHVuc2FmZSB0aGluZ3MgdGhhdCBzaG91bGQgZ2V0IHNhbml0aXplZDoKPGxpPjxzY3JpcHQ+VGhpcyBpc24ndCBhbGxvd2VkITwvc2NyaXB0Pgo8bGk+PGltZyBzcmM9IiIgYWx0PSJJIGFtIGEgZHVtbXkgaW1hZ2UgdHJ5aW5nIHRvIGhhY2sgeW91IiBvbmVycm9yPWFsZXJ0KDEpIC8+CjxsaT48c3ZnIGFyaWEtbGFiZWw9Im1hbGljaW91cyBzdmcgaGVyZSI+PGcvb25sb2FkPWFsZXJ0KDIpLy88cD4KPGxpPjxwPmFiYzxpZnJhbWUvL3NyYz1qQXZhJlRhYjtzY3JpcHQ6YWxlcnQoMyk+ZGVmPC9wPgo8bGk+PG1hdGg+PG1pLy94bGluazpocmVmPSJkYXRhOngsPHNjcmlwdD5hbGVydCg0KTwvc2NyaXB0Pgo8bGk+CjwvdWw+'
),
type: 'message'
});

await pageConditions.numActivitiesShown(1);

const [firstActivityElement] = pageElements.activities();

const link = firstActivityElement.querySelector('[href="http://example.com"]');
const linkImage = link.querySelector('.webchat__render-markdown__external-link-icon');

expect(link.getAttribute('aria-label')).toBe('link in it Opens in a new window; external.');
expect(link.getAttribute('target')).toBe('_blank');
expect(link.getAttribute('rel')).toBe('noopener noreferrer');
expect(linkImage.title).toBe('Opens in a new window; external.');

await host.snapshot();
});
</script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */

describe('markdownRenderHTML when unset', () => {
test('should render sanitized HTML in message activity', () => runHTML('markdownRenderHTML/default.messageActivity'));
});
Loading
Loading