👏

コンポーネントをアクセシブルに保つ技術

2023/12/21に公開

アクセシビリティ Advent Calendar 2023 21日目の記事です。

Ubie株式会社 デザインエンジニアのtakanoripです。

Ubieではデザインシステムの1要素としてコンポーネントライブラリの実装を進めています。その中でコンポーネントをアクセシブルに保つための仕組みをいくつか導入しているので紹介します。

Linter

まず一番オーソドックスなものとして、アクセシビリティ向けLintツールを導入しています。

Ubieではeslint-plugin-jsx-a11yMarkuplintを導入しています。
両者は重複する部分もありますが、eslint-plugin-jsx-a11yはよりReactでの実装を考慮したチェック、Markuplintは純粋なマークアップのチェックに強みがあるので、両方のツールを使用することでより網羅的にチェックができます。

上記Lintはコンポーネントライブラリだけでなくプロダクトのコードにも導入されています。機械チェックをすると間接的にエンジニアの知識も増えていくので、導入してよかったなと思っています。

axe with playwright

Linterだけでは判別できない挙動の部分は@axe-core/playwrightを使用してテストを書きCIで実行できるようにしています。

import AxeBuilder from '@axe-core/playwright';
import { test, expect } from '@playwright/experimental-ct-react';
import { Button } from '../../src/components/Button/Button';
import type { Result } from 'axe-core';

test.use({ viewport: { width: 500, height: 500 } });

test.describe('Axe', () => {
  test('Buttonコンポーネントに有効なテキストを与えていないのでbutton-nameの警告が発生する', async ({ mount, page }) => {
    await mount(<Button></Button>);
    const a11yScanResult = await new AxeBuilder({ page })
      .disableRules(['page-has-heading-one', 'landmark-one-main'])
      .analyze();
    expect(a11yScanResult.violations.length).toEqual(1);
    expect(a11yScanResult.violations[0].id).toEqual('button-name');
  });
 });

Playwrightでは実際にブラウザを立ち上げてテストできるので、より柔軟なテストが行なえます。
特にアコーディオンやモーダルなどインタラクションの多いコンポーネントで効果を発揮できるでしょう。

やっていないこと: @storybook/test-runnerの導入

Ubieでは @storybook/test-runner を導入していません。
Storybookをテスト基盤として活用できるのは魅力的ですが、バージョンアップ対応やテストの柔軟性に対する懸念があり導入を見送っています。Ubieではコスト面の問題からChromaticの導入も見送っており、test-runnerの真価を発揮できるかという不安もありました。

この件に関しては今後も検討を続けていきます。

https://storybook.js.org/docs/7.0/writing-tests/test-runner
https://github.com/storybookjs/test-runner

いかがだったでしょうか。
みなさんも仕組みでアクセシビリティを担保していきましょうね!

Ubie テックブログ

Discussion