Skip to content

Commit 72ed90a

Browse files
authored
Merge pull request RedHatInsights#258 from aferd/RHCLOUD-45246
add support tab user journey
2 parents b85894b + 6ae9ead commit 72ed90a

5 files changed

Lines changed: 274 additions & 7 deletions

File tree

.storybook/mocks/chromeMock.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
export const defaultMockChrome = {
77
auth: {
8+
getToken: async () => 'mock-token',
89
getUser: async () => ({
910
identity: {
1011
account_number: '12345',

src/components/HelpPanel/HelpPanelTabs/SupportPanel.tsx

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,35 @@ const statusTypes = {
5050
redHatWaiting: 'Waiting on Red Hat',
5151
};
5252

53+
// Spacing between status text and icon: --pf-t--global--spacer--sm (.5rem / 8px)
54+
// https://www.patternfly.org/design-foundations/spacers#spacer-tokens
55+
const statusContentClass =
56+
'pf-v6-u-display-inline-flex pf-v6-u-align-items-center pf-v6-u-text-nowrap';
57+
const statusIconSpacerStyle = {
58+
marginInlineStart: 'var(--pf-t--global--spacer--sm)',
59+
};
60+
5361
export const statusIcons = (status: string) => {
5462
const statusMapper = {
5563
[statusTypes.customerWaiting]: (
56-
<Icon className="pf-t--global--icon--color--status--info--default">
57-
{status} <AttentionBellIcon />{' '}
58-
</Icon>
64+
<span className={statusContentClass}>
65+
<span>{status}</span>
66+
<Icon
67+
className="pf-t--global--icon--color--status--info--default"
68+
style={statusIconSpacerStyle}
69+
isInline
70+
>
71+
<AttentionBellIcon />
72+
</Icon>
73+
</span>
5974
),
6075
[statusTypes.redHatWaiting]: (
61-
<Icon>
62-
{status} <InProgressIcon />{' '}
63-
</Icon>
76+
<span className={statusContentClass}>
77+
<span>{status}</span>
78+
<Icon style={statusIconSpacerStyle} isInline>
79+
<InProgressIcon />
80+
</Icon>
81+
</span>
6482
),
6583
};
6684
return statusMapper[status] ?? '';

src/docs/UserJourneys.mdx

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,26 @@ Tests the complete user workflow for accessing and filtering learning resources
4343
**Manual Testing:**
4444
Use the "Manual Testing" story to explore the Help Panel interactively without automated steps running.
4545

46+
### Help Panel / Support Panel
47+
48+
Tests the user workflow for viewing support cases and opening a new case from the Help Panel (My support cases tab).
49+
50+
**Steps:**
51+
1. **Page Loads** - Console page loads with Help button in masthead
52+
2. **Open Help Panel** - User clicks Help button to open the Help Panel drawer
53+
3. **Navigate to Support Tab** - User navigates to the My support cases tab
54+
4. **Empty State and Open Support Case** - User sees empty state and "Open support case" button when there are no cases
55+
5. **With Cases: Table and Pagination** - When cases exist, user sees the cases table and pagination
56+
57+
**What it tests:**
58+
- Console page structure and Help Panel drawer
59+
- Tab navigation to My support cases
60+
- Support panel empty state and primary action (Open support case)
61+
- Support cases table and pagination when mock cases are returned
62+
63+
**Manual Testing:**
64+
Use the "Manual Testing" story to explore the Support tab interactively.
65+
4666
## 🏗️ Creating New Tab Journeys
4767

4868
Use the shared helpers in `src/user-journeys/_shared/helpPanelJourneyHelpers.ts` to create journeys for other Help Panel tabs (APIs, My support cases, Feedback, etc.).
@@ -59,6 +79,8 @@ See `HELP_PANEL_JOURNEY_TEMPLATE.md` for detailed examples.
5979

6080
**`helpPanelMswHandlers`** - Mock API handlers for learning resources (filters, quickstarts, favorites)
6181

82+
**`supportPanelMswHandlers`** - Mock support cases API (empty state). Use with **`supportPanelMswHandlersWithCases`** for table/pagination testing.
83+
6284
### Example: Creating an APIs Tab Journey
6385

6486
```typescript
@@ -174,7 +196,7 @@ parameters: {
174196
npm run storybook
175197
```
176198

177-
Navigate to "User Journeys" → "Help Panel / Learn Panel" section and click on individual stories.
199+
Navigate to "User Journeys" → "Help Panel" (Learn Panel, Support Panel, etc.) and click on individual stories.
178200

179201
### Via Play Function
180202

@@ -194,6 +216,8 @@ The MSW handlers provide mock data for:
194216

195217
This data supports testing bundle scope toggling, content type filtering, and bookmark filtering.
196218

219+
For the Support Panel journey, **supportPanelMswHandlers** returns no cases (empty state); **supportPanelMswHandlersWithCases** returns mock cases for table and pagination steps.
220+
197221
---
198222

199223
User journeys make Help Panel workflows testable and documentable. Use the shared helpers to quickly create journeys for all tabs.
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
import type { Meta, StoryObj } from '@storybook/react-webpack5';
2+
import { expect, waitFor, within } from 'storybook/test';
3+
import { AppEntryWithRouter } from './_shared/components/AppEntryWithRouter';
4+
import {
5+
helpPanelMswHandlers,
6+
navigateToTab,
7+
openHelpPanel,
8+
supportPanelMswHandlers,
9+
supportPanelMswHandlersWithCases,
10+
waitForPageLoad,
11+
} from './_shared/helpPanelJourneyHelpers';
12+
import { TEST_TIMEOUTS, delay } from './_shared/testConstants';
13+
14+
/**
15+
* User Journey: Help Panel - Support Panel
16+
*
17+
* Tests the user workflow for viewing support cases and opening a new case from the Help Panel.
18+
*/
19+
20+
const meta: Meta<typeof AppEntryWithRouter> = {
21+
title: 'User Journeys/Help Panel/Support Panel',
22+
component: AppEntryWithRouter,
23+
parameters: {
24+
layout: 'fullscreen',
25+
msw: {
26+
handlers: [...helpPanelMswHandlers, ...supportPanelMswHandlers],
27+
},
28+
docs: {
29+
description: {
30+
component: `
31+
# Help Panel - Support Panel User Journey
32+
33+
Tests the support cases workflow including:
34+
- Opening the Help Panel
35+
- Navigating to the My support cases tab
36+
- Empty state and Open support case button
37+
- Table and pagination when cases exist
38+
`,
39+
},
40+
},
41+
},
42+
args: {
43+
initialRoute: '/',
44+
bundle: 'insights',
45+
},
46+
};
47+
48+
export default meta;
49+
50+
type Story = StoryObj<typeof meta>;
51+
52+
/**
53+
* Manual Testing Entry Point
54+
*/
55+
export const ManualTesting: Story = {};
56+
57+
/**
58+
* 01 / Page Loads
59+
*/
60+
export const Step01_PageLoads: Story = {
61+
name: '01 / Page Loads',
62+
play: async ({ canvasElement }) => {
63+
await waitForPageLoad(canvasElement);
64+
},
65+
};
66+
67+
/**
68+
* 02 / Open Help Panel
69+
*/
70+
export const Step02_OpenHelpPanel: Story = {
71+
name: '02 / Open Help Panel',
72+
play: async ({ canvasElement }) => {
73+
await openHelpPanel(canvasElement);
74+
},
75+
};
76+
77+
/**
78+
* 03 / Navigate to Support Tab
79+
*/
80+
export const Step03_NavigateToSupportTab: Story = {
81+
name: '03 / Navigate to Support Tab',
82+
play: async ({ canvasElement }) => {
83+
await navigateToTab(canvasElement, 'My support cases');
84+
85+
// Wait for Support content to load (empty state or table)
86+
await waitFor(
87+
() => {
88+
const emptyState = document.querySelector(
89+
'[data-ouia-component-id="help-panel-support-empty-state"]'
90+
);
91+
const table = document.querySelector(
92+
'[data-ouia-component-id="help-panel-support-cases-table"]'
93+
);
94+
expect(emptyState ?? table).toBeInTheDocument();
95+
},
96+
{ timeout: TEST_TIMEOUTS.ELEMENT_WAIT }
97+
);
98+
99+
await delay(TEST_TIMEOUTS.QUICK_SETTLE);
100+
console.log('UJ: ✅ Support tab opened and content loaded');
101+
},
102+
};
103+
104+
/**
105+
* 04 / Empty State and Open Support Case
106+
*/
107+
export const Step04_EmptyStateAndOpenSupportCase: Story = {
108+
name: '04 / Empty State and Open Support Case',
109+
play: async ({ canvasElement }) => {
110+
await navigateToTab(canvasElement, 'My support cases');
111+
112+
// Wait for loading to finish: empty state appears (skeleton disappears)
113+
await waitFor(
114+
() => {
115+
const emptyState = document.querySelector(
116+
'[data-ouia-component-id="help-panel-support-empty-state"]'
117+
);
118+
expect(emptyState).toBeInTheDocument();
119+
},
120+
{ timeout: TEST_TIMEOUTS.ELEMENT_WAIT }
121+
);
122+
123+
await delay(TEST_TIMEOUTS.AFTER_CLICK);
124+
125+
const openSupportCaseButton = document.querySelector(
126+
'[data-ouia-component-id="help-panel-open-support-case-button"]'
127+
);
128+
expect(openSupportCaseButton).toBeInTheDocument();
129+
130+
console.log('UJ: ✅ Empty state and Open support case button verified');
131+
},
132+
};
133+
134+
/**
135+
* 05 / With Cases: Table and Pagination
136+
*/
137+
export const Step05_WithCasesTableAndPagination: Story = {
138+
name: '05 / With Cases: Table and Pagination',
139+
parameters: {
140+
msw: {
141+
handlers: [...helpPanelMswHandlers, ...supportPanelMswHandlersWithCases],
142+
},
143+
},
144+
play: async ({ canvasElement }) => {
145+
await navigateToTab(canvasElement, 'My support cases');
146+
waitForPageLoad(canvasElement);
147+
148+
// Wait for table to appear (API returns mock cases)
149+
await waitFor(
150+
() => {
151+
const table = document.querySelector(
152+
'[data-ouia-component-id="help-panel-support-cases-table"]'
153+
);
154+
expect(table).toBeInTheDocument();
155+
},
156+
{ timeout: TEST_TIMEOUTS.ELEMENT_WAIT }
157+
);
158+
159+
await delay(TEST_TIMEOUTS.AFTER_CLICK);
160+
161+
const canvas = within(canvasElement);
162+
// Verify table has case content (mock case summary)
163+
await waitFor(
164+
() => {
165+
const caseSummary = canvas.queryByText(
166+
/Insights subscription activation/i
167+
);
168+
expect(caseSummary).toBeInTheDocument();
169+
},
170+
{ timeout: TEST_TIMEOUTS.ELEMENT_WAIT }
171+
);
172+
173+
const pagination = document.querySelector(
174+
'[data-ouia-component-id="help-panel-support-pagination"]'
175+
);
176+
expect(pagination).toBeInTheDocument();
177+
178+
console.log('UJ: ✅ Support cases table and pagination verified');
179+
},
180+
};

src/user-journeys/_shared/helpPanelJourneyHelpers.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,50 @@ export const helpPanelMswHandlers = [
287287
}),
288288
];
289289

290+
const supportCasesFilterUrlProd =
291+
'https://api.access.redhat.com/support/v1/cases/filter';
292+
const supportCasesFilterUrlStage =
293+
'https://api.access.stage.redhat.com/support/v1/cases/filter';
294+
295+
const emptySupportCasesResponse = () => HttpResponse.json({ cases: [] });
296+
297+
/**
298+
* MSW handlers for Support Panel - empty state (no open support cases).
299+
*/
300+
export const supportPanelMswHandlers = [
301+
http.post(supportCasesFilterUrlProd, emptySupportCasesResponse),
302+
http.post(supportCasesFilterUrlStage, emptySupportCasesResponse),
303+
];
304+
305+
const mockSupportCases = [
306+
{
307+
id: 'case-1',
308+
caseNumber: '03012345',
309+
summary: 'Insights subscription activation issue',
310+
lastModifiedDate: new Date().toISOString(),
311+
status: 'Waiting on Red Hat',
312+
},
313+
{
314+
id: 'case-2',
315+
caseNumber: '03012346',
316+
summary: 'API rate limit clarification',
317+
lastModifiedDate: new Date(Date.now() - 86400000).toISOString(),
318+
status: 'Waiting on Customer',
319+
},
320+
];
321+
322+
/**
323+
* MSW handlers for Support Panel - with cases (table and pagination).
324+
*/
325+
export const supportPanelMswHandlersWithCases = [
326+
http.post(supportCasesFilterUrlProd, () =>
327+
HttpResponse.json({ cases: mockSupportCases })
328+
),
329+
http.post(supportCasesFilterUrlStage, () =>
330+
HttpResponse.json({ cases: mockSupportCases })
331+
),
332+
];
333+
290334
/**
291335
* Wait for the console page to load.
292336
* Verifies the Help button and header are present.

0 commit comments

Comments
 (0)