כתיבת יוניט טסטים של נגישות עם vitest

יצירת בדיקות נגישות אוטומטיות כחלק מ-CI ביוניט טסטינג. יותר פשוט ממה שאתם חושבים!

פוסט זה מחייב הבנה בשני דברים עיקריים. נגישות אינטרנט מהזווית הטכנית שלה והבנה בנוגע לבדיקות בסביבת ריאקט. אם אתם לא יודעים – אז המאמר הזה על נגישות אינטרנט עם הפניה גם לפודקאסט ב״עושים תוכנה״ וגם להרצאה שלי בריאקט נקסט יעשו לכם סדר בנושא. על יוניט טסטינג כתבתי בספר שלי ״ללמוד ג׳אווהסקריפט בעברית״ ו״ללמוד ריאקט בעברית״ ויש גם פוסט קצת ישן שכתבתי שיעשה לכם סדר או לפחות הקדמה.

אני נורא אוהב יוניט טסטינג (בדיקות יחידה בעברית), למרות שאני יודע שיש כאלו שלא משתגעים עליהן. אבל גם המתנגדים ואלו שחושבים שלא צריך להשקיע בהן, יהיו חייבים להודות שבדיקות יחידה של נגישות יכולות לחסוך לא מעט עצבים וכאב ראש ובהחלט מייצרות קומפוננטות נגישות יותר.

בעוד שיש שפע של חומרים ואפילו פלגין איכותי ופופולרי לבדיקות יחידה על jest, ל-vitest שתופסת תאוצה לא מעטה בזמן האחרון ומהווה חלופה דה פקטו ל Create React App אין תיעוד מספיק טוב ופלגינים פופולריים. אז חשבתי לפרט איך אני כותב בדיקת יחידה עם מנוע axe שבודקות נגישות של קומפוננטות.

הערה: יש כמה פלגינים כרגע ל-vitest אבל הם לא מספיק פופולריים כרגע ואני מעדיף שלא להכניס לריפוזיטורי שלי מודולים שיש להם מעט הורדות או מעט כוכבים, אז אני עובד ישירות עם axe core.

התקנת axe core

למי שלא יודע, מדובר במודול הנגישות של deque ואחד המובילים והמרכזיים שיש. מתקינים אותו באופן הזה:

npm install axe-core --save-dev

עכשיו ניתן להשתמש בו איפה שרוצים. הוא די אגנוסטי אז אפשר להשתמש בו גם ב-vitest וגם ב-jest.

הגדרת setupTests.ts – סט הקונפיגורציה האישי שלכם

אם אין לכם קונפיגורציה משלכם – אז כדאי להגדיר את setupTests.ts, צרו אותו וב-vitest.config.ts – שהוא קובץ הקונפיגורציה של vitest הכניסו קישור אליו באופן הבא:

setupFiles: ["./PATH/TO/setupTests.ts"],

עכשיו נכניס את ההגדרות של axe core לשם. כדי להמנע מהגדרה שלהם בכל בדיקה בנפרד.

import axe from "axe-core";

axe.configure({
  rules: [
    {
      id: "color-contrast",
      enabled: false,
    },
    { id: "region", enabled: false },
    { id: "html-has-lang", enabled: false },
    { id: "document-title", enabled: false },
  ],
});

את הדוקומנטציה המלאה של axe core ומה שאפשר לקבוע (למשל לפי איזה rules אפשר לעבוד, אם איזה תקנים וכו׳) אפשר למצוא פה. אני ביטלתי את ה-rules האלו כי הם פחות ולידיים בבדיקות יחידה. כאשר אני בוחן קומפוננטה, אני לא בודק כל מיני דברים מ-prinicple 4 של תגית html למשל.

אני ממליץ לבטל את ה-ruleים המצוינים בקוד.

ה-rule של color-contrast לא יעבוד ב-JSDOM (כי אין לי רינדור של צבעים שם) אז הוא מבוטל. אפשר להוסיף לא מעט דברים והגדרות משלכם למה שמתאים ונעים.

ו… זהו! עד כאן ההגדרות. איך הבדיקה עובדת? הכי פשוט שיש!

import { run } from "axe-core";

test("passing acessibility test", async () => {
    render(<YourComponent />);
    const results = await run();
    expect(results?.violations.length).toBe(0);
});

כמה הערות חשובות:

חשוב לציין שהבדיקה היא על ה-HTML המרונדר. מה זה אומר? שאם יש לכם שינוי ב-DOM בגלל אירועים אלו ואחרים, אתם תהיו חייבים להפעיל אותם ואז לבצע בדיקה שוב. זה לא ״שגר ושכח״. כלומר משהו בסגנון של:

render(<YourComponent />);
const button = screen.getByRole('button', { name: /click me/i });  
await userEvent.click(button);  

const results = await run();
expect(results?.violations.length).toBe(0);

הקליקים והאירועים יכולים להיות מנוהלים בכל דרך (למשל ב-@testing-library) מה שחשוב הוא שה-DOM החדש ייבדק.

ועוד הערה קטנה – למרות שזה נותן לנו בטחון מסוים בנגישות, עדיין אפשר לקחת שתי קומפוננטות נגישות מאד וליצור ממש מאד לא נגיש (למשל שני כפתורים אחד על השני בזום של 200%) אז גם e2e חשוב מאד פה. אבל זה באמת בסיס ואם אתם משתמשים בו, הוא יחסוך לכם כאב ראש ולב בהמשך.

פוסטים נוספים שכדאי לקרוא

גלילה לראש העמוד