Skip to content

Commit e1cd6f6

Browse files
authored
Add functional test for dashboard assistant trace page (opensearch-project#1012) (opensearch-project#1019)
* Add functional test for trace page Signed-off-by: Hailong Cui <[email protected]> * update to ask question direclty instead of click Signed-off-by: Hailong Cui <[email protected]> * replace focus with click Signed-off-by: Hailong Cui <[email protected]> * add wait before input Signed-off-by: Hailong Cui <[email protected]> * address review comments Signed-off-by: Hailong Cui <[email protected]> --------- Signed-off-by: Hailong Cui <[email protected]> (cherry picked from commit 32cba83)
1 parent 58923a4 commit e1cd6f6

File tree

3 files changed

+116
-1
lines changed

3 files changed

+116
-1
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"completion": " ```json\n{\n \"thought\": \"Thought: Let me use tool to figure out\",\n \"action\": \"CatIndexTool\",\n \"action_input\": \"\"}\n```\n",
3+
"stop_reason": "stop_sequence",
4+
"stop": "\n\nHuman:"
5+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import { BASE_PATH } from '../../../utils/constants';
7+
8+
if (Cypress.env('DASHBOARDS_ASSISTANT_ENABLED')) {
9+
describe('Interaction trace spec', () => {
10+
before(() => {
11+
// Set welcome screen tracking to false
12+
localStorage.setItem('home:welcome:show', 'false');
13+
// Set new theme modal to false
14+
localStorage.setItem('home:newThemeModal:show', 'false');
15+
16+
cy.visit(`${BASE_PATH}/app/home`);
17+
// cy.waitForLoader();
18+
19+
// Common text to wait for to confirm page loaded, give up to 120 seconds for initial load
20+
cy.get(`input[placeholder="Ask question"]`, { timeout: 120000 }).as(
21+
'chatInput'
22+
);
23+
cy.get('@chatInput').should('be.length', 1);
24+
25+
cy.wait(1000);
26+
27+
cy.get('@chatInput')
28+
.click()
29+
.type('What are the indices in my cluster?{enter}');
30+
31+
// should have a LLM Response
32+
cy.contains(
33+
'The indices in your cluster are the names listed in the response obtained from using a tool to get information about the OpenSearch indices.'
34+
);
35+
});
36+
37+
// clean up localStorage items
38+
after(() => {
39+
localStorage.removeItem('home:welcome:show');
40+
localStorage.removeItem('home:newThemeModal:show');
41+
});
42+
43+
describe('Trace page', () => {
44+
it('open trace page and verify page content', () => {
45+
// click How was this generated? to view trace
46+
cy.contains('How was this generated?').click();
47+
48+
cy.get(`.llm-chat-flyout .llm-chat-flyout-body`).as('tracePage');
49+
cy.get('@tracePage')
50+
.find(`button[aria-label="back"]`)
51+
.should('have.length', 1);
52+
53+
cy.get('@tracePage')
54+
.find(`button[aria-label="close"]`)
55+
.should('have.length', 0);
56+
57+
// title
58+
cy.get('@tracePage').contains('h1', 'How was this generated');
59+
60+
// question
61+
cy.get('@tracePage').contains('What are the indices in my cluster?');
62+
63+
// result
64+
cy.get('@tracePage').contains(
65+
'The indices in your cluster are the names listed in the response obtained from using a tool to get information about the OpenSearch indices.'
66+
);
67+
});
68+
69+
it('tools invocation displayed in trace steps', () => {
70+
// trace
71+
cy.get(`.llm-chat-flyout .llm-chat-flyout-body`).as('tracePage');
72+
cy.get('@tracePage').find('.euiAccordion').should('have.length', 1);
73+
74+
cy.get('@tracePage')
75+
.find('.euiAccordion')
76+
// tool name
77+
.contains('Step 1 - CatIndexTool')
78+
.click({ force: true });
79+
80+
// tool output
81+
cy.contains('Output: health status index');
82+
});
83+
84+
it('trace page display correctly in fullscreen mode', () => {
85+
cy.get(`.llm-chat-flyout-header`)
86+
.find(`button[aria-label="fullScreen"]`)
87+
.click({ force: true });
88+
89+
// show close button
90+
cy.get(`.llm-chat-flyout .llm-chat-flyout-body`).as('tracePage');
91+
cy.get('@tracePage')
92+
.find(`button[aria-label="close"]`)
93+
.should('have.length', 1);
94+
95+
cy.get('@tracePage')
96+
.find(`button[aria-label="back"]`)
97+
.should('have.length', 0);
98+
99+
// both chat and trace are both displayed
100+
cy.contains('How was this generated?').click();
101+
});
102+
});
103+
});
104+
}

cypress/support/assistant-dummy-llm.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
*/
55
const http = require('http');
66
const agentFrameworkJson = require('../fixtures/plugins/dashboards-assistant/agent-framework-response.json');
7+
const agentFrameworkThoughtJson = require('../fixtures/plugins/dashboards-assistant/agent-framework-thought-response.json');
78
const suggestionJson = require('../fixtures/plugins/dashboards-assistant/suggestion-response.json');
89

910
const MATCH_AGENT_FRAMEWORK_PROMPT =
1011
'Assistant is designed to be able to assist with a wide range of tasks';
1112
const MATCH_SUGGESTION_PROMPT = 'You are an AI that only speaks JSON';
13+
const TOOL_RESPONSE = 'TOOL RESPONSE:';
1214

1315
const server = http.createServer((req, res) => {
1416
// Set the content type to JSON
@@ -27,7 +29,11 @@ const server = http.createServer((req, res) => {
2729
// Why add a delay here? reference: https://github.com/opensearch-project/ml-commons/issues/1894
2830
setTimeout(() => {
2931
if (requestBody.includes(MATCH_AGENT_FRAMEWORK_PROMPT)) {
30-
return res.end(JSON.stringify(agentFrameworkJson));
32+
if (requestBody.includes(TOOL_RESPONSE)) {
33+
return res.end(JSON.stringify(agentFrameworkJson));
34+
} else {
35+
return res.end(JSON.stringify(agentFrameworkThoughtJson));
36+
}
3137
} else if (requestBody.includes(MATCH_SUGGESTION_PROMPT)) {
3238
return res.end(JSON.stringify(suggestionJson));
3339
}

0 commit comments

Comments
 (0)