Skip to content

Commit 74d02ad

Browse files
author
kim
committed
test: add tests
1 parent 8e2401e commit 74d02ad

File tree

7 files changed

+159
-11
lines changed

7 files changed

+159
-11
lines changed

cypress/e2e/builder/main.cy.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ const PROMPT_TEXT_AREA = '[name="Chatbot Prompt"]';
1414
const CUE_TEXT_AREA = '[name="Conversation Starter"]';
1515
const CHATBOT_NAME_INPUT = '[name="Chatbot Name"]';
1616

17+
const ADD_STARTER_SUGGESTION_BUTTON = '[title="Add starter suggestion"]';
18+
const buildStarterSuggestionInput = (idx: number) =>
19+
`[name="Starter suggestion number ${idx}"]`;
20+
1721
describe('Builder View', () => {
1822
it('Results table', () => {
1923
cy.setUpApi(
@@ -109,4 +113,66 @@ describe('Builder View', () => {
109113
.should('not.contain', 'The cue is empty')
110114
.should('contain', cue);
111115
});
116+
117+
it('Show starter suggestions and edit', () => {
118+
cy.setUpApi(
119+
{ appSettings: [] },
120+
{
121+
context: Context.Builder,
122+
permission: PermissionLevel.Admin,
123+
},
124+
);
125+
cy.visit('/');
126+
127+
cy.get(buildDataCy(TAB_SETTINGS_VIEW_CYPRESS)).click();
128+
129+
// show no starter suggestions
130+
// TODO
131+
132+
cy.get(EDIT_SETTINGS_BUTTON).click();
133+
134+
// change prompt
135+
const prompt = 'my new prompt';
136+
cy.get(PROMPT_TEXT_AREA).clear().type(prompt);
137+
138+
const newSuggestions = ['Hello', 'Hello1', 'Hello2'];
139+
140+
// add suggestions
141+
newSuggestions.forEach((s, idx) => {
142+
cy.get(ADD_STARTER_SUGGESTION_BUTTON).click();
143+
cy.get(buildStarterSuggestionInput(idx)).type(s);
144+
});
145+
146+
cy.get(SAVE_SETTINGS_BUTTON).click();
147+
148+
// show starter suggestions
149+
// for (const s of newSuggestions) {
150+
// cy.get(buildDataCy(CHATBOT_SETTINGS_SUMMARY_CY)).should('contain', s);
151+
// }
152+
153+
cy.wait(1000);
154+
cy.get(EDIT_SETTINGS_BUTTON).click();
155+
156+
// edit suggestions
157+
const editedSuggestions = ['newHello0', 'newHello1', 'newHello2'];
158+
editedSuggestions.forEach((s, idx) => {
159+
cy.get(buildStarterSuggestionInput(idx)).clear().type(s);
160+
});
161+
162+
// delete second suggestion
163+
cy.get(`[title="Delete suggestion number 1"]`).click();
164+
165+
// expect remaining suggestions
166+
const remainingSuggestions = [editedSuggestions[0], editedSuggestions[2]];
167+
for (const s of remainingSuggestions) {
168+
cy.get(`[value="${s}"]`).should('be.visible');
169+
}
170+
171+
cy.get(SAVE_SETTINGS_BUTTON).click();
172+
173+
// show starter suggestions
174+
// for (const s of remainingSuggestions) {
175+
// cy.get(buildDataCy(CHATBOT_SETTINGS_SUMMARY_CY)).should('contain', s);
176+
// }
177+
});
112178
});

cypress/e2e/player/main.cy.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,4 +138,36 @@ describe('Player View', () => {
138138
cy.get('#root').should('contain', 'November 18, 2024');
139139
cy.get('#root').should('contain', 'November 18, 2025');
140140
});
141+
142+
it.only('Use a starter suggestion', () => {
143+
cy.setUpApi(
144+
{
145+
appData: [],
146+
appSettings: [MOCK_APP_SETTING],
147+
},
148+
{
149+
context: Context.Player,
150+
permission: PermissionLevel.Write,
151+
},
152+
);
153+
cy.visit('/');
154+
155+
const suggestion = MOCK_APP_SETTING.data.starterSuggestions[0];
156+
// click suggestion
157+
cy.get(`button:contains("${suggestion}")`).click();
158+
159+
// expect user message
160+
cy.get(buildDataCy(buildCommentContainerDataCy('2'))).should(
161+
'contain',
162+
suggestion,
163+
);
164+
165+
// expect chatbot message
166+
cy.get(buildDataCy(buildCommentContainerDataCy('3'))).should(
167+
'contain',
168+
'i am a bot', // default return value of the mocked chatbot
169+
);
170+
171+
cy.get(`button:contains("${suggestion}")`).should('not.be.visible');
172+
});
141173
});

cypress/fixtures/mockSettings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ export const MOCK_APP_SETTING = {
1414
chatbotCue: 'cue',
1515
chatbotName: 'name',
1616
initialPrompt: [{ role: ChatbotRole.Assistant, content: 'prompt' }],
17+
starterSuggestions: ['Can you spell it for me?', 'Can you explain this?'],
1718
},
1819
};

src/config/appActions.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ export const AppActionsType = {
66
Reply: 'reply_comment',
77
// chatbot actions
88
AskChatbot: 'ask_chatbot',
9+
UseStarter: 'use_starter',
910
} as const;

src/langs/en.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@
6666
"CLOSE": "Close",
6767
"SIGN_OUT_ALERT": "You should be signed in to interact with the chatbot",
6868
"ANALYTICS_CONVERSATION_MEMBER": "Conversation",
69-
"CHATBOT_STARTER_SUGGESTION_HELPER": "This defines suggested messages the user can send at the beginning of the conversation to the chatbot. You can change it to give ideas of interactions."
69+
"CHATBOT_STARTER_SUGGESTION_HELPER": "This defines suggested messages the user can send at the beginning of the conversation to the chatbot. You can change it to give ideas of interactions.",
70+
"ADD_STARTER_SUGGESTION_BUTTON": "Add",
71+
"ADD_STARTER_SUGGESTION_BUTTON_TITLE": "Add starter suggestion",
72+
"STARTER_SUGGESTION_NAME": "Starter suggestion number {{nb}}",
73+
"DELETE_STARTER_SUGGESTION_BUTTON_TITLE": "Delete suggestion number {{nb}}",
74+
"STARTER_SUGGESTION_PLACEHOLDER": "Write a suggestion here",
75+
"STARTER_SUGGESTION_PLAYER_BUTTON_ARIA_LABEL": "Ask {{suggestion}}"
7076
}
7177
}

src/modules/common/Suggestions.tsx

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,56 @@
1+
import { useTranslation } from 'react-i18next';
2+
13
import { Button, Stack, styled } from '@mui/material';
24

5+
import { AppActionsType } from '@/config/appActions';
36
import { ChatbotPromptSettings } from '@/config/appSetting';
7+
import { mutations } from '@/config/queryClient';
8+
import { showErrorToast } from '@/utils/toast';
49

510
import { useSendMessageAndAskChatbot } from './useSendMessageAndAskChatbot';
611

7-
const StyledButton = styled(Button)(({ theme }) => ({
12+
const StyledButton = styled(Button)({
813
borderRadius: 100,
914
textTransform: 'unset',
10-
}));
15+
});
1116

1217
export function Suggestions({
1318
suggestions,
1419
chatbotPrompt,
15-
}: {
20+
}: Readonly<{
1621
chatbotPrompt: ChatbotPromptSettings;
1722
suggestions: string[];
18-
}) {
23+
}>) {
24+
const { t } = useTranslation();
25+
const { mutateAsync: postAction } = mutations.usePostAppAction();
1926
const { send } = useSendMessageAndAskChatbot({ chatbotPrompt });
2027

28+
const onClick = async (suggestion: string) => {
29+
try {
30+
await send(suggestion);
31+
await postAction({
32+
type: AppActionsType.UseStarter,
33+
data: { value: suggestion },
34+
});
35+
} catch (e: unknown) {
36+
if (e instanceof Error) {
37+
showErrorToast(e.message);
38+
}
39+
console.error(e);
40+
}
41+
};
42+
2143
return (
2244
<Stack direction="row" gap={2} justifyContent="right">
2345
{suggestions.map((s) => (
2446
<span key={s}>
25-
<StyledButton onClick={() => send(s)} variant="contained">
47+
<StyledButton
48+
aria-label={t('STARTER_SUGGESTION_PLAYER_BUTTON_ARIA_LABEL', {
49+
suggestion: s,
50+
})}
51+
onClick={() => onClick(s)}
52+
variant="contained"
53+
>
2654
{s}
2755
</StyledButton>
2856
</span>

src/modules/settings/chatbot/StarterSuggestions.tsx

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { useTranslation } from 'react-i18next';
2+
13
import { Button, IconButton, Stack, TextField } from '@mui/material';
24

35
import { PlusIcon, TrashIcon } from 'lucide-react';
@@ -11,10 +13,12 @@ function StarterSuggestions({
1113
starterSuggestions: InternalSuggestion[];
1214
onChange: (args: InternalSuggestion[]) => void;
1315
}>) {
16+
const { t } = useTranslation();
17+
1418
const add = () => {
1519
// increase id based on last one
1620
// this works as long as we don't reorder
17-
const lastId = starterSuggestions.at(-1)?.id ?? 0;
21+
const lastId = starterSuggestions.at(-1)?.id ?? -1;
1822
onChange([
1923
...starterSuggestions,
2024
{
@@ -43,18 +47,28 @@ function StarterSuggestions({
4347
<TextField
4448
size="small"
4549
fullWidth
46-
placeholder="Write a suggestion here"
50+
placeholder={t('STARTER_SUGGESTION_PLACEHOLDER')}
4751
defaultValue={value}
4852
onChange={(e) => edit(e.target.value, id)}
53+
name={t('STARTER_SUGGESTION_NAME', { nb: id })}
4954
/>
50-
<IconButton color="error" onClick={() => remove(id)}>
55+
<IconButton
56+
title={t('DELETE_STARTER_SUGGESTION_BUTTON_TITLE', { nb: id })}
57+
color="error"
58+
onClick={() => remove(id)}
59+
>
5160
<TrashIcon />
5261
</IconButton>
5362
</Stack>
5463
))}
5564
<span>
56-
<Button startIcon={<PlusIcon />} color="primary" onClick={add}>
57-
Add
65+
<Button
66+
startIcon={<PlusIcon />}
67+
color="primary"
68+
onClick={add}
69+
title={t('ADD_STARTER_SUGGESTION_BUTTON_TITLE')}
70+
>
71+
{t('ADD_STARTER_SUGGESTION_BUTTON')}
5872
</Button>
5973
</span>
6074
</Stack>

0 commit comments

Comments
 (0)