كيف اختبرنا السحب والإفلات في HTML5

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



تخيل أنه يشبه المشروع تقنياً للغاية المشروع السابق (في رأينا ، كان له تأثير سلبي صغير من حيث فهم وتحليل المشكلة التي ظهرت بشكل صحيح) ، ولكن تم تغيير إصدار Angular بين المشاريع من 1.x إلى 5.x وتمت إضافة مكتبة Selenide لاختبارات UI الذاتية .

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

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

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

أخيرًا ، تعاملنا مع حقيقة المشكلة وذهبنا للبحث عن حل على الإنترنت. ما الذي فاجأنا عندما وجدنا مشكلة Chrome WebDriver # 3604 من 03/04/2016 . مجرد التفكير ، منذ ربيع عام 2016 ، هناك مشكلة في السحب والإفلات في Chrome WebDriver ، ناهيك عن المتصفحات الأخرى. لا ، إنه يعمل بالتأكيد ، ولكن ليس عند استخدام HTML5. وكما اتضح في عملية تحليل المشكلة ، استخدم تطبيقنا تطبيق السحب والإفلات باستخدام HTML5.

ما هي تطبيقات السحب والإفلات للاختبار في HTML5؟ على الإنترنت ، تم العثور على حلين:

  • استخدم مكتبة Java awt.Robot (أو بعض الفرس التابع لجهة خارجية) ؛
  • استخدام جافا سكريبت.

ربما حصلنا على القليل من المال أو دفننا في المشكلة ، لكن على الفور سأبدي تحفظًا على أن الحل الأول الذي تم اختياره لم يناسبنا :)

ماذا يمكن أن يقال عن التنفيذ على روبوت:

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

ولكن شيئا عن تطبيق جافا سكريبت أصبح في الاعتبار:

  • يحدث كل شيء على JavaScript داخل المستعرض (الإجراءات مخفية عن أعين المختبر وهذه الإجراءات تتداخل مع الكود) ؛
  • من مكتبات js لاختبار السحب والإفلات على الإنترنت ، تم العثور على واحدة ، لم يكن من السهل العثور على مصدرها ؛
  • سيتعين الانتهاء من المكتبة التي تم العثور عليها بملف ليناسب احتياجاتك ، حيث إنه ينفذ السحب والإفلات فقط. ونحن ، على سبيل المثال ، نحتاج إلى السحب -> نقل -> تعليق -> إسقاط ؛
  • يتم تنفيذ المكتبة كإضافة jQuery ، وبالتالي سيكون من الضروري فهم بنية jQuery ؛
  • سيتعين علينا إرسال محددات مواقع إلى css (لا يعمل jquery مع xpath) ؛
  • من المستحيل استخدام البحث عن عناصر السيلينيوم ؛ سيتعين عليك لصق المواقع "الأقلام".

للوهلة الأولى ، كان الحل الأول أكثر ملاءمة وتم اختباره.

//Setup robot Robot robot = new Robot(); robot.setAutoDelay(50); //Fullscreen page so selenium coordinates work robot.keyPress(KeyEvent.VK_F11); Thread.sleep(2000); //Get size of elements Dimension fromSize = dragFrom.getSize(); Dimension toSize = dragTo.getSize(); //Get centre distance int xCentreFrom = fromSize.width / 2; int yCentreFrom = fromSize.height / 2; int xCentreTo = toSize.width / 2; int yCentreTo = toSize.height / 2; //Get x and y of WebElement to drag to Point toLocation = dragTo.getLocation(); Point fromLocation = dragFrom.getLocation(); //Make Mouse coordinate centre of element toLocation.x += xOffset + xCentreTo; toLocation.y += yCentreTo; fromLocation.x += xCentreFrom; fromLocation.y += yCentreFrom; //Move mouse to drag from location robot.mouseMove(fromLocation.x, fromLocation.y); //Click and drag robot.mousePress(InputEvent.BUTTON1_MASK); //Move to final position robot.mouseMove(toLocation.x, toLocation.y); //Drop robot.mouseRelease(InputEvent.BUTTON1_MASK); 

بشكل عام ، الحل يعمل ... ومع ذلك ، في عملية تطويره ، أصبحت مجالات المشكلة واضحة.

  • حركة الماوس أو تصغير المستعرض أثناء تنفيذ الاختبارات يؤدي إلى تداخل أثناء الاختبارات وسقوطها ؛
  • لا يمكن تشغيل الاختبارات بالتوازي باستخدام JUnit / TestNG. ما لم موازاة ذلك من خلال مهام منفصلة في CI.
  • غير قادر على التحكم في الماوس على الجهاز البعيد من خلال شبكة سيلينيوم / سيلينويد ؛
  • في حالة تعطل المتصفح ، يمكن لـ Robot النقر / السحب بسهولة على شيء على سطح المكتب أو في تطبيق مفتوح آخر.

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

أريد أن أقول على الفور أن مشكلة استخدام محددات مواقع xpath قد تم حلها باستخدام jquery plugin jquery.xpath.js.

وأصبحت مكتبة drag_and_drop_helper.js (المصدر هنا ) الأداة الرئيسية للتحكم في عمليات السحب والإفلات. لا يوجد أي معنى لتصنيف عملها ، ولكن حول كيفية عملنا عليه لاحقًا.

الآن مباشرة على التنفيذ في الاختبارات. في Selenide ، كل شيء بسيط. قبل استخدام السحب والإفلات ، تحتاج إلى تحميل مكتبات JS المستخدمة:

 StringBuilder sb = new StringBuilder(); sb.append(readFile("jquery-3.3.1.min.js")); sb.append(readFile("jquery.xpath.min.js")); sb.append(readFile("drag_and_drop_helper.js")); executeJavaScript(sb.toString()); 

بطبيعة الحال ، يجب تحميل jQuery إذا لم يكن موجودًا بالفعل في التطبيق.

في الإصدار الأصلي للمكتبة ، يكفي كتابة ما يلي:

 executeJavaScript("$('" + source + "') .simulateDragDrop({ dropTarget: '" + target + "'});"); 

المصدر والهدف هم مواقع CSS لعناصر السحب والإفلات.

كما ذكر أعلاه ، نستخدم غالبًا محددات xpath في المشروع ، لذلك بعد قليل من التنقيح ، بدأت المكتبة في قبولهم:

 executeJavaScript("$(document).xpath('" + source + "').simulateDragDrop({ dropTarget: '" + target + "'});"); 

الآن ، في الواقع ، حول مكتبة drag_and_drop_helper.js. توجد قطع في كتلة التعليمات البرمجية simulateEvent المسؤولة عن بعض أحداث الماوس. لا فائدة من سرد الأحداث المحتملة لعمليات السحب والإفلات في HTML5 ؛ فهذه المعلومات يسهل العثور عليها.

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

وقياسًا على ذلك ، أضفنا حدث dragner إلى المكتبة (بين dragstart و drop).

 /*Simulating dragenter*/ type = 'dragenter'; var dragenterEvent = this.createEvent(type, {}); dragenterEvent.dataTransfer = event.dataTransfer; this.dispatchEvent($(options.dropTarget)[0], type, dragenterEvent); 

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

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

نريد تلخيص ما سبق. من المستغرب ، حقيقة! تم إصدار HTML5 مرة أخرى في عام 2013 ، وكانت المتصفحات تدعمه منذ عدة سنوات بالفعل ، وقد تم تطوير تطبيقات له ، لكن webDriver ، للأسف ، لا يزال لا يعرف كيفية استخدام قدراته. واختبار عمليات السحب والإفلات يجب أن يتم تنفيذها باستخدام أدوات تابعة لجهات خارجية ، وتعقيد البنية والانتقال إلى جميع أنواع الحيل. نعم ، هناك مثل هذه الأدوات و "الرقص مع الدف" يجعلنا أقوى فقط ، لكنني ما زلت أريد الحصول على حل فعال من الصندوق.

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

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

Source: https://habr.com/ru/post/ar437200/


All Articles