اختبار الوصول بلوحة المفاتيح
يتحقق اختبار إمكانية الوصول بلوحة المفاتيح (Keyboard accessibility testing) من أن كل وظيفة في الصفحة أو التطبيق يمكن الوصول إليها وتشغيلها دون فأرة أو لمس، وأن المستخدم يعرف دائماً أين يقع التركيز (Focus)، وأن التركيز يتنقل بترتيب منطقي. وهو أسرع فحص لإمكانية الوصول ذي قيمة عالية يستطيع المختبِر إجراؤه — كل ما يحتاجه لوحة مفاتيح وانضباط — ويلتقط عيوباً تكسر أيضاً استخدام قارئات الشاشة وأجهزة التبديل والتحكم الصوتي.
يسرد هذا الدليل معايير نجاح WCAG 2.2 المعنية، ويشرح كيف تُدار جلسة اختبار بلوحة المفاتيح، ويوضح ترتيب التركيز وظهوره وعدم حجبه، وفخاخ لوحة المفاتيح وتجاوز الكتل، ويعطي المفاتيح المتوقعة لعناصر الواجهة المخصصة الشائعة من دليل ممارسات تأليف ARIA، ثم يختم بقائمة حالات اختبار وأمثلة عيوب وما يمكن أتمتته.
من يعتمد على لوحة المفاتيح وأي المعايير تنطبق
كثيرون لا يستخدمون الفأرة أبداً: المستخدمون المكفوفون يتنقلون بقارئ شاشة تُشغّله لوحة المفاتيح؛ وذوو الرعاش أو محدودية حركة اليد يستخدمون لوحة المفاتيح أو جهاز تبديل (Switch) أو تحكماً صوتياً يحاكي ضغطات المفاتيح؛ وآخرون يفضّلونها ببساطة. وعلى الهواتف والأجهزة اللوحية تستخدم لوحات المفاتيح الخارجية والوصول بالتبديل نموذج التركيز نفسه. فإذا تعذّر الوصول إلى شيء بلوحة المفاتيح، أُغلق أمام كل هؤلاء.
معايير نجاح WCAG 2.2 التالية هي جوهر اختبار لوحة المفاتيح:
- 2.1.1 Keyboard (A) — كل الوظائف قابلة للتشغيل عبر واجهة لوحة المفاتيح دون اشتراط توقيتات محددة لضغطات المفاتيح (والرسم الحر وما شابهه من إدخال يعتمد على مسار الحركة هو الاستثناء).
- 2.1.2 No Keyboard Trap (A) — إذا أمكن نقل التركيز إلى مكوّن بلوحة المفاتيح، أمكن نقله خارجه بلوحة المفاتيح؛ وإذا لزم مفتاح غير قياسي، يُبلَّغ المستخدم به.
- 2.1.4 Character Key Shortcuts (A) — اختصارات الحرف الواحد يمكن إيقافها أو إعادة تعيينها، أو لا تعمل إلا عندما يكون التركيز على المكوّن المعني.
- 2.4.1 Bypass Blocks (A) — توجد آلية لتخطي الكتل المتكررة في صفحات كثيرة، مثل رابط التخطي.
- 2.4.3 Focus Order (A) — يتنقل التركيز بترتيب يحفظ المعنى وقابلية التشغيل.
- 2.4.7 Focus Visible (AA) — لتركيز لوحة المفاتيح مؤشر مرئي.
- 2.4.11 Focus Not Obscured (Minimum) (AA) — المكوّن الذي عليه التركيز لا يُحجب بالكامل بمحتوى وضعه المؤلف كالترويسات الثابتة أو الأشرطة.
- 3.2.1 On Focus (A) — تلقّي التركيز لا يسبب وحده تغييراً في السياق.
- ذات صلة: 1.4.13 Content on Hover or Focus (AA) للتلميحات والنوافذ المنبثقة، ومعايير AAA وهي 2.1.3 Keyboard (No Exception) و2.4.12 Focus Not Obscured (Enhanced) و2.4.13 Focus Appearance.
كيف تدير جلسة اختبار بلوحة المفاتيح
أبعد الفأرة عن متناول يدك وابدأ والتركيز في شريط العنوان في المتصفح، بحيث يقع أول ضغط على Tab على أول عنصر في الصفحة. تنقّل عبر الصفحة في الاتجاهين وشغّل كل عنصر تحكم. المفاتيح التي تحتاجها:
- Tab وShift+Tab — الانتقال إلى العنصر التالي والسابق القابل للتركيز.
- Enter — تفعيل الروابط والأزرار وإرسال النماذج. Space — تفعيل الأزرار، وتبديل مربعات الاختيار، وفتح بعض القوائم.
- مفاتيح الأسهم — التنقل داخل العناصر المركّبة: مجموعات أزرار الاختيار، والتبويبات، والقوائم، وصناديق القوائم، والمنزلقات، والشبكات.
- Escape — إغلاق نوافذ الحوار والقوائم والنوافذ المنبثقة والتلميحات.
- Home وEnd وPage Up وPage Down — القفز داخل القوائم والمنزلقات والعناصر الطويلة حيث يحددها النمط.
ترتيب التركيز وظهوره وعدم حجبه
يجب أن يتبع ترتيب التركيز ترتيب القراءة في التخطيط: في الصفحة من اليسار إلى اليمين يبدأ من أعلى اليسار إلى أسفل اليمين، وفي الصفحة العربية من اليمين إلى اليسار يبدأ من أعلى اليمين. وينكسر الترتيب عندما يختلف ترتيب DOM عن الترتيب المرئي (إعادة الترتيب بـ CSS grid أو flex، أو اللوحات ذات الموضع المطلق)، أو عندما يستخدم المؤلفون قيم tabindex موجبة تسحب العناصر أمام كل شيء آخر. القيمة tabindex="0" تضيف عنصر تحكم مخصصاً إلى الترتيب الطبيعي، والقيمة tabindex="-1" تجعل العنصر قابلاً للتركيز بالبرمجة فقط؛ أما القيم الموجبة فهي عيب في أغلب الأحوال.
صفحة من اليسار إلى اليمين: dir="ltr"
من أعلى اليسار إلى أسفل اليمين.
- أول ضغطة Tab من شريط العنوان:
- رابط التخطي، أعلى اليسار
صفحة عربية من اليمين إلى اليسار: dir="rtl"
ترتيب DOM نفسه معكوساً: يبدأ من أعلى اليمين.
- أول ضغطة Tab من شريط العنوان:
- رابط التخطي، أعلى اليمين
عيب: قيمة tabindex موجبةفشل
يُسحب الحقل أمام كل شيء آخر: إخفاق في 2.4.3 Focus Order.
- أول ضغطة Tab من شريط العنوان:
- حقل النشرة البريدية في التذييل، قبل رابط التخطي والترويسة
صفحة توضيحية. الأرقام محطات Tab؛ والعنوان بلا رقم لأن أي عنصر غير تفاعلي لا يكون محطة Tab؛ انظر KB-03.
يجب أن يكون مؤشر التركيز مرئياً على كل عنصر قابل للتركيز وعلى كل خلفية يقع عليها. وأكثر أسباب الإخفاق شيوعاً قاعدة «outline: none» عامة دون نمط بديل. افحص الروابط داخل النصوص، والأزرار في الأشرطة الملونة، والبطاقات، وحقول الإدخال في التذييلات الداكنة. يشترط المستوى AA في WCAG 2.2 فقط أن يكون المؤشر مرئياً؛ ويضيف معيار AAA رقم 2.4.13 Focus Appearance متطلبات للحجم والتباين تصلح هدفاً جيداً للتصميم.
وأخيراً تحقق من أن التركيز لا يُحجب بالكامل أبداً. فالترويسات والتذييلات الثابتة، وأشرطة ملفات تعريف الارتباط، وأزرار المحادثة، والأوراق السفلية كثيراً ما تغطي العنصر الذي عليه التركيز أثناء تمرير الصفحة، وهذا إخفاق في 2.4.11 Focus Not Obscured (Minimum). تنقّل بـ Tab في الصفحات الطويلة مع وجود كل العناصر الثابتة، بما في ذلك عند تكبير 200% حيث تغطي جزءاً أكبر من نافذة العرض.
فخاخ لوحة المفاتيح وتجاوز الكتل
فخ لوحة المفاتيح (Keyboard trap) هو أي موضع يستطيع التركيز دخوله ولا يستطيع مغادرته. والمشتبه بهم المعتادون: محتوى الأطراف الثالثة المضمَّن في iframe (الخرائط ومشغلات الفيديو وحقول الدفع)، ومحررات النص المنسق التي تلتقط Tab لإدراج مسافة بادئة، ومنتقيات التاريخ المخصصة، وسكربتات إدارة التركيز في نوافذ الحوار التي تواصل سحب التركيز إليها بعد إغلاقها. اختبر كلاً منها بالدخول بـ Tab ثم محاولة الخروج بـ Tab وShift+Tab وEscape. وإذا تطلب الخروج شيئاً غير معتاد، فيجب أن يخبر المكوّن المستخدم بكيفيته.
أما تجاوز الكتل (Bypass blocks) فيتعلق بالجهد لا بالإمكان. إذا اضطر مستخدم لوحة المفاتيح إلى الضغط على Tab أربعين مرة لتجاوز قائمة التنقل في كل صفحة، فالصفحة قد تكون قابلة للتشغيل لكنها ليست قابلة للاستخدام. ويشترط المعيار 2.4.1 وجود آلية لتخطي الكتل المتكررة. ورابط «التخطي إلى المحتوى الرئيسي» بوصفه أول عنصر قابل للتركيز هو الأكثر مباشرة لمستخدمي لوحة المفاتيح؛ وتخدم المعالم والعناوين مستخدمي قارئات الشاشة أيضاً. تحقق من أن رابط التخطي يظهر عند التركيز عليه، وأن تفعيله ينقل التركيز فعلاً — لا موضع التمرير فقط — بحيث يذهب Tab التالي إلى أول عنصر تحكم في المحتوى الرئيسي.
العناصر المخصصة وأنماط المفاتيح المتوقعة
عناصر التحكم الأصلية في HTML — button، وa مع href، وinput، وselect، وtextarea، وdetails — تأتي بسلوك لوحة مفاتيح مدمج. أما العناصر المخصصة المبنية من div وspan فلا سلوك لها حتى يضيفه المطورون، وأدوار ARIA لا تضيفه أيضاً. ويوثّق دليل ممارسات تأليف ARIA (APG) الصادر عن W3C تفاعل لوحة المفاتيح الذي يتوقعه المستخدمون لكل نمط شائع؛ استخدمه نتيجةً متوقعة في حالات اختبارك. وفي العناصر المركّبة يكون العنصر كله عادةً محطة Tab واحدة، وتتنقل مفاتيح الأسهم داخله.
- الزر — Enter وSpace يفعّلانه. وعنصر div يستجيب للنقر فقط يُعدّ إخفاقاً.
- مربع الاختيار — Space يبدّله. مجموعة أزرار الاختيار — يدخل Tab المجموعة عند الخيار المحدد؛ ومفاتيح الأسهم تتنقل وتحدد.
- التبويبات — ينقل Tab التركيز إلى قائمة التبويبات عند التبويب النشط؛ والسهمان الأيمن والأيسر يتنقلان بين التبويبات؛ وTab مرة أخرى ينتقل إلى اللوحة.
- زر القائمة — Enter أو Space يفتح القائمة ويركّز على أول عنصر (وقد يفتحها السهم للأسفل أيضاً)؛ والأسهم تتنقل؛ وEscape يغلقها ويعيد التركيز إلى الزر.
- مربع التحرير والسرد (Combobox) وصندوق القائمة (Listbox) — السهم للأسفل يفتح الخيارات أو يتنقل فيها؛ وEnter يحدد؛ وEscape يغلق القائمة المنبثقة.
- المنزلق (Slider) — مفاتيح الأسهم تغيّر القيمة بخطوة؛ وHome وEnd ينتقلان إلى الحد الأدنى والأقصى.
- التخطيطات من اليمين إلى اليسار — يحدد APG وظائف مفاتيح الأسهم الأفقية (Right Arrow للتبويب التالي أو لزيادة قيمة المنزلق) دون أن يتناول التخطيطات من اليمين إلى اليسار، فلا يضع قاعدة مستقلة لاتجاه RTL. وفي التخطيط العربي المعكوس، النتيجة المتوقعة المعتمدة في هذا الموضوع (انظر الدليل المحوري لاختبار إمكانية الوصول ودليل اختبار RTL) أن تتبع الأسهم الأفقية الاتجاه المرئي: فالتبويب التالي يقع إلى اليسار، لذا ينتقل إليه السهم الأيسر (Left Arrow)، وفي منزلق معكوس حدّه الأدنى على اليمين يزيد السهم الأيسر القيمة. أما السهمان للأعلى وللأسفل وHome وEnd فتبقى معانيها كما هي. دوّن القاعدة في مواصفة التصميم، وتحقق من أن كل العناصر تطبّقها بالطريقة نفسها.
- الإفصاح والأكورديون — Enter أو Space يوسّع القسم ويطويه.
- نافذة الحوار المشروطة (Modal) — يبقى Tab وShift+Tab داخلها؛ وEscape يغلقها.
نوافذ الحوار المشروطة والقوائم والمحتوى الديناميكي
إدارة التركيز هي الموضع الذي تفشل فيه معظم تطبيقات الصفحة الواحدة. عند فتح نافذة حوار مشروطة يجب أن ينتقل التركيز إليها — إلى الحقل الأول، أو أول عنصر قابل للتنفيذ، أو عنوان النافذة إذا كان المحتوى طويلاً. وما دامت مفتوحة، يجب أن يدور Tab داخلها وألا يمكن الوصول إلى الصفحة خلفها. وعند إغلاقها يجب أن يعود التركيز إلى العنصر الذي فتحها ليكمل المستخدم من حيث كان. ويتولى العنصر الأصلي dialog المفتوح بـ showModal() جزءاً كبيراً من ذلك؛ أما النوافذ المخصصة فيجب أن تفعله بالبرمجة.
طبّق القاعدة نفسها على كل تغيير يطلقه المستخدم: بعد حذف صف، يجب أن ينتقل التركيز إلى صف مجاور أو رسالة حالة، لا أن يعود إلى أعلى المستند؛ وبعد تغيير المسار على جانب العميل، يجب أن ينتقل التركيز إلى عنوان الصفحة الجديدة أو منطقتها الرئيسية؛ والقوائم والنوافذ المنبثقة المفتوحة بلوحة المفاتيح يجب أن تُغلق بـ Escape وتعيد التركيز إلى مطلقها. والمحتوى الذي يظهر عند التمرير بالفأرة يجب أن يظهر أيضاً عند تركيز لوحة المفاتيح وأن يمكن إخفاؤه دون نقل التركيز (1.4.13 Content on Hover or Focus).
حالات اختبار لوحة المفاتيح
نفّذها لكل نوع صفحة ولكل عملية كاملة ضمن النطاق. كل سطر حالة اختبار بنتيجتها المتوقعة؛ وسجّل الإخفاقات مع معيار النجاح.
- KB-01 — أول ضغطة Tab من شريط العنوان تقع على رابط تخطٍّ يظهر عند التركيز عليه.
- KB-02 — تفعيل رابط التخطي ينقل التركيز إلى main؛ وTab التالي يصل إلى أول عنصر تحكم فيه.
- KB-03 — يصل Tab إلى كل عنصر تفاعلي؛ ولا يكون أي عنصر غير تفاعلي محطة Tab.
- KB-04 — يعكس Shift+Tab الترتيب تماماً.
- KB-05 — ترتيب التركيز يطابق ترتيب القراءة (افحص التخطيطين LTR وRTL).
- KB-06 — مؤشر التركيز مرئي على كل محطة وفوق كل خلفية.
- KB-07 — لا يُحجب أي عنصر مركَّز بالكامل خلف ترويسة أو تذييل ثابت أو شريط ملفات تعريف الارتباط أو أداة المحادثة.
- KB-08 — الأزرار تُفعَّل بـ Enter وSpace، والروابط بـ Enter.
- KB-09 — العناصر المخصصة تتبع مفاتيح APG (التبويبات: الأسهم؛ القائمة: Enter/Space وEsc؛ المنزلق: الأسهم وHome/End).
- KB-10 — النافذة المشروطة: ينتقل التركيز إليها عند الفتح، ويدور Tab داخلها، ويغلقها Esc، ويعود التركيز إلى مطلقها.
- KB-11 — لا فخاخ: يستطيع التركيز مغادرة كل عنصر وكل iframe ومشغّل فيديو ومحرّر.
- KB-12 — التلميحات والنوافذ المنبثقة التي تظهر عند التمرير بالفأرة تظهر أيضاً عند التركيز وتُغلق بـ Esc.
- KB-13 — التركيز وحده لا يرسل نموذجاً ولا ينتقل إلى صفحة ولا يغيّر السياق.
- KB-14 — اختصارات المفتاح الواحد يمكن إيقافها أو إعادة تعيينها، أو لا تعمل إلا حين يكون التركيز على المكوّن.
- KB-15 — بعد الحذف أو الإضافة أو تغيير المسار، يقع التركيز على عنصر منطقي لا على جسم المستند (body).
- KB-16 — يمكن إتمام كل عملية كاملة (مثل إتمام الشراء) بلوحة المفاتيح وحدها.
KB-01 First Tab from the address bar lands on a skip link that becomes visible on focus
KB-02 Activating the skip link moves focus to main; next Tab reaches the first control in main
KB-03 Tab reaches every interactive element; nothing non-interactive is a Tab stop
KB-04 Shift+Tab reverses the order exactly
KB-05 Focus order matches the reading order (check LTR and RTL layouts)
KB-06 Focus indicator visible on every stop, on every background
KB-07 No focused element is fully hidden by sticky header, footer, cookie banner or chat widget
KB-08 Buttons activate with Enter and Space; links with Enter
KB-09 Custom widgets follow APG keys (tabs: arrows; menu: Enter/Space, Esc; slider: arrows, Home/End)
KB-10 Modal: focus moves in on open, Tab cycles inside, Esc closes, focus returns to the trigger
KB-11 No trap: focus can leave every widget, iframe, video player and editor
KB-12 Tooltips and popovers shown on hover also show on focus and close with Esc
KB-13 Focus alone never submits, navigates or changes context
KB-14 Single-key shortcuts can be turned off or remapped, or work only when the component has focus
KB-15 After delete, add or route change, focus lands on a sensible element, not the document body
KB-16 Each complete process (e.g. checkout) can be finished with the keyboard onlyجرّبها: مولّد قوائم تحقق QA بالذكاء الاصطناعي جرّبها: مولّد حالات الاختبار
أمثلة على العيوب
مصاغة كعناوين تقارير أخطاء، مع المعيار الذي يخفق فيه كل منها. واذكر في التقرير المتصفح وتسلسل المفاتيح الدقيق والموضع الذي انتهى إليه التركيز.
- «منتقي التاريخ لا يعمل بمفاتيح الأسهم؛ ولا يمكن اختيار التاريخ إلا بالفأرة» — 2.1.1 Keyboard.
- «مربع اختيار الموافقة على الشروط المخصص (div) لا يتبدل بـ Space» — 2.1.1 Keyboard.
- «يعلق تركيز Tab داخل iframe الخريطة المضمّنة في صفحة الفروع» — 2.1.2 No Keyboard Trap.
- «لا رابط تخطٍّ ولا معالم؛ يلزم 42 ضغطة Tab للوصول إلى نتائج البحث» — 2.4.1 Bypass Blocks.
- «قيمة tabindex موجبة على حقل النشرة البريدية ترسل أول ضغطة Tab إلى التذييل قبل رابط التخطي والترويسة» — 2.4.3 Focus Order.
- «ينتقل التركيز إلى بداية المستند بعد إغلاق درج المرشحات» — 2.4.3 Focus Order.
- «أُزيلت حلقة التركيز عن كل الروابط (outline: 0) دون بديل» — 2.4.7 Focus Visible.
- «شريط ملفات تعريف الارتباط الثابت يغطي زر «ادفع الآن» عند التركيز عليه بتكبير 200%» — 2.4.11 Focus Not Obscured (Minimum).
- «التركيز على محدد اللغة يعيد تحميل الصفحة بالعربية فوراً» — 3.2.1 On Focus.
ما الذي يمكن أتمتته
تلتقط محركات القواعد بعض مشكلات لوحة المفاتيح بشكل ثابت — قيم tabindex الموجبة، والأدوار التفاعلية غير القابلة للتركيز، والمناطق القابلة للتمرير دون وصول بلوحة المفاتيح — لكنها لا تحكم على الترتيب أو الظهور. وتسد أتمتة المتصفح جزءاً من الفجوة: فاختبار Playwright أو Cypress أو Selenium يستطيع ضغط المفاتيح والتحقق من العنصر الذي عليه التركيز، مما يجعل التقاط حالات انحدار إدارة التركيز في نوافذ الحوار وتغييرات المسار رخيصاً. واحتفظ بالجولة اليدوية للترتيب والظهور والحجب، فهي تحتاج إلى عين بشرية.
test("edit address dialog returns focus to its trigger", async ({ page }) => {
await page.goto("/account/addresses");
const edit = page.getByRole("button", { name: "Edit address" });
await edit.focus();
await page.keyboard.press("Enter");
await expect(page.getByRole("dialog", { name: "Edit address" })).toBeVisible();
await expect(page.getByRole("textbox", { name: "Street" })).toBeFocused();
await page.keyboard.press("Escape");
await expect(page.getByRole("dialog")).toBeHidden();
await expect(edit).toBeFocused();
});الأسئلة الشائعة
لماذا يتخطى Tab الروابط في Safari على macOS؟
افتراضياً ينقل Safari التركيز بـ Tab بين عناصر النماذج فقط. فعّل خيار «Press Tab to highlight each item on a webpage» في الإعدادات المتقدمة لـ Safari، أو استخدم Option+Tab. وفعّل كذلك التنقل بلوحة المفاتيح في إعدادات لوحة المفاتيح في macOS قبل الاختبار.
هل يجب أن يكون كل عنصر قابلاً للتركيز؟
لا. العناصر التفاعلية وحدها يجب أن تكون محطات Tab. وجعل العناوين أو الفقرات قابلة للتركيز يضيف ضجيجاً لمستخدمي لوحة المفاتيح. استخدم tabindex="-1" عندما يحتاج السكربت إلى نقل التركيز إلى هدف غير تفاعلي، مثل العنوان بعد تغيير المسار.
هل تشترط WCAG وجود رابط تخطٍّ؟
يشترط المعيار 2.4.1 Bypass Blocks وجود آلية لتخطي الكتل المتكررة؛ ورابط التخطي إحدى الطرق، والمعالم والعناوين طرق أخرى. ولمستخدمي لوحة المفاتيح المبصرين يبقى رابط التخطي الذي يظهر عند التركيز الآلية الأكثر مباشرة.
ما الفرق بين Focus Visible وFocus Appearance؟
يشترط 2.4.7 Focus Visible (AA) أن يكون مؤشر التركيز مرئياً. ويضيف 2.4.13 Focus Appearance (AAA) متطلبات على حجم المؤشر وتباينه. واستيفاء AA إلزامي لمعظم الأهداف؛ ومعيار AAA هدف تصميمي جيد.
هل تغني جولة لوحة المفاتيح عن اختبار قارئ الشاشة؟
لا. تُظهر جولة لوحة المفاتيح ما إذا كان يمكن الوصول إلى عناصر التحكم وتشغيلها؛ لكنها لا تُظهر ما إذا كانت لها أسماء وأدوار وحالات صحيحة، أو ما إذا كانت التغييرات تُعلَن. نفّذ الاثنين، ولوحة المفاتيح أولاً.
كيف أختبر الوصول بلوحة المفاتيح في تطبيق جوال؟
اربط لوحة مفاتيح Bluetooth بالجهاز وتنقّل بـ Tab والأسهم، وجرّب الوصول بالتبديل في المنصة. وافحص الأمور نفسها كما في الويب: إمكانية الوصول، والترتيب، والتركيز المرئي، وغياب الفخاخ.
المراجع
- Web Content Accessibility Guidelines (WCAG) 2.2توصية W3C التي تحدد معايير النجاح القابلة للاختبار لإتاحة محتوى الويب، مرتّبةً تحت أربعة مبادئ وثلاثة مستويات مطابقة (A وAA وAAA).
- Understanding WCAG 2.2الشرح التوضيحي لكل إرشاد ومعيار نجاح في WCAG 2.2: الغرض، ومن يستفيد، والأمثلة والتقنيات (غير إلزامي).
- ARIA Authoring Practices Guide (APG)أنماط للعناصر الشائعة (التبويبات والقوائم ونوافذ الحوار والقوائم المنسدلة) مع تفاعل لوحة المفاتيح المتوقع واستخدام ARIA — المرجع الذي تُقارَن به المكونات المخصصة.
- Easy Checks – A First Review of Web Accessibilityفحوص أولية بسيطة يستطيع أي شخص إجراؤها — عنوان الصفحة والبدائل النصية والعناوين والتباين وتكبير النص والوصول بلوحة المفاتيح — قبل التقييم الكامل.
- Accessibility — MDNأدلة عملية لبناء صفحات ويب ميسّرة وفحصها: HTML الدلالي وARIA ودعم لوحة المفاتيح والاختبار.
- Playwright Documentationالتوثيق الرسمي لـ Playwright، إطار الاختبار الشامل الذي يشغّل Chromium وWebKit وFirefox.
تمرين عملي
من ملاحظات جلسة لوحة المفاتيح إلى العيوب
أنت المختبِر في موقع حجز المواعيد لمستشفى خاص (مثال خيالي)، وله واجهة إنجليزية وأخرى عربية. يضيف الإصدار 5.4 صفحة «Book an appointment» لحجز موعد، وهدف إمكانية الوصول هو WCAG 2.2 بالمستوى AA. قبل الاختبار قرأت مقتطفاً مبسّطاً من ترميز الصفحة (Markup)، ثم أجريت جلسة اختبار بلوحة المفاتيح وحدها في Chrome ودوّنت الملاحظات N1–N11. تجد الاثنين أدناه. أما الأسماء والأدوار وما يُعلَن للمستخدم فخارج نطاق اليوم، ومكانها جلسة اختبار قارئ الشاشة.
اعمل على الورق مستعيناً بحالات اختبار لوحة المفاتيح من KB-01 إلى KB-16 وبقائمة معايير النجاح في الدليل. قرّر لكل ملاحظة هل تسجّل إخفاقاً أم سلوكاً متوقعاً، وحوّل الإخفاقات إلى تقارير عيوب يستطيع المطوّر أن يعمل بها. خصّص لذلك 20–30 دقيقة.
موقع حجز المواعيد لمستشفى خاص (مثال خيالي) - ويب، بواجهة إنجليزية وأخرى عربية
يضيف الإصدار 5.4 صفحة «Book an appointment». هدف إمكانية الوصول: WCAG 2.2 بالمستوى AA.
مقتطف من الترميز (مبسّط، بترتيب DOM)
<a class="skip" href="#main">Skip to main content</a>
<header class="site-header">
<a href="/"><img src="logo.svg" alt="Hospital home"></a>
<nav> Home | Clinics | Doctors | Offers | My appointments | Help </nav>
<select aria-label="Language"> English | Arabic </select>
<div class="btn" role="button" tabindex="0" onclick="openSignIn()">Sign in</div>
</header>
<main id="main">
<h1>Book an appointment</h1>
<input type="search" aria-label="Search doctors" tabindex="1">
<div role="tablist"> Dermatology | Dentistry | Paediatrics </div>
<div role="tabpanel"> 6 x (<a href="...">View profile</a> <button>Choose</button>)</div>
<section class="promo"> Winter offers ... <a href="/offers">See offer</a> </section>
<fieldset> Time slot: 8 x <input type="radio" name="slot">, 09:00 ... 12:30 </fieldset>
<div contenteditable="true" aria-label="Notes for the doctor"></div>
<button type="button">Book</button>
</main>
<footer> 4 x <a href="...">...</a>, <a href="/privacy">Privacy</a> </footer>
<button class="chat-launcher">Need help?</button>
<div role="dialog" aria-modal="true" hidden> Confirm booking: Confirm | Cancel </div>
مقتطف من CSS
.site-header { position: sticky; top: 0; }
.chat-launcher { position: fixed; bottom: 16px; }
.promo a:focus { outline: none; } /* no other focus style inside .promo */
وأيضاً: الشريط الترويجي أخضر داكن؛ ولا يكون أي موعد محدداً عند تحميل الصفحة؛
ويفتح «Book» نافذة الحوار بإزالة السمة hidden منها؛ وعلى رابط التخطي سكربت تمرير سلس
يلغي القفز إلى #main ويكتفي بتمرير الصفحة إلى المحتوى الرئيسي.
جلسة لوحة المفاتيح: Chrome على Windows، بناء Staging رقم 5.4.0-rc2، الواجهة الإنجليزية،
وتكبير 100% ما لم يُذكر غير ذلك. أُبعدت الفأرة، والبداية: التركيز في شريط العنوان.
الملاحظة N1: أول ضغطة Tab تضع التركيز على «Search doctors» في المحتوى الرئيسي،
والثانية تُظهر «Skip to main content» أعلى اليسار، ثم تأتي: الشعار، وروابط التنقل
الستة، ومحدد اللغة، و«Sign in».
الملاحظة N2: الضغط على Enter فوق رابط التخطي يمرّر الصفحة إلى «Book an appointment»،
لكن ضغطة Tab التالية تذهب إلى رابط الشعار في الترويسة.
الملاحظة N3: يظهر إطار التركيز على «Sign in»، لكن Enter وSpace لا يفعلان شيئاً.
وعند التحقق لاحقاً بالفأرة فتح النقرُ نافذة تسجيل الدخول.
الملاحظة N4، التبويبات: يقع Tab على التبويب النشط «Dermatology»، وينقل السهم الأيمن
إلى «Dentistry» ويعرض أطباءه، وتدخل ضغطة Tab التالية إلى اللوحة. وفي الواجهة
العربية المعكوسة يقع «الجلدية» على اليمين، وينقل السهم الأيسر إلى «الأسنان».
الملاحظة N5: على «See offer» في الشريط الترويجي لا يظهر أي مؤشر تركيز، بينما
تُظهر الروابط في بقية الصفحة إطاراً أزرق.
الملاحظة N6، المواعيد: يذهب Tab إلى «09:00»، والمواعيد السبعة الأخرى ليست محطات Tab.
وينقل السهم للأسفل إلى «09:30» ويحدده، ثم تذهب ضغطة Tab التالية إلى حقل
الملاحظات «Notes for the doctor».
الملاحظة N7: في حقل «Notes for the doctor» يضيف Tab مسافة بادئة ويزيلها Shift+Tab،
ولا يفعل Esc شيئاً، ولا شيء على الشاشة يوضح كيف تخرج. نقرتَ مرة واحدة تحت
المحرّر لتكمل الجلسة.
الملاحظة N8: الضغط على Enter فوق «Book» يُظهر نافذة «Confirm booking»، لكن التركيز
يبقى على «Book» خلفها. ويمر Tab بروابط التذييل الخمسة وبزر المحادثة «Need help?»
قبل أن يصل إلى «Confirm». ويغلق Esc النافذة، فيضيع التركيز وتعود ضغطة Tab التالية
إلى المحطة الأولى «Search doctors».
الملاحظة N9: بتكبير 200%، وأثناء الرجوع بـ Shift+Tab عبر بطاقات الأطباء، توقف
الزر «Choose» المركَّز مرتين تحت الترويسة الثابتة ولم يظهر منه شيء.
الملاحظة N10: في التذييل يغطي زر المحادثة «Need help?» نحو نصف رابط «Privacy»
المركَّز، ويبقى باقي الرابط وإطار تركيزه ظاهرين.
الملاحظة N11: الضغط على H وحده (دون Ctrl أو Alt) يفتح لوحة Help من أي مكان في
الصفحة عدا حقول النص. ولا يوجد في الإعدادات خيار لإيقافه أو لتغيير المفتاح.- قبل قراءة الملاحظات اقرأ الترميز: توقّع أول خمس محطات Tab بدءاً من شريط العنوان، واذكر ما تتوقع أن يخفق في الترميز ولماذا.
- مرّ على الملاحظات N1–N11. للإخفاق اذكر حالة اختبار KB التي تخفق ومعيار نجاح WCAG 2.2 مع مستواه؛ وللسلوك المتوقع اذكر القاعدة التي يتبعها.
- اكتب لكل إخفاق عنواناً لتقرير خطأ على طريقة أمثلة العيوب في الدليل، مع المعيار، ومع السبب المرجّح حيث يُظهره الترميز.
- أجب عن KB-16: هل يستطيع مستخدم لوحة المفاتيح وحدها إتمام الحجز؟ ثم حدّد أي الإخفاقات يمكن أن يلتقطها محرك قواعد أو اختبار Playwright في التشغيلات اللاحقة، وأيها يحتاج إلى الجولة اليدوية.
إظهار الإجابة النموذجية
الخطوة الأولى، الترميز. أول خمس محطات Tab بالترتيب: «Search doctors»، لأن tabindex="1" يقدّمه على كل ما في الترتيب الطبيعي؛ ثم رابط التخطي؛ ثم رابط الشعار؛ ثم Home؛ ثم Clinics. وبعد «Sign in» تكون المحطة التالية التبويب النشط، ولا يُبلَغ «Search doctors» أبداً في موضعه بعد العنوان. ومن المخاطر التي تستطيع تسميتها قبل الضغط على أي مفتاح: قيمة tabindex الموجبة (خطر على 2.4.3)؛ وسكربت رابط التخطي الذي يلغي القفز ويكتفي بالتمرير، فقد يبقى التركيز على الرابط (خطر على 2.4.1)؛ وعنصر div الذي يحمل role="button" وtabindex="0"، فهو قابل للتركيز ويُعلَن زراً، لكن أياً من السمتين لا يمنحه سلوك Enter أو Space (خطر على 2.1.1)؛ وoutline: none داخل .promo دون بديل (خطر على 2.4.7)؛ والترويسة الثابتة وزر المحادثة الثابت، وقد يغطيان العنصر الذي عليه التركيز، ولا سيما عند تكبير 200% (خطر على 2.4.11)؛ والمحرّر contenteditable الذي قد يلتقط Tab (خطر على 2.1.2)؛ ونافذة الحوار المخصصة، فالسمة aria-modal="true" تخبر التقنيات المساعدة بأن النافذة مشروطة، لكنها لا تنقل التركيز إليها ولا تُبقي Tab داخلها (خطر على 2.4.3). أما ألّا يكون <h1> محطة Tab فصحيح، وكذلك أن تكون أزرار الاختيار الثمانية التي تشترك في name="slot" محطة Tab واحدة. وقراءة الترميز اختبار ساكن (Static testing): تكشف المخاطر وبعض العيوب دون تشغيل أي شيء، ثم تُظهر الجلسة أيها يسبب إخفاقات فعلاً.
N1: إخفاق. تخفق KB-01 (أول ضغطة Tab لا تصل إلى رابط التخطي)، وتخفق KB-05 (الترتيب لا يتبع ترتيب القراءة)، والمعيار هو 2.4.3 Focus Order (A). السبب: tabindex="1" على حقل البحث، والحقل قابل للتركيز من دونه. العنوان: «أول ضغطة Tab تقفز إلى Search doctors في المحتوى الرئيسي قبل رابط التخطي والترويسة (قيمة tabindex موجبة)».
N2: إخفاق، KB-02. سكربت رابط التخطي يمرّر الصفحة ولا ينقل التركيز، فيظل التركيز على الرابط، ويبقى على المستخدم أن يمر بتسع محطات، هي الشعار وروابط التنقل الستة ومحدد اللغة و«Sign in»، قبل أن يبلغ المحتوى الرئيسي. سجّله على 2.4.1 Bypass Blocks (A). وتقبل WCAG المعالم والعناوين أيضاً آليةً للتجاوز، وفي الصفحة <header> و<main> و<h1>، فقد يرى مدقق أن المعيار 2.4.1 مستوفى شكلياً؛ لكنه عيب في الحالتين، لأن الرابط الذي يعتمد عليه مستخدمو لوحة المفاتيح المبصرون لا يفعل ما يَعِد به. المتوقع: ينقل Enter التركيز إلى <main>، وتصل ضغطة Tab التالية إلى أول عنصر تحكم فيه، وهو «Search doctors» بعد إصلاح N1؛ وعلى السكربت الذي يمرّر الصفحة أن ينقل التركيز أيضاً، مثلاً إلى <main> بعد منحه tabindex="-1". العنوان: «رابط التخطي إلى المحتوى الرئيسي يمرّر الصفحة فقط، وضغطة Tab التالية تذهب إلى شعار الترويسة».
N3: إخفاق، KB-08، والمعيار 2.1.1 Keyboard (A). السمتان role="button" وtabindex="0" تجعلان div قابلاً للتركيز وتُعلنانه زراً، لكن أياً منهما لا يضيف سلوك لوحة المفاتيح، ومعالج onclick على div لا يُستدعى عند الضغط على Enter أو Space. الإصلاح المرجّح: عنصر <button> أصلي، فهو يستدعي المعالج نفسه بالمفتاحين. العنوان: «زر Sign in (عنصر div بدور button) يتجاهل Enter وSpace، وتسجيل الدخول لا يعمل إلا بالفأرة».
N5: إخفاق، KB-06، والمعيار 2.4.7 Focus Visible (AA). يُظهر CSS السبب: .promo a:focus { outline: none; } دون أي نمط تركيز آخر. المتوقع: مؤشر تركيز مرئي فوق الشريط الأخضر الداكن. العنوان: «لا مؤشر تركيز على See offer في شريط Winter offers (أُزيلت حلقة التركيز)».
N7: إخفاق، KB-11، والمعيار 2.1.2 No Keyboard Trap (A). يجوز للمحرّر أن يستخدم Tab للمسافة البادئة بشرط وجود طريقة أخرى للخروج، وإن لم تكن مفتاحاً قياسياً وجب إخبار المستخدم بها، مثل «Esc ثم Tab» في تلميح الحقل. وهنا لا شيء يعمل ولا شيء يُقال. العنوان: «التركيز عالق في Notes for the doctor: يغيّر Tab وShift+Tab المسافة البادئة، ولا يفعل Esc شيئاً».
N8: إخفاق، KB-10، مع ثلاث نتائج متوقعة لم تتحقق: لا ينتقل التركيز إلى نافذة الحوار عند فتحها، ويصل Tab إلى الصفحة خلفها، ولا يعود التركيز إلى «Book» عند إغلاقها. سجّله على 2.4.3 Focus Order (A) كما في مثال درج المرشحات في الدليل؛ أما إغلاق النافذة بـ Esc فناجح. ومن المعقول الاكتفاء بتقرير واحد، لأن الثلاث ترجع إلى نقص واحد هو إدارة التركيز في النافذة: العنصر الأصلي dialog المفتوح بـ showModal() يتولى جزءاً كبيراً منها كما يقول الدليل؛ أما النافذة المخصصة فتحتاج إلى سكربت ينقل التركيز إليها ويُبقي Tab داخلها ويعيد التركيز إلى «Book». العنوان: «نافذة تأكيد الحجز: يبقى التركيز على Book خلفها، ويصل Tab إلى الصفحة، ويضيع التركيز عند الإغلاق».
N9: إخفاق، KB-07، والمعيار 2.4.11 Focus Not Obscured (Minimum) (AA)، لأن محتوى وضعه المؤلف، أي الترويسة الثابتة، يحجب الزر الذي عليه التركيز بالكامل. اكتب الظروف في التقرير: تكبير 200%، والتنقل بـ Shift+Tab، والبطاقات التي حدث فيها ذلك. ومن الإصلاحات الشائعة ترك مسافة بارتفاع الترويسة حين تُمرَّر الصفحة إلى العنصر الذي عليه التركيز، مثلاً بالخاصية scroll-padding-top في CSS. العنوان: «عند تكبير 200% تحجب الترويسة الثابتة زر Choose المركَّز بالكامل أثناء التنقل إلى الخلف».
N11: إخفاق، KB-14، والمعيار 2.1.4 Character Key Shortcuts (A). لا يُسمح باختصار الحرف الواحد إلا إذا أمكن للمستخدم إيقافه، أو إعادة تعيينه ليشمل مفتاحاً معدِّلاً مثل Ctrl أو Alt، أو إذا كان لا يعمل إلا حين يكون التركيز على مكوّن بعينه؛ والمفتاح H يعمل في الصفحة كلها ولا ينطبق عليه أي من الثلاثة. ويؤثر هذا أكثر ما يؤثر في مستخدمي الإدخال الصوتي، إذ قد تتحول كلماتهم المنطوقة إلى ضغطات مفاتيح، وفي كل من يضغط مفتاحاً عن غير قصد. العنوان: «اختصار المفتاح الواحد H يفتح Help من أي مكان في الصفحة، ولا يمكن إيقافه أو تغييره».
سلوك متوقع، لا عيوب. الملاحظة N4 ناجحة وفق KB-09: يقع Tab على التبويب النشط، وتتنقل الأسهم بين التبويبات، وتدخل ضغطة Tab التالية إلى اللوحة، كما يصف نمط التبويبات في APG؛ وفي الواجهة العربية المعكوسة، انتقال السهم الأيسر إلى التبويب التالي هو النتيجة المتوقعة المعتمدة في هذا الموضوع، لأن الأسهم الأفقية تتبع الاتجاه المرئي. سجّلها ناجحة، وتحقق من أن العناصر الأفقية الأخرى تطبّق القاعدة نفسها. والملاحظة N6 تستوفي KB-03 ونمط مجموعة أزرار الاختيار: المجموعة محطة Tab واحدة، يدخلها Tab عند الخيار المحدد، أو عند الأول إن لم يُحدَّد شيء، والأسهم تتنقل وتحدد؛ فالإبلاغ بأن «Tab يتخطى 7 مواعيد» إيجابية كاذبة (False positive). أما N10 فليست إخفاقاً في المستوى AA: لا يخفق المعيار 2.4.11 ولا KB-07 إلا إذا حُجب العنصر المركَّز بالكامل، وهنا يبقى نصف الرابط وإطار تركيزه ظاهرين. لكنها تخفق في معيار المستوى AAA وهو 2.4.12 Focus Not Obscured (Enhanced)، الذي لا يسمح بحجب أي جزء؛ ومع هدف AA سجّلها تحسيناً مقترحاً لا إخفاقاً في AA.
تخفق KB-16: لا يستطيع مستخدم لوحة المفاتيح وحدها إتمام الحجز، لأن التركيز يعلق في «Notes for the doctor» قبل زر «Book»، كما في الملاحظة N7، ولم تتجاوزه إلا بالفأرة. لذلك أبلِغ عن N7 أولاً. ويُقصي N3 أيضاً مستخدمي لوحة المفاتيح عن تسجيل الدخول. المجموع ثمانية إخفاقات: ستة من المستوى A، هي N1 وN2 وN3 وN7 وN8 وN11، واثنان من المستوى AA، هما N5 وN9؛ وملاحظتان لسلوك متوقع، هما N4 وN6؛ وتحسين واحد من المستوى AAA، هو N10. وبمصطلحات ISTQB: الملاحظات تسجّل سلوكاً لوحظ، والإخفاق انحراف عن النتيجة المتوقعة، والعيب هو سببه في الشيفرة، مثل tabindex="1" أو حلقة التركيز المُزالة.
الأتمتة للتشغيلات اللاحقة. يلتقط محرك القواعد قيمة tabindex الموجبة في N1 دون الضغط على أي مفتاح. وتناسب اختباراتُ Playwright التي تضغط المفاتيح وتتحقق من العنصر الذي عليه التركيز إصلاحاتِ السلوك: أن ينقل رابط التخطي التركيز إلى <main> في N2، وأن يفتح Enter وSpace على «Sign in» نافذة تسجيل الدخول في N3، وأن يغادر Tab محرّر الملاحظات بالطريقة المتفق عليها في N7، وأن تأخذ نافذة الحوار التركيز وتُبقي Tab داخلها وتعيده إلى «Book» في N8، مثل مثال الدليل، وألّا يفتح المفتاح H لوحة Help خارج الشروط المتفق عليها في N11. واحتفظ بالجولة اليدوية لما يحتاج إلى عين بشرية: المؤشر المرئي فوق كل خلفية في N5، والتركيز المحجوب خلف المحتوى الثابت في N9 وN10، ومنطقية الترتيب في التخطيطين في N1 وN4. ويحتاج كل تقرير أيضاً إلى المتصفح وتسلسل المفاتيح الدقيق والموضع الذي انتهى إليه التركيز، كما يطلب الدليل، وإلى رقم البناء؛ والملاحظات تعطيك الأربعة.
إن اختلفت إجابتك فتحقق من ثلاثة أمور: أن كل إخفاق يذكر المعيار الذي تأتي منه نتيجته المتوقعة؛ وأن N4 وN6 وN10 لم تُسجَّل إخفاقات في المستوى AA؛ وأن كل عنوان يقول ماذا يحدث وأين وبأي مفتاح، ليستطيع المطوّر إعادة إنتاجه.
تقدّمك في هذا الموضوع
سجّل الدخول لتتابع تقدّمك
علّم الموضوعات مكتملة، وتابع من حيث توقفت، وافتح امتحانات التخصص.
جزء من مسار تعلم ضمان الجودة
قبل هذا الموضوع
الموضوعات التالية
الأدوات المذكورة في هذا الدليل
ولّد قائمة تحقق QA مخصّصة (وظيفية وواجهة مستخدم وAPI وأمان وأداء وإمكانية وصول وإصدار) لأي ميزة باستخدام الذكاء الاصطناعي من متقن.
ولّد حالات اختبار منظّمة (المعرّف والعنوان والشروط المسبقة والخطوات والنتيجة المتوقّعة والأولوية) من وصف الميزة وقائمة الحقول.
ولّد عناوين أخطاء واضحة وقابلة للبحث من وصف غير مرتّب باستخدام الذكاء الاصطناعي من متقن.