UCDL Accessibility Use Case Definition Language
Contents

Accessibility Use Case Definition Language (UCDL) and Runner

This section is normative.

12.1 Project configuration file

The default configuration file path is ./usecase-runner.config.yaml. Processors MUST accept an alternative path (e.g., via a CLI flag).

browser: chromium # chromium | firefox | webkit
headed: false # boolean
slow_mo: 0 # integer ms
timeout: 30000 # non-negative integer ms; default step timeout, and the audit engine's page load (§9.6)
viewport:
  width: 1280
  height: 720

continue_on_failure: true # boolean
screenshot_on_failure: true # boolean
screenshot_dir: ./screenshots # string

report_formats: # array of "json" | "html" (and any other formats the processor supports)
  - json
  - html
report_dir: ./reports

global_setup: ./setup/login.ts # optional path to a Playwright global setup
storage_state: ./auth/state.json # optional Playwright storageState.json, seeded
# into the browser context before each use case runs, so a
# pre-authenticated session does not have to be re-established
# by every document
data_files: # array of paths to external data YAMLs
  - ./data/test-accounts.yaml
blocked_hosts: # optional; hosts whose requests the run aborts
  - analytics.google.com
  - "*.doubleclick.net"

Defaults match the table above. A processor MAY add additional fields, but MUST NOT change the meaning of any field defined here.

timeout is a non-negative integer. A processor MUST reject a negative or fractional value when it loads the configuration, rather than pass it to the steps or the engine.

blocked_hosts lists hosts whose requests a run aborts, so that a use case run against a live site does not fire that site's analytics and advertising tags — inflating its traffic, enrolling automated visitors in remarketing audiences, or creating buyer-intent signals that someone then acts on. Each entry is a hostname, which matches that hostname exactly, or *. followed by a hostname, which matches any subdomain of it and not the hostname itself, as a TLS wildcard does. Matching is case-insensitive and ignores scheme and port, and a request to a hostname written fully qualified, with a trailing dot (example.com.), is a request to the same host as one without it: a processor MUST match it as such, since otherwise one character takes a request past every pattern. A processor MUST reject an entry that is neither form — a URL, an entry carrying a port or a path, an IPv6 literal, a wildcard anywhere but as the first label, or * alone — when it loads the configuration: such an entry matches nothing, and the run would read as though it blocked a host it sent every request to. The default is an empty list.

When blocked_hosts is non-empty, a processor MUST abort every request whose URL's hostname matches an entry, from before the navigation to start_location until the use case ends, in both execution modes (§8.3); a generated test carries the list as it was when the test was generated. A request a service worker makes on a page's behalf is outside that requirement, since not every automation engine can intercept one: a processor MAY let such a request through, and if it does, it SHOULD say so in its documentation. The reference implementation routes the browser context, so a page the start page opens is covered as well, and lets service-worker requests through. Blocking a tag can change what the page renders — a consent banner a tag manager injects, for one — so a report of a run with blocking active says so (§10.1).

External YAML files referenced by data_files are loaded and merged in order: later files override earlier ones, and per-document data blocks override files. CLI-provided overrides (e.g., --set k=v) override everything else. The fully merged result is the effective data map used for template interpolation.

# data/test-accounts.yaml
accounts:
  standard_user:
    username: '[email protected]'
    password: 'TestPass123!'

Values in data files MAY be addressed via dot notation:

- enter: field "Email" value "{{ accounts.standard_user.username }}"