fix(a11y): add accessible names to icon-only buttons, fix placeholder - #13666
Conversation
… contrast, and enforce touch target size on /flows
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
WalkthroughAdds ChangesAccessibility improvements across UI components
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Suggested labels
Suggested reviewers
Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (1 error, 3 warnings, 1 inconclusive)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
✅ Test Coverage AdvisorNo source changes detected without accompanying tests. Thanks for keeping coverage up! 🎉
|
There was a problem hiding this comment.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/frontend/src/locales/zh-Hans.json (1)
899-903:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winMissing
header.homelocale key breaks localized accessible name
AppHeadernow readst("header.home")(Line 67 insrc/frontend/src/components/core/appHeaderComponent/index.tsx), but this locale block has noheader.homekey near the other header keys. In zh-Hans, that makes the home button’s aria-label fallback instead of being translated.Suggested patch
"header.goToDiscord": "前往 Discord 服务器", "header.goToGithub": "访问 GitHub 代码库", + "header.home": "返回首页", "header.notifications": "通知和错误", "header.notificationsLabel": "通知",🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/frontend/src/locales/zh-Hans.json` around lines 899 - 903, The zh-Hans.json locale file is missing the header.home key that AppHeader component tries to reference with t("header.home"). Add the missing header.home key to the locale block alongside the other header keys (header.goToDiscord, header.goToGithub, header.notifications, header.notificationsLabel) with an appropriate Chinese translation for the home button's accessible name label.
🧹 Nitpick comments (2)
src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/__tests__/add-folder-button.test.tsx (1)
20-37: ⚡ Quick winReduce primitive UI mocking for this accessibility assertion.
Mocking
@/components/ui/buttonhere can mask real prop-forwarding issues; keep the real button and mock only non-essential dependencies so the aria-label test validates real behavior.As per coding guidelines: "Warn when mocks are used instead of testing real behavior and interactions, and suggest using real objects or test doubles when mocks become excessive."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/__tests__/add-folder-button.test.tsx` around lines 20 - 37, Remove the jest.mock for "`@/components/ui/button`" to use the real Button component instead, since mocking a primitive UI component masks real prop-forwarding issues and prevents validating actual aria-label behavior. Keep only mocks for non-essential dependencies that are not part of the accessibility assertion being tested, so the aria-label test can validate real behavior against the actual Button component.Source: Coding guidelines
src/frontend/src/pages/MainPage/components/header/__tests__/header.test.tsx (1)
236-249: ⚡ Quick winAvoid English-substring filtering for aria-label verification.
Filtering by
"view" | "list" | "grid"makes this test locale-coupled and less reliable for i18n-backed labels. Prefer stable selectors (role + known button identity/testid) and then assertaria-labelis present/non-empty on those exact controls.Refactor direction
- const labelled = container.querySelectorAll("button[aria-label]"); - const viewBtns = Array.from(labelled).filter((b) => { - const label = b.getAttribute("aria-label") ?? ""; - return ( - label.toLowerCase().includes("view") || - label.toLowerCase().includes("list") || - label.toLowerCase().includes("grid") - ); - }); - expect(viewBtns.length).toBeGreaterThanOrEqual(2); + const pressedButtons = container.querySelectorAll("button[aria-pressed]"); + expect(pressedButtons.length).toBe(2); + pressedButtons.forEach((btn) => { + expect(btn).toHaveAttribute("aria-label"); + expect(btn.getAttribute("aria-label")?.trim().length).toBeGreaterThan(0); + });As per coding guidelines, “Tests should cover the main functionality being implemented” and should remain clear about what is being validated rather than relying on brittle heuristics.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/frontend/src/pages/MainPage/components/header/__tests__/header.test.tsx` around lines 236 - 249, The test in the "view toggle buttons have aria-label attributes" test case is using English substring matching to filter buttons, which couples the test to a specific locale and makes it brittle for internationalization. Replace the current filtering logic that checks for "view", "list", and "grid" substrings in aria-label with a more stable approach: use role-based selectors (such as role="button" combined with a specific testid or data-testid attribute on the view toggle controls) to reliably identify the two view toggle buttons regardless of locale, and then assert that each of those identified buttons has a non-empty aria-label attribute. This ensures the test validates that the controls are properly labeled without depending on English text content.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@src/frontend/src/components/common/paginatorComponent/__tests__/PaginatorComponent.test.tsx`:
- Around line 43-47: The SelectTrigger mock in the test file does not properly
forward all props to the underlying div element, which reduces test fidelity.
Instead of only explicitly handling the aria-label prop, use the spread operator
to forward all rest props to the div element (for example, replace
aria-label={rest["aria-label"]} with {...rest}). This change should be applied
at the anchor location in
src/frontend/src/components/common/paginatorComponent/__tests__/PaginatorComponent.test.tsx
at lines 43-47 in the SelectTrigger mock, and at the sibling location at lines
70-76 where the same mock pattern appears, to ensure consistent prop forwarding
behavior across all mocks.
In
`@src/frontend/src/components/core/appHeaderComponent/__tests__/app-header-a11y.test.tsx`:
- Around line 5-91: This test file (app-header-a11y.test.tsx) is over-mocked and
diverges from the frontend Playwright testing pattern. The excessive mocking of
internal UI components (Button, Separator, genericIconComponent, etc.), hooks,
and stores means the test verifies mocked wiring rather than real accessibility
behavior. To fix this: convert the test from Jest/RTL to Playwright following
the frontend testing conventions, minimize mocks to only external boundaries
(API calls, third-party libraries), and rewrite the test to assert on actual
accessible names and ARIA attributes rendered in the real AppHeader UI rather
than testing mocked component interactions. This will ensure the test validates
genuine accessibility behavior as intended.
In
`@src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/__tests__/upload-folder-button.test.tsx`:
- Around line 4-26: Remove the jest.mock calls for the internal UI components
Button, shadTooltipComponent, and genericIconComponent in the test setup. These
mocks are obscuring actual component behavior and should not be mocked according
to testing guidelines. Keep the mock for react-i18next since it is an external
dependency. Either allow the real components to render naturally (by removing
their mock definitions) or replace the mocks with minimal test doubles that
preserve the expected behavior without hiding implementation details. This will
ensure the test verifies real interaction behavior with the actual UI
components.
In `@src/frontend/src/locales/fr.json`:
- Line 70: The French locale file (fr.json) is missing translations for several
accessibility keys that were added for the flows feature, causing French users
to fall back to the default locale. Add French translations for the following
missing keys: header.home, flows.viewList, flows.viewGrid,
flows.downloadSelected, flows.selectFlow, flows.moreOptions, folder.optionsFor,
and paginator.pageLabel to the fr.json file. Each key should have an appropriate
French translation that matches the context and purpose of the original
accessibility label.
- Around line 1558-1559: In the French translation file, fix two issues with the
playground labels. First, correct the broken Trans markup in the
playground.noInputHint string where the XML tags are malformed around "Chat » (
Input" — ensure the opening and closing tags are properly balanced and correctly
delimit the translatable text. Second, replace the noun "Déroulement" in
playground.runFlow with an appropriate action verb that conveys the command to
execute or run the flow, as the current value reads as a descriptive noun rather
than an action label.
In `@src/frontend/src/locales/ja.json`:
- Line 70: The PR introduces new accessibility/i18n contract requirements for
the `/flows` feature, but the corresponding translation keys are missing from
the locale files. Add the following eight missing keys to both
`src/frontend/src/locales/ja.json` (line 70-70) and
`src/frontend/src/locales/pt.json` (line 70-70): `header.home`,
`flows.viewList`, `flows.viewGrid`, `flows.downloadSelected`,
`flows.selectFlow`, `flows.moreOptions`, `folder.optionsFor`, and
`paginator.pageLabel`. Use English text as placeholder values in both files, as
translations can be added later. Ensure the keys are added at the correct
location in the JSON structure where other localization entries are defined,
maintaining consistent formatting with existing entries.
In `@src/frontend/src/pages/MainPage/components/header/__tests__/header.test.tsx`:
- Around line 266-279: The test "exactly one view toggle is aria-pressed=true
and one is false" has assertions that do not match its name. Currently, the
expectations on trueCount and falseCount use toBeGreaterThanOrEqual(1), which
allows for multiple buttons with the same aria-pressed value to pass. Change
both expect(trueCount).toBeGreaterThanOrEqual(1) and
expect(falseCount).toBeGreaterThanOrEqual(1) to use toBe(1) instead to enforce
exactly one button with aria-pressed="true" and exactly one with
aria-pressed="false".
---
Outside diff comments:
In `@src/frontend/src/locales/zh-Hans.json`:
- Around line 899-903: The zh-Hans.json locale file is missing the header.home
key that AppHeader component tries to reference with t("header.home"). Add the
missing header.home key to the locale block alongside the other header keys
(header.goToDiscord, header.goToGithub, header.notifications,
header.notificationsLabel) with an appropriate Chinese translation for the home
button's accessible name label.
---
Nitpick comments:
In
`@src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/__tests__/add-folder-button.test.tsx`:
- Around line 20-37: Remove the jest.mock for "`@/components/ui/button`" to use
the real Button component instead, since mocking a primitive UI component masks
real prop-forwarding issues and prevents validating actual aria-label behavior.
Keep only mocks for non-essential dependencies that are not part of the
accessibility assertion being tested, so the aria-label test can validate real
behavior against the actual Button component.
In `@src/frontend/src/pages/MainPage/components/header/__tests__/header.test.tsx`:
- Around line 236-249: The test in the "view toggle buttons have aria-label
attributes" test case is using English substring matching to filter buttons,
which couples the test to a specific locale and makes it brittle for
internationalization. Replace the current filtering logic that checks for
"view", "list", and "grid" substrings in aria-label with a more stable approach:
use role-based selectors (such as role="button" combined with a specific testid
or data-testid attribute on the view toggle controls) to reliably identify the
two view toggle buttons regardless of locale, and then assert that each of those
identified buttons has a non-empty aria-label attribute. This ensures the test
validates that the controls are properly labeled without depending on English
text content.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: b3604eee-78df-4bf9-95fb-940ac3a3c173
📒 Files selected for processing (20)
src/frontend/src/components/common/paginatorComponent/__tests__/PaginatorComponent.test.tsxsrc/frontend/src/components/common/paginatorComponent/index.tsxsrc/frontend/src/components/core/appHeaderComponent/__tests__/app-header-a11y.test.tsxsrc/frontend/src/components/core/appHeaderComponent/index.tsxsrc/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/__tests__/add-folder-button.test.tsxsrc/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/__tests__/upload-folder-button.test.tsxsrc/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/add-folder-button.tsxsrc/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/select-options.tsxsrc/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/upload-folder-button.tsxsrc/frontend/src/locales/de.jsonsrc/frontend/src/locales/en.jsonsrc/frontend/src/locales/es.jsonsrc/frontend/src/locales/fr.jsonsrc/frontend/src/locales/ja.jsonsrc/frontend/src/locales/pt.jsonsrc/frontend/src/locales/zh-Hans.jsonsrc/frontend/src/pages/MainPage/components/header/__tests__/header.test.tsxsrc/frontend/src/pages/MainPage/components/header/index.tsxsrc/frontend/src/pages/MainPage/components/list/index.tsxsrc/frontend/src/style/index.css
| SelectTrigger: ({ children, ...rest }: any) => ( | ||
| <div data-testid="page-select-trigger" aria-label={rest["aria-label"]}> | ||
| {children} | ||
| </div> | ||
| ), |
There was a problem hiding this comment.
Use a semantic trigger mock that forwards props.
Suggested test-fidelity fix
- SelectTrigger: ({ children, ...rest }: any) => (
- <div data-testid="page-select-trigger" aria-label={rest["aria-label"]}>
- {children}
- </div>
- ),
+ SelectTrigger: ({ children, ...rest }: any) => (
+ <button type="button" data-testid="page-select-trigger" {...rest}>
+ {children}
+ </button>
+ ),As per coding guidelines: "Ensure mocks are used appropriately for external dependencies, not core logic" and "Warn when mocks are used instead of testing real behavior and interactions."
Also applies to: 70-76
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@src/frontend/src/components/common/paginatorComponent/__tests__/PaginatorComponent.test.tsx`
around lines 43 - 47, The SelectTrigger mock in the test file does not properly
forward all props to the underlying div element, which reduces test fidelity.
Instead of only explicitly handling the aria-label prop, use the spread operator
to forward all rest props to the div element (for example, replace
aria-label={rest["aria-label"]} with {...rest}). This change should be applied
at the anchor location in
src/frontend/src/components/common/paginatorComponent/__tests__/PaginatorComponent.test.tsx
at lines 43-47 in the SelectTrigger mock, and at the sibling location at lines
70-76 where the same mock pattern appears, to ensure consistent prop forwarding
behavior across all mocks.
Source: Coding guidelines
| jest.mock("react-i18next", () => ({ | ||
| useTranslation: () => ({ t: (key: string) => key }), | ||
| })); | ||
|
|
||
| jest.mock("@/components/common/genericIconComponent", () => ({ | ||
| __esModule: true, | ||
| default: ({ name }: { name: string }) => ( | ||
| <span data-testid={`icon-${name}`}>{name}</span> | ||
| ), | ||
| })); | ||
|
|
||
| jest.mock("@/components/ui/button", () => ({ | ||
| Button: ({ | ||
| children, | ||
| "aria-label": ariaLabel, | ||
| "data-testid": testId, | ||
| unstyled, | ||
| ...props | ||
| }: any) => ( | ||
| <button aria-label={ariaLabel} data-testid={testId} {...props}> | ||
| {children} | ||
| </button> | ||
| ), | ||
| })); | ||
|
|
||
| jest.mock("@/components/ui/separator", () => ({ | ||
| Separator: () => <hr />, | ||
| })); | ||
|
|
||
| jest.mock("@/components/common/shadTooltipComponent", () => ({ | ||
| __esModule: true, | ||
| default: ({ children }: any) => <>{children}</>, | ||
| })); | ||
|
|
||
| jest.mock("@/components/common/modelProviderCountComponent", () => ({ | ||
| __esModule: true, | ||
| default: () => null, | ||
| })); | ||
|
|
||
| jest.mock("@/alerts/alertDropDown", () => ({ | ||
| __esModule: true, | ||
| default: ({ children }: any) => <>{children}</>, | ||
| })); | ||
|
|
||
| jest.mock("@/assets/LangflowLogo.svg?react", () => ({ | ||
| __esModule: true, | ||
| default: () => <svg data-testid="langflow-logo" />, | ||
| })); | ||
|
|
||
| jest.mock("@/customization/components/custom-AccountMenu", () => ({ | ||
| __esModule: true, | ||
| default: () => null, | ||
| })); | ||
|
|
||
| jest.mock("@/customization/components/custom-langflow-counts", () => ({ | ||
| __esModule: true, | ||
| default: () => null, | ||
| })); | ||
|
|
||
| jest.mock("@/customization/components/custom-org-selector", () => ({ | ||
| CustomOrgSelector: () => null, | ||
| })); | ||
|
|
||
| jest.mock("@/customization/hooks/use-custom-navigate", () => ({ | ||
| useCustomNavigate: () => jest.fn(), | ||
| })); | ||
|
|
||
| jest.mock("@/customization/hooks/use-custom-theme", () => ({ | ||
| __esModule: true, | ||
| default: () => ({ dark: false }), | ||
| })); | ||
|
|
||
| jest.mock("@/stores/alertStore", () => ({ | ||
| __esModule: true, | ||
| default: () => ({ | ||
| notificationCenter: false, | ||
| setNotificationCenter: jest.fn(), | ||
| }), | ||
| })); | ||
|
|
||
| jest.mock("./components/FlowMenu", () => ({ FlowMenu: () => null }), { | ||
| virtual: true, | ||
| }); | ||
| jest.mock("../components/FlowMenu", () => ({ | ||
| __esModule: true, | ||
| default: () => null, | ||
| })); |
There was a problem hiding this comment.
Test is over-mocked and diverges from the frontend testing pattern
This suite mocks most of AppHeader’s runtime surface (UI primitives, dropdowns, hooks/store), so it mostly verifies mocked wiring rather than real accessibility behavior. It also uses Jest/RTL instead of the frontend Playwright pattern.
Please keep unit mocking minimal (external boundaries only) and add/port coverage to a Playwright test that asserts accessible names on the rendered UI.
As per coding guidelines, “Frontend test files should follow the naming convention *.test.ts or *.test.tsx using Playwright” and “Warn when mocks are used instead of testing real behavior and interactions … Recommend integration tests when unit tests become overly mocked.”
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@src/frontend/src/components/core/appHeaderComponent/__tests__/app-header-a11y.test.tsx`
around lines 5 - 91, This test file (app-header-a11y.test.tsx) is over-mocked
and diverges from the frontend Playwright testing pattern. The excessive mocking
of internal UI components (Button, Separator, genericIconComponent, etc.),
hooks, and stores means the test verifies mocked wiring rather than real
accessibility behavior. To fix this: convert the test from Jest/RTL to
Playwright following the frontend testing conventions, minimize mocks to only
external boundaries (API calls, third-party libraries), and rewrite the test to
assert on actual accessible names and ARIA attributes rendered in the real
AppHeader UI rather than testing mocked component interactions. This will ensure
the test validates genuine accessibility behavior as intended.
Source: Coding guidelines
| jest.mock("react-i18next", () => ({ | ||
| useTranslation: () => ({ t: (key: string) => key }), | ||
| })); | ||
|
|
||
| jest.mock("@/components/common/genericIconComponent", () => ({ | ||
| __esModule: true, | ||
| default: ({ name }: { name: string }) => ( | ||
| <span data-testid={`icon-${name}`}>{name}</span> | ||
| ), | ||
| })); | ||
|
|
||
| jest.mock("@/components/common/shadTooltipComponent", () => ({ | ||
| __esModule: true, | ||
| default: ({ children }: { children: React.ReactNode }) => <>{children}</>, | ||
| })); | ||
|
|
||
| jest.mock("@/components/ui/button", () => ({ | ||
| Button: ({ children, "aria-label": ariaLabel, disabled, ...props }: any) => ( | ||
| <button aria-label={ariaLabel} disabled={disabled} {...props}> | ||
| {children} | ||
| </button> | ||
| ), | ||
| })); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify frontend test framework usage and mock density (read-only).
# Expected: if guideline is enforced, frontend *.test.ts/tsx should primarily use Playwright APIs.
echo "== Frontend test files =="
fd -e ts -e tsx '.test$' src/frontend/src
echo
echo "== Files importing Jest/RTL in frontend tests =="
rg -n --type=ts --type=tsx '(`@testing-library/react`|jest\.mock|describe\(|it\()' src/frontend/src --iglob '**/*.test.ts' --iglob '**/*.test.tsx'
echo
echo "== Files importing Playwright in frontend tests =="
rg -n --type=ts --type=tsx '(`@playwright/test`|test\(|expect\()' src/frontend/src --iglob '**/*.test.ts' --iglob '**/*.test.tsx'Repository: langflow-ai/langflow
Length of output: 266
🏁 Script executed:
#!/bin/bash
# Find all test files in frontend with correct syntax
echo "== All test files in frontend =="
find src/frontend -name "*.test.ts" -o -name "*.test.tsx" 2>/dev/null | head -20
echo
echo "== Check specific file existence =="
ls -la "src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/__tests__/upload-folder-button.test.tsx" 2>&1
echo
echo "== Checking package.json for testing framework dependencies =="
cat package.json | grep -A 10 -B 2 '"jest"\|"playwright"\|"vitest"' 2>/dev/null || echo "Not found in top-level search"Repository: langflow-ai/langflow
Length of output: 2229
🏁 Script executed:
#!/bin/bash
# Search for test framework usage without type flags
echo "== Jest usage in frontend tests =="
grep -r "jest.mock\|describe(\|it(" src/frontend --include="*.test.ts*" 2>/dev/null | head -5
echo
echo "== Playwright usage in frontend tests =="
grep -r "`@playwright/test`\|test(" src/frontend --include="*.test.ts*" 2>/dev/null | head -5
echo
echo "== Looking for jest/vitest in package.json =="
grep -i "jest\|vitest\|playwright" package*.json 2>/dev/null | head -20Repository: langflow-ai/langflow
Length of output: 1565
🏁 Script executed:
#!/bin/bash
# Read package.json to check testing framework dependencies
echo "== Frontend package.json test dependencies =="
cat src/frontend/package.json | grep -A 30 '"devDependencies"' | head -40Repository: langflow-ai/langflow
Length of output: 1197
🏁 Script executed:
#!/bin/bash
# Read the specific test file to assess mock usage
echo "== Content of upload-folder-button.test.tsx =="
cat src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/__tests__/upload-folder-button.test.tsxRepository: langflow-ai/langflow
Length of output: 1655
Reduce internal component mocks to test real interaction behavior.
The test mocks internal UI components (Button, shadTooltipComponent, genericIconComponent) that should be rendered for real to verify actual behavior. Per coding guidelines, mocks should be limited to external dependencies (like react-i18next); mocking core UI logic obscures what's actually being tested. Consider importing and rendering the real components, or replacing mocks with minimal test doubles that preserve behavior.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/__tests__/upload-folder-button.test.tsx`
around lines 4 - 26, Remove the jest.mock calls for the internal UI components
Button, shadTooltipComponent, and genericIconComponent in the test setup. These
mocks are obscuring actual component behavior and should not be mocked according
to testing guidelines. Keep the mock for react-i18next since it is an external
dependency. Either allow the real components to render naturally (by removing
their mock definitions) or replace the mocks with minimal test doubles that
preserve the expected behavior without hiding implementation details. This will
ensure the test verifies real interaction behavior with the actual UI
components.
Source: Coding guidelines
| "assistant.loading": "Chargement en cours...", | ||
| "assistant.maxSessionsLabel": "Nbre max. de sessions", | ||
| "assistant.maxSessionsTooltip": "Le nombre maximal de sessions d' {{max}} s a été atteint. Supprimez une session pour en créer une nouvelle.", | ||
| "assistant.mentionNoMatches": "Aucun composant correspondant sur le canevas", |
There was a problem hiding this comment.
Mirror the new /flows accessibility keys in French.
This locale still omits header.home, flows.viewList/viewGrid/downloadSelected/selectFlow/moreOptions, folder.optionsFor, and paginator.pageLabel, so French users will fall back to the default locale for the new aria labels.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/frontend/src/locales/fr.json` at line 70, The French locale file
(fr.json) is missing translations for several accessibility keys that were added
for the flows feature, causing French users to fall back to the default locale.
Add French translations for the following missing keys: header.home,
flows.viewList, flows.viewGrid, flows.downloadSelected, flows.selectFlow,
flows.moreOptions, folder.optionsFor, and paginator.pageLabel to the fr.json
file. Each key should have an appropriate French translation that matches the
context and purpose of the original accessibility label.
| "playground.noInputHint": "Ajoutez un composant « <1>Chat » ( Input</1> ) à votre flux pour envoyer des messages.", | ||
| "playground.runFlow": "Déroulement", |
There was a problem hiding this comment.
Fix the French playground labels.
playground.noInputHint has broken Trans markup, and playground.runFlow reads as a noun (Déroulement) instead of the action label the UI needs.
💡 Suggested copy
- "playground.noInputHint": "Ajoutez un composant « <1>Chat » ( Input</1> ) à votre flux pour envoyer des messages.",
- "playground.runFlow": "Déroulement",
+ "playground.noInputHint": "Ajoutez un composant « <1>Chat Input</1> » à votre flux pour envoyer des messages.",
+ "playground.runFlow": "Exécuter le flux",📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "playground.noInputHint": "Ajoutez un composant « <1>Chat » ( Input</1> ) à votre flux pour envoyer des messages.", | |
| "playground.runFlow": "Déroulement", | |
| "playground.noInputHint": "Ajoutez un composant « <1>Chat Input</1> » à votre flux pour envoyer des messages.", | |
| "playground.runFlow": "Exécuter le flux", |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/frontend/src/locales/fr.json` around lines 1558 - 1559, In the French
translation file, fix two issues with the playground labels. First, correct the
broken Trans markup in the playground.noInputHint string where the XML tags are
malformed around "Chat » ( Input" — ensure the opening and closing tags are
properly balanced and correctly delimit the translatable text. Second, replace
the noun "Déroulement" in playground.runFlow with an appropriate action verb
that conveys the command to execute or run the flow, as the current value reads
as a descriptive noun rather than an action label.
| "assistant.loading": "ロード中...", | ||
| "assistant.maxSessionsLabel": "セッションの最大数", | ||
| "assistant.maxSessionsTooltip": "{{max}} セッションの上限に達しました。 セッションを削除して、新しいセッションを作成します。", | ||
| "assistant.mentionNoMatches": "キャンバス上に一致するコンポーネントがありません", |
There was a problem hiding this comment.
Missing required accessibility i18n keys for the new /flows aria-label wiring.
Both locale files are missing the key set introduced by this PR’s accessibility/i18n contract, so translated labels for the updated controls will not resolve in these locales.
src/frontend/src/locales/ja.json#L70-L70: addheader.home,flows.viewList,flows.viewGrid,flows.downloadSelected,flows.selectFlow,flows.moreOptions,folder.optionsFor, andpaginator.pageLabel(use English placeholders if translation is pending, per PR objective).src/frontend/src/locales/pt.json#L70-L70: addheader.home,flows.viewList,flows.viewGrid,flows.downloadSelected,flows.selectFlow,flows.moreOptions,folder.optionsFor, andpaginator.pageLabel(use English placeholders if translation is pending, per PR objective).
📍 Affects 2 files
src/frontend/src/locales/ja.json#L70-L70(this comment)src/frontend/src/locales/pt.json#L70-L70
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/frontend/src/locales/ja.json` at line 70, The PR introduces new
accessibility/i18n contract requirements for the `/flows` feature, but the
corresponding translation keys are missing from the locale files. Add the
following eight missing keys to both `src/frontend/src/locales/ja.json` (line
70-70) and `src/frontend/src/locales/pt.json` (line 70-70): `header.home`,
`flows.viewList`, `flows.viewGrid`, `flows.downloadSelected`,
`flows.selectFlow`, `flows.moreOptions`, `folder.optionsFor`, and
`paginator.pageLabel`. Use English text as placeholder values in both files, as
translations can be added later. Ensure the keys are added at the correct
location in the JSON structure where other localization entries are defined,
maintaining consistent formatting with existing entries.
| it("exactly one view toggle is aria-pressed=true and one is false", () => { | ||
| const { container } = render( | ||
| <HeaderComponent {...defaultProps} view="grid" />, | ||
| ); | ||
| const allPressed = container.querySelectorAll("button[aria-pressed]"); | ||
| const trueCount = Array.from(allPressed).filter( | ||
| (b) => b.getAttribute("aria-pressed") === "true", | ||
| ).length; | ||
| const falseCount = Array.from(allPressed).filter( | ||
| (b) => b.getAttribute("aria-pressed") === "false", | ||
| ).length; | ||
| expect(trueCount).toBeGreaterThanOrEqual(1); | ||
| expect(falseCount).toBeGreaterThanOrEqual(1); | ||
| }); |
There was a problem hiding this comment.
exactly one assertion currently does not enforce “exactly one”.
This test name promises strict cardinality, but toBeGreaterThanOrEqual(1) allows multiple aria-pressed="true" or multiple "false" buttons to pass.
Proposed fix
- expect(trueCount).toBeGreaterThanOrEqual(1);
- expect(falseCount).toBeGreaterThanOrEqual(1);
+ expect(trueCount).toBe(1);
+ expect(falseCount).toBe(1);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/frontend/src/pages/MainPage/components/header/__tests__/header.test.tsx`
around lines 266 - 279, The test "exactly one view toggle is aria-pressed=true
and one is false" has assertions that do not match its name. Currently, the
expectations on trueCount and falseCount use toBeGreaterThanOrEqual(1), which
allows for multiple buttons with the same aria-pressed value to pass. Change
both expect(trueCount).toBeGreaterThanOrEqual(1) and
expect(falseCount).toBeGreaterThanOrEqual(1) to use toBe(1) instead to enforce
exactly one button with aria-pressed="true" and exactly one with
aria-pressed="false".
Codecov Report❌ Patch coverage is ❌ Your project check has failed because the head coverage (54.33%) is below the target coverage (60.00%). You can increase the head coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## feat/a11y #13666 +/- ##
=============================================
+ Coverage 58.25% 58.31% +0.05%
=============================================
Files 2307 2307
Lines 219525 219551 +26
Branches 31174 32978 +1804
=============================================
+ Hits 127893 128030 +137
+ Misses 90173 90062 -111
Partials 1459 1459
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
this PR should target |
viktoravelino
left a comment
There was a problem hiding this comment.
Frontend a11y review. Left inline comments on blocking issues and test gaps.
| ) | ||
| } | ||
| data-testid="notification_button" | ||
| aria-label={t("header.notifications")} |
There was a problem hiding this comment.
bug: duplicate aria-label prop on same JSX element. npx tsc --noEmit reports TS17001: JSX elements cannot have multiple attributes with the same name.
Suggested change: remove this duplicate and keep the existing aria-label above.
| "mainPage.timeElapsed.hour_other": "{{count}} hours", | ||
| "mainPage.timeElapsed.minute_one": "{{count}} minute", | ||
| "mainPage.timeElapsed.minute_other": "{{count}} minutes", | ||
| "flows.viewList": "List view", |
There was a problem hiding this comment.
bug: these new a11y i18n keys were added only to en.json. de, es, fr, ja, pt, and zh-Hans are missing header.home, flows.viewList, flows.viewGrid, flows.downloadSelected, flows.selectFlow, flows.moreOptions, folder.optionsFor, and paginator.pageLabel, so localized UIs expose raw keys as accessible names.
Suggested change: add the same keys to all locale files, using English placeholders if translations are not ready.
| const { container } = render(<HeaderComponent {...defaultProps} />); | ||
| // Both view toggle buttons must carry an aria-label (actual text depends on loaded locale) | ||
| const labelled = container.querySelectorAll("button[aria-label]"); | ||
| const viewBtns = Array.from(labelled).filter((b) => { |
There was a problem hiding this comment.
risk: test filters view-toggle buttons by English substrings (view, list, grid). That makes the assertion locale-coupled and can miss the actual controls.
Suggested change: select the two button[aria-pressed] controls, assert count is 2, then assert each has a non-empty aria-label.
| const falseCount = Array.from(allPressed).filter( | ||
| (b) => b.getAttribute("aria-pressed") === "false", | ||
| ).length; | ||
| expect(trueCount).toBeGreaterThanOrEqual(1); |
There was a problem hiding this comment.
risk: test name says “exactly one”, but toBeGreaterThanOrEqual(1) allows multiple pressed/unpressed controls.
Suggested change: use expect(trueCount).toBe(1) and expect(falseCount).toBe(1).
… session filter label mismatch on flow editor (#13668) * fix(a11y): fix aria-allowed-attr, invalid sidebar list structure, and session filter label mismatch on flow editor * [autofix.ci] apply automated fixes * improve translations * remove app-header-a11y --------- Co-authored-by: Olayinka Adelakun <olayinkaadelakun@Olayinkas-MacBook-Pro.local> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Olayinka Adelakun <olayinkaadelakun@mac.war.can.ibm.com>
* chore: add accessibility action plan and gap report for IBM Level 1 compliance * feat: integrate accessibility checker for automated a11y scans - Added `accessibility-checker` package to the project dependencies. - Enhanced test fixtures to include accessibility scanning capabilities. - Implemented `runA11yScan` method in the `LangflowPage` type for running accessibility checks. - Created utility functions for building accessibility scan labels, formatting failure messages, and generating summary attachments. - Updated test setup to manage accessibility sessions and assert compliance based on scan results. * feat: add accessibility test usage documentation for IBM scans * feat: enhance accessibility testing with JSON report aggregation and new tests * feat: add GitHub Actions workflow for IBM accessibility scans * feat: update a11y scan workflow to allow testing from feat/a11y branch * feat: skip Puppeteer download during npm install in Dockerfiles for accessibility testing * feat: enhance a11y scan workflow to resolve and scan latest release branches * test: add component a11y unit tests (jest-axe) (langflow-ai#13613) * test: add component a11y unit tests (jest-axe) Cover 14 components in two waves. 16 tests fail by design - each encodes a known gap from a11y-action-plan (phases 0-3) and flips to a regression lock once the component fix lands. 23 tests pass as regression locks for already-correct semantics. * ci: split a11y unit tests into separate workflow Main jest CI excludes *.a11y.test.* so known-gap failures don't block PRs; new a11y-unit-tests.yml runs them as informational check. * fix(a11y): resolve component gaps flagged by a11y unit tests Fixes all 16 failing jest-axe gap tests: - TableHead defaults scope=col - alert display area gets aria-live region - app header becomes <header> landmark; bell button labeled - icon wrapper decorative by default (aria-hidden), ariaLabel opt-in - Input drops wrapping <label> (name pollution) and hides placeholder span - password toggle back in tab order with aria-label/aria-pressed - CheckBoxDiv exposes checkbox role + state - accordion trigger renders native Radix button - dialogs focus container on open instead of suppressing autofocus - full-screen modal exposes dialog role/aria-modal/ariaLabel - flow list card focusable with keyboard activation Also wraps test focus calls in act() and mocks the icon loader so the a11y suite runs without React warnings. * fix: skip Puppeteer Chrome download in remaining Dockerfiles frontend and base images still ran bare npm install; puppeteer (via accessibility-checker, test-only) tried to fetch Chrome and broke the Docker image build in CI. * test: extend a11y unit test coverage (jest-axe) Adds axe + semantics tests for untested primitives (button, alert, textarea, radio-group, dropdown-menu, tooltip, popover) and two known-gap tests that fail by design until fixes land: - copyFieldAreaComponent copy action is a bare div onClick (plan 2.4) - DialogContentWithouFixed renders an empty fragment (plan 1.6) * fix: make webhook copy field a real button (a11y) Copy action was a bare div onClick - no role, name, or keyboard support (a11y-action-plan 2.4). Drops the no-longer-needed DialogContentWithouFixed known-gap test. * feat: update a11y unit tests and improve accessibility semantics in components * feat: enable pull request trigger for a11y scan workflow * feat: Add a11y regression scan suite (langflow-ai#13663) * test: add component a11y unit tests (jest-axe) Cover 14 components in two waves. 16 tests fail by design - each encodes a known gap from a11y-action-plan (phases 0-3) and flips to a regression lock once the component fix lands. 23 tests pass as regression locks for already-correct semantics. * ci: split a11y unit tests into separate workflow Main jest CI excludes *.a11y.test.* so known-gap failures don't block PRs; new a11y-unit-tests.yml runs them as informational check. * fix(a11y): resolve component gaps flagged by a11y unit tests Fixes all 16 failing jest-axe gap tests: - TableHead defaults scope=col - alert display area gets aria-live region - app header becomes <header> landmark; bell button labeled - icon wrapper decorative by default (aria-hidden), ariaLabel opt-in - Input drops wrapping <label> (name pollution) and hides placeholder span - password toggle back in tab order with aria-label/aria-pressed - CheckBoxDiv exposes checkbox role + state - accordion trigger renders native Radix button - dialogs focus container on open instead of suppressing autofocus - full-screen modal exposes dialog role/aria-modal/ariaLabel - flow list card focusable with keyboard activation Also wraps test focus calls in act() and mocks the icon loader so the a11y suite runs without React warnings. * fix: skip Puppeteer Chrome download in remaining Dockerfiles frontend and base images still ran bare npm install; puppeteer (via accessibility-checker, test-only) tried to fetch Chrome and broke the Docker image build in CI. * test: extend a11y unit test coverage (jest-axe) Adds axe + semantics tests for untested primitives (button, alert, textarea, radio-group, dropdown-menu, tooltip, popover) and two known-gap tests that fail by design until fixes land: - copyFieldAreaComponent copy action is a bare div onClick (plan 2.4) - DialogContentWithouFixed renders an empty fragment (plan 1.6) * fix: make webhook copy field a real button (a11y) Copy action was a bare div onClick - no role, name, or keyboard support (a11y-action-plan 2.4). Drops the no-longer-needed DialogContentWithouFixed known-gap test. * feat: update a11y unit tests and improve accessibility semantics in components * feat: enable pull request trigger for a11y scan workflow * test: add a11y regression scan suite * test: make a11y scans non-blocking * test: discover a11y scan specs * ci: group a11y workflow checks * fix(a11y): restore focus-visible indicators (langflow-ai#13664) * fix(a11y): restore focus-visible indicators * [autofix.ci] apply automated fixes --------- Co-authored-by: Olayinka Adelakun <olayinkaadelakun@Olayinkas-MacBook-Pro.local> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Viktor Avelino <64113566+viktoravelino@users.noreply.github.com> * a11y: improve auth accessibility coverage (langflow-ai#13724) * fix: improve auth accessibility coverage * fix(a11y): restore delete trigger tab focus * test(dialog): cover nested description * fix(a11y): add accessible names and hide decorative icons in LangflowCounts (langflow-ai#13731) * fix(a11y): add accessible names and hide decorative icons in LangflowCounts * [autofix.ci] apply automated fixes --------- Co-authored-by: Olayinka Adelakun <olayinkaadelakun@mac.war.can.ibm.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> * fix(a11y): add accessible names to icon-only buttons, fix placeholder (langflow-ai#13666) * fix(a11y): add accessible names to icon-only buttons, fix placeholder contrast, and enforce touch target size on /flows * [autofix.ci] apply automated fixes * fix issues * [autofix.ci] apply automated fixes * fix(a11y): fix aria-allowed-attr, invalid sidebar list structure, and session filter label mismatch on flow editor (langflow-ai#13668) * fix(a11y): fix aria-allowed-attr, invalid sidebar list structure, and session filter label mismatch on flow editor * [autofix.ci] apply automated fixes * improve translations * remove app-header-a11y --------- Co-authored-by: Olayinka Adelakun <olayinkaadelakun@Olayinkas-MacBook-Pro.local> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Olayinka Adelakun <olayinkaadelakun@mac.war.can.ibm.com> * label get-started close button and fix dark-mode placeholder contrast * remove testing change * improve the lint of the testcase --------- Co-authored-by: Olayinka Adelakun <olayinkaadelakun@Olayinkas-MacBook-Pro.local> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Viktor Avelino <64113566+viktoravelino@users.noreply.github.com> Co-authored-by: Olayinka Adelakun <olayinkaadelakun@mac.war.can.ibm.com> * fix: update package dependencies and versions in package-lock.json * chore: Remove accessibility documentation and reports - Deleted the accessibility action plan, gap report, level 1 requirements, and test usage documentation. - This cleanup is part of a broader effort to streamline accessibility resources and focus on actionable items. * chore: Add accessibility scan reports (langflow-ai#13812) * feat: add accessibility scan reports * docs: add a11y scan route map * test(a11y): add manifest-backed scans * ci(a11y): summarize scans by route * fix: update Playwright version to 1.60.0 and enhance a11y scan options * fix(test): keep fixture args destructured * test(a11y): bootstrap asset route scans --------- Co-authored-by: olayinkaadelakun <olayinka.adelakun@ibm.com> Co-authored-by: Olayinka Adelakun <olayinkaadelakun@Olayinkas-MacBook-Pro.local> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Olayinka Adelakun <olayinkaadelakun@mac.war.can.ibm.com>
…eral page (langflow-ai#13811) * chore: add accessibility action plan and gap report for IBM Level 1 compliance * feat: integrate accessibility checker for automated a11y scans - Added `accessibility-checker` package to the project dependencies. - Enhanced test fixtures to include accessibility scanning capabilities. - Implemented `runA11yScan` method in the `LangflowPage` type for running accessibility checks. - Created utility functions for building accessibility scan labels, formatting failure messages, and generating summary attachments. - Updated test setup to manage accessibility sessions and assert compliance based on scan results. * feat: add accessibility test usage documentation for IBM scans * feat: enhance accessibility testing with JSON report aggregation and new tests * feat: add GitHub Actions workflow for IBM accessibility scans * feat: update a11y scan workflow to allow testing from feat/a11y branch * feat: skip Puppeteer download during npm install in Dockerfiles for accessibility testing * feat: enhance a11y scan workflow to resolve and scan latest release branches * test: add component a11y unit tests (jest-axe) (langflow-ai#13613) * test: add component a11y unit tests (jest-axe) Cover 14 components in two waves. 16 tests fail by design - each encodes a known gap from a11y-action-plan (phases 0-3) and flips to a regression lock once the component fix lands. 23 tests pass as regression locks for already-correct semantics. * ci: split a11y unit tests into separate workflow Main jest CI excludes *.a11y.test.* so known-gap failures don't block PRs; new a11y-unit-tests.yml runs them as informational check. * fix(a11y): resolve component gaps flagged by a11y unit tests Fixes all 16 failing jest-axe gap tests: - TableHead defaults scope=col - alert display area gets aria-live region - app header becomes <header> landmark; bell button labeled - icon wrapper decorative by default (aria-hidden), ariaLabel opt-in - Input drops wrapping <label> (name pollution) and hides placeholder span - password toggle back in tab order with aria-label/aria-pressed - CheckBoxDiv exposes checkbox role + state - accordion trigger renders native Radix button - dialogs focus container on open instead of suppressing autofocus - full-screen modal exposes dialog role/aria-modal/ariaLabel - flow list card focusable with keyboard activation Also wraps test focus calls in act() and mocks the icon loader so the a11y suite runs without React warnings. * fix: skip Puppeteer Chrome download in remaining Dockerfiles frontend and base images still ran bare npm install; puppeteer (via accessibility-checker, test-only) tried to fetch Chrome and broke the Docker image build in CI. * test: extend a11y unit test coverage (jest-axe) Adds axe + semantics tests for untested primitives (button, alert, textarea, radio-group, dropdown-menu, tooltip, popover) and two known-gap tests that fail by design until fixes land: - copyFieldAreaComponent copy action is a bare div onClick (plan 2.4) - DialogContentWithouFixed renders an empty fragment (plan 1.6) * fix: make webhook copy field a real button (a11y) Copy action was a bare div onClick - no role, name, or keyboard support (a11y-action-plan 2.4). Drops the no-longer-needed DialogContentWithouFixed known-gap test. * feat: update a11y unit tests and improve accessibility semantics in components * feat: enable pull request trigger for a11y scan workflow * feat: Add a11y regression scan suite (langflow-ai#13663) * test: add component a11y unit tests (jest-axe) Cover 14 components in two waves. 16 tests fail by design - each encodes a known gap from a11y-action-plan (phases 0-3) and flips to a regression lock once the component fix lands. 23 tests pass as regression locks for already-correct semantics. * ci: split a11y unit tests into separate workflow Main jest CI excludes *.a11y.test.* so known-gap failures don't block PRs; new a11y-unit-tests.yml runs them as informational check. * fix(a11y): resolve component gaps flagged by a11y unit tests Fixes all 16 failing jest-axe gap tests: - TableHead defaults scope=col - alert display area gets aria-live region - app header becomes <header> landmark; bell button labeled - icon wrapper decorative by default (aria-hidden), ariaLabel opt-in - Input drops wrapping <label> (name pollution) and hides placeholder span - password toggle back in tab order with aria-label/aria-pressed - CheckBoxDiv exposes checkbox role + state - accordion trigger renders native Radix button - dialogs focus container on open instead of suppressing autofocus - full-screen modal exposes dialog role/aria-modal/ariaLabel - flow list card focusable with keyboard activation Also wraps test focus calls in act() and mocks the icon loader so the a11y suite runs without React warnings. * fix: skip Puppeteer Chrome download in remaining Dockerfiles frontend and base images still ran bare npm install; puppeteer (via accessibility-checker, test-only) tried to fetch Chrome and broke the Docker image build in CI. * test: extend a11y unit test coverage (jest-axe) Adds axe + semantics tests for untested primitives (button, alert, textarea, radio-group, dropdown-menu, tooltip, popover) and two known-gap tests that fail by design until fixes land: - copyFieldAreaComponent copy action is a bare div onClick (plan 2.4) - DialogContentWithouFixed renders an empty fragment (plan 1.6) * fix: make webhook copy field a real button (a11y) Copy action was a bare div onClick - no role, name, or keyboard support (a11y-action-plan 2.4). Drops the no-longer-needed DialogContentWithouFixed known-gap test. * feat: update a11y unit tests and improve accessibility semantics in components * feat: enable pull request trigger for a11y scan workflow * test: add a11y regression scan suite * test: make a11y scans non-blocking * test: discover a11y scan specs * ci: group a11y workflow checks * fix(a11y): restore focus-visible indicators (langflow-ai#13664) * fix(a11y): restore focus-visible indicators * [autofix.ci] apply automated fixes --------- Co-authored-by: Olayinka Adelakun <olayinkaadelakun@Olayinkas-MacBook-Pro.local> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Viktor Avelino <64113566+viktoravelino@users.noreply.github.com> * a11y: improve auth accessibility coverage (langflow-ai#13724) * fix: improve auth accessibility coverage * fix(a11y): restore delete trigger tab focus * test(dialog): cover nested description * fix(a11y): add accessible names and hide decorative icons in LangflowCounts (langflow-ai#13731) * fix(a11y): add accessible names and hide decorative icons in LangflowCounts * [autofix.ci] apply automated fixes --------- Co-authored-by: Olayinka Adelakun <olayinkaadelakun@mac.war.can.ibm.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> * fix(a11y): add accessible names to icon-only buttons, fix placeholder (langflow-ai#13666) * fix(a11y): add accessible names to icon-only buttons, fix placeholder contrast, and enforce touch target size on /flows * [autofix.ci] apply automated fixes * fix issues * [autofix.ci] apply automated fixes * fix(a11y): fix aria-allowed-attr, invalid sidebar list structure, and session filter label mismatch on flow editor (langflow-ai#13668) * fix(a11y): fix aria-allowed-attr, invalid sidebar list structure, and session filter label mismatch on flow editor * [autofix.ci] apply automated fixes * improve translations * remove app-header-a11y --------- Co-authored-by: Olayinka Adelakun <olayinkaadelakun@Olayinkas-MacBook-Pro.local> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Olayinka Adelakun <olayinkaadelakun@mac.war.can.ibm.com> * label get-started close button and fix dark-mode placeholder contrast * remove testing change * improve the lint of the testcase --------- Co-authored-by: Olayinka Adelakun <olayinkaadelakun@Olayinkas-MacBook-Pro.local> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Viktor Avelino <64113566+viktoravelino@users.noreply.github.com> Co-authored-by: Olayinka Adelakun <olayinkaadelakun@mac.war.can.ibm.com> * fix(a11y): resolve WCAG 2.1 Level A and AA violations on settings general page * fix Biome issue * remove files that were added by incorrectly merging Release-1.11.0 * improve testcases --------- Co-authored-by: Viktor Avelino <viktor.avelino@gmail.com> Co-authored-by: Viktor Avelino <64113566+viktoravelino@users.noreply.github.com> Co-authored-by: Olayinka Adelakun <olayinkaadelakun@Olayinkas-MacBook-Pro.local> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Olayinka Adelakun <olayinkaadelakun@mac.war.can.ibm.com>
Summary
Fixes three failing Lighthouse accessibility audits on
/flows, bringing the score from 87 → 100.button-namecolor-contrasttarget-sizeWhat changed
Accessible button names — added
aria-labelto every icon-only button on the/flowspage:aria-pressedstate), bulk downloadPlaceholder contrast (
src/style/index.css) — darkened--placeholder-foregroundin light mode from#a1a1aa(2.56:1 on white) to~#606066(6.1:1). Dark mode unchanged.Touch target (
select-options.tsx) — addedmin-h-[24px] min-w-[24px]to the per-project options trigger.i18n — 8 new translation keys added to all 7 locale files (
en,de,es,fr,ja,pt,zh-Hans) with English placeholder values for non-English locales.Test plan
make test_frontend— all unit tests passQA guildline
https://datastax.jira.com/browse/LE-1568?focusedCommentId=811695
Summary by CodeRabbit
Accessibility Improvements
Internationalization