خارطة الطريق
تستعرض هذه الصفحة الأهداف المتبقية للوصول إلى الغاية المنشودة لبنية وكيل المنصة الأصلي:
Simple Playwright-style test API -> Astur core -> Astur platform driver -> persistent native platform agent -> UiAutomator / XCUITestما تم إنجازه حتى الآن
Section titled “ما تم إنجازه حتى الآن”كتابة الاختبارات
Section titled “كتابة الاختبارات”- المُحدِّدات القابلة للتركيب (Composable Locators) (غير مُصدَرة بعد): حصر البحث داخل عنصر أب، والتصفية عبر
filter({ hasText, hasNotText, has, hasNot })، والدمج المنطقي بـand()وor()، والاختيار بالموضع عبرfirst()وlast()وnth(i). يُحل التركيب مقابل لقطة واحدة من الشجرة على المضيف بدلاً من تمريره إلى الوكلاء (Agents)، ما يبقي المُحدِّد الذي يستقبله المشغّل كما هو تماماً ولا يستدعي أي تغيير في بروتوكول الوكيل على أيٍّ من المنصتين. وإذا وصل المُحدِّد المُركّب إلى عنصر يمكن تسميته بشكل فريد، يُمرَّر مُحدِّده البسيط إلى المشغّل ليطابق سلوك المُحدِّد العادي بدلاً من الهبوط إلى الإحداثيات. - قارئات حالة العناصر ووسائل الراحة (0.5.0-beta):
textContent()وinputValue()وbounds()وcount()وisEnabled()/isDisabled()/isSelected()/isFocused()وclear()، إضافة إلىwaitFor({ state })بأسلوب Playwright. getByPlaceholder()وisChecked()وisEmpty()(غير مُصدَرة بعد)، مع المُطابِقَينtoBeCheckedوtoBeEmpty. وحالة التحديد ثلاثية: العنصر الذي لا يُبلّغ عنها تُسجَّل حالته «غير معروفة» لاfalse.by.native({ ios, android })— مخرج الطوارئ للمُحدِّدات الأصلية (0.5.0-beta)، للعنصر النادر الذي تعجز عنهby.labelوby.idوby.textوby.roleوby.type. الخيارiosهو نص استعلامNSPredicateخام خاص بـ XCUITest — وهي قواعد الاستعلام التصريحية من Apple نفسها، وليست شيفرة قابلة للتنفيذ. أماandroidفهو سلسلة مُهيكلة (className،textContains،resourceId،hasChild،hasDescendant، …) مبنية بالكامل على واجهةBy/BySelectorمن androidx.test.uiautomator — وهي عن قصد ليست لغة تعبيرات حرة: بلاeval، وبلا مُحلِّل خاص، وبلا مُترجم. ويختار الحقل الاختياريinstanceالتطابق رقم n على كلتا المنصتين. يتطلب وكيلاً أصلياً متصلاً. وتبقى استراتيجيةxpathمحجوزة وغير مُنفَّذة، ورسالة خطئها تشير إلى هنا.- البحث متعدد التطابقات أصلياً على Android (0.5.0-beta): يوفّر وكيل UiAutomator الأمرين
element.findAllوelement.findMany، فتُحلqueryAll()وcount()وdevice.findAll()وdevice.findMany()على الجهاز في جولة واحدة بدل سحب شجرة الواجهة كاملة. وتعود الوكلاء الأقدم تلقائياً إلى المسار السابق، أما وكيل iOS فكان يوفّرهما أصلاً.
ما الذي يمكن اختباره
Section titled “ما الذي يمكن اختباره”- Flutter على المنصتين: خدمة Dart VM (شجرة الودجات الحية) على Android، وشجرة إمكانية الوصول لـ XCUITest على iOS مع احتياطي للمطابقة الجزئية على مستوى الوكيل يغطي تسميات Flutter المدمجة.
- التحكم بـ DOM داخل WebView عبر
device.webContext()— جسر يحقن JavaScript ولا يرتبط بمحرك معين، ويقود WebView في تطبيقات Flutter و React Native. مدعوم على Android (Chromium/CDP) وعلى iOS في المحاكي والأجهزة الحقيقية (WKWebView عبرios-webkit-debug-proxy، ويُجسَر المحاكي تلقائياً عبر مقبسwebinspectord_simالخاص به). كما يدمج المُفتّش (Inspector) شجرة DOM ضمن شجرة الواجهة مع مُحدِّدات حقيقية وإمكانية الملء والنقر. - الويب على الجوال (0.6.0-beta): تقود
device.browserصفحة داخل متصفح الجهاز نفسه — Chrome على Android و Safari على iOS. والإعداد الذي يضبطbrowserدونappيُنشئ جلسة متصفح فقط لا تُثبّت شيئاً وتجعل الوكيل الأصلي اختيارياً. يحصل Android على تبويب لكل اختبار، بينما يعيد iOS استخدام تبويب واحد ويحدّثه لأن WebKit لا يكشف دورة حياة التبويب. - مراقبة الشبكة (0.5.0-beta.5): تُبلّغ
device.networkعن حركة HTTP الخاصة بالتطبيق — عبر نطاقNetworkفي CDP لتطبيقات React Native على المنصتين، وعبر مُحلِّل HTTP في Dart VM لتطبيقات Flutter. وتُعلَن التغطية من خلالcapabilities()ليتخطى الاختبار نفسه مع ذكر السبب بدل أن يفشل حيث تتعذر المراقبة. - المقارنة البصرية (0.5.0-beta.5): تعمل
toHaveScreenshot()مقابل صور مرجعية خاصة بكل جهاز، مع الإخفاء (Masking) وحدود التسامح وعرض الفروق كصور في تقرير HTML. وتُفهرَس الصور المرجعية حسب المنصة ومحرك العرض ومقاس الشاشة.
الجهاز والأدوات
Section titled “الجهاز والأدوات”- استكشاف التطبيقات والجهاز (غير مُصدَرة بعد):
device.app.list()وdevice.app.foreground()وdevice.orientation.get(). - الأمر
astur screenshot(غير مُصدَر بعد) يلتقط شاشة الجهاز كصورة PNG دون كتابة اختبار. - تحصين المُفتّش والتوليد التلقائي للشيفرة (0.5.0-beta): يسجّل مُؤلِّف التأكيدات مجموعة المُطابِقات كاملة، وتُسجَّل إيماءات السحب ضمن الشيفرة المولَّدة، وتُرفض خطوات الملء والتأكيد التي لا تحمل مُحدِّداً بدل إنتاج شيفرة معطوبة، ويمكن التصدير بصيغة TypeScript أو JavaScript، ولم يعد الفتح التلقائي للمتصفح يُعطّل الأداة على Windows (#10).
- يُعيد وكيلا Android و iOS تشخيصات مُهيكلة للتوقيت والأعطال عبر البروتوكول المشترك، وتتضمن أعطال قابلية التنفيذ المُحدِّد ولقطة العنصر المرشّح وحالته من حيث الظهور والتفعيل وقابلية النقر والثبات حيثما تكشفها المنصة. ويحتفظ
AsturErrorعلى المضيف بهذه التفاصيل بدل إسقاطها عند حدود النقل. - سير عمل يدوي للفحص السريع على أجهزة ذاتية الاستضافة يفرض مسارات الوكيل الإلزامية على Android ومحاكي iOS وأجهزة iOS الحقيقية المُوقَّعة.
- التوثيق باللغة العربية (0.6.0-beta): جميع الصفحات، على المسار
/ar/.
الخصائص الجاري العمل عليها
Section titled “الخصائص الجاري العمل عليها”- الإجراءات المُعنونة بالفهرس على المسار الأصلي: تُحل
nth(n).tap()فهرسها على المضيف، لذا يعود أي إجراء على مُحدِّد مُركّب يتعذّر تسميته بشكل فريد إلى الإحداثيات. وإضافة معامل فهرس للعنصر في بروتوكول الوكيل ستُبقيه أصلياً من طرف إلى طرف. ويحل الحقلinstanceفيby.native()هذه المسألة اليوم لحالة مخرج الطوارئ تحديداً. - الدالة
fill()على مُحدِّد مُركّب يصل إلى عنصر لا يمكن تسميته: تنقر لتركيز المؤشر ثم تكتب، وهو ما لا يسمح بمسح الحقل أولاً. ويُبلَّغ عن تعذّر ذلك باسمCOMPOSED_LOCATOR_FILL_UNSUPPORTED. - تغطية الإيماءات والإدخال: لا توجد بعد إيماءات التكبير والتصغير (Pinch/Zoom)، ولا تزال
clear()تمر عبرfill('')— وأمر مسح نص أصلي مخصص سيكون أكثر دقة على المنصتين. - التطبيق في المقدمة على iOS: لا يُبلّغ عنه لا
simctlولاdevicectl، ومُشغّل XCTest محصور بالتطبيق الذي أطلقه. أما Android فيقرأه منdumpsys. - اتجاه الشاشة على iOS مُشتق من هندسة إطار العرض، لذا لا يُميَّز بين اتجاهي الوضع الأفقي.
- السحب والإفلات في Flutter على iOS: لا تُسجَّل سوى أول عملية سحب اصطناعية من XCUITest ضمن السلسلة لدى مُتعرِّف الإيماءات في Flutter، ويلزم حاقن سحب متعدد الخطوات (أحداث حركة حقيقية) لتحقيق التكافؤ مع مشغّل Dart VM على Android.
- أجهزة iOS الحقيقية لاستهداف المتصفح: المسار البرمجي موجود (
devicectlثم Safari) لكنه لم يُجرَّب على جهاز فعلي. - عزل بيانات التخزين في المتصفح: التبويب ليس سياق متصفح (Browser Context) بمفهوم Playwright، ولا توفّر أيٌّ من المنصتين ملف تعريف لكل تبويب — فملفات الارتباط و
localStorageمُشتركة. وهذا قيد من قيود المنصة لا بند في قائمة العمل. - لا تستطيع بيئات التكامل المستمر السحابية الافتراضية تشغيل أجهزة جوال حقيقية، وتتطلب مهام الفحص على iOS المُوقَّع و Android الفعلي أجهزة ذاتية الاستضافة تحمل الوسوم المناسبة.
- لا يزال العمل جارياً على توسيع تقارير المُحدِّدات الصارمة، بما فيها قوائم المرشحين المُرتّبة لكل استراتيجية تحديد.
- لا تزال جدولة مجمّعات الأجهزة للأهداف السحابية ومزارع الأجهزة قيد التخطيط، والإعداد السحابي الحالي هيكل أولي لا مسار تنفيذ.
- يحتاج المُفتّش والتوليد التلقائي على أجهزة iOS الحقيقية إلى بث مُصغّر للشجرة الأصلية حتى لا تُعطّل لقطات XCTest الواسعة الشجرة الحية على الشاشات الكبيرة.
- يختار الحقل
instanceفيby.native()على Android التطابق رقم n بعد تطبيق كل قيودhasChildوhasDescendant، لكن لا يوجد مكافئ لتضمين «الابن رقم n لأب محدد» داخل الشرط نفسه — بل عند جذر السلسلة فقط.
الأولويات والخطوات القادمة
Section titled “الأولويات والخطوات القادمة”- تكافؤ المسار الأصلي للمُحدِّدات المُركّبة
- إضافة معامل فهرس للعنصر في بروتوكول الوكيل لتبقى
nth(n).tap()وfill()المُركّبة على المسار الأصلي بدل الهبوط إلى الإحداثيات. - إضافة أمر أصلي مخصص لمسح النص، وهو ما يفتحه العمل نفسه.
- تشخيصات الوكيل والتكافؤ
- إبقاء أشكال نتائج البروتوكول على Android و iOS متوائمة ومُختبرة تعاقدياً.
- توسيع تشخيصات المرشحين للمُحدِّدات المعقّدة دون أن تدفع الإجراءات الاعتيادية ثمن سحب الشجرة كاملة.
- صقل مسار التفاعل الذرّي
- إبقاء البحث والانتظار والتنفيذ ضمن مسار أمر أصلي واحد على المنصتين.
- توسيع تغطية الأدوار وعناصر التحكم مثل أشرطة التمرير ومنتقيات الوسائط والتنبيهات.
- إضافة إيماءات التكبير والتصغير.
- التنفيذ المتوازي
- مواصلة توسيع مجمّعات الأجهزة ليتمكن التوزيع التلقائي للعاملين على الأجهزة المحلية والبعيدة.
- إبقاء المشاريع متعددة المنصات معزولة بمُعرّف الجهاز ومجلد المخرجات.
- الموثوقية والقياس
- عرض توقيت الأوامر وبيانات التتبع باتساق في التقارير، بحيث يكشف التشغيل غير المستقر ما إذا كان التأخير في النقل على المضيف أم في البحث الأصلي أم في تصيير التطبيق أم في تنفيذ الإجراء.
- إضافة توقيتات خاصة بالمُفتّش لتحديث اللقطة وتحديث الشجرة واختبار الإصابة وتسجيل الإجراءات.
- فرض التكامل المستمر والترحيل
- إبقاء سير عمل الفحص بالوكيل الإلزامي ناجحاً على أجهزة Android و iOS ذاتية الاستضافة.
- إبقاء المسارات الاحتياطية للتطوير المحلي حتى تستقر مجموعات الوكيل بما يكفي لجعل مساره إلزامياً في كل مكان.
تجربة المطور المنشودة
Section titled “تجربة المطور المنشودة”هدفنا الأساسي هو ضمان بقاء الأكواد نظيفة، مقروءة، وبسيطة كالتالي:
await device.getByRole('button', { name: 'Sign in' }).tap();await expect(device.getByText('Welcome')).toBeVisible();يجب أن تتكفل بيئة الـ Astur ووكلائها الأصليين (Native Agents) بكافة التفاصيل المُرهقة الخاصة بالانتظار، الترجمة، والفروقات المعقدة بين المنصات، ليبقى تركيزك مُنصباً بالكامل على منطق الاختبار.

