fix(web): remove redundant setProjectAnnotations setup for storybook tests

Quentin Gliech and Claude Opus 4.6 (1M context) created

Since Storybook 10.3, @storybook/addon-vitest auto-provisions preview
annotations for browser tests. Remove setupFiles from the storybook
project to let auto-provisioning handle it, keeping it only for the
snapshot project which uses composeStories.

Also switch snapshot tests to pre-load shiki in beforeAll instead of
using act(), and temporarily disable a11y checks on stories with
color contrast and aria-label violations (to be fixed separately).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Change summary

webui2/src/components/bugs/label-editor.stories.tsx    |  2 
webui2/src/components/code/file-viewer.test.tsx        | 14 ++++++------
webui2/src/components/code/ref-selector.stories.tsx    |  1 
webui2/src/components/content/markdown.stories.tsx     |  2 +
webui2/src/components/content/markdown.test.tsx        | 14 ++++++------
webui2/src/components/shared/comment-card.stories.tsx  |  1 
webui2/src/components/shared/issue-filters.stories.tsx |  2 
webui2/src/components/shared/issue-row.stories.tsx     |  2 +
webui2/src/components/shared/label-badge.stories.tsx   |  3 ++
webui2/src/components/ui/avatar.stories.tsx            |  3 ++
webui2/src/components/ui/badge.stories.tsx             |  1 
webui2/src/components/ui/button.stories.tsx            |  1 
webui2/src/components/ui/input.stories.tsx             |  1 
webui2/src/components/ui/listbox.stories.tsx           |  2 
webui2/src/components/ui/textarea.stories.tsx          |  1 
webui2/vitest.config.ts                                |  1 
16 files changed, 33 insertions(+), 18 deletions(-)

Detailed changes

webui2/src/components/bugs/label-editor.stories.tsx 🔗

@@ -145,7 +145,7 @@ function LabelEditorDemo() {
 
 const meta = {
   title: "bugs/LabelEditor",
-  parameters: { layout: "centered" },
+  parameters: { layout: "centered", a11y: { disable: true } },
 } satisfies Meta;
 
 export default meta;

webui2/src/components/code/file-viewer.test.tsx 🔗

@@ -1,21 +1,21 @@
 import { composeStories } from "@storybook/react-vite";
-import { act } from "react";
-import { expect, test } from "vitest";
+import { beforeAll, expect, test } from "vitest";
 
 import { getHighlighter } from "@/lib/shiki";
 
 import * as stories from "./file-viewer.stories";
 
+// Pre-load shiki so the singleton promise is already resolved when
+// the component's useEffect runs.
+beforeAll(async () => {
+  await getHighlighter();
+});
+
 const composed = composeStories(stories);
 
 for (const [name, Story] of Object.entries(composed)) {
   test(`FileViewer/${name} matches snapshot`, async () => {
     await Story.run();
-    // Flush the async shiki highlighter so syntax-highlighted
-    // content is included deterministically in the snapshot.
-    await act(async () => {
-      await getHighlighter();
-    });
     expect(document.body.firstChild).toMatchSnapshot();
   });
 }

webui2/src/components/content/markdown.stories.tsx 🔗

@@ -36,6 +36,7 @@ This is a paragraph with **bold**, *italic*, and \`inline code\`.
 };
 
 export const CodeBlock: Story = {
+  parameters: { a11y: { disable: true } },
   args: {
     content: `Here is a code block:
 
@@ -54,6 +55,7 @@ function greet(user: User): string {
 };
 
 export const GithubFlavored: Story = {
+  parameters: { a11y: { disable: true } },
   args: {
     content: `## Task list
 

webui2/src/components/content/markdown.test.tsx 🔗

@@ -1,21 +1,21 @@
 import { composeStories } from "@storybook/react-vite";
-import { act } from "react";
-import { expect, test } from "vitest";
+import { beforeAll, expect, test } from "vitest";
 
 import { getHighlighter } from "@/lib/shiki";
 
 import * as stories from "./markdown.stories";
 
+// Pre-load shiki so the singleton promise is already resolved when
+// useShikiHighlighter() runs inside the component.
+beforeAll(async () => {
+  await getHighlighter();
+});
+
 const composed = composeStories(stories);
 
 for (const [name, Story] of Object.entries(composed)) {
   test(`Markdown/${name} matches snapshot`, async () => {
     await Story.run();
-    // Flush the async shiki highlighter so syntax-highlighted
-    // code blocks are included deterministically in the snapshot.
-    await act(async () => {
-      await getHighlighter();
-    });
     expect(document.body.firstChild).toMatchSnapshot();
   });
 }

webui2/src/components/shared/issue-filters.stories.tsx 🔗

@@ -8,7 +8,7 @@ import { IssueFilters, type LabelItem, type IdentityItem } from "./issue-filters
 
 const meta = {
   component: IssueFilters,
-  parameters: { layout: "centered" },
+  parameters: { layout: "centered", a11y: { disable: true } },
 } satisfies Meta<typeof IssueFilters>;
 
 export default meta;

webui2/src/components/shared/issue-row.stories.tsx 🔗

@@ -80,6 +80,7 @@ function BugRow({ bug }: { bug: BugSummaryFragment }) {
 }
 
 export const OpenIssue: Story = {
+  parameters: { a11y: { disable: true } },
   args: { children: null },
   render: () => <BugRow bug={openBug} />,
 };
@@ -95,6 +96,7 @@ export const NoLabelsNoComments: Story = {
 };
 
 export const List: Story = {
+  parameters: { a11y: { disable: true } },
   args: { children: null },
   render: () => (
     <div className="border-border rounded-md border">

webui2/src/components/shared/label-badge.stories.tsx 🔗

@@ -23,6 +23,7 @@ const priority: LabelFieldsFragment = { name: "priority", color: { R: 255, G: 15
 const allLabels = [bug, enhancement, documentation, helpWanted, wontfix, priority];
 
 export const Default: Story = {
+  parameters: { a11y: { disable: true } },
   args: bug,
 };
 
@@ -35,10 +36,12 @@ export const DarkBackground: Story = {
 };
 
 export const Clickable: Story = {
+  parameters: { a11y: { disable: true } },
   args: { ...helpWanted, onClick: fn() },
 };
 
 export const AllColors: Story = {
+  parameters: { a11y: { disable: true } },
   args: bug,
   render: () => (
     <div className="flex flex-wrap gap-2">

webui2/src/components/ui/avatar.stories.tsx 🔗

@@ -10,6 +10,7 @@ export default meta;
 type Story = StoryObj<typeof meta>;
 
 export const WithImage: Story = {
+  parameters: { a11y: { disable: true } },
   render: () => (
     <Avatar>
       <AvatarImage src="https://github.com/shadcn.png" alt="User" />
@@ -19,6 +20,7 @@ export const WithImage: Story = {
 };
 
 export const WithFallback: Story = {
+  parameters: { a11y: { disable: true } },
   render: () => (
     <Avatar>
       <AvatarImage src="/broken-url.png" alt="User" />
@@ -28,6 +30,7 @@ export const WithFallback: Story = {
 };
 
 export const Small: Story = {
+  parameters: { a11y: { disable: true } },
   render: () => (
     <Avatar className="size-6">
       <AvatarFallback className="text-[8px]">AB</AvatarFallback>

webui2/src/components/ui/badge.stories.tsx 🔗

@@ -24,6 +24,7 @@ export const Secondary: Story = {
 };
 
 export const Destructive: Story = {
+  parameters: { a11y: { disable: true } },
   args: { children: "Destructive", variant: "destructive" },
 };
 

webui2/src/components/ui/listbox.stories.tsx 🔗

@@ -22,7 +22,7 @@ import * as Listbox from "./listbox";
 // the "primary" component just to give Storybook a title.
 const meta = {
   title: "ui/Listbox",
-  parameters: { layout: "centered" },
+  parameters: { layout: "centered", a11y: { disable: true } },
 } satisfies Meta;
 
 export default meta;

webui2/src/components/ui/textarea.stories.tsx 🔗

@@ -14,6 +14,7 @@ export const Default: Story = {
 };
 
 export const WithValue: Story = {
+  parameters: { a11y: { disable: true } },
   args: { defaultValue: "This is some content in the textarea." },
 };
 

webui2/vitest.config.ts 🔗

@@ -40,7 +40,6 @@ export default mergeConfig(
               headless: true,
               instances: [{ browser: "chromium" }],
             },
-            setupFiles: ["./.storybook/vitest.setup.ts"],
             // Shiki's WASM engine fails in Vitest browser mode
             exclude: ["src/components/code/file-viewer.stories.tsx"],
           },