نمط كائن الصفحة
تم تصميم الإصدار الخامس من WebdriverIO مع مراعاة دعم نمط كائن الصفحة. من خلال تقديم مبدأ "العناصر كمواطنين من الدرجة الأولى"، أصبح من الممكن الآن بناء مجموعات اختبار كبيرة باستخدام هذا النمط.
لا توجد حزم إضافية مطلوبة لإنشاء كائنات الصفحة. تبين أن الفئات النظيفة والحديثة توفر جميع الميزات الضرورية التي نحتاجها:
- الوراثة بين كائنات الصفحة
- التحميل الكسول للعناصر
- تغليف الطرق والإجراءات
الهدف من استخدام كائنات الصفحة هو فصل أي معلومات صفحة عن الاختبارات الفعلية. من الناحية المثالية، يجب عليك تخزين جميع المحددات أو التعليمات المحددة الفريدة لصفحة معينة في كائن صفحة، بحيث يمكنك الاستمرار في تشغيل اختبارك بعد إعادة تصميم صفحتك بالكامل.
إنشاء كائن صفحة
أولاً، نحتاج إلى كائن صفحة رئيسي نسميه Page.js
. سيحتوي على محددات أو طرق عامة سترثها جميع كائنات الصفحة.
// Page.js
export default class Page {
constructor() {
this.title = 'My Page'
}
async open (path) {
await browser.url(path)
}
}
سنقوم دائمًا بتصدير export
نسخة من كائن الصفحة، ولن نقوم أبدًا بإنشاء تلك النسخة في الاختبار. نظرًا لأننا نكتب اختبارات من النهاية إلى النهاية، فإننا نعتبر دائمًا الصفحة كبناء بلا حالة—تمامًا كما أن كل طلب HTTP هو بناء بلا حالة.
بالتأكيد، يمكن للمتصفح حمل معلومات الجلسة وبالتالي يمكنه عرض صفحات مختلفة بناءً على جلسات مختلفة، ولكن لا ينبغي أن ينعكس ذلك داخل كائن الصفحة. يجب أن تكون أنواع تغييرات الحالة هذه موجودة في اختباراتك الفعلية.
لنبدأ باختبار الصفحة الأولى. لأغراض العرض التوضيحي، نستخدم موقع The Internet بواسطة Elemental Selenium كحقل تجارب. دعنا نحاول بناء مثال كائن صفحة لـ صفحة تسجيل الدخول.
الحصول Get
على المحددات الخاصة بك
الخطوة الأولى هي كتابة جميع المحددات المهمة المطلوبة في كائن login.page
الخاص بنا كدوال getter:
// login.page.js
import Page from './page'
class LoginPage extends Page {
get username () { return $('#username') }
get password () { return $('#password') }
get submitBtn () { return $('form button[type="submit"]') }
get flash () { return $('#flash') }
get headerLinks () { return $$('#header a') }
async open () {
await super.open('login')
}
async submit () {
await this.submitBtn.click()
}
}
export default new LoginPage()
قد يبدو تعريف المحددات في دوال getter غريبًا بعض الشيء، لكنه مفيد حقًا. يتم تقييم هذه الدوال عند الوصول إلى الخاصية، وليس عند إنشاء الكائن. بذلك، فإنك تطلب دائمًا العنصر قبل أن تقوم بإجراء عليه.
تسلسل الأوامر
يتذكر WebdriverIO داخليًا النتيجة الأخيرة لأمر ما. إذا قمت بتسلسل أمر عنصر مع أمر إجراء، فإنه يجد العنصر من الأمر السابق ويستخدم النتيجة لتنفيذ الإجراء. ب ذلك يمكنك إزالة المحدد (المعامل الأول) ويبدو الأمر بسيطًا مثل:
await LoginPage.username.setValue('Max Mustermann')
وهذا هو نفس الشيء مثل:
let elem = await $('#username')
await elem.setValue('Max Mustermann')
أو
await $('#username').setValue('Max Mustermann')