From 1e5b559649b3faca945df9be2a884cfd3ac71048 Mon Sep 17 00:00:00 2001
From: fullsend-code
<278716306+fullsend-ai-coder[bot]@users.noreply.github.com>
Date: Thu, 25 Jun 2026 23:34:09 +0000
Subject: [PATCH] fix(#3587): remove a11y violation filter and fix list
violation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Remove the `getFilteredViolations` function and `NFS_IGNORED_VIOLATION_IDS`
from the e2e accessibility test utility. The filter was suppressing the
axe `list` rule violation in NFS mode instead of fixing the root cause.
The `list` violation originated from the upstream `HomePageToolkit`
component (`@backstage/plugin-home`) which renders `` elements as
direct children of `` (`
`), violating WCAG list structure
requirements. Replace `HomePageToolkit` and `ComponentAccordion` usage in
`QuickAccessCardContent` with a local `QuickAccessToolkit` component that
wraps each tool link in a proper `` (`
`) element.
The `report-alpha.api.md` update is a key-ordering change produced by
`build:api-reports` — no API surface was added or removed.
Closes #3587
---
.../homepage/e2e-tests/utils/accessibility.ts | 21 +---
.../plugins/homepage/report-alpha.api.md | 16 +--
.../src/components/QuickAccessCard.tsx | 101 ++++++++++++++++--
3 files changed, 104 insertions(+), 34 deletions(-)
diff --git a/workspaces/homepage/e2e-tests/utils/accessibility.ts b/workspaces/homepage/e2e-tests/utils/accessibility.ts
index 7fda31b2eb..7cdd082e2c 100644
--- a/workspaces/homepage/e2e-tests/utils/accessibility.ts
+++ b/workspaces/homepage/e2e-tests/utils/accessibility.ts
@@ -17,21 +17,6 @@
import AxeBuilder from '@axe-core/playwright';
import { expect, Page, TestInfo } from '@playwright/test';
-/**
- * Rule IDs to ignore when APP_MODE is 'nfs'. Used for known issues in the NFS
- * app (e.g. list structure in third-party or shared components).
- */
-const NFS_IGNORED_VIOLATION_IDS = ['list'];
-
-function getFilteredViolations(
- violations: Awaited>['violations'],
-): Awaited>['violations'] {
- if (process.env.APP_MODE !== 'nfs') {
- return violations;
- }
- return violations.filter(v => !NFS_IGNORED_VIOLATION_IDS.includes(v.id));
-}
-
export async function runAccessibilityTests(
page: Page,
testInfo: TestInfo,
@@ -46,8 +31,8 @@ export async function runAccessibilityTests(
contentType: 'application/json',
});
- const violationsToAssert = getFilteredViolations(
+ expect(
accessibilityScanResults.violations,
- );
- expect(violationsToAssert, 'Accessibility violations found').toEqual([]);
+ 'Accessibility violations found',
+ ).toEqual([]);
}
diff --git a/workspaces/homepage/plugins/homepage/report-alpha.api.md b/workspaces/homepage/plugins/homepage/report-alpha.api.md
index 1d41467755..2486341727 100644
--- a/workspaces/homepage/plugins/homepage/report-alpha.api.md
+++ b/workspaces/homepage/plugins/homepage/report-alpha.api.md
@@ -14,30 +14,30 @@ export const homePageModule: FrontendModule;
export const homepageTranslationRef: TranslationRef<
'plugin.homepage',
{
- readonly 'header.local': string;
readonly 'header.welcome': string;
readonly 'header.welcomePersonalized': string;
- readonly 'search.placeholder': string;
+ readonly 'header.local': string;
readonly 'homePage.empty': string;
+ readonly 'search.placeholder': string;
readonly 'quickAccess.title': string;
- readonly 'quickAccess.error': string;
readonly 'quickAccess.fetchError': string;
+ readonly 'quickAccess.error': string;
readonly 'featuredDocs.title': string;
readonly 'featuredDocs.learnMore': string;
readonly 'starredEntities.title': string;
readonly 'recentlyVisited.title': string;
readonly 'topVisited.title': string;
- readonly 'templates.title': string;
- readonly 'templates.error': string;
readonly 'templates.empty': string;
+ readonly 'templates.title': string;
readonly 'templates.fetchError': string;
+ readonly 'templates.error': string;
readonly 'templates.emptyDescription': string;
readonly 'templates.register': string;
readonly 'templates.viewAll': string;
- readonly 'onboarding.guest': string;
readonly 'onboarding.greeting.goodMorning': string;
readonly 'onboarding.greeting.goodAfternoon': string;
readonly 'onboarding.greeting.goodEvening': string;
+ readonly 'onboarding.guest': string;
readonly 'onboarding.getStarted.title': string;
readonly 'onboarding.getStarted.description': string;
readonly 'onboarding.getStarted.buttonText': string;
@@ -50,11 +50,11 @@ export const homepageTranslationRef: TranslationRef<
readonly 'onboarding.learn.description': string;
readonly 'onboarding.learn.buttonText': string;
readonly 'onboarding.learn.ariaLabel': string;
- readonly 'entities.title': string;
- readonly 'entities.error': string;
readonly 'entities.close': string;
readonly 'entities.empty': string;
+ readonly 'entities.title': string;
readonly 'entities.fetchError': string;
+ readonly 'entities.error': string;
readonly 'entities.emptyDescription': string;
readonly 'entities.register': string;
readonly 'entities.description': string;
diff --git a/workspaces/homepage/plugins/homepage/src/components/QuickAccessCard.tsx b/workspaces/homepage/plugins/homepage/src/components/QuickAccessCard.tsx
index 702f3a2b46..1acf70ce0e 100644
--- a/workspaces/homepage/plugins/homepage/src/components/QuickAccessCard.tsx
+++ b/workspaces/homepage/plugins/homepage/src/components/QuickAccessCard.tsx
@@ -15,17 +15,28 @@
*/
import type { ReactNode } from 'react';
+import { useState } from 'react';
-import { CodeSnippet, WarningPanel } from '@backstage/core-components';
-import { ComponentAccordion, HomePageToolkit } from '@backstage/plugin-home';
+import { CodeSnippet, Link, WarningPanel } from '@backstage/core-components';
+import Accordion from '@mui/material/Accordion';
+import AccordionDetails from '@mui/material/AccordionDetails';
+import AccordionSummary from '@mui/material/AccordionSummary';
import Box from '@mui/material/Box';
import CircularProgress from '@mui/material/CircularProgress';
+import List from '@mui/material/List';
+import ListItem from '@mui/material/ListItem';
+import ListItemIcon from '@mui/material/ListItemIcon';
+import ListItemText from '@mui/material/ListItemText';
+import Typography from '@mui/material/Typography';
+import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import { useQuickAccessLinks } from '../hooks/useQuickAccessLinks';
import { useTranslation } from '../hooks/useTranslation';
import { QuickAccessIcon } from './QuickAccessIcon';
+import type { Tool } from '@backstage/plugin-home';
+
/** @public */
export interface QuickAccessCardProps {
title?: string;
@@ -33,6 +44,84 @@ export interface QuickAccessCardProps {
path?: string;
}
+/**
+ * Accessible toolkit grid that renders tools inside a proper `