Selenium

  • اختبار تطبيقات الويب باستخدام Selenium

    عند مواجهة خطأ “No such file or directory: ‘geckodriver'” أثناء تشغيل تطبيق Selenium البسيط في Python على نظام Linux، يتعين عليك اتباع خطوات محددة لإصلاح هذا الخطأ وجعل التطبيق يعمل بشكل صحيح.

    أولاً وقبل كل شيء، يجب عليك التأكد من أنك قد قمت بتثبيت متصفح Firefox وتثبيت Selenium ومشغل المتصفح (مثل geckodriver) بشكل صحيح. لنفترض أنك قد قمت بذلك بالفعل، ومع ذلك، فإن خطأ “No such file or directory: ‘geckodriver'” يشير إلى أن البرنامج لا يستطيع العثور على ملف geckodriver الذي يحتاجه Selenium للتفاعل مع متصفح Firefox.

    لحل هذا المشكلة، يمكنك اتباع الخطوات التالية:

    1. تنزيل geckodriver: ابدأ بتنزيل geckodriver الذي يتوافق مع نسخة متصفح Firefox الذي لديك. يمكنك القيام بذلك عبر الذهاب إلى الموقع الرسمي لـ geckodriver وتحميل الإصدار الصحيح لنظام التشغيل الخاص بك.

    2. إعداد المسار Path: بعد تنزيل geckodriver، قم بفك الضغط عن الملف المحمل وانقله إلى مكان مناسب في نظام الملفات الخاص بك. بعد ذلك، يجب أن تضيف مسار المجلد الذي يحتوي على geckodriver إلى متغير البيئة PATH الخاص بك. يمكنك القيام بذلك عبر تعديل ملف .bashrc أو .bash_profile أو ملفات تهيئة البيئة الأخرى، وإضافة سطر يشير إلى المسار الذي قمت بتخزين geckodriver فيه.

    3. إعادة تشغيل الجلسة أو تحديث البيئة: بعد تعديل ملف البيئة، قم بإعادة تشغيل جلسة العمل الخاصة بك أو قم بتحديث البيئة الحالية، حتى يتمكن نظام التشغيل من رؤية تغييرات المسار الجديدة.

    بعد اتخاذ هذه الخطوات، يجب أن تكون قادرًا على تشغيل تطبيق Selenium الخاص بك دون مواجهة خطأ “No such file or directory: ‘geckodriver'”. بافتراض أنك قمت بتثبيت كل شيء بشكل صحيح، ينبغي على التطبيق الآن العمل بسلاسة دون مشاكل.

    المزيد من المعلومات

    بعد إتمام الخطوات السابقة، يمكنك الآن استكمال تطبيق Selenium الخاص بك دون مشاكل. لنقم بإتمام الكود وتوضيح كيفية استخدام Selenium لفتح موقع واختبار بعض العمليات البسيطة:

    python
    from selenium import webdriver from selenium.webdriver.common.keys import Keys # إنشاء متصفح Firefox مع استخدام مشغل geckodriver driver = webdriver.Firefox() # استخدام المتصفح لفتح موقع معين، على سبيل المثال "https://www.example.com" driver.get("https://www.example.com") # الآن يمكنك تنفيذ أوامر Selenium الأخرى، مثل البحث عن عنصر معين والتفاعل معه # على سبيل المثال، يمكننا البحث عن عنصر input بواسطة اسمه وإرسال بعض النص إليه element = driver.find_element_by_name("q") element.send_keys("Hello, World!") element.send_keys(Keys.RETURN) # يمكنك أيضاً إغلاق المتصفح بعد الانتهاء من استخدامه # driver.close() # ولكن لتأكيد إغلاق المتصفح بشكل نهائي، استخدم الأمر التالي driver.quit()

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

    بهذا، يمكنك الآن البدء في تطوير اختبارات Selenium لتطبيقاتك الويب والتحقق من سلامتها وأدائها بسهولة وفعالية. استمتع باستكشاف إمكانيات Selenium وقم بتوسيع معرفتك ومهاراتك في اختبار تطبيقات الويب.

  • مشكلة توقف Selenium: حلول وإرشادات

    من الواضح أنك تواجه مشكلة ملحة في تشغيل Selenium WebDriver مع ChromeDriver، والتي تظهر على شكل استثناء “session not created”. هذه المشكلة قد تنتج من عدة أسباب محتملة، وسأقدم لك تحليلاً شاملاً للمشكلة وبعض الحلول المحتملة:

    1. تحديث إصدار Chrome و ChromeDriver:
      يجب التأكد من أن إصدار متصفح Chrome و ChromeDriver متوافقان. قد يكون التحديث إلى أحدث إصدار من كل منهما يحل المشكلة. يمكنك التحقق من إصدار Chrome الخاص بك من خلال النقر على زر الثلاث نقاط في الزاوية العلوية اليمنى ثم “مساعدة” ثم “حول Google Chrome”. أما بالنسبة لـ ChromeDriver، يمكنك تنزيل أحدث إصدار من موقعهم الرسمي.

    2. تحديث مكتبة Selenium:
      قد يكون هناك توافق مشكل مع إصدار Selenium الخاص بك. حاول تحديث مكتبة Selenium إلى أحدث إصدار باستخدام pip:

      css
      pip install --upgrade selenium
    3. التحقق من التكوين الصحيح:
      تأكد من أن مسار ملف تنفيذ ChromeDriver مضاف إلى PATH الخاص بك بشكل صحيح. يمكنك القيام بذلك عن طريق تشغيل الأمر التالي في سطر الأوامر:

      bash
      echo $PATH

      وتأكد من أن مجلد يحتوي على ملف ChromeDriver موجود في القائمة المعروضة.

    4. مشكلة في الإعدادات المحلية أو الشبكة:
      قد يكون هناك تغيير في الإعدادات المحلية أو في الشبكة يؤثر على قدرة Selenium على إنشاء جلسة مع Chrome. يمكنك التحقق من ذلك عن طريق تشغيل البرنامج باستخدام حساب مستخدم مختلف أو عبر شبكة مختلفة للتحقق مما إذا كانت المشكلة مرتبطة بحساب المستخدم أو الشبكة.

    5. تحليل الرسالة الخطأ بالتفصيل:
      قد تحتوي الرسالة على معلومات إضافية حول الخطأ. قم بتحليل الرسالة بعناية للبحث عن أي معلومات قد تساعد في تحديد مصدر المشكلة. قد تحتاج إلى تصفح سجلات ChromeDriver للعثور على مزيد من التفاصيل.

    6. استشارة المجتمع المتخصص:
      إذا لم تنجح الحلول المذكورة أعلاه، فقد يكون من الأفضل طرح المشكلة في منتديات متخصصة في Selenium أو Stack Overflow، حيث يمكنك الحصول على المساعدة من مجتمع المطورين.

    من المهم أن تتحقق من هذه النقاط بدقة لتحديد السبب الفعلي وراء مشكلتك. باستخدام العملية التجريبية والتحليلية، يمكنك إيجاد الحل الأمثل لمشكلتك واستئناف عملك في أسرع وقت ممكن.

    المزيد من المعلومات

    بالطبع، دعنا نكمل المقال بمزيد من التحليل والتوجيه:

    1. التحقق من تغييرات Chrome و ChromeDriver:
      قد يكون هناك تحديثات أو تغييرات في Chrome أو ChromeDriver قد تؤثر على قدرة Selenium على التفاعل مع المتصفح بشكل صحيح. يمكنك البحث عن أي تقارير حول مشاكل معروفة أو تغييرات في إصدارات ChromeDriver الجديدة وكيفية التعامل معها.

    2. تحليل الكود والبيئة المحلية:
      قم بتحليل الكود الذي تستخدمه بعناية، وتأكد من عدم وجود أخطاء في الاستخدام أو التهيئة. قد يكون هناك تغييرات في بيئة التشغيل المحلية قد تؤثر على تنفيذ الكود، مثل تغييرات في إصدار Python أو الوحدات النمطية الأخرى المستخدمة.

    3. التحقق من الأذونات والتكوينات الأمانية:
      قد تحتاج إلى التحقق من الأذونات والتكوينات الأمانية في النظام الخاص بك للتأكد من أن Selenium و ChromeDriver يمكنهما الوصول إلى الموارد المطلوبة بشكل صحيح، مثل الوصول إلى الإنترنت والملفات المحلية.

    4. استكشاف الخلل بشكل تفصيلي:
      قد يتطلب حل هذه المشكلة استكشاف الخلل بشكل تفصيلي باستخدام أدوات مثل محللي الشبكة وسجلات النظام للعثور على أي مؤشرات على سبب المشكلة. يمكن استخدام أدوات مثل Wireshark لتحليل حركة الشبكة الصادرة والواردة من Selenium و ChromeDriver.

    5. استعادة النسخة الاحتياطية أو تغيير البيئة:
      إذا لم يكن بإمكانك حل المشكلة في الوقت المناسب، فقد يكون من الأفضل استعادة النسخة الاحتياطية من بيئة تشغيل سابقة حيث كان الكود يعمل بشكل صحيح. كما يمكنك أيضًا تجربة تشغيل الكود على بيئة مختلفة للتحقق مما إذا كانت المشكلة مرتبطة بالبيئة المحلية أو لا.

    6. الحصول على المساعدة من متخصصين:
      في حالة عدم القدرة على حل المشكلة بمفردك، فلا تتردد في طلب المساعدة من متخصصين في مجال Selenium و WebDriver. يمكنك الانضمام إلى منتديات عبر الإنترنت أو القنوات الخاصة في منصات التواصل الاجتماعي لطرح الأسئلة والحصول على المساعدة.

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

  • مشاكل تشغيل Selenium: حلول وإرشادات

    عندما تواجه هذا النوع من الأخطاء أثناء تشغيل الكود، فإنه من المهم فهم السبب وكيفية حله لتتمكن من تشغيل برامج Selenium بنجاح.

    في البداية، يبدو أن الخطأ يتعلق بـ “DriverService” في Selenium ويبدو أنك تستخدم متصفح Firefox. يحدث هذا الخطأ عادةً عندما يكون هناك مشكلة في تهيئة خدمة المتصفح (browser service). قد يكون السبب في ذلك هو عدم توافق إصدار المتصفح مع إصدار Selenium أو وجود مشكلة في تثبيت المتصفح نفسه.

    لحل هذه المشكلة، يمكنك القيام بالخطوات التالية:

    1. التأكد من تحديث Selenium ومتصفح Firefox: تأكد من استخدام إصدارات متوافقة مع بعضها البعض. يمكنك التحقق من موقع Selenium للتأكد من أنك تستخدم أحدث إصدار متوافق مع إصدار المتصفح الخاص بك.

    2. التأكد من تثبيت المتصفح بشكل صحيح: تأكد من أن متصفح Firefox مثبت بشكل صحيح على جهازك. قم بفتح المتصفح يدوياً وتأكد من أنه يعمل بدون مشاكل.

    3. التأكد من تهيئة بيئة العمل بشكل صحيح: تأكد من أن مسار متصفح Firefox مضاف إلى متغير البيئة “PATH” على نظام التشغيل الخاص بك.

    4. استخدام متصفح مختلف: في بعض الأحيان، يمكن حل المشكلة ببساطة بتغيير المتصفح المستخدم. جرب استخدام Chrome أو Edge بدلاً من Firefox وتحقق مما إذا كان الكود يعمل بشكل صحيح.

    5. البحث عن حلول عبر الإنترنت: قم بالبحث عبر الإنترنت عن الخطأ الذي تواجهه لربما تجد حالات مشابهة وحلول مقترحة تمكنك من حل المشكلة.

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

    المزيد من المعلومات

    بالطبع، دعوني أكمل المقال لتقديم مزيد من التوجيه والمعلومات:

    1. التحقق من إعدادات البروكسي والحماية: في بعض الأحيان، يمكن أن تكون إعدادات البروكسي أو برامج الحماية مثل جدار الحماية (Firewall) أو برنامج مكافحة الفيروسات تسبب هذا النوع من المشاكل. قم بفحص إعدادات الشبكة الخاصة بك وتأكد من أن Selenium يمكنه الوصول إلى المتصفح بشكل صحيح.

    2. استخدام إصدارات متوافقة من مكتبات WebDriver: تأكد من أنك تستخدم إصدارات متوافقة من مكتبات WebDriver. في بعض الأحيان، قد يكون هناك تعارض بين إصدارات Selenium WebDriver وإصدارات المتصفح.

    3. فحص سجلات الأخطاء (Logs): قم بفحص سجلات الأخطاء الخاصة بالتشغيل لمعرفة المزيد من التفاصيل حول سبب الخطأ. يمكن أن توفر السجلات معلومات قيمة تساعد في تحديد سبب المشكلة.

    4. التحقق من الاستثناءات (Exceptions): يجب أن تتعلم كيفية التعامل مع الاستثناءات في برامج Selenium. استخدم جمل الاستثناءات للتقاط الأخطاء وإدارتها بشكل صحيح لتحسين استقرار برامجك.

    5. البحث عن المجتمع والمنتديات: تفضل بطرح أسئلتك في المجتمعات والمنتديات المخصصة لبرامج Selenium. قد يكون لدى الأشخاص الآخرين تجارب مشابهة وقد يكونون قادرين على تقديم الدعم والمساعدة.

    باستخدام هذه الإرشادات والتوجيهات، يجب أن تكون قادرًا على تجاوز مشكلة الخطأ التي تواجهها أثناء تشغيل برامج Selenium. تذكر دائمًا أن الصبر والمثابرة أمران مهمان عندما يتعلق الأمر بتطوير واختبار البرمجيات.

  • استخراج أرقام من النصوص باستخدام Selenium

    لقراءة الرقم 7 فقط من النص “7 humans” الذي تم العثور عليه داخل عنصر الويب، يمكنك استخدام التالي:

    java
    WebElement element = driver.findElement(By.xpath("//*[@id='filter-row']/div[2]")); String text = element.getText(); // 7 humans // استخدم تعبير النمط العادي (Regular Expression) لاستخراج الأرقام فقط String numberOnly = text.replaceAll("[^0-9]", ""); // سيتم الحفاظ على الأرقام فقط وإزالة أي حروف أو مسافات int count = Integer.parseInt(numberOnly); // قم بتحويل النص إلى عدد صحيح System.out.println("The count is: " + count); // سيتم طباعة: The count is: 7

    تتيح لك هذه الطريقة استخدام تعبير النمط العادي (Regular Expression) لتحديد الأرقام في النص وإزالة أي محتوى غير رقمي. بعد ذلك، يتم تحويل النص المنقى إلى عدد صحيح باستخدام Integer.parseInt() لتمكينك من استخدام القيمة الرقمية في العمليات اللاحقة.

    المزيد من المعلومات

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

    من خلال السؤال المطروح، يظهر لنا مثالًا على كيفية استخراج قيمة رقمية محددة من نص معقد باستخدام Selenium WebDriver ولغة Java. في هذا المثال، يتم استخراج الرقم 7 من النص “7 humans” باستخدام تعبير النمط العادي.

    الخطوات المتبعة في هذا المثال تتضمن:

    1. العثور على العنصر الذي يحتوي على النص المراد استخراج الرقم منه باستخدام Selenium WebDriver. في هذا المثال، تم استخدام xpath لتحديد العنصر.

    2. استخدام getText() لاسترجاع النص الذي يحتوي على الرقم.

    3. استخدام تعبير النمط العادي (Regular Expression) لاستخراج الأرقام فقط من النص. تعبير النمط [0-9] يعني أي رقم من 0 إلى 9، و [^0-9] يعني أي حرف غير رقمي. بالتالي، سيتم إزالة أي حرف غير رقمي من النص، مما يترك لنا الأرقام فقط.

    4. استخدام Integer.parseInt() لتحويل النص المنقى إلى عدد صحيح.

    5. استخدام القيمة العددية المستخرجة في العمليات اللاحقة كما هو مطلوب.

    يعتبر استخدام تعبير النمط العادي مفيدًا لتنظيف البيانات واستخراج القيم المرغوبة من النصوص المعقدة. بعد استخراج القيمة المطلوبة، يمكنك استخدامها في اتخاذ القرارات أو إجراء الاختبارات الضرورية في تطبيقك.

    هذا المثال يوضح كيف يمكن استخدام Selenium WebDriver بالاقتران مع لغة Java لتنفيذ مهام محددة مثل قراءة البيانات من العناصر على صفحات الويب بشكل دقيق وفعال. تطبيق هذه الطريقة يمكن أن يساعد في ضمان دقة الاختبارات الآلية وتحسين فعالية العمليات الخاصة بالاختبار والتحليل.

  • تجنب Null Pointer Exception في Selenium.

    المشكلة التي تواجهك تتمثل في استخدامك لمتغير driver بدون تهيئته بشكل صحيح. في البداية، قمت بتهيئة المتغير driver بقيمة null، ومن ثم حاولت استخدامه دون تهيئته بكائن من فئة ChromeDriver، مما أدى إلى حدوث استثناء “Null Pointer Exception”.

    المشكلة تكمن في أنك قمت بتعريف المتغير driver بشكل محلي داخل الدالة launchBrowser ولكن لم تقم بإرجاعه من الدالة أو تهيئته بشكل عام داخل البرنامج الرئيسي. بالتالي، عند استدعاء الدالة launchBrowser وتم تمرير قيمة "CH" كمعامل، تقوم الدالة بإنشاء كائن ChromeDriver وتهيئته لكنها لا تعيده أو تخزنه في المتغير driver الذي تستخدمه في الجزء الرئيسي من برنامجك.

    لحل هذه المشكلة، يمكنك إما تهيئة المتغير driver بشكل عام داخل الصنف والتأكد من تهيئته في الدالة launchBrowser وإعادتها ككائن من نوع WebDriver، أو يمكنك تخزين الكائن ChromeDriver المعين من داخل الدالة launchBrowser في متغير عالمي يمكنك استخدامه في الجزء الرئيسي من برنامجك.

    في حالة اتخاذ الخيار الأول، يمكن أن يكون مثل الكود التالي:

    java
    import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; public class ArrayLiist { static WebDriver driver; // تعريف المتغير كعام public static void main(String[] args) { launchBrowser("CH"); driver.findElement(By.id("user_login")).sendKeys("admin"); driver.findElement(By.id("user_pass")).sendKeys("demo123"); driver.findElement(By.id("wp-submit")).click(); } public static void launchBrowser(String bn) { if (bn.equals("CH")) { // استخدام equals للمقارنة بين السلاسل System.setProperty("webdriver.chrome.driver", "E:\\Selenium Downloaded\\chrome\\chromedriver.exe"); driver = new ChromeDriver(); // تهيئة المتغير بكائن من فئة ChromeDriver driver.get("http://demosite.center/wordpress/wp-admin/plugins.php"); } } }

    أو يمكنك استخدام الخيار الثاني، وهو تعريف متغير عالمي داخل الصنف:

    java
    import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; public class ArrayLiist { static WebDriver driver; // تعريف المتغير كعالمي public static void main(String[] args) { launchBrowser("CH"); driver.findElement(By.id("user_login")).sendKeys("admin"); driver.findElement(By.id("user_pass")).sendKeys("demo123"); driver.findElement(By.id("wp-submit")).click(); } public static void launchBrowser(String bn) { if (bn.equals("CH")) { System.setProperty("webdriver.chrome.driver", "E:\\Selenium Downloaded\\chrome\\chromedriver.exe"); driver = new ChromeDriver(); driver.get("http://demosite.center/wordpress/wp-admin/plugins.php"); } } }

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

    المزيد من المعلومات

    عند تطوير البرمجيات، يُعتبر العثور على استثناء “Null Pointer Exception” أمرًا شائعًا، ويمكن أن يكون مصدر إزعاج كبير للمطورين. في حالتك، تجد نفسك تواجه هذا الاستثناء في برنامج Selenium الخاص بك، وهو مشهور بتجريب واختبار تطبيقات الويب.

    بعد مراجعة الشيفرة التي قدمتها، يتضح أن المشكلة تكمن في استخدام المتغير driver قبل تهيئته بشكل صحيح. حيث قمت بتعيين قيمته إلى null دون تهيئته بكائن من فئة ChromeDriver. هذا الأمر أدى إلى حدوث الاستثناء “Null Pointer Exception” عندما حاولت استخدام driver داخل الدالة main.

    لحل هذه المشكلة، يجب عليك تهيئة المتغير driver بشكل صحيح قبل استخدامه. يمكنك ذلك بإما تهيئته مباشرة داخل الدالة main أو عن طريق استدعاء الدالة launchBrowser التي تقوم بإنشاء وتهيئة المتغير driver.

    في الشيفرة التي قدمتها، قمت بتعيين المتغير driver محليًا داخل الدالة launchBrowser. ولكن لم يتم استخدامه بشكل صحيح بعد ذلك. لحل هذه المشكلة، يمكنك تعديل الشيفرة لتخزين المتغير driver كعالمي داخل الصنف. هذا سيتيح لك استخدامه بسهولة في جميع أنحاء البرنامج.

    بعد إجراء التعديلات اللازمة، يجب أن يبدو الشيفرة كالتالي:

    java
    import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; public class ArrayLiist { static WebDriver driver; // تعريف المتغير كعالمي public static void main(String[] args) { launchBrowser("CH"); driver.findElement(By.id("user_login")).sendKeys("admin"); driver.findElement(By.id("user_pass")).sendKeys("demo123"); driver.findElement(By.id("wp-submit")).click(); } public static void launchBrowser(String bn) { if (bn.equals("CH")) { System.setProperty("webdriver.chrome.driver", "E:\\Selenium Downloaded\\chrome\\chromedriver.exe"); driver = new ChromeDriver(); driver.get("http://demosite.center/wordpress/wp-admin/plugins.php"); } } }

    باستخدام هذه الشيفرة، يجب أن تتمكن الآن من تشغيل برنامجك دون حدوث استثناء “Null Pointer Exception”. بمجرد تشغيل البرنامج، سيتم فتح متصفح Chrome وتسجيل الدخول إلى صفحة ووردبريس المعينة كما هو موضح في الشيفرة.

  • حلول لمشاكل Python Selenium

    يبدو أن الكود الذي قدمته يحتوي على بعض الأخطاء التي تمنعه من العمل بشكل صحيح. دعني أشرح لك الأخطاء وأقترح التعديلات اللازمة:

    1. في البداية، يجب تعيين القيم الخاصة بـ”passFieldID” و”fbLogoXpath”.
    2. في الدالة “test_Login”، يبدو أنك قمت بتحديد المتغير بشكل غير صحيح. بدلاً من “passFieldID”، يجب استخدام “passFieldElement”.
    3. الاستدعاء الخاطئ لدالة “WebDriverWait”، يجب استخدام القوسين () بدلاً من الأقواس [].
    4. قد يكون هناك خطأ في عنوان XPath لـ”fbLogoXpath”.

    إليك الكود بعد التعديلات:

    python
    from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC import unittest class LoginTest(unittest.TestCase): def setUp(self): self.driver = webdriver.Firefox() self.driver.get("https://www.facebook.com/") def test_Login(self): driver = self.driver facebookUsername = "[email protected]" facebookPassword = "basabasa" emailFieldID = "email" passFieldID = "pass" loginButtonXpath = "//input[@value= 'Log In']" fbLogoXpath = "//a[contains(@href , 'logo')]" emailFieldElement = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, emailFieldID))) passwordFieldElement = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, passFieldID))) loginButtonElement = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, loginButtonXpath))) emailFieldElement.clear() emailFieldElement.send_keys(facebookUsername) passwordFieldElement.clear() passwordFieldElement.send_keys(facebookPassword) loginButtonElement.click() WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, fbLogoXpath))) def tearDown(self): self.driver.quit() if __name__ == '__main__': unittest.main()

    بعد التعديلات، يجب أن يقوم الكود بفتح موقع Facebook وتعبئة حقول البريد الإلكتروني وكلمة المرور ومن ثم النقر على زر تسجيل الدخول. كما يتأكد من وجود الشعار الخاص بـ Facebook بنجاح.

    المزيد من المعلومات

    بالطبع، سأقوم بتكملة المقال لتوضيح المزيد حول كيفية عمل الكود المعدل وبعض النصائح لحل مشاكل شائعة في بيئة Selenium.

    بعد التعديلات التي قمنا بها في الكود، يتوقع أن يعمل الكود بشكلٍ صحيح الآن. ولكن من المهم فهم بعض النقاط الأساسية حول كيفية عمل Selenium وكيفية تجنب الأخطاء المشتركة.

    أولاً، دعنا نفهم بعض الدوال التي استخدمناها في الكود:

    1. WebDriverWait(driver, timeout).until(): هذه الدالة تستخدم للانتظار حتى يتم اكتشاف عنصر معين في صفحة الويب. يتم تحديد المدة الزمنية المسموح بها للانتظار والعنصر الذي نبحث عنه. في حالة عدم اكتشاف العنصر خلال المدة الزمنية المحددة، فإنها ستثير استثناء TimeoutException.

    2. EC.presence_of_element_located((By.ID, id)): هذه دالة تُعطى للـ WebDriverWait لتحديد أن العنصر موجود في الصفحة بناءً على محددات معينة مثل الـ ID في هذه الحالة.

    3. EC.element_to_be_clickable((By.XPATH, xpath)): هذه الدالة تُستخدم للتأكد من أن العنصر الذي نريد النقر عليه جاهز للنقر. إذا كان موجودًا ومُنشطًا ويمكن النقر عليه، فإنها تُرجع True، وإلا فإنها تنتظر حتى يكون العنصر جاهزًا.

    ثانياً، يجب أن نتأكد من تفعيل وحدة WebDriver في Python لكي يتمكن الكود من التفاعل مع المتصفح. يمكن تنزيلها بسهولة باستخدام مدير الحزم pip:

    bash
    pip install selenium

    ثالثاً، يُنصح بتحديث متصفح Selenium (مثل ChromeDriver أو GeckoDriver) للتأكد من توافقه مع إصدار المتصفح الذي تستخدمه.

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

    خامساً، لضمان عمل الكود بشكلٍ صحيح، تأكد من مطابقة محددات العناصر مثل ID و XPath مع عناصر الصفحة الفعلية.

    سادساً، يمكن استخدام وحدة التحكم في المتصفح (DevTools) لفحص العناصر وتحديد محدداتها بشكل دقيق.

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

    اتمنى لك التوفيق في رحلتك التعلمية مع Python وSelenium!

  • حل مشكلة النقر في Selenium

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

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

    علاوة على ذلك، يمكن استخدام أدوات تفحص المطور لمتصفح Chrome أو أي متصفح آخر لتحديد ما إذا كان هناك عنصر يتداخل مع العنصر المستهدف. قد يكون ذلك بسبب تراكم العناصر في الصفحة أو وجود خلل في تصميمها.

    إذا استمرت المشكلة، يمكن التحقق من نسخة متصفح Chrome ومتسخدمها من متصفح Selenium (Chromedriver) للتأكد من التوافق بينهما. قد تحتاج إلى تحديث Chromedriver إلى الإصدار الأحدث لضمان التوافق مع إصدار المتصفح.

    في النهاية، يجب تحليل سياق الخطأ بشكل شامل، بما في ذلك معلومات الجلسة ونسخة المتصفح ونظام التشغيل والسير الزمني للأوامر وبنية الصفحة، لفهم السبب الفعلي وراء الخطأ واتخاذ الإجراءات اللازمة لتجاوزه.

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

    المزيد من المعلومات

    باستكمال النقاش حول الخطأ الذي يحدث في سياق استخدام Selenium، يمكننا أيضًا النظر في بعض النصائح العامة لتجنب مشاكل النقر على العناصر في سياق استخدام Selenium.

    1. تحديد استراتيجية لتفادي التعارض: في بعض الأحيان، قد تواجه مشاكل في النقر بسبب تداخل العناصر في الصفحة. في هذه الحالات، يمكن استخدام تقنيات CSS لتعيين خصائص العناصر بشكل دقيق أو حتى تغيير هيكل الصفحة لتجنب التداخل.

    2. استخدام تأخيرات ذكية: بدلاً من استخدام تأخيرات ثابتة، يمكن استخدام وظيفة WebDriverWait في Selenium لانتظار ظهور العنصر المستهدف قبل محاولة النقر عليه. يمكن تكوين هذه الوظيفة بحيث تنتظر حتى يصبح العنصر قابلًا للنقر قبل تنفيذ الإجراء المطلوب.

    3. التحقق من الأحدث والتوافق: يجب دائمًا التحقق من أن نسخة متصفح Selenium (مثل Chromedriver) متوافقة مع إصدار المتصفح الخاص بك. قد يتسبب تحديث المتصفح في مشاكل مع إصدارات قديمة من متسخدمها، لذا ينبغي تحديث أدوات Selenium بانتظام.

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

    5. التحقق من الصفحة قبل النقر: قبل محاولة النقر على العنصر، ينبغي التحقق من حالة الصفحة بشكل عام، بما في ذلك التأكد من عدم وجود رسائل تنبيه أو صفحات منبثقة أو تغييرات غير متوقعة في هيكل الصفحة.

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

  • تنفيذ تحققات متعددة في اختبارات Selenium باستخدام Pytest

    بالطبع، يُمكنك تنفيذ عدة تحققات في اختبارك باستخدام pytest. يعد pytest أداة تجريبية مرنة وقوية تسمح لك بتنفيذ العديد من التحققات في نفس الاختبار وتقديم تقارير عن جميع القيم التي لا تتطابق.

    في سياق اختبار Selenium الخاص بك، يمكنك استخدام بيثون ومكتبة pytest لتنفيذ تحققات متعددة وتقارير عن جميع القيم التي لا تتطابق. على سبيل المثال، يمكنك تحقق من قيم متعددة باستخدام بيانات مختلفة وتقديم تقرير شامل عن الفروقات بين القيم المتوقعة والفعلية.

    لتحقيق ذلك، يمكنك استخدام بيانات الاختبار المتعددة في دالة متعددة التحققات. على سبيل المثال، يمكنك تنفيذ العديد من التحققات في نفس الدالة وجمع جميع الأخطاء في قائمة لتقديم تقرير شامل بعد اكتمال الاختبار.

    فيما يلي مثال لكيفية تحقيق ذلك باستخدام pytest:

    python
    import pytest # Function to perform multiple assertions def test_multiple_assertions(): errors = [] # List to collect errors # Example values expected_values = [1, 2, 3] actual_values = [1, 4, 5] # Perform multiple assertions for expected, actual in zip(expected_values, actual_values): try: assert expected == actual except AssertionError as e: errors.append(f"Expected: {expected}, Actual: {actual} - {str(e)}") # Check if there are errors, if so, fail the test and print the errors if errors: pytest.fail("\n".join(errors))

    في هذا المثال، تم إنشاء دالة test_multiple_assertions() التي تقوم بتنفيذ عدة تحققات باستخدام قيم متوقعة وفعلية مختلفة. يتم استخدام حلقة for لتنفيذ التحققات وجمع الأخطاء في قائمة errors. بعد اكتمال الاختبار، يتم فحص ما إذا كانت هناك أخطاء في القائمة، وإذا كان الأمر كذلك، يتم فشل الاختبار باستخدام pytest.fail() وطباعة التقرير الشامل للأخطاء.

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

    المزيد من المعلومات

    بالطبع، يُمكنك تنفيذ عدة تحققات في اختباراتك بواسطة pytest، فهو يوفر لك المرونة والقوة لتحقيق ذلك بسهولة. عندما يتعلق الأمر باختبارات Selenium، فإن إمكانية تنفيذ تحققات متعددة تعتبر ضرورية لضمان جودة وموثوقية تطبيقك.

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

    لنلق نظرة عميقة على كيفية إكمال المقال:

    تنفيذ عدة تحققات في اختبارات Selenium باستخدام Pytest

    عند كتابة اختبارات Selenium باستخدام بيثون ومكتبة pytest، يمكنك تنفيذ عدة تحققات في نفس الاختبار بسهولة. هذا يسمح لك بفحص مجموعة متنوعة من السيناريوهات وضمان أن التطبيق يعمل كما هو متوقع.

    الخطوة 1: كتابة الاختبار

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

    python
    import pytest # Function to perform multiple assertions def test_multiple_assertions(): errors = [] # List to collect errors # Example values expected_values = [1, 2, 3] actual_values = [1, 4, 5] # Perform multiple assertions for expected, actual in zip(expected_values, actual_values): try: assert expected == actual except AssertionError as e: errors.append(f"Expected: {expected}, Actual: {actual} - {str(e)}") # Check if there are errors, if so, fail the test and print the errors if errors: pytest.fail("\n".join(errors))

    الخطوة 2: تشغيل الاختبار

    بمجرد كتابة الاختبار، يمكنك تشغيله باستخدام أمر pytest في سطر الأوامر. سترى تقريرًا مفصلًا بما في ذلك الأخطاء إذا كانت هناك فشل في التحققات.

    bash
    $ pytest test_file.py

    الخطوة 3: تحليل النتائج

    بعد تشغيل الاختبار، يمكنك تحليل التقرير لمعرفة القيم التي لم تتطابق والأخطاء المُرتبطة بها. هذا يمكن أن يساعدك في تحديد نقاط الضعف في التطبيق وتحسينه.

    الختام

    باستخدام بيثون ومكتبة pytest، يمكنك بسهولة تنفيذ عدة تحققات في اختبارات Selenium والحصول على تقرير شامل بجميع القيم التي لا تتطابق. هذا يساعد في تحسين جودة التطبيق وضمان أنه يعمل كما هو متوقع في جميع السيناريوهات.

  • جلب رؤوس الطلبات باستخدام Selenium في Python

    في برمجة الويب باستخدام Python ومكتبة Selenium WebDriver، يمكنك بسهولة جلب رؤوس الطلبات باستخدام Selenium بدون الحاجة إلى تشغيل خادم Selenium مستقل.

    لفهم كيفية القيام بذلك، يجب أن نتطرق إلى مفهوم Selenium WebDriver وكيفية استخدامه. Selenium WebDriver هو أداة تتيح لك التحكم في المتصفح بشكل برمجي، مما يتيح لك تنفيذ إجراءات مثل فتح الصفحات، إدخال البيانات، والتفاعل مع العناصر على الصفحة. ومن ضمن هذه الإجراءات يمكنك جلب رؤوس الطلبات.

    بناءً على الكود الذي قدمته، يمكنك جلب رؤوس الطلبات باستخدام خاصية “capabilities” في Selenium WebDriver. يمكنك تضمين هذه الخاصية في متصفح Chrome للحصول على معلومات الرأس من الطلبات.

    في الكود الذي قدمته، يمكنك تعديله ليبدو مثل هذا:

    python
    from selenium import webdriver # تعيين الخيارات للمتصفح للحصول على رؤوس الطلبات chrome_options = webdriver.ChromeOptions() chrome_options.add_argument("--headless") # تشغيل المتصفح بدون واجهة رسومية chrome_options.add_argument("--start-maximized") # تكبير النافذة للحصول على المزيد من المعلومات chrome_options.add_argument("--disable-extensions") # تعطيل الامتدادات للحصول على رؤوس الطلبات بشكل أفضل chrome_options.add_argument("--disable-gpu") # تعطيل محرك المعالجة الرسومية لضمان استجابة أفضل # إنشاء متصفح Chrome مع الخيارات المعطاة driver = webdriver.Chrome(options=chrome_options) # فتح صفحة الويب المطلوبة driver.get('https://login.comcast.net/login?r=comcast.net&s=oauth&continue=https%3A%2F%2Flogin.comcast.net%2Foauth%2Fauthorize%3Fclient_id%3Dxtv-account-selector%26redirect_uri%3Dhttps%3A%2F%2Fxtv-pil.xfinity.com%2Fxtv-authn%2Fxfinity-cb%26response_type%3Dcode%26scope%3Dopenid%2520https%3A%2F%2Flogin.comcast.net%2Fapi%2Flogin%26state%3Dhttps%3A%2F%2Ftv.xfinity.com%2Fpartner-success.html%26prompt%3Dlogin%26response%3D1&reqId=18737431-624b-44cb-adf0-2a85d91bd662&forceAuthn=1&client_id=xtv-account-selector') # جلب رؤوس الطلبات من المتصفح headers = driver.execute_script("return window.performance.getEntries()[0].responseHeaders") # طباعة رؤوس الطلبات print(headers) # إغلاق المتصفح بعد الانتهاء driver.quit()

    هذا الكود يقوم بفتح متصفح Chrome بدون واجهة رسومية ويفتح صفحة الويب المعنية. ثم، يستخدم Selenium لجلب رؤوس الطلبات من الصفحة عن طريق تنفيذ JavaScript في النافذة الحالية. وأخيرًا، يطبع الكود رؤوس الطلبات ويغلق المتصفح بعد الانتهاء.

    باستخدام هذه الطريقة، يمكنك جلب رؤوس الطلبات بدون الحاجة إلى تشغيل خادم Selenium مستقل، مما يجعل عملية جلب المعلومات أكثر فعالية وسهولة.

    المزيد من المعلومات

    بالطبع! دعنا نواصل تعزيز المقال بمزيد من التفاصيل والشروحات لضمان فهم أعمق للقراء.

    للبداية، دعنا نفهم كيف يعمل الكود الجديد الذي تم توسيعه.

    1. الخيارات لمتصفح Chrome:
      في السطر 5-10، يتم تكوين خيارات المتصفح لضبط سلوكه. تم تضمين خيارات مثل --headless لتشغيل المتصفح بدون واجهة رسومية، --start-maximized لتكبير النافذة للحصول على المزيد من المعلومات، و --disable-extensions و --disable-gpu لضمان استجابة أفضل وتجنب مشاكل الامتدادات ومحرك المعالجة الرسومية.

    2. فتح صفحة الويب المطلوبة:
      في السطر 13، يتم استخدام driver.get() لفتح صفحة الويب المعنية التي تحتوي على الرؤوس التي تريد استخراجها.

    3. جلب رؤوس الطلبات:
      في السطر 16، يتم استخدام driver.execute_script() لتنفيذ JavaScript في نطاق الصفحة الحالي. يتم استخدام window.performance.getEntries()[0].responseHeaders للوصول إلى معلومات الرأس لأول طلب. هذا يعود بناءً على أن الطلبات الأولى هي عادةً طلب الصفحة الرئيسية.

    4. طباعة رؤوس الطلبات:
      في السطر 19، يتم طباعة رؤوس الطلبات التي تم جلبها من الصفحة.

    5. إغلاق المتصفح:
      في السطر 22، يتم استدعاء driver.quit() لإغلاق المتصفح بمجرد الانتهاء من استخدامه.

    هذه الطريقة تعتمد على استخدام Selenium WebDriver لتنفيذ JavaScript في نطاق الصفحة للوصول إلى معلومات الرأس، وهي طريقة فعالة وسهلة للحصول على هذه المعلومات بدون الحاجة إلى تشغيل خادم Selenium مستقل.

    من المهم أيضًا التنويه بأنه يمكن تعديل الكود لجلب معلومات الرأس لطلبات أخرى، مثل الطلبات AJAX أو أي طلبات تم تنفيذها بعد التحميل الأولي للصفحة. يمكن ذلك بتعديل الفهرس [0] في window.performance.getEntries()[0] لاختيار الطلب المناسب.

    بهذا الشكل، يمكنك الآن جلب رؤوس الطلبات بسهولة وفعالية باستخدام Selenium WebDriver في Python دون الحاجة إلى تعقيدات إضافية مثل تشغيل خادم Selenium مستقل.

  • الحصول على اسم الصنف في Selenium

    بالطبع، يمكنك الحصول على اسم الصنف (Class Name) لعنصر الويب (WebElement) باستخدام Selenium في Python. تستطيع تحقيق ذلك باستخدام خاصية “get_attribute()” لعنصر الويب، وتمرير اسم الخاصية “class” كمعامل لها. ولكن يجب ملاحظة أن “class” هو كلمة محجوزة في Python، لذلك ستحتاج إلى استخدام اسم مختلف لاسترداد قيمة الصنف. في هذا السياق، يمكنك استخدام “class_name” بدلاً من “class”.

    وإليك كيفية تحقيق ذلك في السياق الخاص بك:

    python
    table_body = table.find_element_by_tag_name('tbody') rows = table_body.find_elements_by_tag_name('tr') for row in rows: class_name = row.get_attribute("class_name") if "date" in class_name: Action1() else: Action2()

    في هذا الكود، نحصل على قيمة الصنف لكل صف (row) باستخدام الأمر “get_attribute()”، ونخزنها في متغير باسم “class_name”. بعد ذلك، نقوم بفحص ما إذا كانت كلمة “date” موجودة في قيمة الصنف المسترجعة. إذا كانت موجودة، نقوم بتنفيذ “Action1()”، وإلا، نقوم بتنفيذ “Action2()”.

    تحقق من أن تضمن تلك الأساليب “Action1()” و “Action2()” السلوك الصحيح الذي ترغب في تنفيذه بناءً على اسماء الصنف. قد تحتاج أيضًا إلى ضبط الشروط وفقًا لمتطلباتك الخاصة، مثل التحقق من وجود كلمة معينة في اسم الصنف أو استخدام نمط معين للتحقق.

    باستخدام هذه الطريقة، يمكنك تحديد الإجراء المناسب بناءً على اسماء الصنف لكل عنصر من عناصر الجدول التي تقوم بجمعها.

    المزيد من المعلومات

    بالطبع، يمكنك الحصول على اسم الصنف (Class Name) لعنصر الويب (WebElement) باستخدام Selenium في Python. تستطيع تحقيق ذلك باستخدام خاصية “get_attribute()” لعنصر الويب، وتمرير اسم الخاصية “class” كمعامل لها. ولكن يجب ملاحظة أن “class” هو كلمة محجوزة في Python، لذلك ستحتاج إلى استخدام اسم مختلف لاسترداد قيمة الصنف. في هذا السياق، يمكنك استخدام “class_name” بدلاً من “class”.

    وإليك كيفية تحقيق ذلك في السياق الخاص بك:

    python
    table_body = table.find_element_by_tag_name('tbody') rows = table_body.find_elements_by_tag_name('tr') for row in rows: class_name = row.get_attribute("class_name") if "date" in class_name: Action1() else: Action2()

    في هذا الكود، نحصل على قيمة الصنف لكل صف (row) باستخدام الأمر “get_attribute()”، ونخزنها في متغير باسم “class_name”. بعد ذلك، نقوم بفحص ما إذا كانت كلمة “date” موجودة في قيمة الصنف المسترجعة. إذا كانت موجودة، نقوم بتنفيذ “Action1()”، وإلا، نقوم بتنفيذ “Action2()”.

    تحقق من أن تضمن تلك الأساليب “Action1()” و “Action2()” السلوك الصحيح الذي ترغب في تنفيذه بناءً على اسماء الصنف. قد تحتاج أيضًا إلى ضبط الشروط وفقًا لمتطلباتك الخاصة، مثل التحقق من وجود كلمة معينة في اسم الصنف أو استخدام نمط معين للتحقق.

    باستخدام هذه الطريقة، يمكنك تحديد الإجراء المناسب بناءً على اسماء الصنف لكل عنصر من عناصر الجدول التي تقوم بجمعها.

    وبالطبع، إذا كنت تواجه أي صعوبات أو لديك أي استفسارات إضافية، فلا تتردد في طرحها.

زر الذهاب إلى الأعلى
إغلاق

أنت تستخدم إضافة Adblock

يرجى تعطيل مانع الإعلانات حيث أن موقعنا غير مزعج ولا بأس من عرض الأعلانات لك فهي تعتبر كمصدر دخل لنا و دعم مقدم منك لنا لنستمر في تقديم المحتوى المناسب و المفيد لك فلا تبخل بدعمنا عزيزي الزائر