نموذج كائن الصفحة والمصنع في Selenium

ما هو نموذج كائن الصفحة؟

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

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

نموذج كائن الصفحة

لماذا نموذج كائن الصفحة؟

بدء أتمتة واجهة المستخدم في Selenium إن WebDriver ليس مهمة صعبة. كل ما عليك فعله هو العثور على العناصر وإجراء العمليات عليها.

فكر في هذا البرنامج النصي البسيط لتسجيل الدخول إلى موقع ويب

نموذج كائن الصفحة

كما ترون، كل ما نقوم به هو العثور على العناصر وملء القيم لتلك العناصر.

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

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

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

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

نموذج كائن الصفحة

مزايا بوم

  1. يقول نمط تصميم كائن الصفحة إن العمليات والتدفقات في واجهة المستخدم يجب أن تكون منفصلة عن التحقق. هذا المفهوم يجعل الكود الخاص بنا أكثر وضوحًا وسهولة في الفهم.
  2. الفائدة الثانية هي أن مستودع الكائنات مستقل عن حالات الاختبار، لذا يمكننا استخدام نفس مستودع الكائنات لغرض مختلف باستخدام أدوات مختلفة. على سبيل المثال، يمكننا دمج نموذج كائن الصفحة في Selenium مع TestNG/JUnit للوظيفة الاختبار وفي نفس الوقت مع JBehave/Cucumber لاختبار القبول.
  3. يصبح الكود أقل ويتم تحسينه بسبب أساليب الصفحة القابلة لإعادة الاستخدام في فئات POM.
  4. تحصل الطرق على أسماء أكثر واقعية والتي يمكن ربطها بسهولة بالعملية التي تحدث في واجهة المستخدم. على سبيل المثال، إذا انتقلنا إلى الصفحة الرئيسية بعد النقر على الزر، فسيكون اسم الطريقة مثل 'gotoHomePage()'.

كيفية تنفيذ بوم؟

بوم بسيط:

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

تنفيذ بوم

مثال كامل

حالة اختبار: انتقل إلى الموقع التجريبي Guru99.

الخطوة 1) انتقل إلى موقع Guru99 التجريبي

تنفيذ بوم

الخطوة 2) في الصفحة الرئيسية، تحقق من وجود النص "Guru99 Bank".

تنفيذ بوم

الخطوة 3) تسجيل الدخول إلى التطبيق

تنفيذ بوم

الخطوة 4) تأكد من أن الصفحة الرئيسية تحتوي على نص باسم "معرف المدير: العرض التوضيحي"

تنفيذ بوم

نحن هنا نتعامل مع صفحتين

  1. صفحة الدخول
  2. الصفحة الرئيسية (تظهر بمجرد تسجيل الدخول)

وفقا لذلك، نقوم بإنشاء 2 POM في Selenium فصول

Guru99 صفحة تسجيل الدخول بوم

package pages;

import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

public class Guru99Login {

    WebDriver driver;

    By user99GuruName = By.name("uid");

    By password99Guru = By.name("password");

    By titleText =By.className("barone");

    By login = By.name("btnLogin");

    public Guru99Login(WebDriver driver){

        this.driver = driver;

    }

    //Set user name in textbox

    public void setUserName(String strUserName){

        driver.findElement(user99GuruName).sendKeys(strUserName);

    }

    //Set password in password textbox

    public void setPassword(String strPassword){

         driver.findElement(password99Guru).sendKeys(strPassword);

    }

    //Click on login button

    public void clickLogin(){

            driver.findElement(login).click();

    }

    //Get the title of Login Page

    public String getLoginTitle(){

     return    driver.findElement(titleText).getText();

    }

    /**

     * This POM method will be exposed in test case to login in the application

     * @param strUserName

     * @param strPasword

     * @return

     */

    public void loginToGuru99(String strUserName,String strPasword){

        //Fill user name

        this.setUserName(strUserName);

        //Fill password

        this.setPassword(strPasword);

        //Click Login button

        this.clickLogin();        
    }

}

Guru99 الصفحة الرئيسية بوم في Selenium

package pages;

import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

public class Guru99HomePage {

    WebDriver driver;

    By homePageUserName = By.xpath("//table//tr[@class='heading3']");

    

    public Guru99HomePage(WebDriver driver){

        this.driver = driver;

    }

    //Get the User name from Home Page

        public String getHomePageDashboardUserName(){

         return    driver.findElement(homePageUserName).getText();

        }

}

Guru99 بوم بسيط في Selenium حالة اختبار

package test;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.firefox.FirefoxDriver;

import org.testng.Assert;

import org.testng.annotations.BeforeTest;

import org.testng.annotations.Test;

import pages.Guru99HomePage;

import pages.Guru99Login;

public class Test99GuruLogin {

    String driverPath = "C:\\geckodriver.exe";
    
    WebDriver driver;

    Guru99Login objLogin;

    Guru99HomePage objHomePage;

    @BeforeTest

    public void setup(){

	System.setProperty("webdriver.gecko.driver", driverPath);
        
        driver = new FirefoxDriver();

        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

        driver.get("https://demo.guru99.com/V4/");

    }

    /**

     * This test case will login in https://demo.guru99.com/V4/

     * Verify login page title as guru99 bank

     * Login to application

     * Verify the home page using Dashboard message

     */

    @Test(priority=0)

    public void test_Home_Page_Appear_Correct(){

        //Create Login Page object

    objLogin = new Guru99Login(driver);

    //Verify login page title

    String loginPageTitle = objLogin.getLoginTitle();

    Assert.assertTrue(loginPageTitle.toLowerCase().contains("guru99 bank"));

    //login to application

    objLogin.loginToGuru99("mgr123", "mgr!23");

    // go the next page

    objHomePage = new Guru99HomePage(driver);

    //Verify home page

    Assert.assertTrue(objHomePage.getHomePageDashboardUserName().toLowerCase().contains("manger id : mgr123"));

    }

ما هو مصنع الصفحة في Selenium?

مصنع الصفحة في Selenium هو مفهوم إطار نموذج كائن الصفحة يحمل في ثناياه عوامل Selenium WebDriver لكنه مُحسّن للغاية. يتم استخدامه لتهيئة كائنات الصفحة أو لإنشاء كائن الصفحة نفسه. يتم استخدامه أيضًا لتهيئة عناصر فئة الصفحة دون استخدام "FindElement/s".

وهنا أيضًا، نتبع مفهوم الفصل بين مستودع كائنات الصفحة وطرق الاختبار. بالإضافة إلى ذلك، بمساعدة فئة PageFactory في Selenium، نستخدم التعليقات التوضيحية @البحث عن طريق للعثور على WebElement. نستخدم طريقة initElements لتهيئة عناصر الويب

مصنع الصفحة في Selenium

@البحث عن طريق تستطيع القبول tagName، PartialLinkText، name، linkText، id، CSS، className، xpath كسمات.

دعونا نلقي نظرة على نفس المثال المذكور أعلاه باستخدام Page Factory

صفحة تسجيل الدخول Guru99 مع Page Factory

package PageFactory;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.WebElement;

import org.openqa.selenium.support.FindBy;

import org.openqa.selenium.support.PageFactory;

public class Guru99Login {

    /**

     * All WebElements are identified by @FindBy annotation

     */

    WebDriver driver;

    @FindBy(name="uid")

    WebElement user99GuruName;

    @FindBy(name="password")

    WebElement password99Guru;    

    @FindBy(className="barone")

    WebElement titleText;

    @FindBy(name="btnLogin")

    WebElement login;

    public Guru99Login(WebDriver driver){

        this.driver = driver;

        //This initElements method will create all WebElements

        PageFactory.initElements(driver, this);

    }

    //Set user name in textbox

    public void setUserName(String strUserName){

        user99GuruName.sendKeys(strUserName);     
    }

    //Set password in password textbox

    public void setPassword(String strPassword){

    password99Guru.sendKeys(strPassword);

    }

    //Click on login button

    public void clickLogin(){

            login.click();

    }  

    //Get the title of Login Page

    public String getLoginTitle(){

     return    titleText.getText();

    }

    /**

     * This POM method will be exposed in test case to login in the application

     * @param strUserName

     * @param strPasword

     * @return

     */

    public void loginToGuru99(String strUserName,String strPasword){

        //Fill user name

        this.setUserName(strUserName);

        //Fill password

        this.setPassword(strPasword);

        //Click Login button

        this.clickLogin();           

    }

}

Guru99 الصفحة الرئيسية مع مصنع الصفحة

package PageFactory;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.WebElement;

import org.openqa.selenium.support.FindBy;

import org.openqa.selenium.support.PageFactory;

public class Guru99HomePage {

    WebDriver driver;

    @FindBy(xpath="//table//tr[@class='heading3']")

    WebElement homePageUserName;    

    public Guru99HomePage(WebDriver driver){

        this.driver = driver;

        //This initElements method will create all WebElements

        PageFactory.initElements(driver, this);

    }   

    //Get the User name from Home Page

        public String getHomePageDashboardUserName(){

         return    homePageUserName.getText();

        }

}

Guru99 TestCase مع مفهوم Page Factory

package test;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.firefox.FirefoxDriver;

import org.testng.Assert;

import org.testng.annotations.BeforeTest;

import org.testng.annotations.Test;

import PageFactory.Guru99HomePage;

import PageFactory.Guru99Login;

public class Test99GuruLoginWithPageFactory {

    String driverPath = "C:\\geckodriver.exe";
    
    WebDriver driver;

    Guru99Login objLogin;

    Guru99HomePage objHomePage; 

    @BeforeTest

    public void setup(){

        System.setProperty("webdriver.gecko.driver", driverPath);
        
        driver = new FirefoxDriver();

        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

        driver.get("https://demo.guru99.com/V4/");

    }

    /**

     * This test go to https://demo.guru99.com/V4/

     * Verify login page title as guru99 bank

     * Login to application

     * Verify the home page using Dashboard message

     */

    @Test(priority=0)

    public void test_Home_Page_Appear_Correct(){

        //Create Login Page object

    objLogin = new Guru99Login(driver);

    //Verify login page title

    String loginPageTitle = objLogin.getLoginTitle();

    Assert.assertTrue(loginPageTitle.toLowerCase().contains("guru99 bank"));

    //login to application

    objLogin.loginToGuru99("mgr123", "mgr!23");

    // go the next page

    objHomePage = new Guru99HomePage(driver);

    //Verify home page

    Assert.assertTrue(objHomePage.getHomePageDashboardUserName().toLowerCase().contains("manger id : mgr123"));

    }

}

سيبدو هيكل المشروع الكامل مثل الرسم التخطيطي:

مصنع الصفحة في Selenium

AjaxElementLocatorFactory

AjaxElementLocatorFactory هو مفهوم التحميل البطيء لـ PageFactory في Selenium. يتم استخدامه للعثور على عناصر الويب فقط عندما يتم استخدام العناصر في أي عملية. فهو يعين مهلة زمنية لعناصر الويب لفئة صفحة الكائن. إحدى المزايا الرئيسية لاستخدام النمط PageFactory في Selenium هي فئة AjaxElementLocatorFactory.

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

مصنع محدد موقع AjaxElement

الملخص

  1. نموذج كائن الصفحة في Selenium WebDriver هو نمط تصميم مستودع الكائنات.
  2. Selenium نموذج كائن الصفحة يجعل كود الاختبار الخاص بنا قابلاً للصيانة وإعادة الاستخدام.
  3. يعد Page Factory طريقة محسنة لإنشاء مستودع الكائنات في مفهوم إطار عمل نموذج كائن الصفحة.
  4. AjaxElementLocatorFactory هو مفهوم تحميل كسول في Page Factory – نمط تصميم كائن الصفحة لتحديد عناصر الويب فقط عند استخدامها في أي عملية.

تحميل Selenium ملفات المشروع للعرض التوضيحي في هذا البرنامج التعليمي

تفاصيل أكثر أقرأ المزيد