UCDL Accessibility Use Case Definition Language
Contents

Accessibility Use Case Definition Language (UCDL) and Runner

This section is normative for the reference implementation; informative for other processors.

The reference implementation exposes the following entry points from @afixt/usecase-runner:

// Parsing
function parseUseCase(filePath: string): Promise<UseCase>;
function parseUseCaseFile(
  filePath: string,
  resolver?: (id: string) => Promise<UseCase | undefined>,
  resolutionChain?: Set<string>,
  externalData?: Record<string, unknown>,
): Promise<UseCase>;
function parseUseCaseDirectory(
  dirPath: string,
  externalData?: Record<string, unknown>,
): Promise<UseCase[]>;
function parseStep(
  stepEntry: Record<string, string>,
  lineNumber?: number,
): Step;
function parseStepEntry(entry: unknown, lineNumber?: number): Step;
function getParseWarnings(): string[];

// Templating
function interpolate(template: string, data: Record<string, unknown>): string;

// Validation
function validateUseCase(data: unknown): UseCaseSchemaType;
function validateConfig(data: unknown): ConfigSchemaType;
function loadConfig(filePath: string): ProjectConfig;
function loadDataFiles(filePaths: string[]): Record<string, unknown>;

// Code generation
function generatePlaywrightTest(
  useCase: UseCase,
  options?: {
    profile?: InteractionProfile;
    timeout?: number;
    screenshotDir?: string;
    blockedHosts?: string[];
  },
): string;
function generateTestFiles(
  useCases: UseCase[],
  outDir: string,
  options?: {
    profile?: InteractionProfile;
    timeout?: number;
    screenshotDir?: string;
    blockedHosts?: string[];
  },
): { filePath: string; useCase: UseCase }[];
function generateStepCode(
  step: Step,
  stepNumber: number,
  pageVar?: string,
  selfVar?: string,
  afterSnapshotIndex?: number,
  screenshotDirVar?: string,
): string;
function buildLocator(
  target: TargetDescriptor,
  pageVar?: string,
  selfVar?: string,
): string;
function buildVerifyAssertion(
  step: Step,
  pageVar?: string,
  selfVar?: string,
): string;

// Direct execution
function runUseCase(
  useCase: UseCase,
  options?: RunOptions,
): Promise<UseCaseResult>;
function executeStep(
  page: PlaywrightPage,
  step: Step,
  stepNumber: number,
  options?: {
    screenshotOnFailure?: boolean;
    screenshotDir?: string;
    profile?: InteractionProfile;
    secrets?: Record<string, string>;
    timeout?: number;
  },
  selfElement?: PlaywrightLocator,
  srContext?: SrContext,
): Promise<StepResult>;
function executeAuditStep(
  page: PlaywrightPage,
  step: Step,
  stepNumber: number,
  selfElement?: PlaywrightLocator,
  options?: { timeout?: number },
): Promise<StepResult>;

// Reporting
function computeScore(stepResults: StepResult[]): UseCaseScore;
function generateJsonReport(result: UseCaseResult, outputDir: string): string;
function generateHtmlReport(result: UseCaseResult, outputDir: string): string;
function generateReport(
  result: UseCaseResult,
  formats: string[],
  outputDir: string,
): string[];
function formatScore(score: UseCaseScore): string;

// Shared resolution
function resolveLocator(
  page: PlaywrightPage,
  target: TargetDescriptor,
  selfElement?: PlaywrightLocator,
): PlaywrightLocator;
function resolveSelectLocator(
  page: PlaywrightPage,
  target: TargetDescriptor,
  selfElement?: PlaywrightLocator,
): Promise<PlaywrightLocator>;
function buildLocatorExpression(
  target: TargetDescriptor,
  pageVar?: string,
  selfVar?: string,
): string;
function buildSelectLocatorExpression(
  target: TargetDescriptor,
  pageVar?: string,
  varPrefix?: string,
  selfVar?: string,
): string;
function escapeForJs(value: string): string;
function escapeForRegex(value: string): string;

// Screen-reader support (§9A.4)
function startVirtualPageSession(
  page: PlaywrightPage,
  loadSource?: BrowserBuildLoader,
): Promise<VirtualPageSession>;
class VirtualScreenReaderUnavailableError extends Error {
  readonly reason: 'not_installed' | 'unsupported_export' | 'injection_failed';
}
function matchSpokenPhrases(
  phrases: string[],
  expectation: { phrase?: string; matches?: string },
  options?: { role?: string | null },
): { matched: boolean; phrases: string[] };
function phraseMatchesRole(phrase: string, role: string): boolean;

// Introspection of the document format: the values §4.2's `type` accepts.
const USE_CASE_TYPES: readonly UseCaseType[];

// Introspection of the step language itself. A processor or tool MAY read
// these to enumerate what this implementation accepts; §5.1's keyword table
// and §7.5's modifier table are held to them by contract tests.
const STEP_KEYWORDS: StepKeyword[];
const VERIFY_SUB_TYPES: VerifySubType[];
const ROLE_MAP: Record<
  string,
  {
    method: 'getByRole' | 'getByLabel' | 'getByText' | 'locator';
    role?: string;
  }
>;
const KNOWN_MODIFIERS: Record<string, Set<string>>;
const BOOLEAN_MODIFIERS: ReadonlySet<string>;

// Version of the installed package, read from its manifest at runtime.
function getPackageVersion(): string;

// The UCDL version this build implements, and the versions a document may
// declare (§2.4). Independent of the package version.
const UCDL_LANGUAGE_VERSION: string;
const SUPPORTED_LANGUAGE_VERSIONS: readonly string[];

Public type exports are UseCase, UseCaseRaw, Step, StepsOverride, TargetDescriptor, StepResult, UseCaseResult, RunOptions, ProjectConfig, ViewportConfig, AuditIssue, AuditResult, ContrastResult, LangCheckResult, SrSaysResult, ReadImageResult, VirtualPageSession, BrowserBuildLoader, and the literal-union types StepKeyword, RoleToken, VerifySubType, UseCaseType, StepStatus, StepOutcome, UseCaseScore, InteractionProfile, StepFailureReason, StepEntry — the either-spelling shape of one step-list entry (§4.5) — and RunEnvironment, the shape of the report's environment record (§10.1).

The structural Playwright types the API accepts and returns are also exported, so a consumer can name them without depending on Playwright's own types: PlaywrightModule, PlaywrightBrowser, PlaywrightBrowserType, PlaywrightBrowserContext, PlaywrightPage, PlaywrightLocator, PlaywrightCookie.

This list is exhaustive and is held to src/index.ts by a contract test — an export added without a corresponding entry here fails the build.