Skip to content

Commit 831e5be

Browse files
opensearch-trigger-bot[bot]wanglamruanyl
authored
feat: add test cases for assistant conversation history (#1010) (#1045)
* feat: add test cases for assistant conversation history Signed-off-by: Lin Wang <[email protected]> * feat: move created history test below Signed-off-by: Lin Wang <[email protected]> * rename coversation_history_spec to conversation_history_spec Signed-off-by: Lin Wang <[email protected]> * Address pr comments Signed-off-by: Lin Wang <[email protected]> * refactor: move setStorageItem to helpers and change to getElementByTestId Signed-off-by: Lin Wang <[email protected]> --------- Signed-off-by: Lin Wang <[email protected]> (cherry picked from commit b65c5de) Co-authored-by: Lin Wang <[email protected]> Co-authored-by: Yulong Ruan <[email protected]>
1 parent 4b8e489 commit 831e5be

File tree

3 files changed

+233
-2
lines changed

3 files changed

+233
-2
lines changed
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
import { BASE_PATH } from '../../../utils/constants';
6+
import { setStorageItem } from '../../../utils/plugins/dashboards-assistant/helpers';
7+
8+
if (Cypress.env('DASHBOARDS_ASSISTANT_ENABLED')) {
9+
describe('Assistant conversation history spec', () => {
10+
let restoreShowHome;
11+
let restoreNewThemeModal;
12+
13+
before(() => {
14+
// Set welcome screen tracking to false
15+
restoreShowHome = setStorageItem(
16+
localStorage,
17+
'home:welcome:show',
18+
'false'
19+
);
20+
// Hide new theme modal
21+
restoreNewThemeModal = setStorageItem(
22+
localStorage,
23+
'home:newThemeModal:show',
24+
'false'
25+
);
26+
// Visit OSD
27+
cy.visit(`${BASE_PATH}/app/home`);
28+
// Common text to wait for to confirm page loaded, give up to 60 seconds for initial load
29+
cy.get(`input[placeholder="Ask question"]`, { timeout: 60000 }).should(
30+
'be.length',
31+
1
32+
);
33+
34+
// Open assistant flyout
35+
// The flyout button will be detached and can't be clicked, add 10s delayed fix it.
36+
cy.wait(10000);
37+
cy.get('img[aria-label="toggle chat flyout icon"]').click();
38+
});
39+
after(() => {
40+
if (restoreShowHome) {
41+
restoreShowHome();
42+
}
43+
if (restoreNewThemeModal) {
44+
restoreNewThemeModal();
45+
}
46+
// Close assistant flyout
47+
cy.get('img[aria-label="toggle chat flyout icon"]').click();
48+
});
49+
50+
beforeEach(() => {
51+
cy.get('.llm-chat-flyout', { timeout: 60000 }).should('be.visible');
52+
});
53+
54+
describe('panel operations', () => {
55+
it('should toggle history list', () => {
56+
cy.get('.llm-chat-flyout button[aria-label="history"]')
57+
.should('be.visible')
58+
.click();
59+
cy.get('.llm-chat-flyout-body')
60+
.contains('Conversations')
61+
.should('be.visible');
62+
63+
cy.get('.llm-chat-flyout button[aria-label="history"]')
64+
.should('be.visible')
65+
.click();
66+
cy.get('textarea[placeholder="Ask me anything..."]').should('exist');
67+
cy.get('.llm-chat-flyout-body')
68+
.contains('Conversations')
69+
.should('not.be.visible');
70+
});
71+
72+
it('should back to chat panel', () => {
73+
cy.get('.llm-chat-flyout button[aria-label="history"]').click();
74+
cy.get('.llm-chat-flyout')
75+
.contains('Conversations')
76+
.should('be.visible');
77+
78+
cy.get('.llm-chat-flyout-body').contains('Back').click();
79+
cy.get('textarea[placeholder="Ask me anything..."]').should('exist');
80+
});
81+
82+
it('should hide back button in fullscreen mode', () => {
83+
cy.get('.llm-chat-flyout button[aria-label="fullScreen"]').click();
84+
cy.get('.llm-chat-flyout button[aria-label="history"]').click();
85+
86+
cy.get('.llm-chat-flyout')
87+
.contains('Conversations')
88+
.should('be.visible');
89+
cy.get('textarea[placeholder="Ask me anything..."]').should('exist');
90+
cy.get('.llm-chat-flyout-body')
91+
.contains('Back', { timeout: 3000 })
92+
.should('not.exist');
93+
94+
// Back to default mode
95+
cy.get('.llm-chat-flyout button[aria-label="fullScreen"]').click();
96+
cy.get('.llm-chat-flyout button[aria-label="history"]').click();
97+
});
98+
});
99+
describe('history item operations', () => {
100+
const conversations = [];
101+
102+
before(() => {
103+
// Create conversations data
104+
cy.sendAssistantMessage({
105+
input: {
106+
type: 'input',
107+
content: 'What are the indices in my cluster?',
108+
contentType: 'text',
109+
},
110+
}).then((result) => {
111+
if (result.status !== 200) {
112+
throw result.body;
113+
}
114+
conversations.push(result.body);
115+
});
116+
});
117+
118+
after(() => {
119+
// Clear created conversations in tests
120+
conversations.map(({ conversationId }) =>
121+
cy.deleteConversation(conversationId)
122+
);
123+
});
124+
125+
it('should show created conversation in the history list', () => {
126+
cy.get('.llm-chat-flyout button[aria-label="history"]').click();
127+
128+
cy.get('.llm-chat-flyout').contains('Conversations');
129+
conversations.forEach(({ conversationId }) => {
130+
cy.getElementByTestId(`chatHistoryItem-${conversationId}`).should(
131+
'exist'
132+
);
133+
});
134+
cy.contains('What are the indices in my cluster?');
135+
cy.get('.llm-chat-flyout button[aria-label="history"]').click();
136+
});
137+
138+
it('should load conversation in chat panel', () => {
139+
cy.get('.llm-chat-flyout button[aria-label="history"]').click();
140+
141+
const conversationToLoad = conversations[0];
142+
143+
cy.getElementByTestId(
144+
`chatHistoryItem-${conversationToLoad.conversationId}`
145+
)
146+
.contains(conversationToLoad.title)
147+
.click();
148+
cy.get('textarea[placeholder="Ask me anything..."]').should('exist');
149+
cy.get('div.llm-chat-bubble-panel-input').contains(
150+
conversationToLoad.title
151+
);
152+
});
153+
154+
it('should able to update conversation title', () => {
155+
cy.get('.llm-chat-flyout button[aria-label="history"]').click();
156+
157+
const conversationToUpdate = conversations[0];
158+
const newTitle = 'New title';
159+
160+
cy.getElementByTestId(
161+
`chatHistoryItem-${conversationToUpdate.conversationId}`
162+
)
163+
.find('button[aria-label="Edit conversation name"]')
164+
.click();
165+
cy.contains('Edit conversation name');
166+
167+
cy.get('input[aria-label="Conversation name input"').type(newTitle);
168+
cy.getElementByTestId('confirmModalConfirmButton')
169+
.contains('Confirm name')
170+
.click();
171+
172+
conversationToUpdate.title = newTitle;
173+
cy.getElementByTestId(
174+
`chatHistoryItem-${conversationToUpdate.conversationId}`
175+
).contains(conversationToUpdate.title);
176+
cy.contains('Edit conversation name', { timeout: 3000 }).should(
177+
'not.exist'
178+
);
179+
180+
// Reset to chat panel
181+
cy.get('.llm-chat-flyout button[aria-label="history"]').click();
182+
});
183+
184+
it('should able to delete conversation', () => {
185+
cy.get('.llm-chat-flyout button[aria-label="history"]').click();
186+
187+
const conversationToDelete = conversations[0];
188+
189+
cy.getElementByTestId(
190+
`chatHistoryItem-${conversationToDelete.conversationId}`
191+
)
192+
.find('button[aria-label="Delete conversation"]')
193+
.click();
194+
cy.getElementByTestId('confirmModalTitleText').contains(
195+
'Delete conversation'
196+
);
197+
198+
cy.getElementByTestId('confirmModalConfirmButton')
199+
.contains('Delete conversation')
200+
.click();
201+
202+
cy.getElementByTestId(
203+
`chatHistoryItem-${conversationToDelete.conversationId}`
204+
).should('not.exist');
205+
conversations.shift();
206+
207+
// Reset to chat panel
208+
cy.get('.llm-chat-flyout button[aria-label="history"]').click();
209+
});
210+
});
211+
});
212+
}

cypress/utils/plugins/dashboards-assistant/commands.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
*/
55

66
import FlowTemplateJSON from '../../../fixtures/plugins/dashboards-assistant/flow-template.json';
7-
import { BACKEND_BASE_PATH } from '../../constants';
8-
import { ML_COMMONS_API } from './constants';
7+
import { BACKEND_BASE_PATH, BASE_PATH } from '../../constants';
8+
import { ML_COMMONS_API, ASSISTANT_API } from './constants';
99
import clusterSettings from '../../../fixtures/plugins/dashboards-assistant/cluster_settings.json';
10+
import { apiRequest } from '../../helpers';
1011

1112
Cypress.Commands.add('addAssistantRequiredSettings', () => {
1213
cy.request('PUT', `${BACKEND_BASE_PATH}/_cluster/settings`, clusterSettings);
@@ -152,3 +153,14 @@ Cypress.Commands.add('stopDummyServer', () => {
152153
}
153154
});
154155
});
156+
157+
Cypress.Commands.add('sendAssistantMessage', (body) =>
158+
apiRequest(`${BASE_PATH}${ASSISTANT_API.SEND_MESSAGE}`, 'POST', body)
159+
);
160+
161+
Cypress.Commands.add('deleteConversation', (conversationId) =>
162+
apiRequest(
163+
`${BASE_PATH}${ASSISTANT_API.CONVERSATION}/${conversationId}`,
164+
'DELETE'
165+
)
166+
);

cypress/utils/plugins/dashboards-assistant/constants.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,10 @@ export const ML_COMMONS_API = {
1515
CREATE_MODEL: `${ML_COMMONS_API_PREFIX}/models/_register`,
1616
CREATE_AGENT: `${ML_COMMONS_API_PREFIX}/agents/_register`,
1717
};
18+
19+
export const ASSISTANT_API_BASE = '/api/assistant';
20+
21+
export const ASSISTANT_API = {
22+
SEND_MESSAGE: `${ASSISTANT_API_BASE}/send_message`,
23+
CONVERSATION: `${ASSISTANT_API_BASE}/conversation`,
24+
};

0 commit comments

Comments
 (0)