Skip to content

Commit 8c9cf52

Browse files
lexi-taylorlexitaylor-workcompulimOEvgeny
authored
Adding a feedback form on reaction button click (#5460)
* initial commit * fix linting errors * add feedback loop property to messages * fix tests * fix format * remove snapshots * changes for regular feedback form * latest changes for tests * remove fragment * fix issue with voteaction * add feedback text area to not reuse the accessible text area which wasnt correct * fix tests * fix loc, add snapshots * update snapshots * ui changes, adding another test * update snapshot * refactor * address PR comments * initial style changes * refactor feedback * Update packages/component/src/Activity/ActivityFeedback.tsx Co-authored-by: William Wong <[email protected]> * add valibot suggestions * correct tab index * test change * some test updates * test changes * remove hook * fix snapshot * styles updates * update snapshots * apply suggestions * fix test * use rows * nits * add dark * add transition * Fix dark mode * Final fix the dark theme * Add background colors * More colors fixed and snaps * Clean up * Naming * Sort and rename * Clean up * Split utils * Simplify * Sort * Sort and comment * Clean up * Add diff from /html2/ * Add PR number --------- Co-authored-by: Lexi Taylor <[email protected]> Co-authored-by: William Wong <[email protected]> Co-authored-by: Eugene <[email protected]>
1 parent 6c68093 commit 8c9cf52

35 files changed

+1187
-25
lines changed

.github/workflows/pull-request-validation.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,9 @@ jobs:
281281
with:
282282
compression-level: 0
283283
name: test-snapshot-diff-html-${{ matrix.shard-index }}
284-
path: ./__tests__/__image_snapshots__/*/__diff_output__/*
284+
path: |
285+
./__tests__/__image_snapshots__/*/__diff_output__/*
286+
./__tests__/html2/**/*.snap-*-diff.png
285287
286288
merge-test-results:
287289
if: always()

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ Notes: web developers are advised to use [`~` (tilde range)](https://github.com/
8585
- Added support of [contentless activity in livestream](https://github.com/microsoft/BotFramework-WebChat/blob/main/docs/LIVESTREAMING.md#scenario-3-interim-activities-with-no-content), in PR [#5430](https://github.com/microsoft/BotFramework-WebChat/pull/5430), by [@compulim](https://github.com/compulim)
8686
- Added sliding dots typing indicator in Fluent theme, in PR [#5447](https://github.com/microsoft/BotFramework-WebChat/pull/5447) and PR [#5448](https://github.com/microsoft/BotFramework-WebChat/pull/5448), by [@compulim](https://github.com/compulim)
8787
- (Experimental) Add an ability to pass `completion` prop into Fluent send box and expose the component, in PR [#5466](https://github.com/microsoft/BotFramework-WebChat/pull/5466), by [@OEvgeny](https://github.com/OEvgeny)
88+
- Added feedback form for like/dislike button when `feedbackActionsPlacement` is `"activity-actions"`, in PR [#5460](https://github.com/microsoft/BotFramework-WebChat/pull/5460), by [@lexi-taylor](https://github.com/lexi-taylor) and [@OEvgeny](https://github.com/OEvgeny)
8889

8990
### Changed
9091

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
<!doctype html>
2+
<html lang="en-US">
3+
<head>
4+
<link href="/assets/index.css" rel="stylesheet" type="text/css" />
5+
<script crossorigin="anonymous" src="https://unpkg.com/@babel/[email protected]/babel.min.js"></script>
6+
<script crossorigin="anonymous" src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
7+
<script crossorigin="anonymous" src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>
8+
<script crossorigin="anonymous" src="/test-harness.js"></script>
9+
<script crossorigin="anonymous" src="/test-page-object.js"></script>
10+
<script crossorigin="anonymous" src="/__dist__/webchat-es5.js"></script>
11+
</head>
12+
<body>
13+
<main id="webchat"></main>
14+
<script type="text/babel">
15+
run(async function () {
16+
const {
17+
React,
18+
ReactDOM: { render },
19+
WebChat: { ReactWebChat }
20+
} = window; // Imports in UMD fashion.
21+
22+
const { directLine, store } = testHelpers.createDirectLineEmulator();
23+
24+
const App = () => (
25+
<React.Fragment>
26+
<ReactWebChat
27+
directLine={directLine}
28+
store={store}
29+
styleOptions={{
30+
feedbackActionsPlacement: 'activity-actions'
31+
}}
32+
/>
33+
</React.Fragment>
34+
);
35+
36+
render(<App />, document.getElementById('webchat'));
37+
38+
await pageConditions.uiConnected();
39+
40+
await directLine.emulateIncomingActivity({
41+
type: 'message',
42+
id: 'a-00000',
43+
timestamp: 0,
44+
text: 'This is a test message to show feedback buttons',
45+
from: {
46+
role: 'bot'
47+
},
48+
locale: 'en-US',
49+
entities: [],
50+
channelData: {
51+
feedbackLoop: {
52+
type: 'default',
53+
disclaimer: 'This is a test disclaimer message'
54+
}
55+
}
56+
});
57+
58+
await pageConditions.numActivitiesShown(1);
59+
60+
pageElements.byTestId('send box text area').focus();
61+
await host.sendShiftTab(3);
62+
63+
await host.sendKeys('ENTER');
64+
await host.sendKeys('ENTER');
65+
66+
await host.snapshot('local');
67+
68+
// Dismiss like button
69+
await host.sendShiftTab(2);
70+
await host.sendKeys('ENTER');
71+
72+
await host.snapshot('local');
73+
74+
// Click like button
75+
await host.sendKeys('ENTER');
76+
77+
await pageConditions.became(
78+
'feedback form is open',
79+
() => document.activeElement === pageElements.byTestId('feedback sendbox'),
80+
1000
81+
);
82+
83+
// Go to cancel button
84+
await host.sendTab(2);
85+
await host.sendKeys('ENTER');
86+
87+
await host.snapshot('local');
88+
89+
// Re-open feedback form
90+
pageElements.byTestId('send box text area').focus();
91+
await host.sendShiftTab(3);
92+
93+
await host.sendKeys('ENTER');
94+
// Send dislike
95+
await host.sendTab(1);
96+
await host.sendKeys('ENTER');
97+
98+
await pageConditions.became(
99+
'feedback form is open',
100+
() => document.activeElement === pageElements.byTestId('feedback sendbox'),
101+
1000
102+
);
103+
104+
await host.sendKeys('Test feedback');
105+
106+
await host.snapshot('local');
107+
108+
const { activity } = await directLine.actPostActivity(async () => {
109+
await host.sendTab(1);
110+
await host.sendKeys('ENTER');
111+
});
112+
113+
expect(activity).toEqual(
114+
expect.objectContaining({
115+
type: 'invoke',
116+
name: 'message/submitAction',
117+
value: {
118+
actionName: 'feedback',
119+
actionValue: {
120+
reaction: 'dislike',
121+
feedback: {
122+
feedbackText: 'Test feedback'
123+
}
124+
}
125+
}
126+
})
127+
);
128+
129+
await host.snapshot('local');
130+
});
131+
</script>
132+
</body>
133+
</html>
26.2 KB
Loading
13.7 KB
Loading
13.4 KB
Loading
22 KB
Loading
13.4 KB
Loading
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
<!doctype html>
2+
<html lang="en-US">
3+
<head>
4+
<link href="/assets/index.css" rel="stylesheet" type="text/css" />
5+
<script crossorigin="anonymous" src="https://unpkg.com/@babel/[email protected]/babel.min.js"></script>
6+
<script crossorigin="anonymous" src="/test-harness.js"></script>
7+
<script crossorigin="anonymous" src="/test-page-object.js"></script>
8+
<script crossorigin="anonymous" src="/__dist__/fluent-bundle.production.min.js"></script>
9+
<script crossorigin="anonymous" src="/__dist__/webchat-es5.js"></script>
10+
<script crossorigin="anonymous" src="/__dist__/botframework-webchat-fluent-theme.production.min.js"></script>
11+
<style type="text/css">
12+
.fluent-provider {
13+
height: 100%;
14+
}
15+
</style>
16+
</head>
17+
18+
<body>
19+
<main id="webchat"></main>
20+
<script type="text/babel">
21+
run(async function () {
22+
const {
23+
Fluent: { FluentProvider, createDarkTheme },
24+
React,
25+
ReactDOMClient: { createRoot },
26+
WebChat: { FluentThemeProvider, ReactWebChat }
27+
} = window; // Imports in UMD fashion.
28+
29+
const { directLine, store } = testHelpers.createDirectLineEmulator();
30+
31+
await host.sendDevToolsCommand('Emulation.setEmulatedMedia', {
32+
features: [
33+
{ name: 'prefers-reduced-motion', value: 'reduce' },
34+
{ name: 'prefers-color-scheme', value: 'dark' }
35+
]
36+
});
37+
38+
const root = createRoot(document.getElementById('webchat'));
39+
40+
function renderWebChat(uiState) {
41+
const theme = {
42+
...createDarkTheme({
43+
10: '#124C32',
44+
20: '#1A5B3E',
45+
30: '#216A4A',
46+
40: '#297956',
47+
50: '#308861',
48+
60: '#38976D',
49+
70: '#40A779',
50+
80: '#158051',
51+
90: '#4FC590',
52+
100: '#56D49C',
53+
110: '#5EE3A8',
54+
120: '#79E8B7',
55+
130: '#94ECC5',
56+
140: '#AFF1D3',
57+
150: '#C9F6E2',
58+
160: '#E4FAF1'
59+
}),
60+
colorNeutralBackground1Disabled: '#101010',
61+
colorNeutralBackground1Hover: '#101010',
62+
colorNeutralForeground5: '#424242',
63+
colorNeutralForegroundOnBrand: '#292929'
64+
};
65+
66+
root.render(
67+
<FluentProvider className="fluent-provider" theme={theme}>
68+
<FluentThemeProvider variant="fluent">
69+
<ReactWebChat directLine={directLine} store={store} uiState={uiState} />
70+
</FluentThemeProvider>
71+
</FluentProvider>
72+
);
73+
}
74+
75+
renderWebChat();
76+
77+
await pageConditions.uiConnected();
78+
79+
await directLine.emulateIncomingActivity({
80+
type: 'message',
81+
id: 'a-00000',
82+
timestamp: 0,
83+
text: 'This is a test message to show feedback buttons',
84+
from: {
85+
role: 'bot'
86+
},
87+
locale: 'en-US',
88+
entities: [],
89+
channelData: {
90+
feedbackLoop: {
91+
type: 'default',
92+
disclaimer: 'This is a test disclaimer message'
93+
}
94+
}
95+
});
96+
97+
await pageConditions.numActivitiesShown(1);
98+
99+
pageElements.byTestId('send box text area').focus();
100+
await host.sendShiftTab(2);
101+
102+
await host.sendKeys('ENTER');
103+
await host.sendKeys('ENTER');
104+
105+
await host.snapshot('local');
106+
107+
// Dismiss like button
108+
await host.sendShiftTab(2);
109+
await host.sendKeys('ENTER');
110+
111+
await host.snapshot('local');
112+
113+
// Click like button
114+
await host.sendKeys('ENTER');
115+
116+
await pageConditions.became(
117+
'feedback form is open',
118+
() => document.activeElement === pageElements.byTestId('feedback sendbox'),
119+
1000
120+
);
121+
122+
// Go to cancel button
123+
await host.sendTab(2);
124+
await host.sendKeys('ENTER');
125+
126+
await host.snapshot('local');
127+
128+
pageElements.byTestId('send box text area').focus();
129+
await host.sendShiftTab(2);
130+
131+
await host.sendKeys('ENTER');
132+
// Send dislike
133+
await host.sendTab(1);
134+
await host.sendKeys('ENTER');
135+
136+
await pageConditions.became(
137+
'feedback form is open',
138+
() => document.activeElement === pageElements.byTestId('feedback sendbox'),
139+
1000
140+
);
141+
142+
await host.sendKeys('Test feedback');
143+
144+
await host.snapshot('local');
145+
146+
const { activity } = await directLine.actPostActivity(async () => {
147+
await host.sendTab(1);
148+
await host.sendKeys('ENTER');
149+
});
150+
151+
expect(activity).toEqual(
152+
expect.objectContaining({
153+
type: 'invoke',
154+
name: 'message/submitAction',
155+
value: {
156+
actionName: 'feedback',
157+
actionValue: {
158+
reaction: 'dislike',
159+
feedback: {
160+
feedbackText: 'Test feedback'
161+
}
162+
}
163+
}
164+
})
165+
);
166+
});
167+
</script>
168+
</body>
169+
</html>
25.6 KB
Loading

0 commit comments

Comments
 (0)