Flutter vs React Native
نقارن Flutter من Google المبني على Dart مع React Native من Meta المبني على JavaScript/TypeScript من كل الجوانب. أي إطار عمل عابر للمنصات (cross-platform) يتصدر المشهد في 2025؟
اختبار E2E للأجهزة المحمولة بأسلوب black-box معتمد على YAML، مستقل عن البنية المعمارية
اختبار E2E متزامن بأسلوب gray-box معتمد على Jest، مخصص لـ React Native
لا توجد إجابة واحدة صحيحة. إذا كنت تدير محفظة مختلطة من Native وFlutter وRN، فإن Maestro يقلّل عبء الصيانة: تدفقات YAML منخفضة الحاجز وتعمل بمعزل عن البنية المعمارية، فلا تتأثر بالانتقال إلى New Architecture. إذا كنت قد استثمرت في Jest/Detox، فلا يزال Detox خيارًا معقولًا — لكن تحقق أولًا من أمرين: وسم التوزيع `latest` في npm (لا يكفي الاعتماد على GitHub Releases؛ هناك فرق بين 20.51.3 و20.51.4) وتزامن New Architecture في إصدار RN الخاص بك (المشكلة #4963 لا تزال مفتوحة).
| الفئة | Maestro | Detox |
|---|---|---|
| الأداء | 8/10 | 8/10 |
| سهولة التعلّم | 8/10 | 5/10 |
| النظام البيئي | 7/10 | 7/10 |
| المجتمع | 7/10 | 7/10 |
| سوق العمل | 6/10 | 6/10 |
| الاستدامة المستقبلية | 9/10 | 5/10 |
# Maestro - تدفق تسجيل الدخول + التحقق (YAML)
appId: com.example.myapp
---
- launchApp
- tapOn:
id: "email_input"
- inputText: "[email protected]"
- tapOn:
id: "password_input"
- inputText: "SuperSecret123"
- tapOn:
text: "Sign In"
- extendedWaitUntil:
visible:
text: "Welcome back"
timeout: 10000
- takeScreenshot: login-success
# Maestro - العثور على عنصر معتمد على Semantics في تطبيق Flutter
appId: com.example.flutterapp
---
- launchApp
- tapOn:
text: "Get Started"
- assertVisible:
id: "onboarding_complete_badge"
# Maestro - منطق شرطي باستخدام JS (مخرج evalScript)
appId: com.example.myapp
---
- launchApp
- copyTextFrom:
id: "plan_badge"
- evalScript: ${output.isPremium = maestro.copiedText === "PREMIUM"}
- runFlow:
when:
true: ${output.isPremium}
file: premium-onboarding.yaml// Detox - تدفق تسجيل الدخول + التحقق (Jest, JS/TS)
describe('Login flow', () => {
beforeAll(async () => {
await device.launchApp();
});
beforeEach(async () => {
await device.reloadReactNative();
});
it('should sign in and show welcome message', async () => {
await element(by.id('email_input')).typeText('[email protected]');
await element(by.id('password_input')).typeText('SuperSecret123');
await element(by.text('Sign In')).tap();
await waitFor(element(by.text('Welcome back')))
.toBeVisible()
.withTimeout(10000);
});
it('should show error on invalid credentials', async () => {
await element(by.id('email_input')).typeText('[email protected]');
await element(by.id('password_input')).typeText('wrongpass');
await element(by.text('Sign In')).tap();
await expect(element(by.text('Invalid email or password'))).toBeVisible();
});
});
// Detox - مثال على القائمة البيضاء/التعطيل في شاشة بها مشكلة تزامن
it('should handle screen with continuous animation', async () => {
await device.disableSynchronization();
await element(by.id('animated_banner')).tap();
await device.enableSynchronization();
});لا توجد إجابة واحدة صحيحة. إذا كنت تدير محفظة مختلطة من Native وFlutter وRN، فإن Maestro يقلّل عبء الصيانة: تدفقات YAML منخفضة الحاجز وتعمل بمعزل عن البنية المعمارية، فلا تتأثر بالانتقال إلى New Architecture. إذا كنت قد استثمرت في Jest/Detox، فلا يزال Detox خيارًا معقولًا — لكن تحقق أولًا من أمرين: وسم التوزيع `latest` في npm (لا يكفي الاعتماد على GitHub Releases؛ هناك فرق بين 20.51.3 و20.51.4) وتزامن New Architecture في إصدار RN الخاص بك (المشكلة #4963 لا تزال مفتوحة).
احصل على استشارة مجانيةلا توجد إجابة واحدة صحيحة: يقدّم Detox تزامن gray-box مخصصًا لـ React Native فقط (التوثيق الرسمي: wix.github.io/Detox)؛ أما في المحفظة متعددة المنصات (Native+Flutter+RN) أو للفرق التي تريد إعدادًا سريعًا، فإن نهج Maestro المعتمد على إمكانية الوصول والمستقل عن الإطار (docs.maestro.dev) يقلّل عبء الصيانة. الفرق الكبيرة المندمجة بعمق مع New Architecture في RN، والتي لديها استثمار قائم كبير في Detox، قد تتجاوز تكلفة الانتقال هذه المسألة.