ملاحظات الإصدار
تعرف على أحدث الميزات والتحسينات في كل إصدار من Astur.
0.6.0-beta
Section titled “0.6.0-beta”اختبار موقع الويب داخل متصفح الجهاز نفسه. تتيح لك device.browser قيادة متصفح Chrome على Android ومتصفح Safari على iOS، وذلك على نفس المحاكي (Emulator) أو المُحاكي (Simulator) أو الجهاز الحقيقي الذي تعمل عليه اختباراتك الأصلية (Native) — وبذلك يمكن تغطية موقع متجاوب وتطبيق أصلي في تشغيلة واحدة وتقرير واحد.
const page = await device.browser.open('https://example.com/pricing');await expect(page.getByRole('heading', { name: 'Pricing' })).toBeVisible();await page.getByTestId('plan-pro').tap();تشمل الواجهة: open، navigate، reload، back، forward، url، و capabilities — وهذه الأخيرة تُجيب على كل المنصات، ما يسمح للاختبار بأن يتخطى نفسه عبر test.skip() مع ذكر السبب، تماماً كما تفعل device.network حالياً. كل عملية تنقل تُعيد كائن WebContext الحيّ، وهو ذات الكائن الذي تُرجعه device.webContext()، لذا تعمل جميع المُحدِّدات (Locators) والإجراءات دون أي تعديل.
اضبط browser بدلاً من app لتتحول الجلسة إلى جلسة متصفح فقط (Browser-only): لا تثبيت للتطبيق، ويصبح الوكيل الأصلي (Native Agent) اختيارياً بدلاً من كونه إلزامياً. وعلى iOS تحديداً، هذا هو الفرق بين فتح صفحة ويب وبين الحاجة إلى هوية توقيع (Signing Identity) أولاً.
يجدر بالذكر أن Playwright يختبر ويب الجوال بكفاءة عبر محاكاة الأجهزة (Device Emulation)، وهو أسرع في بيئات الـ CI. أما هذه الميزة فهي مخصصة للحالة التي لا تكفي فيها المحاكاة: متصفح جوال حقيقي، على نفس مجموعة الأجهزة، وضمن نفس التقرير الذي يضم اختباراتك الأصلية.
ثلاث معضلات جرى حلّها لتحقيق ذلك، بما يتجاوز ناقل الـ DOM القائم:
- تبويب (Tab) لكل اختبار، يُغلق عند انتهائه، على غرار ما يفعله Playwright حين يمنح كل اختبار صفحته الخاصة. يقوم Android بإنشاء التبويبات وإغلاقها عبر مقبس التنقيح (Debugging Socket). أما WebKit فلا يكشف دورة حياة التبويب، لذا يعيد iOS استخدام تبويب واحد ويحدّثه — ولهذا فإن
open()تُحمّل الصفحة دائماً حتى لو كان التبويب يعرض العنوان ذاته، لأن التبويب المُعاد استخدامه يحمل بقايا الـ DOM من الاختبار السابق. - الاستقرار على المستند (Document) لا على العنوان (URL). عملية إعادة التحميل تُبقي العنوان كما هو، وبالتالي فإن أي انتظار مبني على العنوان سيعود فوراً ويسلّمك الصفحة القديمة. لذا يزرع Astur رمزاً (Token) على
windowوينتظر اختفاءه، وهي اللحظة الدقيقة التي يُستبدل فيها المستند فعلياً. - اكتشاف شاشة التشغيل الأول. لا يُنشئ Chrome أي مقبس تنقيح قبل إتمام شاشة الترحيب، ما يعني أن محاكياً جديداً سينتظر إلى ما لا نهاية صفحةً لن تظهر أبداً. يُبلَّغ عن هذه الحالة الآن باسم
BROWSER_FIRST_RUN_PENDINGبدلاً من انتهاء المهلة.
القيود
Section titled “القيود”من المهم معرفتها قبل بناء مجموعة اختبارات على هذه الميزة: التبويب ليس سياق متصفح (Browser Context) بمفهوم Playwright — فملفات الارتباط (Cookies) و localStorage تعود لملف تعريف المتصفح وتُشارَك بين التبويبات. كما أن واجهة المتصفح نفسها هي عناصر أصلية (Native) وليست جزءاً من الصفحة. وأخيراً، مسار أجهزة iOS الحقيقية مكتوب برمجياً لكن لم يجرِ التحقق منه على جهاز فعلي بعد. تجد القائمة الكاملة في صفحة الويب على الجوال.
التوثيق متوفر الآن باللغة العربية، عبر /ar/ — جميع الصفحات، مع الإبقاء على أسماء الواجهات البرمجية والبروتوكولات بالإنجليزية كما هي.
الإصلاحات
Section titled “الإصلاحات”- كان بالإمكان قيادة WebView الخاص بالتطبيق عبر المتصفح بالخطأ. يسمّي Android المقابس بالصيغتين
webview_devtools_remote_<pid>وchrome_devtools_remote، وهي تُرتَّب أبجدياً — لذا كانتdevice.webContext()ترتبط بالمتصفح بدلاً من التطبيق قيد الاختبار عند تشغيل Chrome. أصبحت المقابس الآن تُرتَّب وفقاً لما طلبه المُستدعي.
للاطلاع على التفاصيل الكاملة، راجع سجل التغييرات.
0.5.0-beta.5
Section titled “0.5.0-beta.5”مقارنة لقطات الشاشة بذكاء. تُتيح لك الدالة toHaveScreenshot() فحص مكون معين أو الشاشة بأكملها ومطابقتها مع صورة مرجعية (Baseline) محفوظة مسبقاً. وبذلك، سيفشل الاختبار تلقائياً عند اكتشاف أي تغيير بصري غير متوقع بدلاً من تجاوزه بصمت. وعلى غرار مطابِق Playwright الذي يعتمد على كائن الـ Page، توفر هذه الدالة النسخة الأصلية (Native) والمكافئة له:
await expect(app.home.heroCard).toHaveScreenshot('hero-card.png');// أو فحص الشاشة مع استثناء أجزاء متغيرة:await expect(device).toHaveScreenshot('home.png', { mask: [device.getById('clock')] });يتم حفظ الصور المرجعية بشكل مُنظم لكل منصة، محرك عرض (Engine)، ومقاس شاشة.
- استخدم
maskلتغطية الأجزاء المعرضة للتغيير الطبيعي (كالساعات أو العدادات). - تحكم في مستوى التسامح البصري عبر خيارات:
threshold،maxDiffPixels، وmaxDiffPixelRatio. - عند حدوث فشل، سيُظهر تقرير Playwright (بصيغة HTML) الفروق بشكل دقيق من خلال تبويبات: Diff / Actual / Expected / Slider.
مراقبة الشبكة لتطبيقات React Native (على Android و iOS).
أصبحت الأداة device.network قادرة على قراءة نطاق الـ Network من خلال بروتوكول CDP (وهو ذات النطاق الذي تعتمد عليه React Native DevTools). ولأن المُبلغ البرمجي يقع في نواة ReactCommon المشتركة، فإن هذا التحديث يغطي كلا المنصتين في آنٍ واحد.
const capabilities = await device.network.capabilities();test.skip(!capabilities.observe, capabilities.coverage);يُشترط لنجاح هذه المراقبة أمران أساسيان:
- استخدام بناء Debug مرتبط بـ Metro (حيث يتم استبعاد المُبلغ في البناء النهائي Release).
- أن تكون الطلبات صادرة عبر
XMLHttpRequest(والتي تشمل الـfetchالمُدعم داخل React Native وكذلكaxios). (ملاحظة: لا يشمل الرصد استخدامfetchالأصلي في إطار Expo لأنه يتجاوز طبقة الشبكة المراقبة كلياً).
مراقبة الشبكة لمحاكيات Flutter و iOS. بنفس مستوى الكفاءة المتوفر لـ Flutter على Android، دون أي متطلبات إضافية لتثبيت أو تشغيل التطبيق.
إصلاحات هامة
Section titled “إصلاحات هامة”- سلوك الخيار
--update-snapshots: في السابق، كان الخيار المُبسط-uيُطبق كأنهallدون مبرر. تم إصلاح ذلك ليعمل كـchanged، مما يجعله أكثر كفاءة ودقة عند قبول التغييرات المقصودة. - الفصل الدقيق بين صور Flutter و React Native على iOS: كان النظام يخلط بين صور إطاري العمل على نظام iOS. تم تحديث النظام ليُحدد محرك العرض بشكل دقيق بناءً على حزمة التطبيق. وقد تم إعادة تسجيل الصور المرجعية التي طالتها هذه المشكلة في الإصدار السابق (beta.4).
للاطلاع على السجل الكامل، راجع سجل التغييرات الشامل.
0.5.0-beta.4
Section titled “0.5.0-beta.4”الكتابة المباشرة في الحقول صعبة التحديد. تواجه بعض الحقول تعقيدات تجعل استهدافها مستحيلاً (كحقول الـ OTP المكونة من عدة صناديق منفصلة والتي تُبقي الحقل الفعلي خارج نطاق إمكانية الوصول). الآن، يمكنك إرسال النصوص مباشرة إلى العنصر المفتوح الذي يمتلك التركيز (Focus) عبر لوحة المفاتيح:
await device.getByTestId('otp-input').tap();await device.keyboard.type('123456');- يعمل هذا الكود بتناغم على iOS و Android معاً في نفس ملف الاختبار؛ ففي iOS يقوم XCUITest بالكتابة للمُستجيب الحالي (First Responder)، وفي Android يُرسل المُدخل لعنصر المُركز.
- أصبحت الدالة
pressKey()تكتب حرفاً مطبوعاً منفرداً على المنصتين دون الحاجة لمعاملات خاصة، مما أصلح مشكلة قديمة في Android حيث كان الرقم 4 يُترجم بالخطأ كزر التراجعBACK. - في حال استدعاء الدالة دون وجود لوحة مفاتيح ظاهرة على الشاشة في iOS، سيُطلق النظام خطأ
KEYBOARD_NOT_VISIBLEبشكل صريح بدلاً من التجاهل الصامت.
إصلاح مشكلة “لوحة المفاتيح الوهمية” على Android.
كانت حالة اللوحة في Android تعتمد على مؤشرات غير دقيقة تُوهم النظام بوجود لوحة مفاتيح تغطي الشاشة، مما يُجبر Astur على محاولة إخفائها بمحاكاة النقر على زر التراجع (Back) والخروج من الشاشة بالخطأ.
الآن، تم تحديث النظام ليعتمد على مصدر موثوق لأبعاد اللوحة (WindowInsets)، متجاهلاً الإطارات الفارغة (عديمة الارتفاع). (يتطلب هذا الإصلاح استخدام الوكيل المُحدث المرفق مع @astur-mobile/android).
نصيحة: لا يزال يُفضل استخدام الدالة fill() لملء الحقول القابلة للاستهداف متى ما أمكن، كونها تمسح الحقل وتتأكد من القيمة المدخلة بكفاءة. للمزيد، راجع التعامل مع لوحة المفاتيح والتعبئة.
0.5.0-beta.3
Section titled “0.5.0-beta.3”مراقبة استجابات التطبيق في الوقت الفعلي.
أضفنا دالة device.network الجديدة التي تكشف تفاصيل حركة الـ HTTP أثناء إجراء الاختبار، لتتمكن من فحص الطلبات الفعلية عوضاً عن الاعتماد على التأثيرات البصرية فقط.
const capabilities = await device.network.capabilities();test.skip(!capabilities.observe, capabilities.coverage);
await device.network.clear();await app.login.signIn('qa@astur.dev', 'Astur12345');
const [request] = await device.network.requests({ url: '/api/session' });expect(request).toMatchObject({ method: 'POST', status: 201 });- الميزة مُتاحة لتطبيقات Flutter/Android من خلال مُحلل الـ HTTP الخاص بـ Dart VM، والذي يشمل مكتبات كـ
package:httpوDio. - استعن بالدالة
capabilities()للحصول على تقرير دقيق حول إمكانية الرصد للمنصة الحالية وتخطي الاختبار بشكل منظم في حال عدم الدعم. - يتم تصفية الترويسات الحساسة (Credentials) والحد من أحجام الردود بشكل افتراضي كإجراءات حماية، مع تفريغ سجل التخزين بين الاختبارات.
- ميزة الاعتراض (Intercept) كالتأخير أو تزييف الاستجابات غير متوفرة بعد في هذا الإصدار لاعتمادها على محوّلات مدمجة (In-App Adapters).
إصلاحات لأخطاء كانت تُعطل التشغيلات الكبيرة:
- حُلت مشكلة تدخل وكيل UiAutomator الذي كان يستولي على التفاعلات في جلسات Flutter، مما كان يؤدي لإرسال التطبيق للخلفية وإيقاف الـ Dart VM بالخطأ.
- فشل إجراء النقر على العنصر المُركب لم يُعد يُجهض الاختبار بالكامل، بل يتحول لنقرة إحداثية، مما أصلح مشاكل منتقي الوسائط في React Native على Android.
- إيماءات التمرير (Scroll) أصبحت أكثر انضباطاً (بمعدل 1200 مللي ثانية) بعد أن كانت تتم كقفزات سريعة جداً.
- تمت معالجة مشكلة التجميد (Hang) التي كانت تستمر لـ 7 دقائق متصلة بخدمة Flutter VM؛ أصبحت المحاولات الآن محدودة ومرتبطة بمهلة زمنية (Timeout) واضحة.
0.5.0-beta.2
Section titled “0.5.0-beta.2”الميزات الجديدة
Section titled “الميزات الجديدة”- المُحدد الخام
by.native({ ios, android }): مخرج طوارئ قوي جداً للوصول للعناصر التي تعجز المحددات الأساسية (كـby.labelوby.id) عن التقاطها. يمكنك استخدام استعلاماتNSPredicateلـ iOS، ومحددات مبنية (كـclassNameوresourceId) لـ Android. (راجع دلائل Android و iOS).
التحسينات والإصلاحات
Section titled “التحسينات والإصلاحات”- تم معالجة انهيار الأمر
astur testبالخطأspawn EINVALعلى Node 22/24؛ أصبح التشغيل الآن يمر عبر Playwright مباشرة لضمان استقرار الأداء. - مُفتش Android (Inspector) لم يعد يتأرجح برسالة “UI tree unavailable”؛ حيث تم تطوير دورة حياة الوكيل لتقوم بتنظيف أي بقايا من الجلسات السابقة (كالمنافذ المعلقة) قبل بدء الجلسة الجديدة.
0.5.0-beta.1
Section titled “0.5.0-beta.1”الميزات الجديدة
Section titled “الميزات الجديدة”- تسجيل التوكيدات (Assertions) من الـ Inspector مباشرةً.
يوفر الـ Inspector الآن أدوات للتحقق من حالة العنصر (مفعل، معطل، محدد، ومركز)، بالإضافة لوظيفة (عدد المطابقات يساوي) التي تولّد أمر
toHaveCount(n).
التحسينات والإصلاحات
Section titled “التحسينات والإصلاحات”- إصلاح خطأ
Error: spawn start ENOENTالذي كان يُسقط الـ Inspector في أجهزة Windows (تجاوزنا مشكلة الفتح التلقائي للمتصفح). - أمان توليد الكود: يرفض الـ Inspector تسجيل أي خطوات (كالتعبئة أو التأكيد) ما لم تكن مرتبطة بمُحدد صريح (Selector)، مانعاً بذلك إصدار أكواد معطوبة بصمت.
0.5.0-beta.0
Section titled “0.5.0-beta.0”الميزات الجديدة
Section titled “الميزات الجديدة”- قراءة حالة العنصر المباشرة من المُحددات.
إضافة خصائص كـ
textContent()،inputValue()،bounds()،count()،isEnabled()،isDisabled()،isSelected()،isFocused()، وclear()للتوافق المثالي مع أسلوب Playwright. - التوكيد
toHaveCount: استعلام يستمر بمحاولات إعادة الفحص (Polling) بشكل متسق:await expect(device.getByRole('menuitem')).toHaveCount(3).
التحسينات والإصلاحات
Section titled “التحسينات والإصلاحات”- الاستعلامات المتعددة أسرع على Android: الدوال كـ
queryAll()وdevice.findMany()أصبحت تتنفذ داخلياً بشكل مباشر عبر وكيل UIAutomator بدلاً من الاعتماد المُكلف على سحب وتحليل الشجرة بالكامل.
0.4.0-beta.0
Section titled “0.4.0-beta.0”التحسينات والإصلاحات
Section titled “التحسينات والإصلاحات”- تعبئة نصية أسرع لحقول iOS: القيم القصيرة تُكتب بشكل مباشر وآمن، بينما القيم الطويلة تُرسل كلصق مباشر لضمان السرعة.
- تحكم أفضل بلوحة مفاتيح iOS: تقليل تكرار إخفاء/إظهار اللوحة عند الانتقال بين الحقول لتسريع التفاعل.
- التعبئة في الـ WebViews معزولة: يضمن الـ Inspector بقاء التفاعلات داخل إطار الـ DOM عند التعامل مع المتصفحات المدمجة (WebViews)، متجنباً الإرسال الخاطئ لوكيل الـ iOS الأصلي.
- دعم السحب والإفلات (Drag and Drop): الـ Inspector يدعم الآن تسجيل إجراءات السحب وتصديرها بوضوح.
- تنظيف جلسات
ios-webkit-debug-proxy: يتم إنهاء الاتصالات المعلقة السابقة بشكل نظيف لضمان استقرار الاتصالات اللاحقة.
0.3.0-beta.0
Section titled “0.3.0-beta.0”الميزات الجديدة
Section titled “الميزات الجديدة”- دعم الـ DOM داخل الـ WebView على محاكي iOS: الدالة
device.webContext()قادرة الآن على التعامل مع شجرة الـ WKWebView في محاكيات iOS تماماً كالأجهزة الفعلية، معتمدة على أداةios-webkit-debug-proxy. - دعم أتمتة Flutter على iOS: الـ Inspector ودالة الـ codegen قادران على قراءة واجهات تطبيقات Flutter من خلال شجرة الـ XCUITest.
التحسينات والإصلاحات
Section titled “التحسينات والإصلاحات”- إعادة تنظيم الأمثلة والملفات الأولية: نُقلت الاختبارات لـ
specs/، ووضعت إعدادات المنصات في مجلديconfig/android/وconfig/ios/للحفاظ على هيكلة نقية ومرتبة.
تنويه للإصدارات التجريبية (Beta): قد تخضع واجهات الـ API لبعض التعديلات الدقيقة بين إصدار تجريبي وآخر بناءً على التغذية الراجعة والتحسينات المستمرة.

