← Back to Portfolio

The Problem

Detection Is Still a Manual First Step

Before any accessibility issue can be fixed, it has to be found and documented — and that first step is still largely manual: a human opening a page, checking it against WCAG criteria by hand, and writing up what's wrong. The question behind this project was simple to ask and hard to answer well: can a tool reliably find a known accessibility defect on a real page, highlight it, and screenshot it — driven by an LLM tool call rather than a human picking arguments by hand?

The Approach

LLM Picks the Arguments, Code Does the Check

The core function, find_and_highlight(url, issue_type), is deterministic — Playwright navigates to a page, runs a DOM query for one specific issue type, and takes a tight screenshot of each matched element. The LLM's role is wired in as a real tool call: it describes a goal in plain language, picks the url and issue_type arguments, and the same deterministic function runs — no LLM involvement past choosing the arguments. Detection logic stays predictable and testable; only the argument selection is agentic.

Implementation

Targeted Screenshots, Two Modes

Screenshots are per-matched-element, not full-page — an early test against a real Wikipedia article showed that full-page screenshots of long pages shrink the highlight down to an illegible dot. A Streamlit dashboard wraps the tool in two modes: manual (you pick the arguments) and agent (you describe the goal in plain language) — both with live, step-by-step status instead of a single opaque spinner.

Validation

A Real Bug, Caught by Real Testing

Testing against real Wikipedia pages caught a real mistake in the first version of the detection query: the JavaScript img.alt property returns an empty string both when an image has no alt attribute at all, and when alt="" is explicitly set. Those are very different things — an explicit empty alt="" is the correct, intentional way to mark a decorative image so screen readers skip it; it is not a violation. The query now checks hasAttribute('alt') instead, which can actually tell the two apart — preventing false positives before they ever reach an auditor. A local test fixture keeps an alt="" image specifically to prove the query doesn't flag it.

Current Scope

One Check at a Time — For Now

Right now the scanner checks for one specific issue: images missing their alt text, the description screen readers rely on for blind users. You describe the goal in plain English, the AI picks which page and which check to run, then plain, predictable code does the actual checking and screenshotting — no back-and-forth reasoning, just one decision and one check.

If part of a page genuinely can't be seen or screenshotted — an image that hasn't loaded yet, a collapsed section — the tool says so plainly rather than failing silently or dropping it without a trace. Two clear next steps from here: teaching it to catch more kinds of issues beyond alt text, and letting it reason across several checks and pages in one session, instead of doing just one thing at a time like it does now.

Outcomes

Current State & Direction

  • Working agentic detection loop — LLM tool-call layer over deterministic Playwright automation, validated against real pages
  • Real detection bug found and fixed through testing (missing vs. intentional empty alt text), preventing false positives at the source
  • Streamlit dashboard shipped with manual and agent-driven modes and live scan progress
  • Clear, scoped next steps identified: broader issue-type coverage and a multi-step planning agent

Tech Stack

Python Playwright OpenAI Streamlit WCAG 2.2