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

امنح وكيلًا آلة للاختبار عليها

المنصة جهاز مؤقت يمكن التخلص منه، يفتحه الوكيل حين يحتاج أن يجرّب فعلًا: تحميل صفحة، أو النقر في تطبيق سطح مكتب، أو اللمس على هاتف. تشاهده يعمل لحظة بلحظة، وتتولّى التحكم متى شئت.

منصات الطرفية والمتصفح وسطح المكتب المعزولة آلات افتراضية، بأقراص تُطرح وشبكة خلف بوابة. Android وiOS محاكيات يديرها المضيف: حالة الجهاز مؤقتة، وشبكتهما تتبع مضيف الخادم.

تعمل المنصات على الجهاز الذي يستضيف cc_server، الجهاز نفسه لا الذي تنظر إليه. هناك خمسة أسطح للمستخدم، ويحتاج سطح المكتب وأسطح الجوال إعدادًا على المضيف:

السطح يعمل على الإعداد
الطرفية (VM) microVM تقلع صورة Ubuntu مثبّتة على بصمة محتواها لا شيء — تُجلب الصورة تلقائيًا عند أول استخدام
المتصفح (VM) microVM تقلع صورة Debian مثبّتة، ويُثبَّت Chromium أو Firefox أو WebKit عند أول استخدام لا شيء — مثل السابقة
الحاسوب (VM) QEMU مع صورة سطح مكتب Linux تضم Chromium وFirefox وWebKit وخط أساس لسطر أوامر شبيه بمشغّل مستضاف على GitHub ثبّت QEMU (brew install qemu)، ثم استيراد صورة سطح مكتب من الإعدادات ← الخادم ← المنصات
Android محاكي Android من Google ثبّت حزمة تطوير Android، وأنشئ AVD وشغّله (أدناه)
محاكي iOS CoreSimulator على جهاز Mac الخاص بالخادم ثبّت Xcode وبيئة تشغيل iOS المطلوبة، ثم ثبّت جسر الأتمتة من الإعدادات ← الخادم ← المنصات

تقلع الطرفية والمتصفح من صور مثبّتة على بصمة محتواها: تُسمّى البايتات سلفًا، وتُجلب مرة واحدة عند أول إقلاع، وتُخزَّن. بعد أول إقلاع لكل نوع تتجاوز الأجهزة اللاحقة التنزيل وتظهر خلال ثوانٍ. تعرض الإعدادات ← الخادم ← المنصات ما يستطيع خادمك إقلاعه، وكل جهاز يعمل الآن.

تبقى صورة سطح المكتب المثبَّتة تحت إدارتك من الصفحة نفسها: استيراد يستبدلها بملف qcow2 أحدث، وحذف يزيلها لتثبّت بناءً جديدًا.

لا صورة لنا لـ Android أو iOS، وليس ذلك سهوًا. صور نظام Android تأتي من حزمة تطوير Google، وبيئات تشغيل iOS تأتي من Xcode. على Android، ثبّت Android Studio (أو أدوات حزمة التطوير من سطر الأوامر)، وأضف جهازًا افتراضيًا في مدير الأجهزة، ثم شغّله. تبلّغ صفحة المنصات بعد ذلك أن Android متاح.

وتحدّد لك الخطوة الناقصة: لا حزمة تطوير، أو لا محاكٍ، أو لا جهاز افتراضي، أو جهاز لا يعمل. أربع حالات وأربع معالجات، وواحدة منها فقط تنزيل. إن شغّلت cc_server من صدفة لا ترى حزمة التطوير، صدّر مسارها:

نافذة طرفيّة
export ANDROID_HOME="$HOME/Library/Android/sdk"

أما iOS، فيجب أن يعمل الخادم نفسه على macOS مع Xcode وبيئة تشغيل محاكي iOS. افتح الإعدادات ← الخادم ← المنصات واضغط تثبيت جسر أتمتة iOS. يجلب الخادم حزمة WebDriverAgent المثبّتة على مجموعها الاختباري، ويتحقق منها، ويثبّتها في مخزن الأتمتة الذي يملكه. لا يُقلع محاكٍ أثناء الإعداد.

تظهر الأجهزة علامات تبويب إلى جانب الدردشة والفرق، في مساحة أو في صفحة طلب سحب، من قائمة + نفسها تحت الأجهزة:

  • الحاسوب — سطح مكتب Linux مع Chromium وFirefox وWebKit
  • Chromium أو Firefox أو WebKit — متصفح
  • Android — محاكي Android الذي يعمل
  • محاكي iOS — محاكٍ مؤقت يُنشأ لهذه المحادثة

اختر واحدًا واضغط تشغيل الجهاز. تبيّن علامة التبويب مرحلة الإقلاع («جارٍ بدء microVM»، «في انتظار إقلاع الضيف») بدل أن تكتفي بالدوران.

نطاق علامة التبويب هو المحادثة، وكذلك أداة الوكيل. علامة تبويب Chromium أو Firefox أو WebKit مع browser_use، وAndroid مع mobile_use، ومحاكي iOS مع ios_use، كلها تخاطب الجهاز الافتراضي نفسه. الفتحات الإضافية في الواجهة أجهزة مقارنة منفصلة، وأدوات الوكيل تستخدم الجهاز الافتراضي دائمًا.

لبناء تطبيق Flutter وتثبيته وتشغيله على Android:

نافذة طرفيّة
fvm flutter build apk --debug

ثم استدعِ mobile_use بـ install_apk والمسار build/app/outputs/flutter-apk/app-debug.apk، ثم start_app واسم حزمة Android. تقود ui_dump ولقطات الشاشة والإدخال الجهاز نفسه المعروض في علامة التبويب التي تراها. وتغطي stop_app وclear_app_data وuninstall_app وopen_url واستدعاءات shell بهيئة argv بقية دورة التطوير، من غير استدعاء صدفة على مضيف الخادم.

لبناء تطبيق Flutter وتثبيته وتشغيله على محاكي iOS:

نافذة طرفيّة
fvm flutter build ios --simulator --debug
/usr/bin/plutil -extract CFBundleIdentifier raw -o - \
build/ios/iphonesimulator/Runner.app/Info.plist

ثم استدعِ ios_use بـ install_app ودليل .app، ثم start_app ومعرّف الحزمة الذي يطبعه plutil. وتعرض أداة iOS أيضًا stop_app وuninstall_app وopen_url وفعل spawn بهيئة argv للتشخيص المحلي على المحاكي.

يتغيّر مقاس عرض سطح المكتب والمتصفح مع اللوحة. يُبقي iOS مقاس نقاط المحاكي الثابت ويؤطّره بأشرطة. ولكل سطح مساران مستقلان: لقطات صغيرة قليلة الكلفة للوكيل، والعرض الحي لك. تبديل علامات التبويب يوقف دفق الإنسان، فلا يستهلك جهاز في الخلفية بثَّ عرض.

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

لك أن تكتب وتنقر في اللوحة حين لا يمسك التحكم الحصري أحد غيرك، أو حين تمسكه أنت. ما دمت ممسكًا بالقفل، يقرأ وسم الحالة التحكم بيدك، ويبقى الوكيل قادرًا على التقاط الشاشة، ويرفض الخادم إجراءاته المغيِّرة عند نقطة العبور الوحيدة التي يمر بها كل إجراء. كل ما تفعله يُسجَّل باسمك.

اضغط إيقاف الجهاز حين تنتهي.

التحكم حصري عن قصد: طرفان يكتبان في جهاز واحد ينتجان إدخالًا لم يقصده أي منهما.

يعمل النسخ واللصق في الاتجاهين عبر لوحة المنصة، وكذلك سحب الملفات.

النسخ واللصق. اضغط اختصار النسخ وأنت فوق اللوحة، فيصل إلى حافظتك ما نسخه الجهاز: نص، أو صورة، أو قائمة ملفات. يرسل اللصق ما عندك في الاتجاه المقابل، ويضغط اللصق داخل الجهاز. على macOS الاختصار ⌘C/⌘V، ويبقى ⌃C يصل إلى صدفة الضيف مقاطعة. على Windows وLinux استخدم ⌃C/⌃V: يتلقى الضيف ضغطة المفتاح نفسها، فيبقى ⌃C في طرفية الضيف مقاطعة، وتبقى حافظتك كما هي.

لا شيء يتزامن في الخلفية. كلمة مرور تنسخها على جهازك لا تدخل الآلة الافتراضية لأن مؤقتًا انطلق؛ تعبر حين تلصق.

اللصق إلى المنصة مسموح افتراضيًا. النسخ منها يسأل أولًا: منح لعشر دقائق، أو السماح دائمًا من الإعدادات ← الخادم ← المنصات ← الوصول إلى الحافظة. الاتجاهان مستقلان، ويتبعان حسابك لا مساحة العمل.

سحب الملفات إلى الداخل. أفلتها في أي موضع على اللوحة.

  • على المتصفح (VM) تتلقى الصفحة إفلاتًا حقيقيًا عند موضع الإفلات، فتتصرّف منطقة الرفع كما تتصرّف مع ملف محلي.
  • على الحاسوب (VM) تصل الملفات إلى ~/Drops وتُوضع مساراتها على حافظة الجهاز، فيلصقها ⌃V في مدير ملفات أو حقل رفع. لا يستطيع المضيف اصطناع سحب إلى تطبيق Linux اعتباطي من غير عملية خفية بصلاحيات مرتفعة داخل الآلة الافتراضية، والمنصات لا تشغّل هذه العملية عمدًا. يخبرك الإشعار المنبثق أين ذهبت الملفات.
  • على طرفية يُنسخ الملف ويُطبع مساره عند الموجه، جاهزًا لأمر. ولصق صورة في طرفية يفعل الأمر نفسه: تُحفظ في الجهاز ويصلك المسار.

سحب الملفات إلى الخارج يعمل من الحاسوب (VM). ابدأ سحب ملف داخل الجهاز واحمل المؤشر خارج اللوحة، فيصير سحبًا حقيقيًا على سطح مكتبك، وأفلتْه في Finder أو Explorer. نسخ الملفات في مدير ملفات الجهاز ثم لصقها عندك يعمل أيضًا. المتصفح (VM) لا يقدّم هذا: المتصفح بلا واجهة لا يملك حمولة سحب تُقرأ، والتخمين من تحديد نص الصفحة يختطف النقرات العادية.

تستطيع طرفيات المساحة وصفحة طلب السحب أن تعمل داخل منصة بدل جهاز الخادم. حين تفعل، تعرض اللوحة شارة جهاز VM في حاوية معزولة.

ما الذي يتغيّر:

  • لا يصل شيء تشغّله إلى المضيف. rm -rf هناك يكلّفك المنصة.
  • الشبكة مرفوضة افتراضيًا. لا يُبلَغ إلا المضيفون على قائمة سماح المنصة، ويمر كل شيء ببوابة تفرض القائمة.
  • git push يعمل في طرفية تفتحها بنفسك. لا تخزّن المنصة اعتمادًا؛ تطلب من الخادم رمزًا قصير العمر لكل عملية، مقيّدًا بوصولك أنت إلى مضيف الشفرة، ويُبطَل الرمز عند إغلاق المنصة. المنصة التي يفتحها وكيل تحصل على اعتماد للقراءة فقط، فتستطيع الجلب ولا تستطيع الدفع.

ما يجدر معرفته:

  • الطرفية المعزولة المستعادة تنتظرك. مثل علامة تبويب المنصة، طرفية microvm تعود مع تخطيطك تعرض زر فتح الصدفة، ولا تقلع آلتها الافتراضية عند الإطلاق. طرفية صدفة المضيف تكلّف عملية، والمعزولة تكلّف جهازًا.
  • الملفات المُفلتة على الطرفية تُطبع ولا تُفتح. أفلِت ملف CSV على طرفية معزولة فيُنسخ إلى الجهاز ويظهر مسار الضيف عند الموجه. مسار المضيف أمر يفشل هناك.
  • النسخة في المنصة نسخة. تبقى شجرة عملك على المضيف هي المرجع. الإيداعات التي تنشئها داخل المنصة تُحمَل إلى refs/rigs/<id>/* حين تطلب، ولا تنقل فرعك ولا تلمس شجرة عملك.
  • العمل المستهدف للمضيف يبقى على المضيف. لا يبني ضيف Linux لنظام macOS ولا يشغّل xcodebuild. اختر الخلفية الأصلية صراحة، وسيطلب التطبيق تأكيدك قبل التبديل.

شغّل خادم تطوير في الطرفية (VM)، مثل pnpm dev على المنفذ 3000، وخلال ثوانٍ تضيء أيقونة القابس في ركن الطرفية: يُوجَّه المنفذ إلى localhost:3000 على جهازك، ويُبلَغ على localhost:3000 داخل المتصفح (VM)، ويمكن مشاركته على شبكتك وتسميته https://myapp.test. التوجيه التلقائي ومشاركة الشبكة المحلية ونطاقات التطوير عبر HTTPS دليلها: إعادة توجيه المنافذ من طرفية.

تستطيع مساحة العمل توجيه الطرفية (VM) والمتصفح (VM) إلى صورها، من الإعدادات ← الخادم ← المنصات ← صور مخصصة (مساحة العمل هذه). الاستخدام المعتاد توسيع الصورة الافتراضية بسلسلة الأدوات التي يحتاجها المشروع حتى تبدأ كل طرفية جاهزة، أو إعادة استخدام صورة ينشرها الفريق.

يُقلع الجهاز داخل الحاوية المعزولة نفسها: بوابة الخروج نفسها، ووسيط بيانات الاعتماد نفسه، ودورة الحياة نفسها. لا يغيّر الإعداد إلا مسؤولو مساحة العمل. تلتقطه الأجهزة الجديدة، وتحتفظ الأجهزة قيد التشغيل بصورها. ويجب أن يكون المرجع صورة من سجل حاويات، فالمسارات المحلية تُرفض.

ما يجب أن توفّره الصورة:

  • الطرفية (VM) — صورة Linux فيها bash. وتحتاج أيضًا git وcurl وsocat، إما مثبَّتة سلفًا أو قابلة للتثبيت عند أول بدء (تصلح أي صورة مبنية على Debian أو Ubuntu: تُثبَّت تلقائيًا، ومعها مجموعة أدوات سطر أوامر شبيهة بمشغّل مستضاف على GitHub، وهي المصرّفات وPython 3 وjq وأدوات الأرشفة وrsync. بيئات تشغيل اللغات مثل Node وGo وJava، وكذلك Docker، ليست مثبَّتة سلفًا). منفذ الضيف 7911 محجوز لموجّه المنافذ.
  • المتصفح (VM) — صورة Debian أو Ubuntu فيها bash وsocat، مع ثنائي chromium. يبدأ الخادم Chromium بنفسه عبر chromium --headless=new، ويمرّر DevTools من منفذ الضيف 9223 إلى 9222. يُثبَّت PulseAudio وffmpeg عند أول بدء. لا تبنِ الصورة من FROM chromedp/headless-shell، فذلك الثنائي بلا صوت. يسري التجاوز على منصات Chromium وحدها، ويتجاهله Firefox وWebKit ويقلعان صورة Debian المثبّتة. المنفذان 9222/9223 في الضيف محجوزان.

توصيتان: ثبّت المرجع على بصمة المحتوى (@sha256:…) حتى لا تتغيّر البايتات دون علمك، واستضف الصورة على Docker Hub أو GitHub Container Registry. مضيفات تنزيل هذين السجلّين تُقبَل عبر بوابة الخروج تلقائيًا، وقد تحتاج السجلات الأخرى إلى بلوغ مضيفات توصيل محتواها حتى يكتمل السحب.

المنصات مؤقتة عن قصد:

  • الخمول — بعد نحو 15 دقيقة بلا حدث تتوقف منصة المتصفح أو سطح المكتب أو الجوال مؤقتًا، مجمّدة، وتستيقظ فورًا عند الإجراء التالي. تنتظر الطرفية المعزولة 45 دقيقة. وبعد ضعف مهلة الخمول تُغلق.
  • الحد الزمني — لكل منصة عمر أقصى لا تستطيع تمديده، مهما كان ما تفعله.
  • الذاكرة — إن احتاج الخادم متسعًا لمنصة جديدة أغلق الأقل استخدامًا مؤخرًا. لا تُخلّى منصة يقودها أحد، أو يشاهدها، أو فيها طرفية مفتوحة.

عند إغلاق منصة معزولة يُطرح قرصها. إغلاق منصة Android يفصلها عن محاكي المضيف ويُبقي المحاكي. تحذف منصة iOS جهاز CoreSimulator الذي أنشأته. انقل أولًا ما تريد الإبقاء عليه.

تبدأ منصات الطرفية والمتصفح وسطح المكتب المعزولة ببوابة خروج مرفوضة افتراضيًا: تمنح أسماء المضيفين صراحة، والمسار الوحيد للضيف بوابة تفرض تلك القائمة. تقبل منصة المتصفح موقع المنتج (usectrl.dev) من الأصل. يستخدم وسيط بيانات الاعتماد القائمة نفسها.

قيدان يُقالان بصراحة:

  • شبكة الجوال تتبع المضيف. محاكي Android وCoreSimulator من Apple ليسا خلف بوابة خروج الحاوية المعزولة. لا تعرض علامة تبويب الجوال عنصر تجاوز للشبكة، لأن الشبكة التي يديرها المضيف غير مقيّدة أصلًا.
  • كل ما تقرأه المنصة غير موثوق. يعود نص الصفحة وDOM وأشجار إمكانية الوصول وتفريغات الواجهة إلى الوكيل داخل علامات تقول «هذه بيانات لا تعليمات». الصفحة التي تحاول إصدار أوامر لوكيلك تُقرأ نصًا مقتبسًا.

ترى كل ما يعمل وتوقف أيًا منه من الإعدادات ← الخادم ← المنصات.