Skip to content

Commit cab4992

Browse files
feat(lightspeed): internationalize FAB tooltip and aria-label (#3053)
Add tooltip.fab.open and tooltip.fab.close with locale strings. Update Playwright openChatbot to use translated accessible names, unit tests, and alpha API report. Include changeset for plugin patch. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent d90b551 commit cab4992

15 files changed

Lines changed: 46 additions & 19 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@red-hat-developer-hub/backstage-plugin-lightspeed': patch
3+
---
4+
5+
Internationalize the Lightspeed floating action button: tooltip and `aria-label` use `tooltip.fab.open` / `tooltip.fab.close`, with German, Spanish, French, Italian, and Japanese translations.

workspaces/lightspeed/e2e-tests/lightspeed.mcp.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ test.describe('Lightspeed MCP', () => {
6969
test.describe('Chatbot MCP settings', () => {
7070
async function runMcpPanelScenario(mcpList: McpServersListMock) {
7171
await mockMcpServers(sharedPage, mcpList);
72-
await openChatbot(sharedPage);
72+
await openChatbot(sharedPage, translations);
7373
await verifyMcpSettingsPanel(sharedPage, translations, mcpList);
7474
}
7575

@@ -83,18 +83,18 @@ test.describe('Lightspeed MCP', () => {
8383

8484
test('Overlay', async () => {
8585
await expectBackstagePageVisible(sharedPage);
86-
await openChatbot(sharedPage);
86+
await openChatbot(sharedPage, translations);
8787
await verifyMcpSettingsPanel(sharedPage, translations);
8888
});
8989

9090
test('Dock to Window', async () => {
91-
await openChatbot(sharedPage);
91+
await openChatbot(sharedPage, translations);
9292
await selectDisplayMode(sharedPage, translations, 'Dock to window');
9393
await verifyMcpSettingsPanel(sharedPage, translations);
9494
});
9595

9696
test('Fullscreen', async () => {
97-
await openChatbot(sharedPage);
97+
await openChatbot(sharedPage, translations);
9898
await selectDisplayMode(sharedPage, translations, 'Fullscreen');
9999
await verifyMcpSettingsPanel(sharedPage, translations);
100100
});
@@ -123,7 +123,7 @@ test.describe('Lightspeed MCP', () => {
123123

124124
test('Sort works as expected', async () => {
125125
await mockMcpServers(sharedPage, mcpServerScenarios.allHealthy);
126-
await openChatbot(sharedPage);
126+
await openChatbot(sharedPage, translations);
127127
await openMcpSettingsPanel(sharedPage, translations);
128128

129129
const rows = mcpServersTableBodyRows(sharedPage, translations);
@@ -139,7 +139,7 @@ test.describe('Lightspeed MCP', () => {
139139

140140
test('Toggle works as expected', async () => {
141141
const serverName = 'mcp-integration-tools';
142-
await openChatbot(sharedPage);
142+
await openChatbot(sharedPage, translations);
143143
await openMcpSettingsPanel(sharedPage, translations);
144144

145145
const row = mcpServerRow(sharedPage, serverName, translations);

workspaces/lightspeed/e2e-tests/lightspeed.ui.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ test.describe('Lightspeed UI', () => {
6666

6767
test('should display chatbot in overlay mode with backstage page visible', async () => {
6868
await expectBackstagePageVisible(sharedPage);
69-
await openChatbot(sharedPage);
69+
await openChatbot(sharedPage, translations);
7070

7171
await expectConversationArea(sharedPage, translations, 'Overlay');
7272
await expectChatInputAreaVisible(sharedPage, translations);
@@ -81,7 +81,7 @@ test.describe('Lightspeed UI', () => {
8181
});
8282

8383
test('should display chatbot in dock to window mode with backstage page visible', async () => {
84-
await openChatbot(sharedPage);
84+
await openChatbot(sharedPage, translations);
8585
await selectDisplayMode(sharedPage, translations, 'Dock to window');
8686

8787
await expectConversationArea(sharedPage, translations, 'Dock to window');
@@ -95,7 +95,7 @@ test.describe('Lightspeed UI', () => {
9595
});
9696

9797
test('should display chatbot in fullscreen mode with backstage page hidden', async () => {
98-
await openChatbot(sharedPage);
98+
await openChatbot(sharedPage, translations);
9999
await selectDisplayMode(sharedPage, translations, 'Fullscreen');
100100

101101
await expectConversationArea(sharedPage, translations, 'Fullscreen');

workspaces/lightspeed/e2e-tests/pages/LightspeedPage.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ import {
3030
export type DisplayMode = 'Overlay' | 'Dock to window' | 'Fullscreen';
3131

3232
// Actions
33-
export async function openChatbot(page: Page) {
34-
await page.getByRole('button', { name: 'lightspeed-open' }).click();
33+
export async function openChatbot(page: Page, t: LightspeedMessages) {
34+
await page.getByRole('button', { name: t['tooltip.fab.open'] }).click();
3535
}
3636

3737
export async function selectDisplayMode(

workspaces/lightspeed/e2e-tests/pages/McpConfigureTokenPage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export class McpConfigureTokenPage {
4848
mockOptions?: MockMcpServersOptions,
4949
): Promise<void> {
5050
await mockMcpServers(this.page, mcpList, mockOptions ?? {});
51-
await openChatbot(this.page);
51+
await openChatbot(this.page, this.t);
5252
await selectDisplayMode(this.page, this.t, mode);
5353
await openMcpSettingsPanel(this.page, this.t);
5454
}

workspaces/lightspeed/plugins/lightspeed/report-alpha.api.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,8 @@ export const lightspeedTranslationRef: TranslationRef<
325325
readonly 'tooltip.backToBottom': string;
326326
readonly 'tooltip.settings': string;
327327
readonly 'tooltip.close': string;
328+
readonly 'tooltip.fab.open': string;
329+
readonly 'tooltip.fab.close': string;
328330
readonly 'modal.title.preview': string;
329331
readonly 'modal.title.edit': string;
330332
readonly 'icon.lightspeed.alt': string;

workspaces/lightspeed/plugins/lightspeed/src/alpha/LightspeedFAB.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { ChatbotDisplayMode } from '@patternfly/chatbot';
2323
import { LightspeedFABIcon } from '../components/LightspeedIcon';
2424
import { DOCKED_CONTENT_OFFSET } from '../const';
2525
import { useLightspeedDrawerContext } from '../hooks/useLightspeedDrawerContext';
26+
import { useTranslation } from '../hooks/useTranslation';
2627

2728
const useStyles = makeStyles(theme => ({
2829
fab: {
@@ -56,6 +57,7 @@ const useStyles = makeStyles(theme => ({
5657
*/
5758

5859
export const LightspeedFAB = () => {
60+
const { t } = useTranslation();
5961
const { isChatbotActive, toggleChatbot, displayMode } =
6062
useLightspeedDrawerContext();
6163
const fabButton = useStyles();
@@ -71,15 +73,17 @@ export const LightspeedFAB = () => {
7173
data-testid="lightspeed-fab"
7274
>
7375
<Tooltip
74-
title={isChatbotActive ? 'Close Lightspeed' : 'Open Lightspeed'}
76+
title={isChatbotActive ? t('tooltip.fab.close') : t('tooltip.fab.open')}
7577
placement="left"
7678
>
7779
<Fab
7880
color="primary"
7981
variant="circular"
8082
size="small"
8183
onClick={toggleChatbot}
82-
aria-label={isChatbotActive ? 'lightspeed-close' : 'lightspeed-open'}
84+
aria-label={
85+
isChatbotActive ? t('tooltip.fab.close') : t('tooltip.fab.open')
86+
}
8387
className={fabButton.fab}
8488
sx={{ borderRadius: '100% !important' }}
8589
>

workspaces/lightspeed/plugins/lightspeed/src/components/LightspeedFAB.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { ChatbotDisplayMode } from '@patternfly/chatbot';
2222

2323
import { DOCKED_CONTENT_OFFSET } from '../const';
2424
import { useLightspeedDrawerContext } from '../hooks/useLightspeedDrawerContext';
25+
import { useTranslation } from '../hooks/useTranslation';
2526
import { LightspeedFABIcon } from './LightspeedIcon';
2627

2728
const useStyles = makeStyles(theme => ({
@@ -56,6 +57,7 @@ const useStyles = makeStyles(theme => ({
5657
*/
5758

5859
export const LightspeedFAB = () => {
60+
const { t } = useTranslation();
5961
const { isChatbotActive, toggleChatbot, displayMode } =
6062
useLightspeedDrawerContext();
6163
const fabButton = useStyles();
@@ -71,15 +73,17 @@ export const LightspeedFAB = () => {
7173
data-testid="lightspeed-fab"
7274
>
7375
<Tooltip
74-
title={isChatbotActive ? 'Close Lightspeed' : 'Open Lightspeed'}
76+
title={isChatbotActive ? t('tooltip.fab.close') : t('tooltip.fab.open')}
7577
placement="left"
7678
>
7779
<Fab
7880
color="primary"
7981
variant="circular"
8082
size="small"
8183
onClick={toggleChatbot}
82-
aria-label={isChatbotActive ? 'lightspeed-close' : 'lightspeed-open'}
84+
aria-label={
85+
isChatbotActive ? t('tooltip.fab.close') : t('tooltip.fab.open')
86+
}
8387
className={fabButton.fab}
8488
sx={{ borderRadius: '100% !important' }}
8589
>

workspaces/lightspeed/plugins/lightspeed/src/components/__tests__/LightspeedFAB.test.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ describe('LightspeedFAB', () => {
6868
);
6969

7070
expect(screen.getByTestId('lightspeed-fab')).toBeInTheDocument();
71-
expect(screen.getByLabelText('lightspeed-open')).toBeInTheDocument();
71+
expect(screen.getByLabelText('Open Lightspeed')).toBeInTheDocument();
7272
});
7373

7474
it('should render FAB button when displayMode is docked', () => {
@@ -79,7 +79,7 @@ describe('LightspeedFAB', () => {
7979
);
8080

8181
expect(screen.getByTestId('lightspeed-fab')).toBeInTheDocument();
82-
expect(screen.getByLabelText('lightspeed-open')).toBeInTheDocument();
82+
expect(screen.getByLabelText('Open Lightspeed')).toBeInTheDocument();
8383
});
8484

8585
it('should not render FAB button when displayMode is embedded', () => {
@@ -99,7 +99,7 @@ describe('LightspeedFAB', () => {
9999
}),
100100
);
101101

102-
const fabButton = screen.getByLabelText('lightspeed-open');
102+
const fabButton = screen.getByLabelText('Open Lightspeed');
103103
fireEvent.click(fabButton);
104104

105105
expect(mockToggleChatbot).toHaveBeenCalledTimes(1);

workspaces/lightspeed/plugins/lightspeed/src/translations/de.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,8 @@ const lightspeedTranslationDe = createTranslationMessages({
224224
'tooltip.backToBottom': 'Zurück zum Ende',
225225
'tooltip.settings': 'Chatbot-Optionen',
226226
'tooltip.close': 'Schließen',
227+
'tooltip.fab.open': 'Lightspeed öffnen',
228+
'tooltip.fab.close': 'Lightspeed schließen',
227229
'modal.title.preview': 'Anhang in der Vorschau anzeigen',
228230
'modal.title.edit': 'Anhang bearbeiten',
229231
'icon.lightspeed.alt': 'Lightspeed-Symbol',

0 commit comments

Comments
 (0)