تخطَّ إلى المحتوى

iOS

أتمتة iOS متاحة على macOS فقط. ويستخدم Astur أدوات Apple نفسها بدل خادم Appium:

  • simctl لدورة حياة المحاكي
  • devicectl لدورة حياة الأجهزة الحقيقية
  • xcodebuild لبدء مشغّل XCUITest المرفق بلغة Swift
  • ووكيل XCUITest في Astur للبحث الأصلي والانتظار والإيماءات ولقطات الشاشة والتحكم بلوحة المفاتيح

يهيّئ Astur الوكيل المرفق تلقائيًا. ولا ينبغي للمستخدمين بناؤه أو تثبيته يدويًا في التشغيلات المحلية العادية، لكن أجهزة iOS الحقيقية ما زالت تتطلب فريق توقيع من Apple لأن مشغّلات XCTest يجب أن تكون موقّعة. وللأجهزة الحقيقية الموصولة بـ USB، يفضّل Astur نفق Xcode/CoreDevice لجسر المضيف قبل اللجوء إلى عنوان على الشبكة المحلية.

وحين يكتمل كل شيء، يبثّ codegen مرآة حيّة للجهاز وشجرة الواجهة كاملةً ومحدِّدات جاهزة للّصق:

‏Astur Inspector يعمل مقابل محاكي iOS: مرآة الجهاز الحيّة في الوسط، وشجرة XCUITest على اليمين، والمحدِّدات المولَّدة على اليسار.

ما تحتاجه محاكي iOS iPhone / iPad حقيقي
‏macOS مع Xcode (يُفتح مرة وتُقبل الرخصة) مطلوب مطلوب
أدوات سطر الأوامر: xcrun, simctl, xcodebuild مطلوب مطلوب
بيئة تشغيل محاكي iOS (‏Xcode ← Settings ← Platforms) مطلوب
devicectl (يأتي مع Xcode) مطلوب
ملف التطبيق ملف .app مبني للمحاكي ملف .ipa موقّع للجهاز
فريق التوقيع لدى Apple (ASTUR_IOS_DEVELOPMENT_TEAM) غير مطلوب مطلوب
الجهاز موثوق لدى Mac مع تفعيل وضع المطوّر مطلوب
وكيل XCUITest يُبنى ويُشغَّل تلقائيًا يُبنى و يُوقَّع ويُشغَّل تلقائيًا

أنت لا تثبّت الوكيل ولا تجهّزه يدويًا أبدًا. يبني Astur مشغّل XCUITest المرفق بلغة Swift ويشغّله عبر Xcode في كل جلسة، ويعيد استخدام بناء مخزّن (DerivedData) في التشغيلات اللاحقة. وعلى الأجهزة الحقيقية يوقّع ذلك المشغّل بفريقك لدى Apple — وهي الخطوة الإضافية الوحيدة التي تتخطّاها المحاكيات. والقاعدة التي يجدر تذكّرها هي قاعدة الملفات: محاكي = .app، وجهاز حقيقي = .ipa.

ثبّت Xcode، وافتحه مرة، واقبل الرخص، وثبّت أي مكوّنات يطلبها.

Terminal window
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
xcodebuild -version
npx astur-mobile doctor

اختر أصغر إعداد iOS يوافق ما تريد فعله:

الهدف تبني تطبيقك أولًا؟ الملف توقيع Apple؟ الأمر
تجربة Astur على محاكي بتطبيق العرض لا (نزّل ملف العرض .app) Astur.app لا npx astur-mobile codegen --ios --simulator --app ./Astur.app --app-id com.astur.demo
فحص أو اختبار تطبيقك على محاكي نعم ملف .app مبني للمحاكي لا npx astur-mobile codegen --ios --simulator --app ./MyApp.app --app-id com.example.myapp
الفحص أو الاختبار على iPhone أو iPad حقيقي نعم ملف .ipa موقّع للجهاز نعم npx astur-mobile codegen --ios --real --device <device-udid> --app ./MyApp.ipa --app-id com.example.myapp

تريد تطبيقًا جاهزًا للتجربة أولًا؟ تطبيق العرض من Astur (Astur.app للمحاكيات و astur.demo.ios.ipa للأجهزة الحقيقية، بمعرّف الحزمة com.astur.demo) يُشحن في مستودع أمثلة Astur. نزّله ووجّه --app إليه، أو استبدله ببنائك الخاص أدناه.

لا توقيع من Apple ولا شهادات — وهذه أسرع طريقة للبدء.

الخطوة 1 — ثبّت بيئة تشغيل محاكي (مرة واحدة): ‏Xcode ← Settings ← Platforms ← أضف بيئة تشغيل iOS.

الخطوة 2 — تحقّق من أن سلسلة الأدوات ترى محاكيًا:

Terminal window
xcrun simctl list devices available
npx astur-mobile devices --ios

الخطوة 3 — شغّل الـ Inspector وتوليد الكود. وجّه --app إلى ملف .app مبني للمحاكي ومرّر معرّف حزمته. ولتجربة Astur فورًا استخدم تطبيق العرض المُنزَّل؛ وإلا فاستخدم بناءك الخاص:

Terminal window
# تطبيق العرض (نزّل Astur.app من مستودع الأمثلة)
npx astur-mobile codegen --ios --simulator --app ./Astur.app --app-id com.astur.demo
# تطبيقك أنت
npx astur-mobile codegen --ios --simulator --app ./MyApp.app --app-id com.example.myapp

ويُفتح تبويب متصفح تلقائيًا. وخلال ثوانٍ ينبغي أن ترى مرآة الجهاز الحيّة وشجرة واجهة ممتلئة (انظر اللقطة أعلاه). والتشغيل الأول أبطأ لأن Xcode يبني الوكيل مرة واحدة؛ أما التشغيلات اللاحقة فتعيد استخدام البناء المخزّن.

استخدام تطبيقك على محاكي

Section titled “استخدام تطبيقك على محاكي”

لفحص تطبيقك أو اختباره على محاكي، عليك بناء التطبيق أولًا. فـ Astur يتوقّع ملف .app مبنيًا للمحاكي من Xcode، ولا يترجم التطبيق نيابةً عنك. ومسار المخرجات المعتاد في Xcode يقع داخل DerivedData، مثل .../Build/Products/Debug-iphonesimulator/MyApp.app.

ولتشغيل الاختبارات، أضف Astur إلى إعدادات Playwright ثم نفّذ npx astur-mobile test:

playwright.config.ts
import { defineConfig } from '@astur-mobile/test';
export default defineConfig({
testDir: './tests',
use: {
astur: {
platform: 'ios',
device: { kind: 'simulator', name: 'iPhone 16' },
app: {
path: './build/MyApp.app',
bundleId: 'com.example.myapp'
}
}
}
});
Terminal window
npx astur-mobile test # كل الاختبارات
npx astur-mobile test tests/login.test.ts

إعداد الأجهزة الحقيقية

Section titled “إعداد الأجهزة الحقيقية”

الأجهزة الحقيقية هي المقايضة المعاكسة: توقيع Apple مطلوب. وشيئان يُوقَّعان، ويتعامل Astur معهما بشكل مختلف:

  1. تطبيقك — أنت من يجهّز ملف .ipa موقّعًا للجهاز. فـ Astur لا يوقّع تطبيقك نيابةً عنك.
  2. وكيل XCUITest — يبنيه Astur و يوقّعه لك عند بدء الجلسة، لكن Apple تشترط فريق تطوير لذلك. أنت توفّر الفريق، و Astur يتولّى الباقي (دون عناء ملفات provisioning اليدوية).

ولا وجود لإعداد التوقيع هذا على المحاكيات.

الخطوة 1 — جهّز الجهاز:

  1. وصّل iPhone أو iPad عبر USB.
  2. اضغط Trust على الجهاز عند الطلب.
  3. فعّل وضع المطوّر (‏Settings ← Privacy & Security ← Developer Mode) ثم أعد التشغيل.
  4. أضف حساب Apple Developer في ‏Xcode ← Settings ← Accounts.

الخطوة 2 — وفّر فريق التوقيع. وهذا هو المتغيّر الوحيد المطلوب للأجهزة الحقيقية:

Terminal window
export ASTUR_IOS_DEVELOPMENT_TEAM=ABCDE12345 # معرّف فريقك لدى Apple من 10 محارف

تجد معرّف الفريق في Xcode ← Settings ← Accounts ← فريقك، أو على developer.apple.com ← Membership. وعند التشغيل من مستودع المصدر يستطيع Astur استنتاجه من agents/ios-xctest-agent/AsturIOSAgent.xcodeproj إذا كان المشروع موقّعًا في Xcode — لكن في تثبيتات npm و CI اضبط ASTUR_IOS_DEVELOPMENT_TEAM صراحةً دائمًا. ويوقّع Astur الوكيل بالـ provisioning التلقائي (-allowProvisioningUpdates)؛ ولا تضبط ASTUR_IOS_CODE_SIGN_IDENTITY إلا إذا كانت بيئتك تحتاج هوية بعينها.

الخطوة 3 — تأكد من أن ملف .ipa موقّع لهذا الجهاز. إذ يجب أن يتضمّن ملف provisioning الخاص بالتطبيق رقم UDID لهذا الجهاز. وإن لم يتضمّنه فشل التثبيت أو التشغيل بالخطأ IOS_APP_INSTALL_SIGNATURE_INVALID.

الخطوة 4 — جسر المضيف (تلقائي عادةً). يعلن Astur عن نفق USB من Xcode/CoreDevice للوكيل على الجهاز تلقائيًا. ولا تضبط عنوان Mac على الشبكة المحلية إلا إذا عجز الهاتف عن الوصول إلى الجسر المكتشَف تلقائيًا:

Terminal window
export ASTUR_IOS_AGENT_HOST=192.168.0.14

قد يستغرق أول تشغيل على جهاز حقيقي عدة دقائق بينما يبني Xcode الوكيل ويوقّعه. أما التشغيلات اللاحقة فتعيد استخدام البناء المخزّن وتبدأ خلال ثوانٍ.

للتحقق من الجهاز:

Terminal window
xcrun devicectl list devices
npx astur-mobile devices --ios

ومن المفترض أن يبلّغ doctor عن الجهاز الحقيقي الموصول، وفريق توقيع مضبوط، ومشروع وكيل XCUITest المرفق:

Terminal window
npx astur-mobile doctor --verbose

إعدادات الجهاز الحقيقي:

import { defineConfig } from '@astur-mobile/test';
export default defineConfig({
testDir: './tests',
use: {
astur: {
platform: 'ios',
device: {
kind: 'real',
id: '00008030-000548220EF0802E'
},
app: {
path: './build/MyApp.ipa',
bundleId: 'com.example.myapp'
}
}
}
});

ثم شغّل المجموعة عبر الـ CLI المنشور:

Terminal window
export ASTUR_IOS_DEVELOPMENT_TEAM=ABCDE12345
npx astur-mobile test

ويمكن استنتاج bundleId من ملف .app أو .ipa محلي حين يحتوي التطبيق على Info.plist قابل للقراءة، لكن ضبطه صراحةً يبقى موصى به في CI. وتأكد من أن ملف .ipa موقّع للجهاز الموصول — وإلا فشل التثبيت بالخطأ IOS_APP_INSTALL_SIGNATURE_INVALID.

يستخدم Astur قيمًا افتراضية مدركة لنظام التشغيل في iOS:

automation: {
engine: 'agent',
legacyFallback: 'never',
startupTimeoutMs: 60_000,
commandTimeoutMs: 15_000
},
agent: {
mode: 'required',
install: true
}

وأنت تُغفلها عادةً. ولا تتجاوزها إلا عند تشخيص نقطة نهاية وكيل مخصّصة أو مضيف CI بطيء.

لوحة المفاتيح والتعبئة

Section titled “لوحة المفاتيح والتعبئة”

تستخدم تعبئة النص في iOS الأمر typeText من XCTest للقيم الآمنة والقصيرة، ومسارًا مدعومًا باللصق لعمليات الاستبدال الأطول غير الآمنة. وهذا يُبقي حقول كلمات المرور موثوقة مع تفادي الإدخال البطيء حرفًا حرفًا للنصوص الطويلة.

await device.getByTestId('forms-main-input').fill('Astur native form automation');
await device.keyboard.hide();
await device.keyboard.show(device.getByTestId('forms-main-input'));

كما يتوفّر اللصق كخيار صريح للحقول غير الآمنة:

await device.getByLabel('Bio').fill('Long local-only text', { textInputMode: 'paste' });

الكتابة في عنصر لا تستطيع الشجرة وصفه

Section titled “الكتابة في عنصر لا تستطيع الشجرة وصفه”

بعض العناصر لا تملك ما يُعبَّأ. وحقل OTP متعدد الصناديق هو الحالة الشائعة: فالصناديق الظاهرة عروض عادية، والحقل الحقيقي UITextField خلفها لا يُكشف لـ XCUITest أبدًا، فلا يجد getByType('textField') شيئًا ولا تملك fill() هدفًا.

وتكتب device.keyboard.type() فيما يملك تركيز لوحة المفاتيح حاليًا، فتعمل حيث تعجز التعبئة المرتكزة على عنصر. ركّز العنصر أولًا — والنقر على صندوق يفعل ذلك عادةً:

await device.getByTestId('otp-input').tap();
await device.keyboard.type('123456');

ويعمل النداء نفسه على Android، إذ يرسل الأحرف إلى العرض المركَّز. كما أن التدفّق رقمًا رقمًا قابل للنقل أيضًا، لأن pressKey تقبل حرفًا مطبوعًا واحدًا على المنصتين:

for (const digit of '123456') {
await device.pressKey(digit);
}

وأمران يجدر معرفتهما قبل اللجوء إليها:

  • فضّل fill() كلما كان الحقل قابلًا للاستهداف. فهي تحلّ العنصر وتمسحه وتتحقق من وصول القيمة. أما keyboard.type() فتستهدف التركيز، فلا شيء يؤكّد أين ذهبت الأحرف — وهذه هي المقايضة مقابل الوصول إلى عنصر تعجز الشجرة عن وصفه.
  • يجب أن تكون لوحة المفاتيح ظاهرة. فبلا لوحة مفاتيح على الشاشة لا يوجد ما هو مركَّز لتكتب فيه، ويفشل الوكيل بالخطأ KEYBOARD_NOT_VISIBLE بدل أن يصمت.

ويمكن ضبط سلوك لوحة المفاتيح عمومًا:

use: {
astur: {
platform: 'ios',
keyboard: {
dismiss: 'auto'
}
}
}

تمرّ أتمتة iOS الأصلية عبر XCTest. وكل نقرة وتعبئة وتمريرة وسحبة تنتظر أن يصبح التطبيق خاملًا (بلا عمل جارٍ في UIKit أو CoreAnimation) قبل الحدث وبعده. وهذا ما يُبقي XCTest موثوقًا، لكنه يعني أيضًا أن أي شيء يُبقي التطبيق متحركًا يجعل الإجراءات المنفردة بطيئة أو تبدو معلّقة حتى تنتهي مهلة الأمر. وإعدادان في الجهاز يزيلان أشيع مصادر هذا العبء. طبّقهما مرة على المحاكي أو الجهاز الحقيقي الذي تختبر عليه.

عطّل التعبئة التلقائية لكلمات المرور. فحين تركّز حقلًا آمنًا أو بنمط تسجيل دخول، يعرض iOS نافذة كلمة المرور القوية أو التعبئة التلقائية فوق لوحة المفاتيح. وهي تدخل وتخرج بحركة متكرّرة، ما يُبقي التطبيق غير خامل ويجعل fill على تلك الحقول بطيئة رغم كتابة القيمة في النهاية. عطّلها في أجهزة الاختبار:

Settings > Passwords > Password Options > AutoFill Passwords -> off

فعّل تقليل الحركة. فحركات UIKit الأقصر تتيح لـ XCTest بلوغ حالة الخمول أسرع، ما يسرّع الإيماءات ويمنع التوقّفات الطويلة أثناء الانتقالات المتحركة مثل تأثيرات الالتقاط في السحب والإفلات:

Settings > Accessibility > Motion > Reduce Motion -> on

إرشادات إضافية:

  • اكشف معرّفات إمكانية وصول ثابتة لكل عنصر تتفاعل معه. فـ getByTestId / getById تُحلّ باستعلام واحد؛ بينما تعداد النصوص أو الأدوار الواسع أبطأ بطبيعته، خصوصًا على الأجهزة الحقيقية.
  • أبقِ الحركات المخصّصة داخل التطبيق قصيرة أو غير متكرّرة في الشاشات قيد الاختبار. فالعرض الذي يتحرك باستمرار لا يدع XCTest يبلغ الخمول أبدًا، فينتظر الإجراء التالي مهلة الأمر كاملةً قبل أن يفشل.
  • وتستخدم عمليات الاستبدال الطويلة غير الآمنة اللصق تفاديًا للإدخال البطيء حرفًا حرفًا. أما الحقول الآمنة فتكتب دائمًا، ويفرض { textInputMode: 'type' } الإدخال حرفًا حرفًا حين يرفض التطبيق اللصق.

يشغّل codegen الـ Inspector في Astur — مرآة حيّة للجهاز، وشجرة واجهة XCUITest، وتوليد محدِّدات بالنقر، وتسجيل خطوات يصدّر اختبارًا جاهزًا للتشغيل (كما في أعلى هذه الصفحة). راجع الـ Inspector وتوليد الكود للجولة الكاملة لوحةً لوحة.

ابدأ توليد الكود بمسار تطبيق ومعرّف حزمة يوافقان هدفك:

Terminal window
# محاكي (.app، بلا توقيع)
npx astur-mobile codegen --ios --simulator --app ./MyApp.app --app-id com.example.myapp
# جهاز حقيقي (.ipa، يحتاج ASTUR_IOS_DEVELOPMENT_TEAM)
npx astur-mobile codegen --ios --real --device <device-udid> --app ./MyApp.ipa --app-id com.example.myapp

ولاستهداف محاكي أو جهاز بعينه بدل أول مطابقة، أضف --device <device-udid> (تجد الـ UDID عبر npx astur-mobile devices --ios).

الجلسة سليمة حين ترى في تبويب المتصفح الذي يُفتح:

  1. تحوّل شارة الحالة إلى Live (أعلى اليسار، بالأخضر).
  2. عرض اللوحة الوسطى مرآة حيّة لشاشة الجهاز.
  3. امتلاء لوحة UI TREE على اليمين بالعناصر.
  4. توليد اقتراحات محدِّدات على اليسار عند النقر على عنصر (أو على عقدة في الشجرة).

وإذا بقيت الشارة على Connecting… أو لم تظهر المرآة أبدًا، راجع حل المشكلات ← الـ Inspector لا يصبح جاهزًا أبدًا.

إذا كان التطبيق أو الوكيل مفقودًا

Section titled “إذا كان التطبيق أو الوكيل مفقودًا”

استخدم هذه القاعدة العملية لاختيار الأمر:

  • في التشغيل الأول أو حين لا يكون التطبيق مثبّتًا بعد: أدرج --app كي يستطيع Astur التثبيت قبل الاتصال.
  • وإذا كان التطبيق مثبّتًا أصلًا: يكفي --app-id.
  • وإذا كان التطبيق مفقودًا ومرّرت --app-id وحده، أعاد Astur الخطأ IOS_APP_NOT_INSTALLED.

أمثلة على الأوامر:

Terminal window
# محاكي: التثبيت والاتصال بأمر واحد.
npx astur-mobile codegen --ios --simulator --app ./MyApp.app --app-id com.example.myapp
# جهاز حقيقي: التثبيت والاتصال بأمر واحد.
ASTUR_IOS_DEVELOPMENT_TEAM=ABCDE12345 \
npx astur-mobile codegen --ios --real --device <device-udid> --app ./MyApp.ipa --app-id com.example.myapp
# تطبيق مثبّت أصلًا، مع إغفال المسار.
npx astur-mobile codegen --ios --simulator --app-id com.example.myapp

سلوك وكيل iOS في Astur:

  • لا تلزم خطوة تثبيت يدوية للوكيل على المحاكي ولا على الجهاز الحقيقي.
  • يبدأ Astur مشغّل XCUITest المرفق بلغة Swift تلقائيًا في كل جلسة.
  • وعلى المحاكي والجهاز الحقيقي معًا، تُقدَّم المرآة وشجرة الواجهة ولقطات الشاشة والتفاعلات الأصلية جميعها من وكيل XCUITest حالما يبدأ ويرتبط بمعرّف الحزمة المستهدف.
  • وأعطال المحاكي عادةً مشكلات في Xcode أو في إقلاع بيئة التشغيل.
  • أما أعطال الأجهزة الحقيقية فتتطلب عادةً إعداد التوقيع (ASTUR_IOS_DEVELOPMENT_TEAM، وجهاز موثوق، وسلسلة مفاتيح غير مقفلة).

وللحلول الخاصة بكل عطل، راجع حل المشكلات.

التنظيف التلقائي للجلسات

Section titled “التنظيف التلقائي للجلسات”

يملك Astur دورة حياة وكيل XCUITest، فلا يترك جلسةً محتجزةً لجهازك أبدًا:

  • يعمل كل وكيل في مجموعة عمليات خاصة به، فالخروج العادي أو Ctrl-C يفكّك كلًا من xcodebuild ومشغّل الاختبار الذي يولّده.
  • وقبل بدء جلسة جديدة ينظّف Astur أي عملية وكيل متبقية للمشروع والجهاز نفسيهما (مثلًا بعد قتل تشغيل سابق قسرًا). ويمكن تعطيل ذلك بـ ASTUR_IOS_AGENT_REAP=0 إذا كنت تدير وكيلًا خارجيًا مشتركًا بنفسك.
Terminal window
# سجّل كل أمر يضعه المضيف في الطابور ويسلّمه ويتلقّى استجابته.
ASTUR_IOS_AGENT_TRACE=1 npx astur-mobile codegen --ios --simulator --app ./MyApp.app --app-id com.example.myapp

راجع الإعدادات ← متغيرات بيئة iOS للقائمة الكاملة (تجاوزات مشروع الوكيل ومخططه، والمنافذ، ومسار derived-data، وهوية التوقيع، ومسارات الأدوات).

النقل مع الأجهزة الحقيقية

Section titled “النقل مع الأجهزة الحقيقية”

للتنفيذ على الأجهزة الحقيقية في Astur اتصالان:

الاتصال يملكه ملاحظات
دورة حياة التطبيق devicectl + وكيل XCUITest يقوم devicectl بالتثبيت وإلغاء التثبيت وسرد الأجهزة. وحالما يتصل الوكيل، يمرّ تشغيل التطبيق وإنهاؤه عبر XCUITest كي يبقى المشغّل والتطبيق مرتبطين بالجلسة نفسها.
الأتمتة الأصلية وكيل XCUITest في Astur يقرأ شجرة الواجهة، وينفّذ النقر والتعبئة والتمرير، ويتعامل مع الاتجاه، ويلتقط لقطات الشاشة.
جسر المضيف بيئة تشغيل Astur يستخدم نفق CoreDevice عبر USB متى توفّر؛ ويعود إلى ASTUR_IOS_AGENT_HOST أو إلى عنوان Mac قابل للوصول.

وإذا تضمنت مخرجات XCUITest العبارة Local network prohibited، فأبقِ الجهاز موصولًا بـ USB وأزل أي قيمة مفروضة لـ ASTUR_IOS_AGENT_HOST كي يستطيع Astur استخدام نفق CoreDevice. ولا تفرض ASTUR_IOS_AGENT_HOST إلا في البيئات التي يستطيع فيها الهاتف الوصول إلى Mac عبر الشبكة ويكون إذن الشبكة المحلية مسموحًا.

الواجهة المحاكي الجهاز الحقيقي ملاحظات
device.app.install() نعم نعم استخدم .app مبنيًا للمحاكي على المحاكيات، و .ipa موقّعًا على الأجهزة الحقيقية. ويفكّ Astur محتويات IPA داخليًا قبل التثبيت.
device.app.launch() نعم نعم يشغّل معرّف الحزمة المضبوط.
device.app.terminate() نعم نعم تُنهي الأجهزة الحقيقية بمطابقة عملية التطبيق المشغّلة.
device.app.reset({ reinstall: true, launch: true }) نعم نعم تصفير بإلغاء التثبيت وإعادته.
device.app.uninstall() نعم نعم يزيل معرّف الحزمة المضبوط.
device.permissions.grant('camera') نعم لا يستخدم simctl privacy؛ ولا توفّر Apple تحكمًا مكافئًا على الأجهزة الحقيقية.
device.permissions.revoke('camera') نعم لا القيد نفسه كما في المنح.
device.setOrientation('landscape') نعم نعم يمرّ عبر وكيل XCUITest لجلسات الواجهة الأصلية.
device.orientation.portrait() نعم نعم غلاف للراحة.
device.lock() / device.unlock() نعم لا تدعم المحاكيات التحكم في طاقة الشاشة؛ أما الأجهزة الحقيقية فتُدار يدويًا.
device.screenshot() نعم نعم تلتقط الأجهزة الحقيقية عبر وكيل XCUITest.
تسجيل الفيديو نعم لا للمحاكي فقط حاليًا. وإذا فُعّل على جهاز حقيقي، يتخطّى Astur مرفق الفيديو الأصلي بدل إفشال الاختبار.
المحدِّدات والإيماءات الأصلية نعم نعم تتطلب وكيل XCUITest.
locator.scrollIntoView() نعم نعم تعمل عبر المنصات. تمرّر داخل الشاشة (أو داخل حاوية محدّدة) حتى يظهر العنصر. راجع وثائق Android للخيارات.

ولأسرع تنفيذ على الأجهزة الحقيقية، اكشف معرّفات إمكانية وصول ثابتة للعناصر وللقيم المتغيّرة. فـ XCTest يستطيع النقر والتعبئة بالمعرّف بسرعة، لكن التعداد النصي الواسع مثل «ابحث عن كل رقم ظاهر على الشاشة» أبطأ بطبيعته على الأجهزة الحقيقية.

مخرج الطوارئ للمحدِّد الأصلي (by.native)

Section titled “مخرج الطوارئ للمحدِّد الأصلي (by.native)”

للعنصر النادر الذي تعجز by.label و by.id و by.text و by.role و by.type عن التعبير عنه، تقبل by.native() نص NSPredicate خامًا من XCUITest، يُطبَّق عبر app.descendants(matching: .any).matching(NSPredicate(format:)) — وهي قواعد الـ predicate التعريفية نفسها التي تستخدمها واجهات Apple واستراتيجية -ios predicate string في Appium. وهي بيانات للغة استعلام مقيّدة، ولا تُنفَّذ ككود أبدًا:

await device.find(by.native({
ios: "type == 'Button' AND label CONTAINS[cd] 'Save'"
})).tap();
// التمييز بين المطابقات المتطابقة بالموضع (يبدأ من 0):
await device.find(by.native({
ios: "type == 'StaticText' AND label == 'Delete'",
instance: 2
})).tap();

ولأن NSPredicate يستطيع جمع أي عدد من الشروط في نص واحد (AND/OR، و CONTAINS/BEGINSWITH/MATCHES، و [cd] لتجاهل حالة الأحرف)، فإن معظم حاجات التمييز تُحلّ بـ predicate واحد دون الحاجة إلى الفهرسة بالموضع إطلاقًا.

وتتطلب by.native() وكيلًا أصليًا متصلًا — إذ لا يمكن حلّها مقابل لقطة مخزّنة لشجرة الواجهة، ولذلك تُطلق الجلسة القديمة أو التي بلا وكيل الخطأ NATIVE_SELECTOR_REQUIRES_AGENT بدل أن تطابق لا شيء بصمت. ولاستهداف Android بالمحدِّد نفسه، أضف سلسلة android بجوار ios — راجع ‏Android: مخرج الطوارئ للمحدِّد الأصلي.

  • يجب توقيع تطبيقات iOS الحقيقية ومشغّلات XCTest بفريقك.
  • ولا يمكن أتمتة تنبيهات النظام إلا حين يكشفها XCTest لمشغّل الاختبار.
  • ولا يوفّر iOS واجهة عامة لمسح بيانات أو ذاكرة تطبيق بعينه مباشرةً؛ فاستخدم التصفير بإلغاء التثبيت وإعادته.
  • والقفل وفتح القفل وتعديل الأذونات على الأجهزة الحقيقية غير موثوقة عبر الأدوات المحلية العامة.

ومصدر الوكيل موجود في:

agents/ios-xctest-agent/

وهو يرتبط بمعرّف حزمة التطبيق، ويقرأ شجرة إمكانية الوصول، وينفّذ الإجراءات الأصلية، ويجسر نتائج JSON المضغوطة إلى بيئة Node.js.