|
5 | 5 | import { appMeta, AppWithMocks, type AppStory } from "./meta.js"; |
6 | 6 | import { setupSimpleChatStory, setReviews, createReview } from "./storyHelpers"; |
7 | 7 | import { createUserMessage, createAssistantMessage } from "./mockFactory"; |
| 8 | +import { within, userEvent, waitFor } from "@storybook/test"; |
8 | 9 |
|
9 | 10 | export default { |
10 | 11 | ...appMeta, |
@@ -156,3 +157,93 @@ export const ManyReviews: AppStory = { |
156 | 157 | /> |
157 | 158 | ), |
158 | 159 | }; |
| 160 | + |
| 161 | +/** |
| 162 | + * Shows multiple attached reviews in ChatInput with "Clear all" button. |
| 163 | + * Also shows pending reviews in banner with "Attach all to chat" button. |
| 164 | + */ |
| 165 | +export const BulkReviewActions: AppStory = { |
| 166 | + render: () => ( |
| 167 | + <AppWithMocks |
| 168 | + setup={() => { |
| 169 | + const workspaceId = "ws-bulk-reviews"; |
| 170 | + |
| 171 | + setReviews(workspaceId, [ |
| 172 | + // Attached reviews - shown in ChatInput with "Clear all" button |
| 173 | + createReview( |
| 174 | + "review-attached-1", |
| 175 | + "src/api/auth.ts", |
| 176 | + "42-48", |
| 177 | + "Consider using a constant for the token expiry", |
| 178 | + "attached" |
| 179 | + ), |
| 180 | + createReview( |
| 181 | + "review-attached-2", |
| 182 | + "src/utils/helpers.ts", |
| 183 | + "15-20", |
| 184 | + "This function could be simplified using reduce", |
| 185 | + "attached" |
| 186 | + ), |
| 187 | + createReview( |
| 188 | + "review-attached-3", |
| 189 | + "src/hooks/useAuth.ts", |
| 190 | + "30-35", |
| 191 | + "Missing error handling for network failures", |
| 192 | + "attached" |
| 193 | + ), |
| 194 | + // Pending reviews - shown in banner with "Attach all to chat" button |
| 195 | + createReview( |
| 196 | + "review-pending-1", |
| 197 | + "src/components/LoginForm.tsx", |
| 198 | + "55-60", |
| 199 | + "Add loading state while authenticating", |
| 200 | + "pending" |
| 201 | + ), |
| 202 | + createReview( |
| 203 | + "review-pending-2", |
| 204 | + "src/services/api.ts", |
| 205 | + "12-18", |
| 206 | + "Consider adding retry logic for failed requests", |
| 207 | + "pending" |
| 208 | + ), |
| 209 | + createReview( |
| 210 | + "review-pending-3", |
| 211 | + "src/types/user.ts", |
| 212 | + "5-10", |
| 213 | + "Make email field optional for guest users", |
| 214 | + "pending" |
| 215 | + ), |
| 216 | + ]); |
| 217 | + |
| 218 | + return setupSimpleChatStory({ |
| 219 | + workspaceId, |
| 220 | + workspaceName: "feature/auth-improvements", |
| 221 | + projectName: "my-app", |
| 222 | + messages: [ |
| 223 | + createUserMessage("msg-1", "Help me fix the authentication issues", { |
| 224 | + historySequence: 1, |
| 225 | + }), |
| 226 | + createAssistantMessage("msg-2", "I'll help you address the authentication issues.", { |
| 227 | + historySequence: 2, |
| 228 | + }), |
| 229 | + ], |
| 230 | + }); |
| 231 | + }} |
| 232 | + /> |
| 233 | + ), |
| 234 | + play: async ({ canvasElement }: { canvasElement: HTMLElement }) => { |
| 235 | + const canvas = within(canvasElement); |
| 236 | + |
| 237 | + // Expand the ReviewsBanner to show "Attach all to chat" button |
| 238 | + // The banner shows "3 pending reviews" but number is in separate span, |
| 239 | + // so we click on "pending review" text |
| 240 | + await waitFor(async () => { |
| 241 | + const bannerButton = canvas.getByText(/pending review/i); |
| 242 | + await userEvent.click(bannerButton); |
| 243 | + }); |
| 244 | + |
| 245 | + // Wait for any auto-focus timers, then blur |
| 246 | + await new Promise((resolve) => setTimeout(resolve, 150)); |
| 247 | + (document.activeElement as HTMLElement)?.blur(); |
| 248 | + }, |
| 249 | +}; |
0 commit comments