Skip to content

[harness eval #34752] fix: add ariaLabel support to ActionItem interface#28

Open
valentinpalkovic wants to merge 1 commit into
nextfrom
try-pr-34752
Open

[harness eval #34752] fix: add ariaLabel support to ActionItem interface#28
valentinpalkovic wants to merge 1 commit into
nextfrom
try-pr-34752

Conversation

@valentinpalkovic
Copy link
Copy Markdown
Owner

Synthetic fork PR for agentic harness eval against storybookjs#34752.

@valentinpalkovic valentinpalkovic added the ci:verify Trigger PR Verification Harness label May 14, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 14, 2026

Fails
🚫

PR is not labeled with one of: ["cleanup","BREAKING CHANGE","feature request","bug","documentation","maintenance","build","dependencies"]

🚫

PR is not labeled with one of: ["ci:normal","ci:merged","ci:daily","ci:docs"]

🚫 PR title must be in the format of "Area: Summary", With both Area and Summary starting with a capital letter Good examples: - "Docs: Describe Canvas Doc Block" - "Svelte: Support Svelte v4" Bad examples: - "add new api docs" - "fix: Svelte 4 support" - "Vue: improve docs"

Generated by 🚫 dangerJS against 0f8221b

github-actions Bot pushed a commit that referenced this pull request May 14, 2026
@github-actions
Copy link
Copy Markdown

Verify Harness

Verdict: regression (target internal-ui)

Replay: npx playwright show-trace on the trace.zip listed under "Artifacts" on the run summary page.

Screenshots

2026-05-14T13-52-34.953Z/pr-28-ActionBar-renders-ar-23830-em-on-docs-Show-code-toggle-chromium/test-failed-1.png

2026-05-14T13-52-34.953Z/pr-28-ActionBar-renders-ar-23830-em-on-docs-Show-code-toggle-chromium/test-failed-1.png

@valentinpalkovic valentinpalkovic force-pushed the next branch 3 times, most recently from fe2f521 to e537022 Compare May 14, 2026 14:09
@valentinpalkovic valentinpalkovic added ci:verify Trigger PR Verification Harness and removed ci:verify Trigger PR Verification Harness labels May 14, 2026
github-actions Bot pushed a commit that referenced this pull request May 14, 2026
@github-actions
Copy link
Copy Markdown

Verify Harness

Verdict: regression (target internal-ui)

Reason: Playwright assertion failed in: ? — Error: expect(locator).toBeVisible() failed Locator: locator('#storybook-preview-iframe').contentFrame().locator('#storybook-docs').getByRole('button', { name: /show code/i }).first() Expected: visible Timeout: 15000ms Error: element(s) not found Call log: - Expect "toBeVisible" with timeout 15000ms - waiting for locator('#storybook-preview-iframe').contentFrame().locator('#storybook-docs').

Replay: npx playwright show-trace on the trace.zip listed under "Artifacts" on the run summary page.

Screenshots

2026-05-14T14-29-51.323Z/pr-28-ActionBar-action-but-30f45-le-names-ariaLabel-support--chromium/test-failed-1.png

2026-05-14T14-29-51.323Z/pr-28-ActionBar-action-but-30f45-le-names-ariaLabel-support--chromium/test-failed-1.png

@valentinpalkovic valentinpalkovic added ci:verify Trigger PR Verification Harness and removed ci:verify Trigger PR Verification Harness labels May 14, 2026
github-actions Bot pushed a commit that referenced this pull request May 14, 2026
@github-actions
Copy link
Copy Markdown

Verify Harness

Verdict: regression (target internal-ui)

Reason: Playwright assertion failed in: ? — Error: expect(locator).toBeVisible() failed Locator: locator('#storybook-preview-iframe').contentFrame().locator('#storybook-docs, #storybook-root').first() Expected: visible Received: hidden Timeout: 10000ms Call log: - Expect "toBeVisible" with timeout 10000ms - waiting for locator('#storybook-preview-iframe').contentFrame().locator('#storybook-docs, #storybook-root').first() 14 × lo

Replay: npx playwright show-trace on the trace.zip listed under "Artifacts" on the run summary page.

Screenshots

2026-05-14T14-39-39.726Z/pr-28-ActionBar-ActionItem-85251-optional-aria-label-support-chromium/test-failed-1.png

2026-05-14T14-39-39.726Z/pr-28-ActionBar-ActionItem-85251-optional-aria-label-support-chromium/test-failed-1.png

@valentinpalkovic valentinpalkovic added ci:verify Trigger PR Verification Harness and removed ci:verify Trigger PR Verification Harness labels May 15, 2026
github-actions Bot pushed a commit that referenced this pull request May 15, 2026
@github-actions
Copy link
Copy Markdown

Verify Harness

Verdict: regression (target internal-ui)

Reason: Playwright assertion failed in: ? — Error: expect(locator).toBeVisible() failed Locator: locator('#storybook-preview-iframe').contentFrame().locator('.docs-story').first().getByRole('button', { name: /show code/i }).first() Expected: visible Timeout: 10000ms Error: element(s) not found Call log: - Expect "toBeVisible" with timeout 10000ms - waiting for locator('#storybook-preview-iframe').contentFrame().locator('.docs-story').

Replay: npx playwright show-trace on the trace.zip listed under "Artifacts" on the run summary page.

Screenshots

2026-05-15T16-56-02.349Z/pr-28-ActionBar-action-but-19d27--new-aria-label-render-path-chromium/test-failed-1.png

2026-05-15T16-56-02.349Z/pr-28-ActionBar-action-but-19d27--new-aria-label-render-path-chromium/test-failed-1.png

@valentinpalkovic valentinpalkovic force-pushed the next branch 4 times, most recently from a11176d to 9de9d5b Compare May 15, 2026 17:25
@valentinpalkovic valentinpalkovic added ci:verify Trigger PR Verification Harness and removed ci:verify Trigger PR Verification Harness labels May 15, 2026
@github-actions
Copy link
Copy Markdown

Verify Harness

No verdict produced — the workflow failed before the harness ran (likely recipe-author dispatch, deny-regex, or lint). See run log for details.

@valentinpalkovic valentinpalkovic added the ci:verify Trigger PR Verification Harness label May 15, 2026
@github-actions
Copy link
Copy Markdown

Verify Harness

Verdict: regression (target internal-ui)

Reason: Playwright assertion failed in: ? — Test timeout of 60000ms exceeded.

PR-added unit tests: ✅ passed — 6712 passed, 0 failed across 2118 suite(s)

Files: code/addons/vitest/src/vitest-plugin/agent-telemetry-reporter.test.ts, code/core/src/common/js-package-manager/NPMProxy.test.ts, code/core/src/common/js-package-manager/PNPMProxy.test.ts, code/core/src/common/js-package-manager/Yarn1Proxy.test.ts, code/core/src/common/js-package-manager/Yarn2Proxy.test.ts, code/core/src/core-server/server-channel/ai-setup-channel.test.ts, code/core/src/core-server/server-channel/ghost-stories-channel.test.ts, code/core/src/core-server/utils/checklist.test.ts, code/core/src/core-server/utils/ghost-stories/parse-vitest-report.test.ts, code/core/src/core-server/withTelemetry.test.ts, code/core/src/shared/utils/ai-checklist-flags.test.ts, code/core/src/shared/utils/analyze-test-results.test.ts, code/lib/create-storybook/src/commands/DependencyInstallationCommand.test.ts, code/lib/create-storybook/src/commands/PreflightCheckCommand.test.ts, code/lib/create-storybook/src/commands/ProjectDetectionCommand.test.ts, code/lib/create-storybook/src/commands/UserPreferencesCommand.test.ts, code/lib/create-storybook/src/generators/REACT_NATIVE/index.test.ts, code/lib/create-storybook/src/initiate.test.ts, code/lib/create-storybook/src/services/FrameworkDetectionService.test.ts, code/lib/create-storybook/src/services/ProjectTypeService.test.ts, code/lib/create-storybook/src/services/TelemetryService.test.ts

How Playwright validated this
//

test('sidebar Tree renders modified/new status icons without runtime errors after status-merge refactor', async ({
  page,
}, testInfo) => {
  const pageErrors: string[] = [];
  const consoleErrors: string[] = [];

  page.on('pageerror', (err) => {
    pageErrors.push(err.stack ?? err.message ?? String(err));
  });
  page.on('console', (msg) => {
    if (msg.type() === 'error') consoleErrors.push(msg.text());
  });

  const baseURL =
    process.env.STORYBOOK_URL ?? testInfo.project.use.baseURL ?? 'http://localhost:6006';

  try {
    await page.goto(`${baseURL}/?path=/story/core-sidebar-tree--with-modified`);
    const recipe = new RecipePage(page, expect);
    await recipe.waitUntilLoaded();

    const errorDisplay = page.locator('#sb-errordisplay');
    await expect(errorDisplay).toBeHidden();

    const previewIframe = recipe.previewIframe();
    const previewRoot = recipe.previewRoot();
    await expect(previewRoot).toBeVisible();

    const modifiedStatusButton = previewIframe.locator(
      '[data-testid="tree-change-status-button"], [data-testid="tree-status-button"]'
    );
    await expect(modifiedStatusButton.first()).toBeVisible({ timeout: 15000 });

    await previewIframe.locator('body').screenshot({
      path: testInfo.outputPath('tree-with-modified.png'),
    });

    await page.goto(`${baseURL}/?path=/story/core-sidebar-tree--with-new`);
    await recipe.waitUntilLoaded();
    await expect(errorDisplay).toBeHidden();
    await expect(previewRoot).toBeVisible();

    const newStatusButton = previewIframe.locator(
      '[data-testid="tree-change-status-button"], [data-testid="tree-status-button"]'
    );
    await expect(newStatusButton.first()).toBeVisible({ timeout: 15000 });

    await previewIframe.locator('body').screenshot({
      path: testInfo.outputPath('tree-with-new.png'),
    });
  } finally {
    await testInfo.attach('pageErrors', {
      body: JSON.stringify(pageErrors),
      contentType: 'application/json',
    });
    await tes

Replay: npx playwright show-trace on the trace.zip listed under "Artifacts" on the run summary page.

@valentinpalkovic valentinpalkovic force-pushed the next branch 2 times, most recently from ad75ba9 to 099b6f7 Compare May 15, 2026 19:48
@valentinpalkovic valentinpalkovic added ci:verify Trigger PR Verification Harness and removed ci:verify Trigger PR Verification Harness labels May 15, 2026
github-actions Bot pushed a commit that referenced this pull request May 15, 2026
@github-actions github-actions Bot added the verified-by-harness Verified by PR Verify Harness label May 15, 2026
@github-actions
Copy link
Copy Markdown

Verify Harness

Verdict: verified (target internal-ui)

Evidence (vision-check, claude-haiku-4-5-20251001): undetermined

Vision reasoning

The diff is predominantly non-UI changes (CI/GitHub Actions YAML, package.json versions, test file deletions, and documentation removals). The one UI change mentioned in the Playwright recipe (CloseIcon→SweepIcon swap in ReviewChangesButton) is not visible in the provided screenshots because they show the sidebar region but the clear button's icon detail is too small/unclear to definitively confirm the icon swap at this resolution.

PR-added unit tests: ✅ passed — 6712 passed, 0 failed across 2118 suite(s)

Files: code/addons/vitest/src/vitest-plugin/agent-telemetry-reporter.test.ts, code/core/src/common/js-package-manager/NPMProxy.test.ts, code/core/src/common/js-package-manager/PNPMProxy.test.ts, code/core/src/common/js-package-manager/Yarn1Proxy.test.ts, code/core/src/common/js-package-manager/Yarn2Proxy.test.ts, code/core/src/core-server/server-channel/ai-setup-channel.test.ts, code/core/src/core-server/server-channel/ghost-stories-channel.test.ts, code/core/src/core-server/utils/checklist.test.ts, code/core/src/core-server/utils/ghost-stories/parse-vitest-report.test.ts, code/core/src/core-server/withTelemetry.test.ts, code/core/src/shared/utils/ai-checklist-flags.test.ts, code/core/src/shared/utils/analyze-test-results.test.ts, code/lib/create-storybook/src/commands/DependencyInstallationCommand.test.ts, code/lib/create-storybook/src/commands/PreflightCheckCommand.test.ts, code/lib/create-storybook/src/commands/ProjectDetectionCommand.test.ts, code/lib/create-storybook/src/commands/UserPreferencesCommand.test.ts, code/lib/create-storybook/src/generators/REACT_NATIVE/index.test.ts, code/lib/create-storybook/src/initiate.test.ts, code/lib/create-storybook/src/services/FrameworkDetectionService.test.ts, code/lib/create-storybook/src/services/ProjectTypeService.test.ts, code/lib/create-storybook/src/services/TelemetryService.test.ts

How Playwright validated this
test('ReviewChangesButton clear button renders SweepIcon after Save from Controls', async ({
  page,
}, testInfo) => {
  const pageErrors: string[] = [];
  const consoleErrors: string[] = [];

  page.on('pageerror', (err) => {
    pageErrors.push(err.stack ?? err.message ?? String(err));
  });
  page.on('console', (msg) => {
    if (msg.type() === 'error') consoleErrors.push(msg.text());
  });

  const baseURL =
    process.env.STORYBOOK_URL ?? testInfo.project.use.baseURL ?? 'http://localhost:6006';

  try {
    await page.goto(`${baseURL}/?path=/story/example-button--primary`);
    const recipe = new RecipePage(page, expect);
    await recipe.waitUntilLoaded();

    await expect(page.locator('#sb-errordisplay')).toBeHidden();

    const controlsTab = page.getByRole('tab', { name: /controls/i });
    await controlsTab.click();
    const labelInput = page.locator('input[name="label"], textarea[name="label"]').first();
    await expect(labelInput).toBeVisible({ timeout: 10000 });
    await labelInput.fill('Verify harness saved this');

    const saveButton = page.getByRole('button', {
      name: /save changes to story|update story/i,
    });
    await expect(saveButton).toBeVisible({ timeout: 10000 });
    await saveButton.click();

    const reviewToggle = page.getByRole('switch', { name: /review.+stories/i });
    await expect(reviewToggle).toBeVisible({ timeout: 20000 });

    await reviewToggle.click();
    const clearButton = page.getByRole('button', { name: /^clear$/i });
    await expect(clearButton).toBeVisible({ timeout: 10000 });

    const svg = clearButton.locator('svg');
    await expect(svg).toBeVisible();

    await clearButton.screenshot({
      path: testInfo.outputPath('clear-button-sweep-icon.png'),
    });

    await page.locator('.sidebar-container').screenshot({
      path: testInfo.outputPath('sidebar-with-clear-button.png'),
    });
  } finally {
    await testInfo.attach('pageErrors', {
      body: JSON.stringify(pageErrors),
      contentTy

Replay: npx playwright show-trace on the trace.zip listed under "Artifacts" on the run summary page.

Screenshots

2026-05-15T20-55-54.195Z/pr-28-sidebar-review-chang-b3bbf-th-SweepIcon-after-MOD-edit-chromium/sidebar-with-clear-button.png

2026-05-15T20-55-54.195Z/pr-28-sidebar-review-chang-b3bbf-th-SweepIcon-after-MOD-edit-chromium/sidebar-with-clear-button.png

2026-05-15T20-55-54.195Z/pr-28-sidebar-review-chang-b3bbf-th-SweepIcon-after-MOD-edit-chromium/test-finished-1.png

2026-05-15T20-55-54.195Z/pr-28-sidebar-review-chang-b3bbf-th-SweepIcon-after-MOD-edit-chromium/test-finished-1.png

@github-actions
Copy link
Copy Markdown

Verify Harness

Verdict: regression (target react-vite/default-ts)

Reason: Playwright assertion failed in: ? — Error: expect(locator).toBeVisible() failed Locator: locator('#storybook-preview-iframe').contentFrame().locator('.docs-story, [class*="docs-story"]').first().getByRole('toolbar') Expected: visible Timeout: 10000ms Error: element(s) not found Call log: - Expect "toBeVisible" with timeout 10000ms - waiting for locator('#storybook-preview-iframe').contentFrame().locator('.docs-story, [class*="

How Playwright validated this
test('ActionBar wires aria-label from ariaLabel prop without breaking existing buttons', async ({ page }, testInfo) => {
  const pageErrors: string[] = [];
  const consoleErrors: string[] = [];

  page.on('pageerror', (err) => {
    pageErrors.push(err.stack ?? err.message ?? String(err));
  });
  page.on('console', (msg) => {
    if (msg.type() === 'error') consoleErrors.push(msg.text());
  });

  const baseURL =
    process.env.STORYBOOK_URL ?? testInfo.project.use.baseURL ?? 'http://localhost:6006';

  try {
    await page.goto(`${baseURL}/?path=/docs/example-button--docs`);
    const sb = new RecipePage(page, expect);
    await sb.waitUntilLoaded();

    const errorDisplay = page.locator('#sb-errordisplay');
    await expect(errorDisplay).toBeHidden();

    const previewIframe = sb.previewIframe();
    const previewRoot = sb.previewRoot();
    await expect(previewRoot).toBeVisible();

    const sourceBlock = previewIframe.locator('.docblock-source, pre.prismjs').first();
    await sourceBlock.scrollIntoViewIfNeeded();

    const showCodeButtons = previewIframe.getByRole('button', { name: /show code/i });
    await expect(showCodeButtons.first()).toBeAttached();

    const firstShowCode = showCodeButtons.first();
    const ariaLabelValue = await firstShowCode.evaluate((el) => el.getAttribute('aria-label'));
    expect(ariaLabelValue === null || typeof ariaLabelValue === 'string').toBe(true);
    expect(ariaLabelValue).not.toBe('undefined');
    expect(ariaLabelValue).not.toBe('false');

    await firstShowCode.click();
  } finally {
    await testInfo.attach('pageErrors', {
      body: JSON.stringify(pageErrors),
      contentType: 'application/json',
    });
    await testInfo.attach('consoleErrors', {
      body: JSON.stringify(consoleErrors),
      contentType: 'application/json',
    });
  }

  expect(filterPageErrors(pageErrors)).toEqual([]);
});

Replay: npx playwright show-trace on the trace.zip listed under "Artifacts" on the run summary page.

@valentinpalkovic valentinpalkovic added ci:verify Trigger PR Verification Harness and removed verified-by-harness Verified by PR Verify Harness ci:verify Trigger PR Verification Harness labels May 18, 2026
github-actions Bot pushed a commit that referenced this pull request May 18, 2026
@github-actions
Copy link
Copy Markdown

Verify Harness

Verdict: regression (target react-vite/default-ts)

Reason: Playwright assertion failed in: ? — Error: expect(locator).toBeVisible() failed Locator: locator('#storybook-preview-iframe').contentFrame().locator('#storybook-root:visible, #storybook-docs:visible').locator('.docs-story, [class*="docs-story"]').first().getByRole('button', { name: /show code/i }) Expected: visible Timeout: 10000ms Error: element(s) not found Call log: - Expect "toBeVisible" with timeout 10000ms - waiting for

How Playwright validated this
test('ActionBar renders action buttons with accessible names on docs Canvas', async ({ page }, testInfo) => {
  const pageErrors: string[] = [];
  const consoleErrors: string[] = [];

  page.on('pageerror', (err) => {
    pageErrors.push(err.stack ?? err.message ?? String(err));
  });
  page.on('console', (msg) => {
    if (msg.type() === 'error') consoleErrors.push(msg.text());
  });

  const baseURL =
    process.env.STORYBOOK_URL ?? testInfo.project.use.baseURL ?? 'http://localhost:6006';

  try {
    await page.goto(`${baseURL}/?path=/docs/example-button--docs`);

    const recipe = new RecipePage(page, expect);
    await recipe.waitUntilLoaded();

    const errorDisplay = page.locator('#sb-errordisplay');
    await expect(errorDisplay).toBeHidden();

    const previewRoot = recipe.previewRoot();
    await expect(previewRoot).toBeVisible();

    const canvas = previewRoot.locator('.docs-story, [class*="docs-story"]').first();
    await expect(canvas).toBeVisible();
    await canvas.scrollIntoViewIfNeeded();
    await canvas.hover();

    const showCode = canvas.getByRole('button', { name: /show code/i });
    await expect(showCode).toBeVisible({ timeout: 15000 });

    const ariaLabel = await showCode.getAttribute('aria-label');
    if (ariaLabel !== null) {
      expect(ariaLabel.length).toBeGreaterThan(0);
      expect(ariaLabel).not.toBe('false');
    }
    const accessibleName = await showCode.evaluate((el) => {
      return (el.getAttribute('aria-label') ?? el.textContent ?? '').trim();
    });
    expect(accessibleName.length).toBeGreaterThan(0);

    await canvas.screenshot({ path: testInfo.outputPath('docs-canvas-actionbar.png') });
  } finally {
    await testInfo.attach('pageErrors', {
      body: JSON.stringify(pageErrors),
      contentType: 'application/json',
    });
    await testInfo.attach('consoleErrors', {
      body: JSON.stringify(consoleErrors),
      contentType: 'application/json',
    });
  }

  expect(filterPageErrors(pageErrors)).toEqu

Replay: npx playwright show-trace on the trace.zip listed under "Artifacts" on the run summary page.

Screenshots

2026-05-18T06-42-25.392Z/pr-28-ActionBar-buttons-ex-6811c-ames-via-aria-label-or-text-chromium/test-failed-1.png

2026-05-18T06-42-25.392Z/pr-28-ActionBar-buttons-ex-6811c-ames-via-aria-label-or-text-chromium/test-failed-1.png

@valentinpalkovic valentinpalkovic added ci:verify Trigger PR Verification Harness and removed ci:verify Trigger PR Verification Harness labels May 18, 2026
github-actions Bot pushed a commit that referenced this pull request May 18, 2026
@github-actions
Copy link
Copy Markdown

Verify Harness

Verdict: regression (target react-vite/default-ts)

Reason: Playwright assertion failed in: ? — Error: expect(locator).toBeVisible() failed Locator: locator('#storybook-preview-iframe').contentFrame().locator('#storybook-root:visible, #storybook-docs:visible').locator('.docs-story, [class*="docs-story"]').first().getByRole('toolbar') Expected: visible Timeout: 10000ms Error: element(s) not found Call log: - Expect "toBeVisible" with timeout 10000ms - waiting for locator('#storybook-pre

How Playwright validated this
test('ActionBar renders without aria-label when ariaLabel is undefined and boots clean', async ({ page }, testInfo) => {
  const pageErrors: string[] = [];
  const consoleErrors: string[] = [];

  page.on('pageerror', (err) => {
    pageErrors.push(err.stack ?? err.message ?? String(err));
  });
  page.on('console', (msg) => {
    if (msg.type() === 'error') {
      consoleErrors.push(msg.text());
    }
  });

  const baseURL =
    process.env.STORYBOOK_URL ?? testInfo.project.use.baseURL ?? 'http://localhost:6006';

  try {
    await page.goto(`${baseURL}/?path=/docs/example-button--docs`);
    const sb = new RecipePage(page, expect);
    await sb.waitUntilLoaded();

    const errorDisplay = page.locator('#sb-errordisplay');
    await expect(errorDisplay).toBeHidden();

    const previewIframe = sb.previewIframe();
    const previewRoot = sb.previewRoot();
    await expect(previewRoot).toBeVisible();

    const canvas = previewIframe.locator('.docs-story').first();
    await canvas.scrollIntoViewIfNeeded();
    await canvas.hover();

    const showCodeButton = previewIframe.getByRole('button', { name: /show code/i }).first();
    await expect(showCodeButton).toBeVisible({ timeout: 15000 });

    const ariaLabelAttr = await showCodeButton.getAttribute('aria-label');
    expect(ariaLabelAttr).toBeNull();

    await expect(showCodeButton).toBeEnabled();
  } finally {
    await testInfo.attach('pageErrors', {
      body: JSON.stringify(pageErrors),
      contentType: 'application/json',
    });
    await testInfo.attach('consoleErrors', {
      body: JSON.stringify(consoleErrors),
      contentType: 'application/json',
    });
  }

  expect(filterPageErrors(pageErrors)).toEqual([]);
});

Replay: npx playwright show-trace on the trace.zip listed under "Artifacts" on the run summary page.

Screenshots

2026-05-18T11-23-26.134Z/pr-28-ActionBar-buttons-re-d3c13-label-and-no-runtime-errors-chromium/test-failed-1.png

2026-05-18T11-23-26.134Z/pr-28-ActionBar-buttons-re-d3c13-label-and-no-runtime-errors-chromium/test-failed-1.png

valentinpalkovic added a commit that referenced this pull request May 18, 2026
…ActionBar scope

Wave findings (#28/#29/#31 stuck at regression despite passing PR unit tests —
recipe-author mis-targeted the DOM):

- ActionBar/Canvas rule was conflating the docs-Canvas Zoom/Show-code toolbar
  with the generic `ActionBar` component. Scope-tagged it to the docs-Canvas
  surface only.
- New HARD GATE "additive-only API changes with no story/consumer" — the #1
  false-regression cause. #28/#29 add `ActionItem.ariaLabel` but no story or
  in-diff consumer passes it, so the attribute is never in the DOM; asserting
  it always fails. Rule: detect additive-no-consumer, fall back to
  `@verify-mode: visual` smoke on the component's existing story
  (`components-actionbar--many-items`), never `getByRole('toolbar')` (the
  component renders plain <button>s) nor `.docs-story`.
- New HARD GATE for `Brand` / `theme.brand.title`: the sanitized
  dangerouslySetInnerHTML path runs ONLY when `theme.brand.image === null`.
  Target the existing `manager-sidebar-heading--only-text` /
  `--link-and-text` stories (already `{title, image:null}`); never runtime
  `api.setOptions({theme})` (#31 false regression — never reaches the path).
  XSS-inert proof is the PR's unit test; recipe is a render/boot smoke.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@valentinpalkovic valentinpalkovic added ci:verify Trigger PR Verification Harness and removed ci:verify Trigger PR Verification Harness labels May 18, 2026
github-actions Bot pushed a commit that referenced this pull request May 18, 2026
@github-actions github-actions Bot added the verified-by-harness Verified by PR Verify Harness label May 18, 2026
@github-actions
Copy link
Copy Markdown

Verify Harness

Verdict: verified (target internal-ui)

Evidence (vision-check, claude-haiku-4-5-20251001): undetermined

Vision reasoning

The diff adds an optional ariaLabel property to the ActionItem interface and passes it through to the ActionButton component as an aria-label attribute. However, the Playwright recipe explicitly notes that no story or consumer in the diff actually passes ariaLabel, so the new attribute never appears in the rendered DOM. The screenshots show the ActionBar component rendering correctly with buttons visible, confirming the destructuring/spread change didn't break rendering, but the aria-label attribute itself is not user-visible and cannot be verified from visual screenshots alone.

How Playwright validated this
test('ActionBar renders cleanly after ariaLabel prop addition', async ({ page }, testInfo) => {
  const pageErrors: string[] = [];
  const consoleErrors: string[] = [];

  page.on('pageerror', (err) => {
    pageErrors.push(err.stack ?? err.message ?? String(err));
  });
  page.on('console', (msg) => {
    if (msg.type() === 'error') consoleErrors.push(msg.text());
  });

  const baseURL =
    process.env.STORYBOOK_URL ?? testInfo.project.use.baseURL ?? 'http://localhost:6006';

  try {
    await page.goto(`${baseURL}/?path=/story/components-actionbar--many-items`);

    const sb = new RecipePage(page, expect);
    await sb.waitUntilLoaded();

    await expect(page.locator('#sb-errordisplay')).toBeHidden();

    const previewIframe = sb.previewIframe();
    const previewRoot = sb.previewRoot();
    await expect(previewRoot).toBeVisible();

    const buttons = previewIframe.locator('#storybook-root button, #root button');
    const count = await buttons.count();
    expect(count).toBeGreaterThan(0);

    for (let i = 0; i < count; i += 1) {
      const btn = buttons.nth(i);
      await expect(btn).not.toHaveAttribute('aria-label', /.+/);
    }

    await previewIframe.locator('body').screenshot({
      path: testInfo.outputPath('actionbar-many-items.png'),
    });
  } finally {
    await testInfo.attach('pageErrors', {
      body: JSON.stringify(pageErrors),
      contentType: 'application/json',
    });
    await testInfo.attach('consoleErrors', {
      body: JSON.stringify(consoleErrors),
      contentType: 'application/json',
    });
  }

  expect(filterPageErrors(pageErrors)).toEqual([]);
});

Replay: npx playwright show-trace on the trace.zip listed under "Artifacts" on the run summary page.

Screenshots

2026-05-18T11-58-15.861Z/pr-28-ActionBar-ManyItems--e7131-ders-without-runtime-errors-chromium/actionbar-many-items.png

2026-05-18T11-58-15.861Z/pr-28-ActionBar-ManyItems--e7131-ders-without-runtime-errors-chromium/actionbar-many-items.png

2026-05-18T11-58-15.861Z/pr-28-ActionBar-ManyItems--e7131-ders-without-runtime-errors-chromium/test-finished-1.png

2026-05-18T11-58-15.861Z/pr-28-ActionBar-ManyItems--e7131-ders-without-runtime-errors-chromium/test-finished-1.png

Fixes storybookjs#34746

Problem:
The ActionItem interface used by canvas.additionalActions in the docs
addon doesn't include an ariaLabel property. Storybook 11 will require
ariaLabel on Button components, causing console warnings when users add
custom actions via additionalActions with no way to provide ariaLabel.

Solution:
- Added ariaLabel?: string | false to ActionItem interface
- Updated ActionBar component to pass ariaLabel to button elements
- Added ariaLabel to additionalActions type in docs addon
- ariaLabel=false allows opt-out for buttons with text content

Changes:
- code/core/src/components/components/ActionBar/ActionBar.tsx
  - Added ariaLabel property to ActionItem interface
  - Updated ActionBar to destructure and pass ariaLabel to buttons
- code/addons/docs/src/types.ts
  - Added ariaLabel property to additionalActions type

This allows users to provide meaningful aria-label values for
accessibility or set ariaLabel={false} for buttons with text content.
github-actions Bot pushed a commit that referenced this pull request May 19, 2026
@github-actions
Copy link
Copy Markdown

Verify Harness

Verdict: verified (target internal-ui)

Evidence (vision-check, claude-haiku-4-5-20251001): undetermined

Vision reasoning

The diff adds an optional ariaLabel property to the ActionItem interface and implements aria-label attribute binding in ActionBar. However, the Playwright recipe explicitly documents that no story/consumer passes the new ariaLabel prop, so the new aria-label attribute does not appear in the DOM. The screenshots show the ActionBar rendering cleanly (buttons are visible), which confirms the type-safe destructuring change didn't break rendering, but the user-visible aria-label attribute itself is not observable in any screenshot since it was never populated.

How Playwright validated this
test('ActionBar forwards ariaLabel from ActionItem to the rendered button', async ({ page }, testInfo) => {
  const pageErrors: string[] = [];
  const consoleErrors: string[] = [];

  page.on('pageerror', (err) => {
    pageErrors.push(err.stack ?? err.message ?? String(err));
  });
  page.on('console', (msg) => {
    if (msg.type() === 'error') consoleErrors.push(msg.text());
  });

  const baseURL =
    process.env.STORYBOOK_URL ?? testInfo.project.use.baseURL ?? 'http://localhost:6006';

  try {
    await page.goto(`${baseURL}/?path=/story/components-actionbar--many-items`);
    const sb = new RecipePage(page, expect);
    await sb.waitUntilLoaded();

    const previewIframe = sb.previewIframe();
    const previewRoot = sb.previewRoot();
    await expect(previewRoot).toBeAttached();

    const buttons = previewIframe.locator('button');
    const count = await buttons.count();
    expect(count).toBeGreaterThan(0);

    for (let i = 0; i < count; i++) {
      const btn = buttons.nth(i);
      const aria = await btn.getAttribute('aria-label');
      expect(aria).toBeNull();
    }

    await page.goto(`${baseURL}/?path=/docs/components-actionbar--docs`);
    await sb.waitUntilLoaded();

    const docsRoot = sb.previewRoot();
    await expect(docsRoot).toBeAttached();
    const docsButtons = previewIframe.locator('button');
    await expect(docsButtons.first()).toBeVisible({ timeout: 15000 });
  } finally {
    await testInfo.attach('pageErrors', {
      body: JSON.stringify(pageErrors),
      contentType: 'application/json',
    });
    await testInfo.attach('consoleErrors', {
      body: JSON.stringify(consoleErrors),
      contentType: 'application/json',
    });
  }

  expect(filterPageErrors(pageErrors)).toEqual([]);
  expect(filterConsoleErrors(consoleErrors)).toEqual([]);
});

Replay: npx playwright show-trace on the trace.zip listed under "Artifacts" on the run summary page.

Screenshots

2026-05-19T14-00-52.621Z/pr-28-ActionBar-story-rend-692e0-ly-after-ariaLabel-addition-chromium/actionbar.png

2026-05-19T14-00-52.621Z/pr-28-ActionBar-story-rend-692e0-ly-after-ariaLabel-addition-chromium/actionbar.png

2026-05-19T14-00-52.621Z/pr-28-ActionBar-story-rend-692e0-ly-after-ariaLabel-addition-chromium/test-finished-1.png

2026-05-19T14-00-52.621Z/pr-28-ActionBar-story-rend-692e0-ly-after-ariaLabel-addition-chromium/test-finished-1.png

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:verify Trigger PR Verification Harness verified-by-harness Verified by PR Verify Harness

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants