Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions e2e/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ export const SMOKE_ROUTES: Record<string, string> = {
"/privacy/": "Privacy Policy - OffOn",
"/accessibility/": "Accessibility Statement - OffOn",
"/404/": "Page Not Found - OffOn",
// GENERATED:accessibility-nightmare-smoke
"/adventures/accessibility-nightmare/": "The Accessibility Nightmare - OffOn Adventures",
"/adventures/accessibility-nightmare/levels/beginner/": "The Initial Audit - The Accessibility Nightmare - OffOn",
// /GENERATED:accessibility-nightmare-smoke
};

export const A11Y_PAGES: string[] = [
Expand Down Expand Up @@ -86,6 +90,10 @@ export const A11Y_PAGES: string[] = [
"/adventures/the-ai-observatory/levels/expert/",
"/adventures/the-ai-observatory/levels/intermediate/",
"/404/",
// GENERATED:accessibility-nightmare-a11y
"/adventures/accessibility-nightmare/",
"/adventures/accessibility-nightmare/levels/beginner/",
// /GENERATED:accessibility-nightmare-a11y
];

/**
Expand Down Expand Up @@ -121,4 +129,11 @@ export const ROUTES_WITHOUT_FULL_COVERAGE: string[] = [
"/challenges/spring-boot/",
"/challenges/tdd/",
"/challenges/trivy/",
// GENERATED:accessibility-nightmare-challenges
"/challenges/axe-core/",
"/challenges/playwright/",
"/challenges/lighthouse/",
"/challenges/wcag-2-2/",
"/challenges/react/",
// /GENERATED:accessibility-nightmare-challenges
];
197 changes: 197 additions & 0 deletions src/data/adventures/accessibility-nightmare/adventure.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
slug: accessibility-nightmare
meta_description: Audit the ShopSmart homepage and fix critical WCAG 2.2 accessibility violations before the initial compliance review.
name: The Accessibility Nightmare
icon: Accessibility
emoji: ♿
month: SEP 2026
tags:
- Accessibility
- WCAG 2.2
- React
- Playwright
- axe-core
- Lighthouse
- Guidepup Virtual Screen Reader
backstory:
- "ShopSmart is an online retailer moving into the European market. The redesign brief was explicit: anyone should be
able to shop there, on any device, with any input method or assistive technology. Months on, support has traced a
run of abandoned orders back to the storefront itself."
- Product photos carry no text alternative. Neither described nor marked decorative, they leave a screen reader
stopping on each one with nothing to say. The banner image at the top, which no nearby text describes, is silent
too.
- Submitting the checkout form produces a validation error no screen reader will announce. The message sits on screen
in red beside its field, but nothing in the markup ties the two together, and nothing tells assistive technology
that new text has appeared. The customer knows the order failed and cannot find out why.
- Others never reach checkout. Someone with a tremor or limited hand movement works from the keyboard instead of a
mouse. The main menu cannot be reached that way, and the focus outline is styled off across the site, so anyone on a
keyboard has no idea where they are on the page.
- There is no accessible fallback and no second route to a purchase. Complaints reached the company, then a legal
notice citing the ADA and the European Accessibility Act. The EU launch is on hold until the storefront can be shown
to work.
- You are the lead frontend engineer. Audit the storefront, fix what blocks these customers, and add checks that stop
the same faults shipping again.
overview:
- "Assistive technology works from the semantics a page exposes: what each element is, what it is called, what state
it is in, what it belongs to. A screen reader, a switch device and a braille display all read that same layer.
Replace a button with a styled div and the information is gone for all of them, and nothing downstream can
reconstruct it."
- Around 16% of people live with a significant disability. Since June 2025 the European Accessibility Act has put EU
e-commerce in legal scope, and the standard it points to, EN 301 549, sets WCAG 2.2 AA as the bar in practice.
- "The premise here is that accessibility is how a page behaves under real use, not what its markup contains. Scanners
inspect the rendered DOM and settle only what is statically decidable: a missing alt attribute, a contrast ratio, an
ARIA role that contradicts its required children. Whether alt text is meaningful, whether focus order follows the
layout, whether an error is announced, whether a widget behaves like the role it claims, none of that is decidable
from a snapshot. A page can pass every rule in the ruleset and remain unusable."
- "Three levels cover both sides of that line. The homepage audit takes what scanning does well, contrast ratios and
missing text alternatives, then the first thing it cannot see, whether the page works from a keyboard at all.
Checkout takes the rest: containers dressed as controls that report clean while stranding a keyboard user behind a
modal and swallowing a validation error. The last level turns to the accessibility gate, green for months without
once loading the pages a customer pays on."
- What you leave with is a sense of how far each layer of testing reaches. Linting reads your source and catches
authoring mistakes before anything renders, but it stops at code you wrote. Scanning reads the rendered DOM and
catches faults in a snapshot. Driving the page with a keyboard catches behavior, which a snapshot never shows.
Watching real sessions catches what changed after you shipped, which is the only layer that reaches code you do not
control.
- The storefront is pre-provisioned in a Dev Container, so the work is the audit, the repairs and the test coverage.
contributor:
name: Homayoun Mohammadi
url: https://homayounmmdy.vercel.app
about: "Frontend developer with 4+ years building production apps in Next.js, React, and TypeScript. Open-source
contributor to projects at Microsoft, W3C, and GitHub. Author of two npm packages: a 12-language RTL text engine and
a TypeScript SVG mapping toolkit."
levels:
- level: beginner
emoji: 🟢
title: The Initial Audit
devcontainer: accessibility-nightmare_beginner
community_url: ""
topics:
- axe-core
- Playwright
- Lighthouse
- WCAG 2.2
- React
meta_description: Audit a React storefront for WCAG 2.2 failures with axe-core, Playwright, and Lighthouse. Fix color
contrast, alt text, semantic HTML, keyboard navigation, and visible focus indicators.
summary: Audit the ShopSmart homepage and fix critical WCAG 2.2 accessibility violations before the initial compliance
review.
audience: Frontend developers who understand basic HTML, CSS, React, and browser developer tools but are new to
systematic accessibility testing.
backstory:
- ShopSmart has received an urgent legal notice about accessibility barriers on its public storefront.
- Customers cannot reliably navigate the page by keyboard, important images have no text alternatives, several
controls use incorrect semantics, and the visual design does not meet WCAG contrast requirements.
- Your task is to audit the homepage, understand the failures, and repair the most serious problems before
regulators escalate the case.
objective:
- Remove all serious and critical axe-core violations from the ShopSmart homepage.
- Provide meaningful alternative text for every informative image.
- Ensure the menu and primary call-to-action are semantic, keyboard-focusable controls.
- Add visible focus indicators for interactive elements.
- Achieve a Lighthouse accessibility score of at least 95.
what_you_learn:
- How to interpret automated [axe-core](https://github.com/dequelabs/axe-core) accessibility reports.
- How semantic HTML affects keyboard and assistive-technology behavior.
- How to identify and correct WCAG color-contrast failures.
- How to provide useful text alternatives for images.
- How to verify accessibility outcomes with [Playwright](https://playwright.dev/) and
[Lighthouse](https://developer.chrome.com/docs/lighthouse/overview/).
architecture:
- A React and Vite storefront runs on port 5173 inside the Dev Container.
- Playwright launches Chromium and uses axe-core to scan the rendered homepage.
- Lighthouse CI measures the accessibility category and requires a score of 95 or higher.
- Players edit src/App.jsx and src/styles.css. The tests and verification scripts define the required outcomes and
should not be weakened or bypassed.
toolbox:
- name: axe-core
url: https://github.com/dequelabs/axe-core
description: Automated accessibility engine used to detect WCAG violations.
- name: Playwright
url: https://playwright.dev/
description: Browser automation framework used for accessibility and keyboard tests.
- name: Lighthouse
url: https://developer.chrome.com/docs/lighthouse/
description: Browser audit tool used to measure the final accessibility score.
- name: WCAG 2.2
url: https://www.w3.org/TR/WCAG22/
description: Accessibility standard that defines the success criteria for this level.
services:
- name: ShopSmart
url: http://localhost:5173
description: The intentionally inaccessible React storefront.
how_to_play:
- id: start
title: Start ShopSmart
content: |
Start the application:

```bash
make app
```

Then open port 5173 in your browser.
- id: explore
title: Explore the Broken Storefront
content: |
Open ShopSmart on port 5173 and navigate the page using only the keyboard.

Run the automated checks:

```bash
npm run test:a11y
npm run test:lighthouse
```

Review the reported axe rule IDs, affected elements, keyboard failures,
and Lighthouse score before changing the implementation.
- id: implement
title: Repair the Accessibility Failures
content: |
Work primarily in:

```text
src/App.jsx
src/styles.css
```

Correct the semantic controls, image alternatives, contrast problems,
keyboard behavior, and focus appearance.

Do not remove tests, lower score thresholds, disable axe rules, or weaken
the verification logic.

When ready, run:

```bash
./verify.sh
```
helpful_links:
- title: Understanding WCAG 2.2
url: https://www.w3.org/WAI/WCAG22/Understanding/
description: Plain-language explanations of the relevant WCAG success criteria.
- title: axe-core Playwright integration
url: https://playwright.dev/docs/accessibility-testing
description: Guidance for running axe accessibility scans in Playwright.
- title: Keyboard accessibility
url: https://www.w3.org/WAI/WCAG22/Understanding/keyboard
description: Explains why functionality must be available from a keyboard.
- title: Focus appearance
url: https://www.w3.org/WAI/WCAG22/Understanding/focus-appearance
description: Explains the WCAG 2.2 requirements for visible keyboard focus.
contributor:
name: Ehtasham Yasin
url: https://weblight-app.vercel.app
about: Full-stack and AI Automation Engineer with 4+ years of frontend experience building React and Next.js
applications, API-driven systems, and automated workflows with Docker and n8n. Interested in DevSecOps and
open-source development.
verification:
command: ./verify.sh
description: Once you think you've solved the challenge, run the verification script. If it fails it will tell you which
checks didn't pass. If it passes, it generates a Certificate of Completion you can paste into the discussion.
upcoming_levels:
- level: intermediate
name: Intermediate
difficulty: Intermediate
- level: expert
name: Expert
difficulty: Expert
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"discussionUrl": "",
"discussionPosts": [],
"totalReplies": 0
}
Loading