Complete Guide to Web Accessibility: From Automated Testing with Lighthouse / axe and Defining WCAG Criteria to Keyboard Operation and Screen Reader Support
Introduction
Web accessibility is an essential element to ensure that all users can use websites comfortably. In particular, for elderly users and users with visual or hearing impairments, if appropriate accessibility measures are not implemented, their access to information will be restricted.
This article explains in detail concrete methods for improving web accessibility, such as automating accessibility tests using Lighthouse and axe, establishing evaluation criteria based on WCAG guidelines, improving screen reader support, optimizing color contrast, and introducing ARIA landmarks. By continuously implementing these efforts, you can create a website that is easier to use for a wider range of users.
Automating Accessibility Testing (Monitoring with Lighthouse / axe)
By automating accessibility testing, you can ensure continuous quality assurance. In particular, Lighthouse and axe-core are representative tools that are easy to integrate into your development flow.
Accessibility testing with Lighthouse
Lighthouse is an open-source auditing tool provided by Google that can automatically check the following points:
- Accessibility (usability of web content)
- Performance (page speed)
- SEO (search engine optimization)
- Best Practices (security and mobile support)
- PWA (progressive web app compliance)
How to run Lighthouse
- Open the target page in Chrome.
- Open DevTools with F12 or Cmd + Option + I (Mac) / Ctrl + Shift + I (Windows).
- Select the Lighthouse tab and check "Accessibility".
- Click Analyze page load to run the analysis.
Accessibility testing with axe-core
axe-core, developed by Deque Systems, is an accessibility testing tool for developers with the following features:
- Detects accessibility violations on web pages in detail
- Can be integrated with test frameworks such as Jest and Cypress
- Also available as a browser extension (axe DevTools)
1. Combining Cypress + axe-core
You can also run accessibility tests in the E2E testing tool Cypress by using cypress-axe.
Installing cypress-axe
npm install --save-dev cypress-axe
Using axe-core in Cypress tests
describe("Accessibility check", () => {
it("Should have no detectable accessibility violations", () => {
cy.visit("https://example.com");
cy.injectAxe();
cy.checkA11y();
});
});
cy.injectAxe(): Loadsaxe-coreinto the page.cy.checkA11y(): Detects accessibility violations on the page.
Benefits
✅ Detects accessibility violations across the entire page
✅ Can be validated in a real browser environment
✅ Can also test keyboard operations and focus movement
2. Using Playwright + axe-core
Besides Cypress, you can also use axe-core within E2E tests using Playwright.
Installing Playwright + axe-core
npm install --save-dev @playwright/test @axe-core/playwright
Using axe-core in Playwright tests
import { test, expect } from "@playwright/test";
import { injectAxe, checkA11y } from "@axe-core/playwright";
test("Page should be accessible", async ({ page }) => {
await page.goto("https://example.com");
await injectAxe(page);
await checkA11y(page);
});
How to use Lighthouse and axe-core appropriately
| Tool | Use / Characteristics |
|---|---|
| Lighthouse | Good at calculating accessibility scores and generating reports. Suitable for understanding overall areas for improvement. |
| axe-core | Detects accessibility violations in detail and is suitable for automated tests with Jest or Cypress. |
Establishing Accessibility Evaluation Criteria (Defining Criteria Based on WCAG Guidelines)
Web accessibility evaluation criteria are defined based on WCAG (Web Content Accessibility Guidelines). WCAG is an international guideline to ensure that all users can access web content, and it is based mainly on four principles.
The four principles of WCAG
1. Perceivable
Ensure that users can perceive content through vision, hearing, touch, etc.
- Examples
- Set alternative text (alt attribute) for images.
- Provide captions or transcripts for videos and audio.
- Ensure sufficient contrast ratio (e.g., contrast ratio of at least 4.5:1 between text and background colors).
- Mark up content so that information is read correctly by screen readers.
2. Operable
Ensure that all users can operate the content.
- Examples
- Support keyboard operation (usable without a mouse).
- Set focus management appropriately (clear navigation with the Tab key).
- Provide leeway for time-limited operations (give enough time for auto-logout or pop-ups).
- Suppress flashing or strong animations (to avoid triggering photosensitive seizures).
3. Understandable
Ensure that users can understand the content.
- Examples
- Use concise and easy-to-understand language.
- Clearly convey form error messages (e.g., instead of "Input required", use "Please enter a valid email address").
- Maintain consistency in navigation (avoid different layouts on each page).
4. Robust
Ensure compatibility with assistive technologies and future usability.
- Examples
- Use appropriate HTML markup (proper use of heading tags h1–h6, use of ARIA attributes).
- Support modern web technologies (e.g., basic operations should be possible even without JavaScript).
- Test with multiple assistive technologies (screen readers, voice input software, etc.).
Benefits for companies in establishing accessibility evaluation criteria
-
Improved user experience (UX)
Improving accessibility allows more people to use your site comfortably. -
Compliance with legal regulations
Japan: Provide reasonable accommodation based on the “Act for Eliminating Discrimination against Persons with Disabilities”.
EU: Comply with the “European Accessibility Act (EAA)”.
USA: Standards such as “ADA (Americans with Disabilities Act)” and “Section 508”. -
Impact on SEO (search engine optimization)
Proper HTML structure and alt text settings also benefit SEO. -
Corporate social responsibility (CSR)
Inclusive design contributes to enhancing corporate brand value.
Steps for establishing evaluation criteria within a company
1. Decide on the WCAG conformance level
WCAG has three conformance levels: A, AA, and AAA.
- A (minimum level): Meets minimum accessibility requirements (e.g., setting alt text for images).
- AA (recommended level): Criteria that allow many users to use the content (e.g., ensuring color contrast ratio).
- AAA (high level): Ensures a high level of accessibility (e.g., providing sign language interpretation).
2. Document evaluation criteria suitable for your products
- Define criteria according to your company’s business and target users.
- Create an evaluation criteria document and share it with relevant stakeholders within the company.
Example) Documenting evaluation criteria
| Item | Description | Conformance Level |
|---|---|---|
| Alt attribute for images | Set appropriate alt text for all images | A |
| Keyboard operation | All UI elements must be operable via keyboard | AA |
| Color contrast ratio | 4.5:1 or higher (between text and background) | AA |
| Form labels | Attach clear labels to input fields | AA |
| Video captions | Provide captions for all videos | AAA |
3. Conduct regular evaluations combining automated and manual tests
- Automated tests
- Regularly scan using tools such as Axe, Lighthouse, and WAVE.
- Manual tests
- Check operation using keyboard only.
- Validate with screen readers (NVDA, VoiceOver, JAWS).
- Conduct usability tests (evaluation by actual users).
4. Document audit results and establish an improvement cycle
- Create audit reports and clarify issues and improvement measures.
- Develop an improvement plan and review it regularly (e.g., quarterly accessibility reviews).
Checking Keyboard Operation (Verify That All Functions Are Operable via Keyboard)
Checking keyboard operation is essential for improving accessibility (A11Y). In particular, users who cannot use a mouse or who use screen readers need to be able to use all functions with the keyboard alone.
Key points for checking keyboard operation
1. Can you move through all interactive elements with the Tab key?
- When pressing the
tabkey, focusable elements on the page such as buttons, links, and input fields must be reachable. - Also check that you can move in reverse order with
Shift + Tab. - Elements with tabindex="-1" cannot receive focus, so set tabindex="0" as needed.
2. Can buttons be activated with Enter / Space?
- Check that buttons (
<button>,<a href>,<input type="submit">) can trigger actions with Enter or Space. - If you are using
divorspaninstead of a button, addingrole="button"alone is not enough. You also need to handleEnterandSpacein thekeydownevent.
3. Can you close modals with the Escape key?
- Check that pressing
Escapewhen a modal window is open will close it. - Check that
aria-hiddenandaria-modal="true"are set appropriately.
4. Is the focus indicator (outline) displayed appropriately?
- Check that
outline: noneis not specified (it is important not only for appearance but also for visibility). - When applying custom focus styles, using
:focus-visibleallows you to hide them during mouse operation.
button:focus-visible {
outline: 2px solid #005fcc; /* Accessible focus color */
border-radius: 4px;
}
Checking via manual testing
Use the tab key to check focus movement.
Checking via automated testing
Cypress is a convenient tool for E2E testing and can also test keyboard operations.
describe('Keyboard Navigation Test', () => {
it('should allow navigation via Tab key', () => {
cy.visit('https://example.com');
cy.get('button').first().focus().should('have.css', 'outline');
cy.tab().should('have.focus'); // Move to the next element with the Tab key
});
it('should close modal on Escape key press', () => {
cy.get('#open-modal').click();
cy.get('#modal').should('be.visible');
cy.get('body').type('{esc}');
cy.get('#modal').should('not.exist');
});
});
Playwright can test detailed keyboard operations using keyboard.press().
import { test, expect } from '@playwright/test';
test('Keyboard navigation works correctly', async ({ page }) => {
await page.goto('https://example.com');
// Focus the button with the Tab key
await page.keyboard.press('Tab');
await expect(page.locator('button')).toBeFocused();
// Press Enter to click and show the modal
await page.keyboard.press('Enter');
await expect(page.locator('#modal')).toBeVisible();
// Press Escape to close the modal
await page.keyboard.press('Escape');
await expect(page.locator('#modal')).not.toBeVisible();
});
Optimizing Color Contrast (Ensuring High Contrast for Color Blind and Low-Vision Users)
Importance of color contrast
- It is necessary to create a site that is easy to read and distinguish for people with visual impairments or color vision deficiencies (color blindness). If the contrast between text color and background color is insufficient, the text becomes difficult to distinguish.
- It is also effective for elderly people and those with reduced vision, allowing text information to be conveyed clearly and improving accessibility.
- WCAG (Web Content Accessibility Guidelines) 2.1 recommends adhering to specific contrast ratios to improve text readability and distinguishability.
Such considerations form the foundation for creating a website that is “comfortable and easy to read for everyone who views it.” By understanding this value and working carefully, you will help many users and, as a result, improve overall satisfaction with the service.
Recommended contrast ratios
- Normal text: Contrast ratio of at least 4.5:1
- Large text (18px or larger, or 14px bold): Contrast ratio of at least 3:1
“Contrast ratio” is a numerical representation of the difference in brightness between the background color and the foreground color (text color). The higher this ratio, the more clearly the two colors can be distinguished, meaning better readability.
Examples)
- Black text (#000000) on a white background (#FFFFFF) has a contrast ratio of 21:1, which is the highest level.
- Gray text (#767676) on a white background (#FFFFFF) has a relatively low contrast ratio and may not meet the criteria in some cases.
Testing tools
-
Lighthouse
- An auditing tool built into Google Chrome DevTools.
- If there are issues related to color contrast, they will appear under the “Accessibility” section.
-
axe DevTools
- A browser extension provided by Deque Systems.
- Scans the page and automatically lists accessibility issues. It also makes it easy to find contrast violations.
-
Contrast Checker
- Online tools such as “WebAIM’s Contrast Checker”.
- When you manually enter color codes, it checks the contrast ratio and pass/fail.
- When working with designers, it becomes easier to make concrete suggestions such as “This color has a contrast ratio of 4.2:1, so let’s make it a bit lighter.”
Improving Screen Reader Support (Proper Setting of the alt Attribute)
In particular, setting an appropriate alt attribute for images (<img> tags) is essential for screen reader users. By following the rules below, you can improve accessibility.
Basic rules for the alt attribute
1. Decorative images (purely visual decoration)
- Use
alt=""(leave it empty) - Using
role="presentation"together makes the screen reader completely ignore it - Example: Icon used as background decoration
<img src="decorative-icon.png" alt="" role="presentation">
2. Meaningful images (images intended to provide information)
- Set an
altthat briefly describes the content of the image - If you use role="presentation" together, the screen reader will completely ignore it
- Example: Product image
<img src="product.jpg" alt="Red sneakers">
3. Images inside links
- Put text in alt that describes the content of the link destination
- Example: Company logo used as a link
<a href="https://example.com"> <img src="logo.png" alt="Go to Example’s homepage"> </a>
4. Images containing text
- Write the text in the image directly in the alt attribute
- Example: Banner image
<img src="sale-banner.jpg" alt="All items 20% off! Until this weekend">
5. Figures and graphs
- Write a summary in alt and use figcaption or longdesc for detailed descriptions
- Example: Graph
<figure> <img src="sales-chart.png" alt="Bar chart showing sales trends"> <figcaption>Sales trends from January to March 2024</figcaption> </figure>
Enhancing accessibility using ARIA attributes
In cases where the alt attribute alone is not sufficient, you can use ARIA (aria-*) attributes to ensure that screen readers convey information correctly.
aria-label / aria-labelledby
-
aria-label: Attach a label directly to an element<button aria-label="Open menu">☰</button> -
aria-labelledby: Attach a label by referencing another element<h2 id="section-title">Product list</h2> <section aria-labelledby="section-title"> <p>Here we introduce our latest product lineup.</p> </section>
aria-live (live region)
aria-live (live region) is an attribute that instructs the screen reader: “If the content in this area changes, notify the user.”
When content on a web page changes dynamically, the change may be visually apparent but not announced to the screen reader.
Therefore, by applying aria-live, you can notify the screen reader of the change.
<p id="status" aria-live="polite">There are no items in your cart.</p>
<button onclick="document.getElementById('status').textContent = 'An item has been added to your cart!'">
Add to cart
</button>
- When the page is opened, the screen reader reads “There are no items in your cart.”
- When the button is pressed, the content of
<p>changes to “An item has been added to your cart!”. - Because of
aria-live="polite", the screen reader reads “An item has been added to your cart!” at an appropriate timing.
How to test with screen readers
Testing using screen readers
- Windows: NVDA
- Mac: VoiceOver (start with
Command + F5) - iPhone / iPad: VoiceOver (
Settings > Accessibility > VoiceOver)
Points to test
- Whether
altis read out appropriately - Operation of
aria-label/aria-labelledby - Whether important information is properly conveyed via
aria-live
Automated testing tools
Using axe-core, you can efficiently detect accessibility issues.
- Install the Chrome extension "
axe DevTools" - Open DevTools (
F12) and run “axe DevTools” - Detect images without
altand errors inaria-*attributes
Introducing ARIA Landmarks
ARIA (Accessible Rich Internet Applications) landmarks play an important role in making the main sections of a web page easier for screen readers and assistive technologies to recognize. By setting them appropriately, users with visual impairments can quickly grasp the structure of the page and efficiently access the information they need.
Types of landmarks and how to apply them
In HTML5, many elements already have implicit ARIA roles, but in some cases you can explicitly specify the role attribute to enhance screen reader behavior.
| Element | Default role | Recommended role | Description |
|---|---|---|---|
<header> |
banner (conditional) |
role="banner" |
Indicates the header of the entire site or a section. |
<nav> |
navigation |
role="navigation" |
Indicates a navigation menu. |
<main> |
main |
role="main" |
The main content area of the page. |
<aside> |
complementary |
role="complementary" |
Provides supplementary information (such as a sidebar). |
<footer> |
contentinfo (conditional) |
role="contentinfo" |
Indicates the footer (such as copyright information). |
Points
- For
<header>and<footer>, applyingrole="banner"orrole="contentinfo"is recommended only when they are used as the header or footer for the entire page. (Do not apply them when used within a section.) - There should be only one
<main>element on a page. - If you place multiple
<nav>elements, it is desirable to usearia-labelto clarify which navigation each one represents.
Code example
The following code sets ARIA landmarks appropriately, making the structure easy for screen readers to recognize.
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ARIADetailed landmark example</title>
</head>
<body>
<!-- Header -->
<header role="banner">
<h1>Site title</h1>
</header>
<!-- Global Navigation -->
<nav role="navigation" aria-label="Global Navigation">
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">Products</a></li>
<li><a href="#">Support</a></li>
</ul>
</nav>
<div style="display: flex;">
<!-- Main Content -->
<main role="main">
<h2>Main Content</h2>
<p>This section contains the main information of the page.</p>
</main>
<!-- Related Information -->
<aside role="complementary" aria-labelledby="related-info">
<h3 id="related-info">Related Information</h3>
<p>Provides supplementary information.</p>
</aside>
</div>
<!-- Sub navigation -->
<nav role="navigation" aria-label="Side Navigation">
<ul>
<li><a href="#">User Guide</a></li>
<li><a href="#">FAQ</a></li>
</ul>
</nav>
<!-- Footer -->
<footer role="contentinfo">
<p>© 2025 Company Name</p>
</footer>
</body>
</html>
Points
- Use
aria-labelledby="related-info"to clarify what the supplementary information in theasiderelates to. - Use
aria-label="Global Navigation"andaria-label="Side Navigation"to distinguish the roles of different navigation areas. - Use a
divto adjust the layout and placemainandasideside by side.
Improving Form Accessibility
By properly associating form labels and input fields, you can design forms that are easier to use for visually impaired users who use screen readers and for users who operate via keyboard. This not only improves accessibility but also enhances the user experience.
Explicitly associating the label element
By associating the label element with the input element using the for attribute, screen readers can correctly read each input field in the form.
<label for="username">Username</label>
<input type="text" id="username" name="username">
Points
- Match the value of the
forattribute oflabelwith theidof the correspondinginput. - Placing the
labelnext to theinputalso makes it visually easier to understand.
Benefits
- Screen readers will read “Username, input field” appropriately.
- Clicking the
labelmoves focus to the associatedinput, making it easier to click.
Using aria-labelledby
By using aria-labelledby, you can associate one label with multiple input fields or use it as an alternative when it is difficult to visually place a label.
<div>
<span id="email-label">Email Address</span>
<input type="email" id="email" aria-labelledby="email-label">
</div>
Points
- Set the
idof the element to be associated as the value ofaria-labelledby. - Useful in situations where you cannot use a
labelelement (for example, for buttons or complex form layouts).
Benefits
- Even without a
label, screen readers can read the field appropriately. - You can associate one label with multiple fields.
Using aria-describedby
When providing supplementary explanations, using aria-describedby allows you to convey supplementary explanations for input fields to screen readers.
<input type="text" id="phone" aria-describedby="phone-desc">
<span id="phone-desc">Please enter without hyphens.</span>
Points
- Set the
idof the supplementary explanation as the value of aria-describedby. - You can add usage hints or explanations of error messages.
Benefits
- When the user focuses on the field, the screen reader reads the supplementary explanation.
- Also effective for conveying error messages.
Checking Modal Window Operation
By properly managing modal windows, you can improve the comfort of keyboard operation and accessibility. This section explains in detail the importance of focus control and how to implement it correctly.
Properly managing focus within a modal
- Moving initial focus
Move focus to an appropriate element (such as a close button or input field) when the modal opens. - Preventing focus on background content
While the modal is open, control focus so that pressing the Tab key does not move focus to background elements. - Closing the modal with the Esc key
Allow users to close the modal when they press the Esc key.
Code example (React + TypeScript modal)
import { useEffect, useRef } from "react";
interface ModalProps {
isOpen: boolean;
onClose: () => void;
}
const Modal: React.FC<ModalProps> = ({ isOpen, onClose }) => {
const modalRef = useRef<HTMLDivElement>(null);
const closeButtonRef = useRef<HTMLButtonElement>(null);
useEffect(() => {
if (isOpen) {
// Set initial focus when modal opens
setTimeout(() => {
closeButtonRef.current?.focus();
}, 0);
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === "Escape") {
onClose();
} else if (event.key === "Tab") {
// Loop focus
const focusableElements = modalRef.current?.querySelectorAll(
'a[href], button, textarea, input, select'
) as NodeListOf<HTMLElement>;
if (!focusableElements) return;
const firstElement = focusableElements[0];
const lastElement = focusableElements[focusableElements.length - 1];
if (event.shiftKey) {
if (document.activeElement === firstElement) {
event.preventDefault();
lastElement.focus();
}
} else {
if (document.activeElement === lastElement) {
event.preventDefault();
firstElement.focus();
}
}
}
};
document.addEventListener("keydown", handleKeyDown);
return () => document.removeEventListener("keydown", handleKeyDown);
}
}, [isOpen, onClose]);
if (!isOpen) return null;
return (
<div
ref={modalRef}
role="dialog"
aria-hidden={!isOpen}
aria-labelledby="modal-title"
className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50"
>
<div className="bg-white p-6 rounded-lg shadow-lg w-96">
<h2 id="modal-title" className="text-lg font-bold mb-4">
Modal Title
</h2>
<p className="mb-4">Modal content goes here.</p>
<button
ref={closeButtonRef}
onClick={onClose}
className="bg-red-500 text-white px-4 py-2 rounded"
>
Close
</button>
</div>
</div>
);
};
export default Modal;
Points
- Managing modal open/close with
isOpen- The modal is displayed only when
isOpenistrue. - When
isOpenisfalse, it returnsnulland is hidden.
- The modal is displayed only when
- Focus management
- When the modal is opened, initial focus is set to the Close button.
- Focus loops with the
Tabkey (firstElement⇄lastElement).
- Closing with the Esc key
- Listen for the
keydownevent and runonClose()when theEscapekey is pressed.
- Listen for the
- Accessibility support
- Set
role="dialog"on the<div>and usearia-hiddenfor screen reader support. - Set
aria-labelledby="modal-title"so that the title is read out.
- Set
Usage example (App.tsx)
Place a button to open/close the modal in App.tsx and manage state using useState.
import { useState } from "react";
import Modal from "./Modal";
const App = () => {
const [isModalOpen, setIsModalOpen] = useState(false);
return (
<div className="flex flex-col items-center justify-center h-screen">
<button
onClick={() => setIsModalOpen(true)}
className="bg-blue-500 text-white px-4 py-2 rounded"
>
Open modal
</button>
<Modal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)} />
</div>
);
};
export default App;
With this code, you can confirm the following behavior:
- Clicking the “Open modal” button displays the modal.
- Pressing the Tab key moves focus only among elements inside the modal.
- Pressing the Esc key closes the modal.
- When the modal closes, focus returns to the original “Open modal” button.
Checking Responsive Design
Responsive design is a design approach that adjusts the layout appropriately according to different devices and screen sizes. By especially considering accessibility (ease of use), you can build a website that all users can operate comfortably. Here, we explain in detail media queries and the viewport meta tag, which are the basics of responsive design.
Using media queries
Media queries are a CSS feature that allows you to apply different styles depending on screen size and device characteristics.
@media (max-width: 600px) {
nav {
display: block;
}
}
This media query is applied when the screen width is 600px or less.
@media (max-width: 600px) { ... }- Applied when the screen width is 600px or less
- Assumes smartphones and small devices
nav { display: block; }- Normally,
navis often displayed horizontally withdisplay: flexordisplay: inline-block. - On small screens, changing to
display: block;allows vertical display. - This prevents menus from becoming cramped and makes them easier for users to operate.
- Normally,
/* Large screens (for desktops) */
@media (min-width: 1024px) {
body {
font-size: 18px;
}
}
/* Medium screens (for tablets) */
@media (max-width: 1023px) and (min-width: 601px) {
body {
font-size: 16px;
}
}
/* Small screens (for smartphones) */
@media (max-width: 600px) {
body {
font-size: 14px;
}
}
You can also apply different designs for each screen size.
Setting the viewport meta tag
<meta name="viewport" content="width=device-width, initial-scale=1.0">
This <meta> tag is used to properly set the display area (viewport) of the page.
Meaning of each attribute:
name="viewport"- Specifies that viewport settings are being configured
content="width=device-width"- Automatically adjusts the page width to match the device width
- Without this, the desktop layout will be displayed as-is, causing text to become extremely small or horizontal scrolling to occur
initial-scale=1.0- Sets the initial zoom level to 1.0 (100%)
- Prevents the browser from zooming automatically unless the user zooms in or out
Problems when the viewport meta tag is not set:
- When viewed on mobile, the desktop design is displayed as-is
- Text may become small and unreadable without zooming
- Users may have to scroll or zoom unintentionally to operate the page
Regular Generation of Accessibility Reports
By regularly generating accessibility (A11y) reports, you can keep your web application consistently easy to use for users.
In this process, you use automated testing tools to detect accessibility issues early and help with improvements.
Accessibility testing using axe-core
axe-core is an industry-standard accessibility testing library developed by Deque Systems.
By using @testing-library/react and jest-axe to test React components, you can detect accessibility violations.
Installing jest-axe
npm install --save-dev jest-axe @testing-library/react
Accessibility testing for React components
import React from "react";
import { render } from "@testing-library/react";
import { axe, toHaveNoViolations } from "jest-axe";
import MyComponent from "../MyComponent";
expect.extend(toHaveNoViolations);
test("MyComponent is accessible", async () => {
const { container } = render(<MyComponent />);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
Points
axe(container): Checks for accessibility violations in the DOM.toHaveNoViolations(): Confirms that there are no accessibility violations.
Benefits
- You can run accessibility tests at the component level.
- You can integrate it into your CI/CD pipeline to automatically check accessibility.
How to integrate Lighthouse into CI/CD
Place lighthouserc.json in the root of your project.
{
"ci": {
"collect": {
"url": ["https://example.com"],
"numberOfRuns": 3
},
"assert": {
"assertions": {
"categories:accessibility": ["error", { "minScore": 0.9 }]
}
},
"upload": {
"target": "temporary-public-storage"
}
}
}
Points
numberOfRuns: Setting to run the same test multiple times to obtain stable results.assertions: Throws an error if the accessibility score is below 0.9.upload: Uploads results to temporary storage.
Next, use GitHub Actions to run Lighthouse in CI/CD.
name: Lighthouse Accessibility Check
on:
schedule:
- cron: '0 0 * * 1' # Run every Monday
jobs:
lighthouse:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Run Lighthouse
run: |
npx lighthouse --config-path=lighthouserc.json
Conclusion
Improving web accessibility is not just about complying with laws or ticking off checklists; the goal is to provide a comfortable and fair experience for all users. By putting into practice the methods introduced in this article—such as using Lighthouse and axe for automated testing, improving keyboard operation and screen reader support, and introducing ARIA landmarks—you can build highly accessible websites.
However, accessibility measures are not something you can set once and forget; continuous improvement is required. It is important to keep improving by regularly generating reports and conducting user tests, incorporating feedback from actual users.
Let’s start working on improving accessibility today, aiming for a web that all users can use comfortably.
Questions about this article 📝
If you have any questions or feedback about the content, please feel free to contact us.Go to inquiry form
Related Articles
Introduction to Automating Development Work: A Complete Guide to ETL (Python), Bots (Slack/Discord), CI/CD (GitHub Actions), and Monitoring (Sentry/Datadog)
2024/02/12CI/CD Strategies to Accelerate and Automate Your Development Flow: Leveraging Caching, Parallel Execution, and AI Reviews
2024/03/12Strengthening Dependency Security: Best Practices for Vulnerability Scanning, Automatic Updates, and OSS License Management
2024/01/29Bringing a Go + Gin App Up to Production Quality: From Configuration and Structure to CI
2023/12/06Test Automation with Jest and TypeScript: A Complete Guide from Basic Setup to Writing Type-Safe Tests
2023/09/13ESLint / Prettier Introduction Guide: Thorough Explanation from Husky, CI/CD Integration, to Visualizing Code Quality
2024/02/12Building a Mock Server for Frontend Development: A Practical Guide Using @graphql-tools/mock and Faker
2024/12/30Streamlining API Mocking and Testing with Mock Service Worker (MSW)
2023/09/25