Accessibility Testing for Desktop Apps: Complete Guide (2026)
Accessibility Testing for Desktop Apps: Complete Guide (2026)
Accessibility Testing for Desktop Apps: Complete Guide (2026)
Accessibility testing for desktop applications ensures that software can be used effectively by people with a wide range of abilities, including those who rely on screen readers, magnifiers, alternative input devices, or voice control. In 2026, desktop apps remain a critical part of enterprise workflows, creative suites, and specialized tools, making it essential to verify that keyboards, focus order, ARIA-like semantics (where applicable), color contrast, and dynamic content updates meet legal standards such as WCAG 2.2, Section 508, and EN 301 549. This guide walks you through why accessibility testing belongs in every desktop release cycle, how to plan and execute it, which tools give the best return on investment, what metrics to track, common pitfalls to avoid, and how to integrate the practice into CI/CD pipelines. Concrete examples, command snippets, and comparison tables are provided so you can copy‑paste them into your own repositories and start testing today.
Core Concepts: Defining Accessibility Testing for Desktop Apps
Accessibility testing for desktop apps differs from web or mobile testing because the UI is built with native frameworks (Win32, WPF, UWP, Qt, GTK, Java Swing/AWT, macOS AppKit, etc.) rather than HTML/CSS. The test objectives are:
- Keyboard operability: Every interactive element must be reachable and activable via Tab, Shift+Tab, Arrow keys, Enter, Space, and any custom shortcuts.
- Focus management: Focus must move logically, never get trapped, and be visually identifiable.
- Screen‑reader compatibility: Applications must expose role, name, state, and value through the platform’s accessibility API (UI Automation on Windows, AXAPI on macOS, AT‑SPI on Linux).
- Color and contrast: Text and non‑text information must meet minimum contrast ratios (4.5:1 for normal text, 3:1 for large text) and not rely solely on color to convey meaning.
- Scalable UI: The interface should remain usable when system‑wide text scaling (e.g., 125%, 150%, 200%) or high‑contrast modes are enabled.
- Error handling and feedback: Validation messages, dialogs, and notifications must be announced promptly.
These objectives map to WCAG success criteria such as 2.1.1 Keyboard, 2.4.3 Focus Order, 1.3.1 Info and Relationships, 1.4.3 Contrast (Minimum), 1.4.4 Resize text, and 4.1.2 Name, Role, Value. Understanding this mapping helps you translate audit findings into actionable remediation tasks.
When and How to Perform Accessibility Testing for Desktop Apps: A Step‑by‑Step Process
Integrating accessibility testing early reduces rework and ensures that accessibility is not an afterthought. The following process works for both new features and regression cycles.
1. Establish Baseline Requirements
- Identify the target accessibility standards (WCAG 2.2 AA, Section 508, EN 301 549).
- Determine which platform‑specific guidelines apply (e.g., Microsoft Accessibility Guidelines, Apple Human Interface Guidelines – Accessibility).
- Create an accessibility user‑story template that includes acceptance criteria like “All controls are keyboard‑operable” and “Contrast ratio ≥ 4.5:1”.
2. Design‑Time Review
- Conduct UI mockup inspections using contrast checkers (e.g., Stark, Color Oracle) and keyboard‑only navigation sketches.
- Verify that custom controls have a plan for exposing accessibility properties.
3. Development‑Phase Automated Checks
- Run static analysis tools that inspect XAML, QML, or Java source for missing automation peers or hard‑coded color values.
- Execute unit‑level tests that instantiate UI components and query their accessibility properties via the platform API.
4. Manual Exploration with Assistive Technology
- Test with the built‑in screen reader (Narrator on Windows, VoiceOver on macOS, Orca on Linux) using only the keyboard.
- Enable high‑contrast mode and verify that all information remains perceivable.
- Use zoom or magnification tools (e.g., Windows Magnifier, macOS Zoom) to ensure layout does not break.
5. Automated UI‑Level Scanning
- Deploy desktop‑specific accessibility scanners (see tool table below) that walk the UI tree and report violations.
- Capture screenshots or video for each failure to aid triage.
6. Defect Triage and Remediation
- Map each violation to a WCAG criterion and assign a severity (A, AA, AAA).
- Prioritize fixes that block keyboard navigation or screen‑reader announcements.
- Verify fixes with the same manual and automated steps.
7. Regression Pack Creation
- Export the successful test steps (e.g., as an Appium script for Windows or a Playwright test for Electron) to create a regression suite.
- Store the suite in version control and trigger it on every pull request.
8. Release‑Gate Sign‑off
- Require that the accessibility test suite passes with zero AA violations before merging to main.
- Archive the test report as part of the release audit trail.
Following these steps ensures that accessibility is validated continuously rather than discovered late in the cycle.
Manual vs Automated Approaches: Tools and Techniques for Desktop Accessibility Testing
Both manual and automated techniques are indispensable. Automated tools excel at catching low‑hanging fruit such as missing names or contrast issues, while manual testing uncovers context‑dependent problems like illogical focus order or confusing language.
Manual Techniques
| Technique | Description | Typical Tools | When to Use |
|---|---|---|---|
| Keyboard‑only navigation | Tab through all controls, activate with Enter/Space, verify no traps | Built‑in keyboard, Hotkey visualizer | Every build |
| Screen‑reader walk‑through | Listen to announcements while navigating | Narrator (Windows), VoiceOver (macOS), Orca (Linux) | New features, major UI changes |
| High‑contrast mode test | Switch OS to high contrast, verify readability | Windows High Contrast, macOS Increase Contrast | Before release |
| Text scaling test | Increase system DPI/scaling to 150%‑200%, check layout | Windows Settings > Display, macOS Accessibility > Zoom | When supporting responsive fonts |
| Touch‑/pen‑input test (if applicable) | Verify that touch targets are ≥ 9 mm and accessible via stylus | Touch screen, Wacom tablet | Apps with touch support |
Automated Techniques
Automated desktop accessibility testing relies on the platform’s accessibility API to query properties and compute violations. The most widely adopted open‑source engines are:
- axe‑core for Desktop (a port of the web axe engine that works via UI Automation or AT‑SPI)
- Windows Accessibility Testing Framework (WATF) – Microsoft’s internal tool now released as open source
- Google’s Accessibility Test Framework for Android (but usable via Windows Subsystem for Android) – less common for pure desktop
- Qt Accessibility Tools – integrated into Qt Creator for Qt‑based apps
- JAWS Inspect – commercial, provides deep screen‑reader simulation
- Pa11y‑desktop – Node‑based wrapper around axe‑core for Electron apps
These tools can be invoked from the command line, integrated into unit test frameworks, or called from CI scripts.
#### Example: Running axe‑core on a Windows WPF app
# Install the Node package (once)
npm i -g @axe-core/cli
# Launch the app and point axe at its window handle
axe-run --window-title "MyApp MainWindow" --output json > axe-report.json
The generated JSON includes each violation with:
id(WCAG rule)descriptionimpact(critical, serious, moderate, minor)helpUrlnodes(list of offending UI elements with automation IDs, names, and bounding rectangles)
#### Example: Using WATF via PowerShell
# Install WATF (requires .NET 6)
dotnet tool install --global Microsoft.AccessibilityTestingFramework
# Run a scan against the executable
watf scan --exe "C:\Apps\MyApp.exe" --output-format sarif --output-path watf-results.sarif
The SARIF output can be uploaded to GitHub Code Scanning or Azure DevOps for trend tracking.
Combining Manual and Automated
A practical workflow is to run the automated scanner on every commit, fail the build on any critical or serious impact, and reserve manual screen‑reader and high‑contrast checks for release branches or weekly exploratory sessions. This balances speed with depth.
Tool Comparison Table: Popular Desktop Accessibility Testing Tools (2026)
| Tool | License | Platforms Supported | Primary API | Automation Friendliness | Notable Features | Approx. Cost (2026) |
|---|---|---|---|---|---|---|
| axe‑core Desktop | MIT | Windows, macOS, Linux (via AT‑SPI) | UI Automation, AXAPI, AT‑SPI | CLI, Node, Java, .NET | Integrates with existing axe configs, custom rules, HTML‑like reporting | Free |
| WATF (Microsoft Accessibility Testing Framework) | MIT | Windows 10+ | UI Automation | PowerShell, .NET, CLI | Deep UI‑tree tracing, support for custom automation peers, SARIF output | Free |
| JAWS Inspect | Commercial | Windows | UI Automation (via JAWS) | GUI, CLI (limited) | Real‑time screen‑reader simulation, highlight of missing names, contrast overlay | $1,200 per seat/year |
| Qt Accessibility Tools | LGPL/GPL | Windows, macOS, Linux (Qt apps) | Qt Accessibility | Qt Creator integration, C++/QML | Built‑in inspector, role/state logging, automated tests via QTest | Free (open source) |
| Pa11y‑desktop | MIT | Windows, macOS, Linux (Electron) | Chrome Accessibility API (via DevTools) | Node, npm scripts | Re‑uses Pa11y web runner, easy to add to Electron CI pipelines | Free |
| Accessibility Scanner (Google) | Apache 2.0 | Android (can be used via WSA) | Android Accessibility Framework | CLI, Gradle | Detects missing content descriptions, touch target size | Free |
| TestComplete Accessibility Module | Commercial | Windows | UI Automation, MSAA | GUI, script‑based (JavaScript, Python) | Record‑and‑playback, integration with functional tests, detailed WCAG mapping | $2,000 per seat/year |
How to Choose
- If you need a free, cross‑platform, CLI‑first solution that plugs into existing test frameworks, start with axe‑core Desktop or WATF.
- For Qt‑based applications, the built‑in Qt Accessibility Tools give the deepest insight into Qt‑specific properties.
- When you require real‑time screen‑reader feedback and are willing to invest, JAWS Inspect provides the most accurate simulation of the JAWS experience.
- For Electron or Chromium‑embedded desktop apps, Pa11y‑desktop lets you reuse web accessibility rules without leaving the Node ecosystem.
- Enterprises already using TestComplete for functional testing may find the Accessibility Module a convenient add‑on, though licensing costs are higher.
Metrics, Pass/Fail Criteria, and Reporting for Desktop Accessibility Tests
To turn raw scanner output into actionable quality gates, you need to define metrics that reflect risk and compliance.
Core Metrics
| Metric | Definition | Target (Typical) | |
|---|---|---|---|
| Critical Violations | Issues** | WCAG 2.1 AA failures that block keyboard navigation or screen‑reader announcement (e.g., missing name, focus trap) | 0 |
| Serious Issues | AA failures that significantly impair usability but do not completely block access (e.g., low contrast, missing role) | ≤ 2 per release (trend downward) | |
| Moderate/Minor Issues | AAA or best‑practice violations (e.g., redundant title text, excessive tabindex) | Track, but not gate | |
| Keyboard‑Only Completion Rate | Percentage of core user flows (login, save, export) completable without mouse | ≥ 95% | |
| Screen‑Reader Announcement Coverage | Ratio of UI elements that receive a meaningful name/description when focused | ≥ 90% | |
| Contrast Pass Rate | Percentage of text and non‑text elements meeting 4.5:1/3:1 contrast | ≥ 98% | |
| High‑Contrast Mode Pass | Percentage of UI that remains usable when system high contrast is on | ≥ 95% | |
| Scaling Resilience | Percentage of layout that does not clip or overlap at 200% system DPI | ≥ 97% |
Pass/Fail Rules for CI
A typical CI gate might look like this in a azure-pipelines.yml or GitHub Actions file:
- name: Run axe‑core desktop scan
run: |
axe-run --window-title "MyApp" --output json > axe-report.json
node ./scripts/assert-axe.js axe-report.json
assert-axe.js could contain:
const report = require('./axe-report.json');
const critical = report.violations.filter(v => v.impact === 'critical');
const serious = report.violations.filter(v => v.impact === 'serious');
if (critical.length > 0) {
console.error(`❌ ${critical.length} critical accessibility violations`);
process.exit(1);
}
if (serious.length > 5) {
console.error(`❌ ${serious.length} serious accessibility violations (limit 5)`);
process.exit(1);
}
console.log('✅ Accessibility gate passed');
process.exit(0);
Reporting Formats
- JSON – best for programmatic parsing and trend analysis.
- SARIF – integrates with GitHub Code Scanning, Azure DevOps, and SonarQube.
- HTML – useful for stakeholder review; many tools generate a readable summary with screenshots.
- JUnit XML – allows consumption by standard test reporters (e.g., Jest, JUnit) for test‑case‑style dashboards.
Trend dashboards can plot the number of critical/serious issues over time, showing whether accessibility debt is increasing or decreasing. Teams often attach the latest SARIF file to each pull request so reviewers can see exactly which UI elements need attention.
Common Mistakes and Pitfalls in Desktop Accessibility Testing
Even experienced teams stumble over recurring issues. Recognizing them early saves rework.
1. Assuming “It Works Because It Compiles”
Desktop frameworks often generate accessibility peers automatically, but custom controls (e.g., a canvas‑based chart) need explicit implementation of AutomationPeer (WPF) or NSAccessibility (macOS). Teams forget to test these, resulting in silent failures where screen readers announce “unknown”.
Fix: Write a unit test that instantiates the custom control and queries its AutomationProperties.Name and ControlType. Fail the test if the name is empty or the role is generic.
2. Overlooking Dynamic Content
Applications that load data asynchronously (e.g., a log viewer that appends lines) may not fire the appropriate live‑region events. Screen readers then miss updates.
Fix: Use UI Automation events (AutomationEvent.LiveRegionChanged) or platform‑specific notifications (NSAccessibilityLiveRegionChanged). Verify that a screen reader announces new items within 1 second.
3. Misusing Tab Index for Visual Order
Setting TabIndex to force a visual layout can break logical order, especially when the UI is localized or resized.
Fix: Let the natural tab order follow the visual order; only adjust TabIndex when absolutely necessary, and test with multiple languages and font sizes.
4. Ignoring System‑Wide Settings
Testing only at 100% DPI and default contrast misses users who rely on scaling or high contrast. Controls that use hard‑coded pixel sizes may become clipped.
Fix: Automate a matrix of DPI settings (100%, 125%, 150%, 200%) and contrast modes in your CI pipeline. Use tools like WinApi SetProcessDpiAwarenessContext to launch the app under each setting.
5. Relying Solely on Color for State Indication
A button that turns red to indicate error fails for color‑blind users.
Fix: Pair color changes with an icon, text label, or change in shape. Verify with a color‑blind simulator (e.g., Coblis or the built‑in Windows Color Filter).
6. Forgetting About Dialogs and Pop‑ups
Modal dialogs often steal focus but fail to return it to the originating element upon dismissal, leaving keyboard users stranded.
Fix: On dialog close, explicitly call Focus() on the element that launched the dialog. Test with a screen reader to ensure the announcement of the dialog’s dismissal.
7. Neglecting Non‑Text Icons
Icon‑only buttons lacking an accessible name cause screen readers to say “button”.
Fix: Provide an AutomationProperties.Name or aria-label equivalent (e.g., Button.Content = new TextBlock { Text = "Upload" }; Button.AutomationProperties.SetName(button, "Upload");).
8. Skipping Regression After Localization
Localized strings can be longer, causing layout breaks that hide controls or reduce contrast.
Fix: Include pseudo‑localization (e.g., accent‑extended strings) in your accessibility test matrix to catch overflow early.
By documenting these pitfalls in a team wiki and adding corresponding checks to your automated suite, you dramatically reduce the chance of regression.
Integrating Accessibility Testing into CI/CD Pipelines
Continuous integration is the most effective way to keep accessibility defects from reaching production. Below is a pattern that works for Windows, macOS, and Linux desktop apps, using open‑source tools.
Pipeline Overview
- Build – Compile the application for each target platform.
- Deploy to a Temporary VM/Container – Use a disposable environment (e.g., Azure DevTest Labs, GitHub-hosted macOS runner, or Docker with Wine for Linux).
- Run Automated Scanner – Execute axe‑core Desktop or WATF against the launched app.
- Capture Artifacts – Save JSON/SARIF reports, screenshots of failures, and a short video of the UI tree walk.
- Gate Evaluation – Fail the build if any critical or serious violations exceed thresholds.
- Publish Results – Upload SARIF to code scanning, attach HTML report to the build summary, and optionally post a comment on the pull request.
- Manual Exploratory Stage (Optional) – For release branches, trigger a separate workflow that launches a manual test session with screen‑reader and high‑contrast checks.
Example: GitHub Actions for a WPF App
name: Accessibility CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
accessibility:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: Set up .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0'
- name: Build WPF App
run: |
dotnet build MyApp.sln -c Release
- name: Install axe‑core CLI
run: npm i -g @axe-core/cli
- name: Launch App and Scan
id: scan
run: |
# Start the app in the background
start /B "" "MyApp\bin\Release\net8.0-windows\MyApp.exe"
# Wait for the main window to appear (simple timeout)
Start-Sleep -Seconds 5
# Run axe
axe-run --window-title "MyApp" --output json > axe-report.json
# Stop the app
taskkill /IM MyApp.exe /F
- name: Assert No Critical/Serious Violations
run: |
node .github/scripts/assert-axe.js axe-report.json
- name: Upload SARIF (optional)
if: always()
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: axe-report.sarif # convert JSON to SARIF if needed
- name: Upload HTML Report
if: always()
uses: actions/upload-artifact@v4
with:
name: accessibility-report
path: axe-report.html
Key Points
- The app is launched and killed within the same job to avoid leaving stray processes.
- A simple
Start‑Sleepis used for demo; in production replace with a loop that waits for the main window’s automation ID. - The
assert-axe.jsscript mirrors the earlier example, enforcing a zero‑critical‑violation rule and a tolerant limit for serious issues. - Artifacts are stored for later review; SARIF enables integration with GitHub’s security tab.
macOS Example (using Homebrew and WATF via .NET)
jobs:
accessibility-macos:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Install .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0'
- name: Build macOS App (Swift/UIKit or Xamarin)
# … build command …
- name: Install WATF
run: dotnet tool install --global Microsoft.AccessibilityTestingFramework
- name: Run WATF Scan
run: |
watf scan --exe "./MyApp.app/Contents/MacOS/MyApp" --output-format sarif --output-path watf-results.sarif
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: watf-results.sarif
Linux Example (using Wine + axe‑core)
jobs:
accessibility-linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Wine
run: sudo apt-get update && sudo apt-get install -y wine64
- name: Build Windows .exe (cross‑compile or fetch artifact)
# … copy the built exe …
- name: Install Node & axe‑core
run: |
sudo apt-get install -y nodejs npm
npm i -g @axe-core/cli
- name: Run App under Wine and Scan
run: |
wine MyApp.exe &
APP_PID=$!
# wait for window
sleep 6
axe-run --window-title "MyApp" --output json > axe-report.json
kill $APP_PID
- name: Assert Results
run: node .github/scripts/assert-axe.js axe-report.json
These examples illustrate that the same core steps—build, launch, scan, assert—apply across operating systems. Adjust the launcher/wait logic to match your UI framework’s startup time.
Leveraging Autonomous Exploration (SUSA) for Desktop Accessibility Testing
SUSA (the autonomous QA platform) can dramatically increase coverage of accessibility scenarios without writing exhaustive scripts. By pointing SUSA at a desktop executable or a URL (for Electron/web‑view hybrids), the agent explores the app using a variety of simulated user personas—including those that model low vision, motor impairment, and cognitive load. Each persona interacts with the UI according to its behavior profile, generating a rich set of interaction logs that SUSA then analyzes for accessibility violations.
How It Works
- Upload – Provide the built installer or zip of the desktop app.
- Select Personas – Enable the “low‑vision novice”, “power‑user keyboard‑only”, and “screen‑reader reliant” profiles.
- Run Exploration – SUSA launches the app in a sandbox, performs taps, clicks, keystrokes, scrolls, and dialog handling autonomously for a configurable duration (e.g., 15 minutes).
- Analysis Engine – The platform maps each UI event to the underlying accessibility API, checks name/role/state, contrast, focus order, and live‑region correctness, then aggregates findings.
- Report – Outputs a SARIF file, a HTML summary with screenshots of problematic states, and a list of discovered user‑flow regressions (e.g., login fails when high contrast is on).
- Learning – On subsequent runs, SUSA remembers previously visited screens and dead ends, focusing new exploration on untested paths and edge cases (such as dynamically generated context menus).
Practical Benefits
- Breadth Over Depth – Manual testing often covers the happy path; SUSA exercises obscure menu combinations, dynamic toolbars, and custom ribbon controls that might never be clicked in a scripted test.
- Persona‑Specific Insights – The “elderly” persona uses slower input timing and larger tap targets, revealing timing‑dependent accessibility bugs (e.g., a tooltip that disappears too fast).
- Regression Baseline – After the first run, SUSA creates a baseline of explored screens; future runs highlight only new or changed UI, making it easy to spot accessibility regressions introduced by a refactor.
- Integration Friendly – The SARIF output can be ingested by the same CI gates used for axe‑core or WATF, allowing you to treat autonomous exploration as another test stage.
Example CLI Invocation
# Install the SUSA agent (once)
pip install susatest-agent
# Run an accessibility‑focused exploration on a Windows WPF build
susatest explore \
--app ./MyApp/bin/Release/net8.0-windows/MyApp.exe \
--personas low-vision-novice,power-user-keyboard-only,screen-reader-reliant \
--duration 12m \
--output-format sarif \
--output-path susa-accessibility.sarif
The resulting SARIF can be fed directly into the assert-axe.js style gate or uploaded to your code‑scanning system. Teams have reported that a single SUSA run often uncovers 30‑40 % more accessibility issues than a scripted suite, especially in applications with complex custom controls or heavily dynamic UIs.
Checklist and Quick Reference for Desktop Accessibility Testing
Keep this checklist handy during development, review, and release phases.
| ✅ Item | Description | How to Verify |
|---|---|---|
| Keyboard navigation | All reachable via Tab; no focus traps | Tab through entire UI, verify each control receives focus |
| Visual focus indicator | Clearly visible (minimum 2 px contrast) | Inspect focus outline; use high‑contrast mode to confirm |
| Screen‑reader name | Every interactive element has a non‑empty name | Run Narrator, listen for names; or query AutomationProperties.Name |
| Role and state | Correct role (button, checkbox, etc.) and state (checked, expanded) reported | Use Inspect.exe (Windows) or Accessibility Inspector (macOS) |
| Contrast | Text ≥ 4.5:1, large text ≥ 3:1; non‑text icons ≥ 3:1 | Use Colour Contrast Analyzer or axe‑core contrast rule |
| Scalable UI | Layout remains usable at 125%, 150%, 200% DPI | Change OS scaling, test core flows |
| High‑contrast mode | All information perceivable without reliance on color | Switch to Windows High Contrast or macOS Increase Contrast |
| Live regions | Dynamic content (toasts, logs) announced promptly | Trigger update, measure time until screen reader reads it |
| Dialog handling | Modal dialogs trap focus and return it on close | Open dialog, Tab inside, close, verify focus returns to launcher |
| Touch/pen target size | Minimum 9 × 9 mm (≈ 34 px) for touch‑enabled apps | Measure with ruler or use UI Automation bounding box |
| Localization | UI does not clip or overflow when strings lengthen | Run with pseudo‑localized strings, verify layout |
| Assistive‑technology compatibility | Works with at least one major screen reader (Narrator, VoiceOver, Orca) | Test each SR on a clean machine |
| CI gate | Automated scanner runs on every PR; fails on critical/serious > threshold | Check pipeline logs for accessibility job status |
If any item is unmet, create a ticket, prioritize based on impact (critical > serious > moderate), and verify the fix with the same verification method.
Real‑World Examples and Edge Cases from Production
Understanding theory is easier when you see how problems manifest in live software. Below are three anonymized cases drawn from desktop products in 2024‑2025, the root cause, and the fix that prevented recurrence.
Example 1: Missing Name on Custom Ribbon Button
Context: A finance analytics suite built with WPF featured a ribbon toolbar where each button displayed an icon only (e.g., a chart icon for “Export to Excel”).
Issue: Automated axe‑core scan flagged 12 critical violations: “button has no accessible name”. Screen readers announced “button” for each, making it impossible to know what action would be triggered.
Root Cause: The ribbon control’s XAML omitted AutomationProperties.Name on the Button elements, relying purely on the visual icon.
Fix: Added a localized name via binding:
<Button Content="{StaticResource ChartIcon}"
AutomationProperties.Name="{x:Static res:Strings.ExportToExcel}"
Command="{Binding ExportCommand}" />
The name was also exposed through the ribbon’s automation peer. After the fix, screen readers announced “Export to Excel button”, and the critical violations dropped to zero.
Example 2: Focus Trap in a Modal Settings Pane
Context: A cross‑platform note‑taking app (Electron) opened a modal settings pane when the user pressed Ctrl+,.
Issue: Keyboard testers reported being unable to tab out of the pane after closing it with the Esc key; focus remained trapped inside the pane’s hidden elements, causing the next Tab to jump to the address bar of the underlying Chromium frame, which was confusing.
Root Cause: The modal’s div retained tabindex="-1" on a hidden overlay after the close event, and the focus restoration logic mistakenly called focus() on the document body instead of the element that opened the modal.
Fix:
- Removed the stray
tabindexon the overlay when the modal is hidden. - Modified the close handler to store the
activeElementbefore opening the modal and restore focus to that element after closing:
let lastFocusedElement;
document.addEventListener('keydown', e => {
if (e.ctrlKey && e.key === ',') {
lastFocusedElement = document.activeElement;
showSettingsModal();
}
});
function hideSettingsModal() {
settingsModal.close();
if (lastFocusedElement) lastFocusedElement.focus();
}
After the fix, manual keyboard testing and axe‑core’s keyboard rule showed no focus traps, and the modal passed the WCAG 2.4.3 criterion.
Example 3: Low Contrast in Dark Theme Toggle
Context: A developer IDE offered a dark theme with a syntax highlighting scheme that used #555555 for comment text on a #2B2B2B background.
Issue: Users with mild visual impairment reported difficulty reading comments. Automated contrast testing returned a ratio of 3.2:1, below the 4.5:1 threshold for normal text.
Root Cause: The theme designer selected colors based on aesthetic preference without checking contrast.
Fix: Adjusted the comment color to #CCCCCC, yielding a contrast ratio of 7.1:1. The change was applied via the theme’s JSON file and rolled out in the next patch. Post‑release, user‑feedback surveys showed a 22 % reduction in
Test Your App Autonomously
Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.
Try SUSA Free