Skip to content

Commit bc4bafa

Browse files
authored
Merge branch 'main' into fix-aae-page-embedding-models-and-configure-playground
2 parents c92a00b + 47c36db commit bc4bafa

13 files changed

Lines changed: 298 additions & 172 deletions

File tree

packages/gen-ai/frontend/src/__tests__/cypress/cypress/pages/chatbotPage.ts

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -405,16 +405,11 @@ class ChatbotPage {
405405
return cy.get('[data-testid^="chatbot-pane-"][role="region"]');
406406
}
407407

408-
// Find a specific chatbot pane by index (0 = Model 1, 1 = Model 2)
408+
// Find a specific chatbot pane by index (0 = Chat 1, 1 = Chat 2)
409409
findChatbotPaneByIndex(index: number): Cypress.Chainable<JQuery<HTMLElement>> {
410410
return this.findAllChatbotPanes().eq(index);
411411
}
412412

413-
// Find pane settings button by pane index
414-
findPaneSettingsButton(index: number): Cypress.Chainable<JQuery<HTMLElement>> {
415-
return this.findChatbotPaneByIndex(index).find('[data-testid$="-settings-button"]');
416-
}
417-
418413
// Find pane close button by pane index
419414
findPaneCloseButton(index: number): Cypress.Chainable<JQuery<HTMLElement>> {
420415
return this.findChatbotPaneByIndex(index).find('[data-testid$="-close-button"]');
@@ -425,12 +420,28 @@ class ChatbotPage {
425420
return this.findChatbotPaneByIndex(index).findByTestId('chatbot-model-selector-toggle');
426421
}
427422

428-
// Find pane label text (e.g., "Model 1", "Model 2")
423+
// Find pane label text (e.g., "Chat 1", "Chat 2")
429424
findPaneLabel(index: number): Cypress.Chainable<JQuery<HTMLElement>> {
430-
const labelText = `Model ${index + 1}`;
425+
const labelText = `Chat ${index + 1}`;
431426
return this.findChatbotPaneByIndex(index).contains(labelText);
432427
}
433428

429+
// Find the global Settings button in the page header
430+
findSettingsButton(): Cypress.Chainable<JQuery<HTMLElement>> {
431+
return cy.findByTestId('settings-button');
432+
}
433+
434+
// Find the config switcher toggle group inside the settings panel
435+
findConfigSwitcher(): Cypress.Chainable<JQuery<HTMLElement>> {
436+
return cy.findByTestId('chatbot-config-switcher');
437+
}
438+
439+
// Find the button inside a config tab in the settings panel switcher (1-based)
440+
// aria-pressed is on the inner button, not the wrapper div
441+
findConfigTab(chatNumber: number): Cypress.Chainable<JQuery<HTMLButtonElement>> {
442+
return cy.findByTestId(`chatbot-config-tab-${chatNumber}`).find('button');
443+
}
444+
434445
// Verify we are in compare mode (two panes visible)
435446
verifyInCompareMode(): void {
436447
this.findAllChatbotPanes().should('have.length', 2);
@@ -451,22 +462,27 @@ class ChatbotPage {
451462
this.findCompareChatButton().click();
452463
}
453464

454-
// Exit compare mode by closing a pane
465+
// Exit compare mode by closing a pane (confirms the modal)
455466
closePaneByIndex(index: number): void {
456467
this.findPaneCloseButton(index).click();
468+
cy.findByTestId('close-compare-modal').findByTestId('modal-submit-button').click();
457469
}
458470

459-
// Open settings panel for a specific pane
460-
openPaneSettings(index: number): void {
461-
// First ensure any existing settings panel is closed
462-
this.closeSettingsPanel();
463-
// Then click the settings button for the specified pane
464-
this.findPaneSettingsButton(index).click({ force: true });
471+
// Open the settings panel via the header Settings button and switch to the given pane (1-based)
472+
openPaneSettings(chatNumber: number): void {
473+
// Only click Settings button if the panel isn't already open
474+
cy.get('body').then(($body) => {
475+
if (!$body.find('[data-testid="chatbot-config-switcher"]').is(':visible')) {
476+
this.findSettingsButton().click();
477+
}
478+
});
479+
this.findConfigSwitcher().should('be.visible');
480+
// Use force:true to avoid detachment during drawer open animation
481+
this.findConfigTab(chatNumber).click({ force: true });
465482
}
466483

467-
// Find settings panel header (shows "Configure - 1" or "Configure - 2")
484+
// Find settings panel header (single mode only — shows "Configure")
468485
findSettingsPanelHeader(): Cypress.Chainable<JQuery<HTMLElement>> {
469-
// Wait for the drawer to be visible before finding the header
470486
return cy.findByTestId('chatbot-settings-panel-header', { timeout: 10000 });
471487
}
472488

@@ -489,8 +505,6 @@ class ChatbotPage {
489505
const closeButton = $body.find('[aria-label="Close settings panel"]');
490506
if (closeButton.length > 0 && closeButton.is(':visible')) {
491507
cy.get('[aria-label="Close settings panel"]').click({ force: true });
492-
// Wait for panel to close
493-
cy.get('[data-testid="chatbot-settings-panel-header"]').should('not.exist');
494508
}
495509
});
496510
}

packages/gen-ai/frontend/src/__tests__/cypress/cypress/tests/mocked/chatbot/compareMode.cy.ts

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -158,11 +158,11 @@ describe('Chatbot - Compare Mode (Mocked)', () => {
158158
cy.step('Verify in compare mode with two panes');
159159
chatbotPage.verifyInCompareMode();
160160

161-
cy.step('Verify Model 1 pane exists');
161+
cy.step('Verify Chat 1 pane exists');
162162
chatbotPage.findChatbotPaneByIndex(0).should('be.visible');
163163
chatbotPage.findPaneLabel(0).should('be.visible');
164164

165-
cy.step('Verify Model 2 pane exists');
165+
cy.step('Verify Chat 2 pane exists');
166166
chatbotPage.findChatbotPaneByIndex(1).should('be.visible');
167167
chatbotPage.findPaneLabel(1).should('be.visible');
168168
},
@@ -182,29 +182,26 @@ describe('Chatbot - Compare Mode (Mocked)', () => {
182182
'should display model selector in each pane',
183183
{ tags: ['@GenAI', '@Chatbot', '@CompareMode', '@UI'] },
184184
() => {
185-
cy.step('Verify Model 1 pane has model selector');
185+
cy.step('Verify Chat 1 pane has model selector');
186186
chatbotPage.findPaneModelSelector(0).should('be.visible');
187187

188-
cy.step('Verify Model 2 pane has model selector');
188+
cy.step('Verify Chat 2 pane has model selector');
189189
chatbotPage.findPaneModelSelector(1).should('be.visible');
190190
},
191191
);
192192

193193
it(
194-
'should display settings and close buttons in each pane',
194+
'should display close button in each pane and settings button in header',
195195
{ tags: ['@GenAI', '@Chatbot', '@CompareMode', '@UI'] },
196196
() => {
197-
cy.step('Verify Model 1 pane has settings button');
198-
chatbotPage.findPaneSettingsButton(0).should('be.visible');
199-
200-
cy.step('Verify Model 1 pane has close button');
197+
cy.step('Verify Chat 1 pane has close button');
201198
chatbotPage.findPaneCloseButton(0).should('be.visible');
202199

203-
cy.step('Verify Model 2 pane has settings button');
204-
chatbotPage.findPaneSettingsButton(1).should('be.visible');
205-
206-
cy.step('Verify Model 2 pane has close button');
200+
cy.step('Verify Chat 2 pane has close button');
207201
chatbotPage.findPaneCloseButton(1).should('be.visible');
202+
203+
cy.step('Verify global Settings button is in header');
204+
chatbotPage.findSettingsButton().should('be.visible');
208205
},
209206
);
210207

@@ -228,26 +225,28 @@ describe('Chatbot - Compare Mode (Mocked)', () => {
228225
});
229226

230227
it(
231-
'should open settings for Model 1 when clicking Model 1 settings button',
228+
'should open settings panel via header button and switch to Chat 1',
232229
{ tags: ['@GenAI', '@Chatbot', '@CompareMode', '@Settings'] },
233230
() => {
234-
cy.step('Click settings button on Model 1 pane');
235-
chatbotPage.openPaneSettings(0);
231+
cy.step('Open settings panel and switch to Chat 1');
232+
chatbotPage.openPaneSettings(1);
236233

237-
cy.step('Verify settings panel shows Configure - 1');
238-
chatbotPage.findSettingsPanelHeader().should('contain.text', 'Configure - 1');
234+
cy.step('Verify config switcher is visible with Chat 1 selected');
235+
chatbotPage.findConfigSwitcher().should('be.visible');
236+
chatbotPage.findConfigTab(1).should('have.attr', 'aria-pressed', 'true');
239237
},
240238
);
241239

242240
it(
243-
'should open settings for Model 2 when clicking Model 2 settings button',
241+
'should switch settings panel to Chat 2 via config switcher',
244242
{ tags: ['@GenAI', '@Chatbot', '@CompareMode', '@Settings'] },
245243
() => {
246-
cy.step('Click settings button on Model 2 pane');
247-
chatbotPage.openPaneSettings(1);
244+
cy.step('Open settings panel and switch to Chat 2');
245+
chatbotPage.openPaneSettings(2);
248246

249-
cy.step('Verify settings panel shows Configure - 2');
250-
chatbotPage.findSettingsPanelHeader().should('contain.text', 'Configure - 2');
247+
cy.step('Verify config switcher is visible with Chat 2 selected');
248+
chatbotPage.findConfigSwitcher().should('be.visible');
249+
chatbotPage.findConfigTab(2).should('have.attr', 'aria-pressed', 'true');
251250
},
252251
);
253252
});
@@ -295,10 +294,10 @@ describe('Chatbot - Compare Mode (Mocked)', () => {
295294
});
296295

297296
it(
298-
'should exit compare mode when closing Model 1 pane',
297+
'should exit compare mode when closing Chat 1 pane',
299298
{ tags: ['@GenAI', '@Chatbot', '@CompareMode', '@E2E'] },
300299
() => {
301-
cy.step('Close Model 1 pane');
300+
cy.step('Close Chat 1 pane');
302301
chatbotPage.closePaneByIndex(0);
303302

304303
cy.step('Verify exited compare mode');
@@ -310,10 +309,10 @@ describe('Chatbot - Compare Mode (Mocked)', () => {
310309
);
311310

312311
it(
313-
'should exit compare mode when closing Model 2 pane',
312+
'should exit compare mode when closing Chat 2 pane',
314313
{ tags: ['@GenAI', '@Chatbot', '@CompareMode', '@E2E'] },
315314
() => {
316-
cy.step('Close Model 2 pane');
315+
cy.step('Close Chat 2 pane');
317316
chatbotPage.closePaneByIndex(1);
318317

319318
cy.step('Verify exited compare mode');

packages/gen-ai/frontend/src/app/Chatbot/ChatbotHeaderActions.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
MenuToggle,
1212
Tooltip,
1313
} from '@patternfly/react-core';
14-
import { CodeIcon, ColumnsIcon, EllipsisVIcon, PlusIcon } from '@patternfly/react-icons';
14+
import { CodeIcon, ColumnsIcon, CogIcon, EllipsisVIcon, PlusIcon } from '@patternfly/react-icons';
1515
import { ChatbotContext } from '~/app/context/ChatbotContext';
1616
import { useChatbotConfigStore, selectSelectedModel, selectConfigIds } from './store';
1717

@@ -21,6 +21,8 @@ type ChatbotHeaderActionsProps = {
2121
onDeletePlayground: () => void;
2222
onNewChat: () => void;
2323
onCompareChat: () => void;
24+
onSettingsClick: () => void;
25+
isSettingsOpen: boolean;
2426
isCompareMode: boolean;
2527
};
2628

@@ -30,6 +32,8 @@ const ChatbotHeaderActions: React.FC<ChatbotHeaderActionsProps> = ({
3032
onDeletePlayground,
3133
onNewChat,
3234
onCompareChat,
35+
onSettingsClick,
36+
isSettingsOpen,
3337
isCompareMode,
3438
}) => {
3539
const { lsdStatus, lastInput } = React.useContext(ChatbotContext);
@@ -72,6 +76,18 @@ const ChatbotHeaderActions: React.FC<ChatbotHeaderActionsProps> = ({
7276
</Button>
7377
</ActionListItem>
7478
)}
79+
<ActionListItem>
80+
<Button
81+
variant="link"
82+
aria-label="Settings"
83+
aria-expanded={isSettingsOpen}
84+
icon={<CogIcon />}
85+
onClick={onSettingsClick}
86+
data-testid="settings-button"
87+
>
88+
Settings
89+
</Button>
90+
</ActionListItem>
7591
<ActionListItem>
7692
<Button
7793
variant="link"

packages/gen-ai/frontend/src/app/Chatbot/ChatbotMain.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ const ChatbotMain: React.FunctionComponent = () => {
5454
const { isPromptManagementModalOpen } = usePlaygroundStore();
5555
// Track which pane's settings are active in compare mode
5656
const [activePaneConfigId, setActivePaneConfigId] = React.useState<string>(DEFAULT_CONFIG_ID);
57+
const [isDrawerExpanded, setIsDrawerExpanded] = React.useState(true);
5758

5859
// Ref to clear all chat messages (will be set by ChatbotPlayground)
5960
const clearAllMessagesRef = React.useRef<(() => void) | null>(null);
@@ -167,6 +168,8 @@ const ChatbotMain: React.FunctionComponent = () => {
167168
setIsCompareChatModalOpen(true);
168169
fireSimpleTrackingEvent('Playground Compare Chat Selected');
169170
}}
171+
onSettingsClick={() => setIsDrawerExpanded((prev) => !prev)}
172+
isSettingsOpen={isDrawerExpanded}
170173
isCompareMode={isCompareMode}
171174
/>
172175
)
@@ -219,6 +222,8 @@ const ChatbotMain: React.FunctionComponent = () => {
219222
setActivePaneConfigId={setActivePaneConfigId}
220223
onClosePane={handleClosePane}
221224
clearAllMessagesRef={clearAllMessagesRef}
225+
isDrawerExpanded={isDrawerExpanded}
226+
setIsDrawerExpanded={setIsDrawerExpanded}
222227
/>
223228
)
224229
) : lsdStatus?.phase === 'Failed' ? (

packages/gen-ai/frontend/src/app/Chatbot/ChatbotPane.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@ interface ChatbotPaneProps {
1111
displayLabel: string;
1212
selectedModel: string;
1313
onModelChange: (model: string) => void;
14-
onSettingsClick: () => void;
1514
onClose: () => void;
1615
children: React.ReactNode;
1716
/** Metrics from the last response (latency, tokens, TTFT) */
1817
metrics?: ResponseMetrics | null;
1918
/** Whether a response is currently being generated */
2019
isLoading?: boolean;
20+
isSettingsOpen?: boolean;
21+
isActiveConfig?: boolean;
2122
}
2223

2324
/**
@@ -29,11 +30,12 @@ const ChatbotPane: React.FC<ChatbotPaneProps> = ({
2930
displayLabel,
3031
selectedModel,
3132
onModelChange,
32-
onSettingsClick,
3333
onClose,
3434
children,
3535
metrics,
3636
isLoading,
37+
isSettingsOpen,
38+
isActiveConfig,
3739
}) => {
3840
const isDarkMode = useDarkMode();
3941
return (
@@ -49,10 +51,11 @@ const ChatbotPane: React.FC<ChatbotPaneProps> = ({
4951
label={displayLabel}
5052
selectedModel={selectedModel}
5153
onModelChange={onModelChange}
52-
onSettingsClick={onSettingsClick}
5354
onCloseClick={onClose}
5455
metrics={metrics}
5556
isLoading={isLoading}
57+
isSettingsOpen={isSettingsOpen}
58+
isActiveConfig={isActiveConfig}
5659
hasDivider
5760
testIdPrefix={`chatbot-pane-${configId}`}
5861
isDarkMode={isDarkMode}

0 commit comments

Comments
 (0)