testing-libraryの中身追ってみる
雰囲気使っているライブラリの中身を追ってみようシリーズ
ByRole
とりあえず、 '@testing-library/dom'
に実体がありそう
screen.getByRole("xxx")
みたいな使い方を考える
screenはここ。getQueriesForElement に生えてそう
辿っていくと、queries の定義に行き着く
src/queries/role.ts
に全部ある
実体
なお、取得には queryByRole, getAllByRole, getByRole, findAllByRole, findByRole の種類があるが、このあたりは buildQueries によって汎用的に生成する仕組みになっているらしい
内部的には dom-accessibility-api
と aria-query
へ依存している
dom-accessibility-api
アクセシブルなNameとDescriptionの算出ルールに関して記したW3C
に沿う形で、算出ロジックをJavaScriptで実装したものテストコードとかを見るとわかりやすい
computeAccessibleName
を呼ぶことで、該当のmarkupからアクセシブルなNameを取得している
実際試してみるとこんな感じ
import { computeAccessibleName } from "dom-accessibility-api";
import { JSDOM } from "jsdom";
const { document } = new JSDOM(`
<button><img alt="foo" /></button>
`).window;
console.log(computeAccessibleName(document.querySelector("button") as Element));
aria-query
Programmatic access to the WAI-ARIA 1.2 Roles Model. This package tracks the W3C Recommendation (last update: 6 June 2023).
WAI-ARIA 1.2 Roles Model に、各Roleについての仕様が定義されている。
これにはRoleとDOMの対応や、暗黙的に保持するaria属性が何かといった情報が含まれる。
この定義をJavaScriptから簡単にアクセスできるようにしたものが aria-queryらしい。
たとえば、const role = allRoles.get("alert")
などでアクセスすると、alert
ロールの情報を参照できる。alert
ロールは暗黙的に aria-atomic
が true となるが、コード上 alert.props["aria-atomic"]
を参照すると "true" が取得できる。
基本的には dom-accessibility-api と aria-query の組み合わせで取得しているようだが、getByRoleには他にもいくつかオプションがある。
たとえば、hidden
を true にすると、不可視状態のものでも取得できる。
これはどうやってるのか
このあたりはtesting-library内部で頑張って実装してるぽい。
hiddenの場合はこのへん
この src/role-helpers.js の中に、各オプションに対応したヘルパーが定義されてる
まとめとしては、dom-accessibility-api と aria-query に頼りつつ、その他は独自で実装しているという具合っぽかった。わかりやすかった