Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
249 changes: 143 additions & 106 deletions __tests__/html2/fluentTheme/defaultFeedback.activity.html
Original file line number Diff line number Diff line change
@@ -1,127 +1,164 @@
<!doctype html>
<html lang="en-US">
<head>
<link href="/assets/index.css" rel="stylesheet" type="text/css" />
<script crossorigin="anonymous" src="https://unpkg.com/@babel/standalone@7.8.7/babel.min.js"></script>
<script crossorigin="anonymous" src="https://unpkg.com/react@16.8.6/umd/react.production.min.js"></script>
<script crossorigin="anonymous" src="https://unpkg.com/react-dom@16.8.6/umd/react-dom.production.min.js"></script>
<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>
<script crossorigin="anonymous" src="/__dist__/botframework-webchat-fluent-theme.production.min.js"></script>
</head>

<body>
<main id="webchat"></main>
<script type="text/babel">
run(async function () {
const {
React,
ReactDOM: { render },
WebChat: { FluentThemeProvider, ReactWebChat }
} = window; // Imports in UMD fashion.

const { directLine, store } = testHelpers.createDirectLineEmulator();

const App = () => <ReactWebChat directLine={directLine} store={store} />;

render(
<FluentThemeProvider>
<App />
</FluentThemeProvider>,
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'
}

<head>
<link href="/assets/index.css" rel="stylesheet" type="text/css" />
<script crossorigin="anonymous" src="https://unpkg.com/@babel/standalone@7.8.7/babel.min.js"></script>
<script crossorigin="anonymous" src="https://unpkg.com/react@16.8.6/umd/react.production.min.js"></script>
<script crossorigin="anonymous" src="https://unpkg.com/react-dom@16.8.6/umd/react-dom.production.min.js"></script>
<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>
<script crossorigin="anonymous" src="/__dist__/botframework-webchat-fluent-theme.production.min.js"></script>
</head>

<body>
<main id="webchat"></main>
<script type="text/babel">
run(async function () {
const {
React,
ReactDOM: { render },
WebChat: { FluentThemeProvider, ReactWebChat }
} = window; // Imports in UMD fashion.

const { directLine, store } = testHelpers.createDirectLineEmulator();

const App = () => <ReactWebChat directLine={directLine} store={store} />;

render(
<FluentThemeProvider>
<App />
</FluentThemeProvider>,
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'
}
});
}
});

await pageConditions.numActivitiesShown(1);
await pageConditions.numActivitiesShown(1);

pageElements.byTestId('send box text area').focus();
await host.sendShiftTab(2);
pageElements.byTestId('send box text area').focus();
await host.sendShiftTab(2);

await host.sendKeys('ENTER');
await host.sendKeys('ENTER');
await host.sendKeys('ENTER');
await host.sendKeys('ENTER');

await host.snapshot('local');
await host.snapshot('local');

// Dismiss like button
await host.sendShiftTab(2);
await host.sendKeys('ENTER');
// Dismiss like button
await host.sendShiftTab(2);
await host.sendKeys('ENTER');

await host.snapshot('local');
await host.snapshot('local');

// Click like button
await host.sendKeys('ENTER');
// Click like button
await host.sendKeys('ENTER');

await pageConditions.became(
'feedback form is open',
() => document.activeElement === pageElements.byTestId('feedback sendbox'),
1000
);
await pageConditions.became(
'feedback form is open',
() => document.activeElement === pageElements.byTestId('feedback sendbox'),
1000
);

// Go to cancel button
await host.sendTab(2);
await host.sendKeys('ENTER');
// Go to cancel button
await host.sendTab(2);
await host.sendKeys('ENTER');

await host.snapshot('local');
await host.snapshot('local');

pageElements.byTestId('send box text area').focus();
await host.sendShiftTab(2);
pageElements.byTestId('send box text area').focus();
await host.sendShiftTab(2);

await host.sendKeys('ENTER');
// Send dislike
await host.sendKeys('ENTER');
// Send dislike
await host.sendTab(1);
await host.sendKeys('ENTER');

await pageConditions.became(
'feedback form is open',
() => document.activeElement === pageElements.byTestId('feedback sendbox'),
1000
);

await host.sendKeys('Test feedback');

await host.snapshot('local');

const { activity } = await directLine.actPostActivity(async () => {
await host.sendTab(1);
await host.sendKeys('ENTER');
});

await pageConditions.became(
'feedback form is open',
() => document.activeElement === pageElements.byTestId('feedback sendbox'),
1000
);

await host.sendKeys('Test feedback');

await host.snapshot('local');

const { activity } = await directLine.actPostActivity(async () => {
await host.sendTab(1);
await host.sendKeys('ENTER');
});

expect(activity).toEqual(
expect.objectContaining({
type: 'invoke',
name: 'message/submitAction',
value: {
actionName: 'feedback',
actionValue: {
reaction: 'dislike',
feedback: {
feedbackText: 'Test feedback'
}
expect(activity).toEqual(
expect.objectContaining({
type: 'invoke',
name: 'message/submitAction',
value: {
actionName: 'feedback',
actionValue: {
reaction: 'dislike',
feedback: {
feedbackText: 'Test feedback'
}
}
})
);
}
})
);


await directLine.emulateIncomingActivity({
Comment thread
compulim marked this conversation as resolved.
Outdated
type: 'message',
id: 'a-00001',
timestamp: 0,
text: 'This is a a test message without a disclaimer',
from: {
role: 'bot'
},
locale: 'en-US',
entities: [],
channelData: {
feedbackLoop: {
type: 'default',
}
}
});
</script>
</body>
</html>

pageElements.byTestId('send box text area').focus();
await host.sendShiftTab(2);

await host.sendKeys('ENTER');

await host.sendKeys('ENTER');


await pageConditions.became(
'feedback form is open',
() => document.activeElement === pageElements.byTestId('feedback sendbox'),
1000
);

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.
4 changes: 2 additions & 2 deletions packages/component/src/Activity/private/getDisclaimer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { type WebChatActivity } from 'botframework-webchat-core';
import hasFeedbackLoop from './hasFeedbackLoop';
import { hasDisclaimer } from './hasFeedbackLoop';

export default function getDisclaimer(activity: WebChatActivity): string | undefined {
return hasFeedbackLoop(activity) ? activity.channelData.feedbackLoop.disclaimer : undefined;
return hasDisclaimer(activity) ? activity.channelData.feedbackLoop.disclaimer : undefined;
}
28 changes: 23 additions & 5 deletions packages/component/src/Activity/private/hasFeedbackLoop.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,35 @@
import { type WebChatActivity } from 'botframework-webchat-core';
import { literal, object, safeParse, string, type InferOutput } from 'valibot';
import { literal, string, object, safeParse, type InferOutput, nullish } from 'valibot';
Comment thread
lexi-taylor marked this conversation as resolved.
Outdated

const activityWithFeedbackLoopSchema = object({
const activityWithFeedbackLoopSchemaWithDisclaimer = object({
channelData: object({
feedbackLoop: object({
disclaimer: string(),
disclaimer: nullish(string()),
Comment thread
lexi-taylor marked this conversation as resolved.
Outdated
type: literal('default')
})
})
});

type FeedbackActivity = WebChatActivity & InferOutput<typeof activityWithFeedbackLoopSchema>;
const activityWithFeedbackLoopSchemaWithOutDisclaimer = object({
channelData: object({
feedbackLoop: object({
type: literal('default')
})
})
});

type FeedbackActivityWithDisclaimer = WebChatActivity &
Comment thread
compulim marked this conversation as resolved.
Outdated
InferOutput<typeof activityWithFeedbackLoopSchemaWithDisclaimer>;

type FeedbackActivityWithoutDisclaimer = WebChatActivity &
InferOutput<typeof activityWithFeedbackLoopSchemaWithOutDisclaimer>;

type FeedbackActivity = FeedbackActivityWithDisclaimer | FeedbackActivityWithoutDisclaimer;

export function hasDisclaimer(activity: WebChatActivity): activity is FeedbackActivityWithDisclaimer {
return safeParse(activityWithFeedbackLoopSchemaWithDisclaimer, activity).success;
}

export default function hasFeedbackLoop(activity: WebChatActivity): activity is FeedbackActivity {
return safeParse(activityWithFeedbackLoopSchema, activity).success;
return safeParse(activityWithFeedbackLoopSchemaWithOutDisclaimer, activity).success;
}