Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
0c4bfec
initial commit
lexitaylor-work Apr 2, 2025
358d40b
fix linting errors
lexi-taylor Apr 3, 2025
5f612cc
add feedback loop property to messages
lexi-taylor Apr 3, 2025
a20ea33
fix tests
lexi-taylor Apr 4, 2025
a60dc45
fix format
lexi-taylor Apr 4, 2025
de79d7a
remove snapshots
lexi-taylor Apr 4, 2025
aff52e5
changes for regular feedback form
lexi-taylor Apr 9, 2025
da0cb7a
latest changes for tests
lexi-taylor Apr 11, 2025
e95912a
remove fragment
lexi-taylor Apr 11, 2025
70d9a0c
fix issue with voteaction
lexi-taylor Apr 11, 2025
768dc1a
add feedback text area to not reuse the accessible text area which wa…
lexi-taylor Apr 15, 2025
1111001
fix tests
lexi-taylor Apr 15, 2025
093fcbc
fix loc, add snapshots
lexi-taylor Apr 15, 2025
80ec79b
update snapshots
lexi-taylor Apr 15, 2025
6afc70c
ui changes, adding another test
lexi-taylor Apr 15, 2025
8180a52
update snapshot
lexi-taylor Apr 15, 2025
9eec0e5
refactor
lexi-taylor Apr 16, 2025
11d1a75
address PR comments
lexi-taylor Apr 16, 2025
0c78fc4
initial style changes
lexi-taylor Apr 17, 2025
aae2854
refactor feedback
lexi-taylor Apr 17, 2025
2f9fdf2
Update packages/component/src/Activity/ActivityFeedback.tsx
lexi-taylor Apr 17, 2025
5bd6876
add valibot suggestions
lexi-taylor Apr 17, 2025
ddf400c
correct tab index
lexi-taylor Apr 17, 2025
b890857
test change
lexi-taylor Apr 17, 2025
a35f5ee
some test updates
lexi-taylor Apr 17, 2025
09a411f
test changes
lexi-taylor Apr 17, 2025
d6c8e3b
remove hook
lexi-taylor Apr 17, 2025
30304c8
fix snapshot
lexi-taylor Apr 17, 2025
a980913
styles updates
lexi-taylor Apr 22, 2025
8f18314
update snapshots
lexi-taylor Apr 22, 2025
8e26a56
apply suggestions
lexi-taylor Apr 22, 2025
36b4043
fix test
lexi-taylor Apr 22, 2025
6cdf49e
use rows
lexi-taylor Apr 22, 2025
b3eb896
nits
lexi-taylor Apr 22, 2025
e900501
add dark
lexi-taylor Apr 22, 2025
552eab2
add transition
lexi-taylor Apr 22, 2025
3911e52
Fix dark mode
lexi-taylor Apr 22, 2025
51ca789
Final fix the dark theme
OEvgeny Apr 22, 2025
32d1afb
Add background colors
OEvgeny Apr 22, 2025
0488ef0
More colors fixed and snaps
OEvgeny Apr 22, 2025
6b5da06
Clean up
compulim Apr 22, 2025
bb20137
Naming
compulim Apr 22, 2025
52a7bf4
Sort and rename
compulim Apr 22, 2025
476ef80
Clean up
compulim Apr 22, 2025
e1dc0f1
Split utils
compulim Apr 22, 2025
9cb5e60
Simplify
compulim Apr 22, 2025
e980c17
Sort
compulim Apr 22, 2025
4b894ac
Sort and comment
compulim Apr 22, 2025
716d6a9
Clean up
compulim Apr 22, 2025
a04c4b5
Merge branch 'main' into users/lexi-taylor/feedbackform
lexi-taylor Apr 23, 2025
a2a322d
Add diff from /html2/
compulim Apr 23, 2025
8042bbe
Add PR number
compulim Apr 23, 2025
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
4 changes: 3 additions & 1 deletion .github/workflows/pull-request-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,9 @@ jobs:
with:
compression-level: 0
name: test-snapshot-diff-html-${{ matrix.shard-index }}
path: ./__tests__/__image_snapshots__/*/__diff_output__/*
path: |
./__tests__/__image_snapshots__/*/__diff_output__/*
./__tests__/html2/**/*.snap-*-diff.png

merge-test-results:
if: always()
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ Notes: web developers are advised to use [`~` (tilde range)](https://github.com/
- 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)
- 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)
- (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)
- 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)

### Changed

Expand Down
133 changes: 133 additions & 0 deletions __tests__/html2/activity/feedback.form.activity.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<!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>
</head>
<body>
<main id="webchat"></main>
<script type="text/babel">
run(async function () {
const {
React,
ReactDOM: { render },
WebChat: { ReactWebChat }
} = window; // Imports in UMD fashion.

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

const App = () => (
<React.Fragment>
<ReactWebChat
directLine={directLine}
store={store}
styleOptions={{
feedbackActionsPlacement: 'activity-actions'
}}
/>
</React.Fragment>
);

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

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

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

await host.snapshot('local');

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

await host.snapshot('local');

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

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');

await host.snapshot('local');

// Re-open feedback form
pageElements.byTestId('send box text area').focus();
await host.sendShiftTab(3);

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');
});

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

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.
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.
169 changes: 169 additions & 0 deletions __tests__/html2/fluentTheme/defaultFeedback.activity.dark.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
<!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="/test-harness.js"></script>
<script crossorigin="anonymous" src="/test-page-object.js"></script>
<script crossorigin="anonymous" src="/__dist__/fluent-bundle.production.min.js"></script>
<script crossorigin="anonymous" src="/__dist__/webchat-es5.js"></script>
<script crossorigin="anonymous" src="/__dist__/botframework-webchat-fluent-theme.production.min.js"></script>
<style type="text/css">
.fluent-provider {
height: 100%;
}
</style>
</head>

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

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

await host.sendDevToolsCommand('Emulation.setEmulatedMedia', {
features: [
{ name: 'prefers-reduced-motion', value: 'reduce' },
{ name: 'prefers-color-scheme', value: 'dark' }
]
});

const root = createRoot(document.getElementById('webchat'));

function renderWebChat(uiState) {
const theme = {
...createDarkTheme({
10: '#124C32',
20: '#1A5B3E',
30: '#216A4A',
40: '#297956',
50: '#308861',
60: '#38976D',
70: '#40A779',
80: '#158051',
90: '#4FC590',
100: '#56D49C',
110: '#5EE3A8',
120: '#79E8B7',
130: '#94ECC5',
140: '#AFF1D3',
150: '#C9F6E2',
160: '#E4FAF1'
}),
colorNeutralBackground1Disabled: '#101010',
colorNeutralBackground1Hover: '#101010',
colorNeutralForeground5: '#424242',
colorNeutralForegroundOnBrand: '#292929'
};

root.render(
<FluentProvider className="fluent-provider" theme={theme}>
<FluentThemeProvider variant="fluent">
<ReactWebChat directLine={directLine} store={store} uiState={uiState} />
</FluentThemeProvider>
</FluentProvider>
);
}

renderWebChat();

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);

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

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

await host.snapshot('local');

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

await host.snapshot('local');

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

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');

await host.snapshot('local');

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

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');
});

expect(activity).toEqual(
expect.objectContaining({
type: 'invoke',
name: 'message/submitAction',
value: {
actionName: 'feedback',
actionValue: {
reaction: 'dislike',
feedback: {
feedbackText: 'Test feedback'
}
}
}
})
);
});
</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.
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
Loading