page object model with page factory selenium tutorial
Bu Kapsamlı Eğitim, Sayfa Nesne Modeli (POM) Hakkında Her Şeyi Örnekler Kullanarak Pagefactory ile Açıklar. Selenyumda POM Uygulamasını da Öğrenebilirsiniz:
Bu eğiticide, Sayfa Fabrikası yaklaşımını kullanarak bir Sayfa Nesne Modelinin nasıl oluşturulacağını anlayacağız. Şunlara odaklanacağız:
- Fabrika Sınıfı
- Sayfa Fabrikası Kalıbı Kullanılarak Temel POM Nasıl Oluşturulur
- Sayfa Fabrikası Yaklaşımında Kullanılan Farklı Ek Açıklamalar
Pagefactory'nin ne olduğunu ve Sayfa nesne modeliyle birlikte nasıl kullanılabileceğini görmeden önce, genellikle POM olarak bilinen Sayfa Nesne Modeli'nin ne olduğunu anlayalım.
=> Selenium Eğitim Serisini Herkes İçin Görmek İçin Burayı Ziyaret Edin.
Ne öğreneceksin:
- Sayfa Nesne Modeli (POM) Nedir?
- Pagefactory nedir?
- Sayfa Fabrikasını Kullanan POM
- Sıkça Sorulan Sorular
- Sonuç
Sayfa Nesne Modeli (POM) Nedir?
Teorik terminolojiler, Sayfa Nesne Modeli test edilen uygulamada bulunan web öğeleri için bir nesne deposu oluşturmak için kullanılan bir tasarım modeli olarak. Çok az kişi, test edilen belirli bir uygulama için bunu Selenium otomasyonu için bir çerçeve olarak görüyor.
Bununla birlikte, Sayfa Nesne Modeli teriminden anladığım şey şudur:
# 1) Uygulamadaki her bir ekrana veya sayfaya karşılık gelen ayrı bir Java sınıf dosyasına sahip olduğunuz bir tasarım modelidir. Sınıf dosyası, UI öğelerinin nesne havuzunu ve ayrıca yöntemleri içerebilir.
#iki) Bir sayfada muazzam web öğeleri olması durumunda, bir sayfanın nesne veri havuzu sınıfı, karşılık gelen sayfa için yöntemleri içeren sınıftan ayrılabilir.
Misal: Hesabı Kaydet sayfasında birçok giriş alanı varsa, kayıt hesapları sayfasındaki UI öğeleri için nesne havuzunu oluşturan bir RegisterAccountObjects.java sınıfı olabilir.
Sayfada farklı eylemler gerçekleştiren tüm yöntemleri içeren RegisterAccountObjects'i genişleten veya devralan ayrı bir sınıf dosyası RegisterAccount.java oluşturulabilir.
# 3) Ayrıca, bir {roperties dosyası, Excel test verileri ve bir paket altında Ortak yöntemler içeren genel bir paket olabilir.
Misal: Uygulama içerisindeki tüm sayfalarda çok rahatlıkla kullanılabilen DriverFactory
Örnekle POM'u Anlamak
Kontrol İşte POM hakkında daha fazla bilgi edinmek için.
Aşağıda Web Sayfasının bir anlık görüntüsü bulunmaktadır:
Bu bağlantıların her birine tıklamak kullanıcıyı yeni bir sayfaya yönlendirecektir.
İşte Selenium ile proje yapısının, web sitesindeki her sayfaya karşılık gelen Sayfa nesne modeli kullanılarak nasıl oluşturulduğunun anlık görüntüsü. Her Java sınıfı, sayfa içinde farklı eylemler gerçekleştirmek için nesne deposu ve yöntemler içerir.
Ayrıca, bu sayfaların sınıf dosyalarına çağrı yapan başka bir JUNIT veya TestNG veya bir Java sınıfı dosyası olacaktır.
Neden Sayfa Nesne Modelini Kullanıyoruz?
POM veya sayfa nesnesi modeli olarak adlandırılan bu güçlü Selenium çerçevesinin kullanımıyla ilgili bir tartışma var. Şimdi soru “Neden POM kullanılıyor?” Olarak ortaya çıkıyor.
Bunun basit cevabı, POM'un veriye dayalı, modüler ve hibrit çerçevelerin bir kombinasyonu olmasıdır. Komut dosyalarını, QA'nın kodu sorunsuz bir şekilde korumasını kolaylaştıracak ve aynı zamanda gereksiz veya yinelenen kodların önlenmesine yardımcı olacak şekilde sistematik olarak organize etmeye yönelik bir yaklaşımdır.
Örneğin, belirli bir sayfadaki yer belirleyici değerinde bir değişiklik varsa, o zaman kodu başka bir yerde etkilemeden yalnızca ilgili sayfanın komut dosyasında bu hızlı değişikliği tanımlamak ve yapmak çok kolaydır.
Selenium Webdriver'da Sayfa Nesne Modeli konseptini aşağıdaki nedenlerden dolayı kullanıyoruz:
- Bu POM modelinde bir nesne deposu oluşturulur. Test durumlarından bağımsızdır ve farklı bir proje için yeniden kullanılabilir.
- Yöntemlerin isimlendirme kuralı çok kolay, anlaşılır ve daha gerçekçidir.
- Sayfa nesne modeli altında, başka bir projede tekrar kullanılabilecek sayfa sınıfları oluşturuyoruz.
- Sayfa nesne modeli, çeşitli avantajları nedeniyle geliştirilen çerçeve için kolaydır.
- Bu modelde, bir web uygulamasının farklı sayfaları için oturum açma sayfası, ana sayfa, çalışan ayrıntı sayfası, şifre değiştirme sayfası vb. Gibi ayrı sınıflar oluşturulur.
- Bir web sitesinin herhangi bir öğesinde herhangi bir değişiklik varsa, o zaman tüm sınıflarda değil, yalnızca bir sınıfta değişiklik yapmamız gerekir.
- Tasarlanan komut dosyası, sayfa nesne modeli yaklaşımında daha yeniden kullanılabilir, okunabilir ve sürdürülebilirdir.
- Proje yapısı oldukça kolay ve anlaşılırdır.
- Web öğesini başlatmak ve öğeleri önbellekte saklamak için sayfa nesne modelinde PageFactory kullanabilir.
- TestNG, Sayfa Nesne Modeli yaklaşımına da entegre edilebilir.
Selenyumda Basit POM Uygulaması
# 1) Otomatikleştirme Senaryosu
Şimdi verilen senaryoyu Sayfa Nesne Modelini kullanarak otomatikleştiriyoruz.
Senaryo aşağıda açıklanmıştır:
Aşama 1: 'Https: //demo.vtiger.com' sitesini başlatın.
Adım 2: Geçerli kimlik bilgilerini girin.
Aşama 3: Siteye giriş yapın.
4. Adım: Ana sayfayı doğrulayın.
Adım 5: Siteden çıkış yapın.
6. Adım: Tarayıcıyı kapatın.
# 2) POM'da Yukarıdaki Senaryo İçin Selenyum Komut Dosyaları
Şimdi Eclipse'de POM Yapısını aşağıda açıklandığı gibi oluşturuyoruz:
Aşama 1: Eclipse - POM Tabanlı Yapıda Proje Oluşturun:
a) Proje 'Sayfa Nesne Modeli' oluşturun.
b) Proje kapsamında 3 Paket oluşturun.
- kütüphane
- sayfaları
- test durumları
Kütüphane: Bunun altına, Tarayıcı başlatma, Ekran görüntüleri gibi test durumlarımızda tekrar tekrar çağrılması gereken kodları koyuyoruz. Kullanıcı proje ihtiyacına göre altına daha fazla sınıf ekleyebilir.
Sayfalar: Bunun altında, web uygulamasındaki her sayfa için sınıflar oluşturulur ve uygulamadaki sayfa sayısına bağlı olarak daha fazla sayfa sınıfı eklenebilir.
Test durumları: Bunun altında, oturum açma test durumunu yazıyoruz ve tüm uygulamayı test etmek için gerektiği kadar daha fazla test durumu ekleyebiliriz.
c) Paketler altındaki sınıflar aşağıdaki görselde gösterilmiştir.
Adım iki: Kitaplık paketi altında aşağıdaki sınıfları oluşturun.
Browser.java: Bu sınıfta 3 tarayıcı (Firefox, Chrome ve Internet Explorer) tanımlanır ve oturum açma test durumunda çağrılır. Kullanıcı, ihtiyaca bağlı olarak uygulamayı farklı tarayıcılarda da test edebilir.
package library; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.ie.InternetExplorerDriver; public class Browser { static WebDriver driver; public static WebDriver StartBrowser(String browsername , String url) { // If the browser is Firefox if (browsername.equalsIgnoreCase('Firefox')) { // Set the path for geckodriver.exe System.setProperty('webdriver.firefox.marionette',' E://Selenium//Selenium_Jars//geckodriver.exe '); driver = new FirefoxDriver(); } // If the browser is Chrome else if (browsername.equalsIgnoreCase('Chrome')) { // Set the path for chromedriver.exe System.setProperty('webdriver.chrome.driver','E://Selenium//Selenium_Jars//chromedriver.exe'); driver = new ChromeDriver(); } // If the browser is IE else if (browsername.equalsIgnoreCase('IE')) { // Set the path for IEdriver.exe System.setProperty('webdriver.ie.driver','E://Selenium//Selenium_Jars//IEDriverServer.exe'); driver = new InternetExplorerDriver(); } driver.manage().window().maximize(); driver.get(url); return driver; } }
ScreenShot.java: Bu sınıfta bir ekran görüntüsü programı yazılır ve kullanıcı testin başarısız olup olmadığına dair bir ekran görüntüsü almak istediğinde test senaryosunda çağrılır.
package library; import java.io.File; import org.apache.commons.io.FileUtils; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.WebDriver; public class ScreenShot { public static void captureScreenShot(WebDriver driver, String ScreenShotName) { try { File screenshot=((TakesScreenshot)driver).getScreenshotAs(OutputType. FILE ); FileUtils.copyFile(screenshot, new File('E://Selenium//'+ScreenShotName+'.jpg')); } catch (Exception e) { System. out .println(e.getMessage()); e.printStackTrace(); } } }
Aşama 3 : Sayfa paketi altında sayfa sınıfları oluşturun.
HomePage.java: Bu, ana sayfanın tüm öğelerinin ve yöntemlerinin tanımlandığı Giriş sayfası sınıfıdır.
package pages; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; public class HomePage { WebDriver driver; By logout = By.id('p_lt_ctl03_wSOB_btnSignOutLink'); By home = By.id('p_lt_ctl02_wCU2_lblLabel'); //Constructor to initialize object public HomePage(WebDriver dr) { this .driver=dr; } public String pageverify() { return driver.findElement(home).getText(); } public void logout() { driver.findElement(logout).click(); } }
LoginPage.java: Bu, oturum açma sayfasının tüm öğelerinin ve yöntemlerinin tanımlandığı Oturum Açma sayfası sınıfıdır.
package pages; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; public class LoginPage { WebDriver driver; By UserID = By.xpath('//*(contains(@id,'Login1_UserName'))'); By password = By.xpath('//*(contains(@id,'Login1_Password'))'); By Submit = By.xpath('//*(contains(@id,'Login1_LoginButton'))'); //Constructor to initialize object public LoginPage(WebDriver driver) { this .driver = driver; } public void loginToSite(String Username, String Password) { this .enterUsername(Username); this .enterPasssword(Password); this .clickSubmit(); } public void enterUsername(String Username) { driver.findElement(UserID).sendKeys(Username); } public void enterPasssword(String Password) { driver.findElement(password).sendKeys(Password); } public void clickSubmit() { driver.findElement(Submit).click(); } }
4. Adım: Oturum açma senaryosu için Test Senaryoları oluşturun.
LoginTestCase.java: Bu, test olayının yürütüldüğü LoginTestCase sınıfıdır. Kullanıcı ayrıca proje ihtiyacına göre daha fazla test senaryosu oluşturabilir.
package testcases; import java.util.concurrent.TimeUnit; import library.Browser; import library.ScreenShot; import org.openqa.selenium.WebDriver; import org.testng.Assert; import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import pages.HomePage; import pages.LoginPage; public class LoginTestCase { WebDriver driver; LoginPage lp; HomePage hp; int i = 0; // Launch of the given browser. @BeforeTest public void browserlaunch() { driver = Browser.StartBrowser('Chrome', 'http://demostore.kenticolab.com/Special-Pages/Logon.aspx'); driver.manage().timeouts().implicitlyWait(30,TimeUnit. SECONDS ); lp = new LoginPage(driver); hp = new HomePage(driver); } // Login to the Site. @Test(priority = 1) public void Login() { lp.loginToSite('gaurav.3n@gmail.com','Test@123'); } // Verifing the Home Page. @Test(priority = 2) public void HomePageVerify() { String HomeText = hp.pageverify(); Assert.assertEquals(HomeText, 'Logged on as'); } // Logout the site. @Test(priority = 3) public void Logout() { hp.logout(); } // Taking Screen shot on test fail @AfterMethod public void screenshot(ITestResult result) { i = i+1; String name = 'ScreenShot'; String x = name+String.valueOf(i); if (ITestResult. FAILURE == result.getStatus()) { ScreenShot.captureScreenShot(driver, x); } } @AfterTest public void closeBrowser() { driver.close(); } }
Adım 5: 'LoginTestCase.java' yı yürütün.
6. Adım: Sayfa Nesne Modelinin Çıktısı:
- Chrome tarayıcıyı başlatın.
- Demo web sitesi tarayıcıda açılır.
- Demo sitesine giriş yapın.
- Ana sayfayı doğrulayın.
- Siteden çıkış yapın.
- Tarayıcıyı kapatın.
Şimdi, bu öğreticinin dikkati çeken ana konseptini inceleyelim. 'Sayfa fabrikası'.
Pagefactory nedir?
PageFactory, 'Sayfa Nesne Modeli' ni uygulamanın bir yoludur. Burada, Sayfa Nesne Deposu ve Test Yöntemlerinin ayrılması ilkesini takip ediyoruz. Çok optimize edilmiş dahili bir Sayfa Nesne Modeli kavramıdır.
Şimdi Pagefactory terimine daha fazla açıklık getirelim.
# 1) İlk olarak, Pagefactory adlı kavram, bir sayfadaki web öğeleri için bir nesne deposu oluşturmak için sözdizimi ve anlambilim açısından alternatif bir yol sağlar.
#iki) İkinci olarak, web öğelerinin başlatılması için biraz farklı bir strateji kullanır.
# 3) UI web öğeleri için nesne deposu aşağıdakiler kullanılarak oluşturulabilir:
- Her zamanki 'Pagefactory olmadan POM' ve,
- Alternatif olarak, 'Pagefactory ile POM' kullanabilirsiniz.
Aşağıda verilen, aynı şeyin resimli bir temsilidir:
Şimdi, Pagefactory ile olağan POM'u POM'dan ayıran tüm yönlere bakacağız.
a) Normal POM ve Pagefactory ile POM kullanarak bir öğeyi bulmanın sözdizimindeki fark.
Örneğin , Tıklayın İşte sayfada görünen arama alanını bulmak için.
Pagefactory Olmadan POM:
# 1) Aşağıda, normal POM kullanarak arama alanını nasıl bulacağınız açıklanmaktadır:
WebElement searchNSETxt=driver.findElement(By.id(“searchBox”));
# 2) Aşağıdaki adım, 'yatırım' değerini NSE Ara alanına iletir.
searchNSETxt.sendkeys(“investment”);
Pagefactory Kullanan POM:
# 1) Aşağıda gösterildiği gibi Pagefactory'yi kullanarak arama alanını bulabilirsiniz.
Ek açıklama @Findby Pagefactory'de bir öğeyi tanımlamak için kullanılırken, Pagefactory olmadan POM, driver.findElement () bir öğeyi bulma yöntemi.
Pagefactory için ikinci ifade @Findby bir tür atamaktır WebElement Yöntemin dönüş türü olarak WebElement sınıfı türündeki bir öğe adının atanmasına tam olarak benzer şekilde çalışan sınıf driver.findElement () normal POM'da kullanılır (bu örnekte searchNSETxt).
Bakacağız @Findby Bu eğiticinin sonraki bölümünde ayrıntılı ek açıklamalar.
@FindBy(id = 'searchBox') WebElement searchNSETxt;
#iki) Aşağıdaki adım, 'yatırım' değerini Arama NSE alanına aktarır ve sözdizimi, normal POM (Pagefactory olmadan POM) ile aynı kalır.
searchNSETxt.sendkeys(“investment”);
b) Normal POM ve Pagefactory ile POM kullanılarak Web Öğelerinin Başlatma stratejisindeki fark.
Pagefactory Olmadan POM'u Kullanma:
Aşağıda, Chrome sürücü yolunu ayarlamak için bir kod parçası verilmiştir. Sürücü adıyla bir WebDriver örneği oluşturulur ve ChromeDriver 'sürücüye' atanır. Aynı sürücü nesnesi daha sonra Ulusal Menkul Kıymetler Borsası web sitesini başlatmak, arama kutusunu bulmak ve alana dize değerini girmek için kullanılır.
Burada vurgulamak istediğim nokta, sayfa fabrikası olmayan POM olduğunda, sürücü örneğinin başlangıçta yaratılması ve her web öğesinin, driver.findElement () veya sürücü kullanılarak o web öğesine her çağrı yapıldığında yeniden başlatılmasıdır. .findElements ().
Bu nedenle, bir öğe için yeni bir driver.findElement () adımıyla, DOM yapısı yeniden taranır ve öğenin yenilenmiş tanımlaması o sayfada yapılır.
System.setProperty('webdriver.chrome.driver', 'C:\eclipse-workspace\automationframework\src\test\java\Drivers\chromedriver.exe'); WebDriver driver = new ChromeDriver(); driver.get('http://www.nseindia.com/'); WebElement searchNSETxt=driver.findElement(By.id(“searchBox”)); searchNSETxt.sendkeys(“investment”);
POM'u Pagefactory ile Kullanma:
Driver.findElement () yöntemi yerine @FindBy ek açıklamasını kullanmanın yanı sıra, aşağıdaki kod parçacığı ayrıca Pagefactory için de kullanılır. PageFactory sınıfının statik initElements () yöntemi, sayfa yüklenir yüklenmez sayfadaki tüm UI öğelerini başlatmak için kullanılır.
public PagefactoryClass(WebDriver driver) { this.driver = driver; PageFactory.initElements(driver, this); }
Yukarıdaki strateji, PageFactory yaklaşımını normal POM'dan biraz farklı kılar. Her zamanki POM'da, web öğesi açıkça başlatılırken, Pagefactory yaklaşımında tüm öğeler, her web öğesini açıkça başlatmadan initElements () ile başlatılır.
Örneğin: WebElement bildirilmişse ancak normal POM'da başlatılmamışsa, 'değişken başlat' hatası veya NullPointerException atılır. Bu nedenle, olağan POM'da, her WebElement'in açıkça başlatılması gerekir. PageFactory, bu durumda normal POM'a göre bir avantajla geliyor.
Web öğesini başlatmayalım BDate (Pagefactory olmadan POM), 'Değişkeni Başlat' hatasının görüntülendiğini ve kullanıcıdan onu boş değer olarak başlatmasını istediğini görebilirsiniz, bu nedenle, öğelerin konumlandırıldığında örtük olarak başlatılacağını varsayamazsınız.
Öğe BDate açıkça başlatıldı (Pagefactory olmadan POM):
Şimdi, uygulama yönünün anlaşılmasındaki herhangi bir belirsizliği ortadan kaldırmak için PageFactory kullanan eksiksiz bir programın birkaç örneğine bakalım.
Örnek 1:
- 'Http://www.nseindia.com/' adresine gidin
- Arama alanının yanındaki açılır menüden 'Para Birimi Türevleri' ni seçin.
- 'USDINR' araması yapın. Ortaya çıkan sayfada 'ABD Doları-Hindistan Rupisi - USDINR' metnini doğrulayın.
Program Yapısı:
- Tüm web öğelerini başlatmak için bir yapıcı olan nseindia.com için sayfa fabrikası konseptini kullanan bir nesne deposu içeren PagefactoryClass.java oluşturulur, Arama kutusu açılır alanından değer seçmek için selectCurrentDerivative () yöntemini kullanın, üzerinde bir sembol seçmek için sonra görünen sayfa ve doğrulama metni (), sayfa üstbilgisinin beklendiği gibi olup olmadığını doğrulamak için.
- NSE_MainClass.java, yukarıdaki tüm yöntemleri çağıran ve NSE sitesinde ilgili eylemleri gerçekleştiren ana sınıf dosyasıdır.
PagefactoryClass.java
package com.pagefactory.knowledge; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.ui.Select; public class PagefactoryClass { WebDriver driver; @FindBy(id = 'QuoteSearch') WebElement Searchbox; @FindBy(id = 'cidkeyword') WebElement Symbol; @FindBy(id = 'companyName') WebElement pageText; public PagefactoryClass(WebDriver driver) { this.driver = driver; PageFactory.initElements(driver, this); } public void selectCurrentDerivative(String derivative) { Select select = new Select(Searchbox); select.selectByVisibleText(derivative); // 'Currency Derivatives' } public void selectSymbol(String symbol) { Symbol.sendKeys(symbol); } public void verifytext() { if (pageText.getText().equalsIgnoreCase('U S Dollar-Indian Rupee - USDINR')) { System.out.println('Page Header is as expected'); } else System.out.println('Page Header is NOT as expected'); } }
NSE_MainClass.java
package com.pagefactory.knowledge; import java.util.List; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.StaleElementReferenceException; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; public class NSE_MainClass { static PagefactoryClass page; static WebDriver driver; public static void main(String() args) { System.setProperty('webdriver.chrome.driver', 'C:\Users\eclipse-workspace\automation-framework\src\test\java\Drivers\chromedriver.exe'); driver = new ChromeDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get('https://www.nseindia.com/'); driver.manage().window().maximize(); test_Home_Page_ofNSE(); } public static void test_Home_Page_ofNSE() throws StaleElementReferenceException { page = new PagefactoryClass(driver); page.selectCurrentDerivative('Currency Derivatives'); page.selectSymbol('USD'); List Options = driver.findElements(By.xpath('//span(contains(.,'USD'))')); int count = Options.size(); for (int i = 0; i Örnek 2:
- 'Https://www.shoppersstop.com/brands' adresine gidin
- Haute curry bağlantısına gidin.
- Haute Curry sayfasının 'Yeni Bir Şey Başlatın' metnini içerip içermediğini doğrulayın.
Program yapısı
- shoppersstop.com için pagefactory konseptini kullanan ve tüm web öğelerini başlatmak için bir yapıcı olan bir nesne deposu içeren shopperstopPagefactory.java oluşturulur, açılan bir uyarı açılır kutusunu işlemek için closeExtraPopup () yöntemleri, Haute Curry'ye tıklamak içinOnHauteCurryLink () öğesini tıklayın Haute Curry sayfasının 'Yeni bir şey başlat' metnini içerip içermediğini doğrulamak için bağlantı kurun ve doğrulayınStartNewSomething ().
- Shopperstop_CallPagefactory.java, yukarıdaki tüm yöntemleri çağıran ve NSE sitesinde ilgili eylemleri gerçekleştiren ana sınıf dosyasıdır.
shopperstopPagefactory.java
package com.inportia.automation_framework; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; public class shopperstopPagefactory { WebDriver driver; @FindBy(id='firstVisit') WebElement extrapopup; @FindBy(xpath='//img(@src='https://sslimages.shoppersstop.com /sys-master/root/haf/h3a/9519787376670/brandMedia_HauteCurry_logo.png')') WebElement HCLink; @FindBy(xpath='/html/body/main/footer/div(1)/p') WebElement Startnew; public shopperstopPagefactory(WebDriver driver) { this.driver=driver; PageFactory.initElements(driver, this); } public void closeExtraPopup() { extrapopup.click(); } public void clickOnHauteCurryLink() { JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript('arguments(0).click();',HCLink); js.executeAsyncScript('window.setTimeout(arguments(arguments.length - 1), 10000);'); if(driver.getCurrentUrl().equals('https://www.shoppersstop.com/haute-curry')) { System.out.println('We are on the Haute Curry page'); } else { System.out.println('We are NOT on the Haute Curry page'); } } public void verifyStartNewSomething() { if (Startnew.getText().equalsIgnoreCase('Start Something New')) { System.out.println('Start new something text exists'); } else System.out.println('Start new something text DOESNOT exists'); } }
Shopperstop_CallPagefactory.java
package com.inportia.automation_framework; import java.util.concurrent.TimeUnit; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; public class Shopperstop_CallPagefactory extends shopperstopPagefactory { public Shopperstop_CallPagefactory(WebDriver driver) { super(driver); // TODO Auto-generated constructor stub } static WebDriver driver; public static void main(String() args) { System.setProperty('webdriver.chrome.driver', 'C:\eclipse-workspace\automation-framework\src\test\java\Drivers\chromedriver.exe'); driver = new ChromeDriver(); Shopperstop_CallPagefactory s1=new Shopperstop_CallPagefactory(driver); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get('https://www.shoppersstop.com/brands'); s1.clickOnHauteCurryLink(); s1.verifyStartNewSomething(); } }
Sayfa Fabrikasını Kullanan POM
Eğitim Videoları - Sayfa Fabrikası ile POM
Bölüm I
Bölüm II
Sayfa Nesnelerini kullanmayı daha basit ve daha kolay hale getirmek için bir Factory sınıfı kullanılır.
- Öncelikle, web öğelerini ek açıklama ile bulmamız gerekiyor @Findby sayfa sınıflarında .
- Ardından sayfa sınıfını başlatırken öğeleri initElements () kullanarak başlatın.
# 1) @FindBy:
@FindBy ek açıklaması, PageFactory'de farklı konumlayıcılar kullanarak web öğelerini bulmak ve bildirmek için kullanılır.Burada, web öğesini bulmak için kullanılan özniteliği ve değerini @FindBy ek açıklamasına iletiriz ve ardından WebElement bildirilir.
Ek açıklamanın kullanılabileceği 2 yol vardır.
Örneğin:
@FindBy(how = How.ID, using='EmailAddress') WebElement Email; @FindBy(id='EmailAddress') WebElement Email;
Bununla birlikte, birincisi, WebElements'i bildirmenin standart yoludur.
'Nasıl' bir sınıftır ve ID, XPATH, CLASSNAME, LINKTEXT, vb. gibi statik değişkenlere sahiptir.
'Kullanma' - Statik değişkene bir değer atamak için.
Yukarıda misal , 'E-posta' web öğesini bulmak için 'kimlik' özelliğini kullandık. Benzer şekilde, aşağıdaki konum belirleyicileri @FindBy ek açıklamalarıyla kullanabiliriz:
- sınıf adı
- css
- isim
- xpath
- etiket adı
- linkText
- kısmiLinkText
# 2) initElements ():
İnitElements, @FindBy ek açıklaması tarafından bulunan tüm web öğelerini başlatmak için kullanılan PageFactory sınıfının statik bir yöntemidir. Böylece, Sayfa sınıflarını kolayca somutlaştırır.
initElements(WebDriver driver, java.lang.Class pageObjectClass)
Ayrıca POM'un OOPS ilkelerini takip ettiğini anlamalıyız.
- WebElements, özel üye değişkenleri (Veri Gizleme) olarak bildirilir.
- WebElement'leri karşılık gelen yöntemlerle bağlama (Kapsülleme).
Sayfa Fabrikası Modelini Kullanarak POM Oluşturma Adımları
# 1) Her web sayfası için ayrı bir Java sınıf dosyası oluşturun.
#iki) Her bir Sınıfta, tüm WebElement'ler değişken olarak bildirilmeli (annotation - @FindBy kullanılarak) ve initElement () yöntemi kullanılarak başlatılmalıdır. Bildirilen WebElement'lerin eylem yöntemlerinde kullanılmak üzere başlatılması gerekir.
# 3) Bu değişkenlere etki eden ilgili yöntemleri tanımlayın.
Basit bir senaryo örneğini ele alalım:
- Bir uygulamanın URL'sini açın.
- E-posta Adresi ve Parola verilerini yazın.
- Oturum Aç düğmesine tıklayın.
- Arama Sayfasındaki başarılı giriş mesajını doğrulayın.
Sayfa Katmanı
Burada 2 sayfamız var,
- Ana Sayfa - URL girildiğinde açılan ve giriş için verileri girdiğimiz sayfa.
- Arama Sayfası - Başarılı bir oturum açtıktan sonra görüntülenen bir sayfa.
Sayfa Katmanında, Web Uygulamasındaki her sayfa ayrı bir Java Sınıfı olarak ilan edilir ve burada yer belirleyicileri ve eylemlerinden bahsedilir.
Gerçek Zamanlı Örnekle POM Oluşturma Adımları
# 1) Her sayfa için bir Java Sınıfı oluşturun:
Bunda misal , 2 web sayfasına, “Ana Sayfa” ve “Arama” sayfalarına erişeceğiz.
Bu nedenle, Sayfa Katmanında (veya bir pakette com.automation.pages gibi) 2 Java sınıfı oluşturacağız.
Package Name :com.automation.pages HomePage.java SearchPage.java
# 2) @ FindBy Annotation kullanarak WebElements öğesini değişken olarak tanımlayın:
Şunlarla etkileşim kuracağız:
- Ana Sayfadaki E-posta, Şifre, Oturum Aç düğmesi alanı.
- Arama Sayfasında başarılı mesaj.
Bu yüzden WebElements'i @FindBy kullanarak tanımlayacağız.
Örneğin: E-posta Adresini öznitelik kimliği kullanarak tanımlayacaksak, değişken bildirimi
//Locator for EmailId field @FindBy(how=How.ID,using='EmailId') private WebElementEmailIdAddress;
# 3) WebElements üzerinde gerçekleştirilen eylemler için yöntemler oluşturun.
WebElements üzerinde aşağıdaki eylemler gerçekleştirilir:
- E-posta Adresi alanına eylem yazın.
- Parola alanına eylem yazın.
- Oturum Açma Düğmesindeki eylemi tıklayın.
Örneğin, WebElement üzerindeki her eylem için kullanıcı tanımlı yöntemler şu şekilde oluşturulur:
public void typeEmailId(String Id){ driver.findElement(EmailAddress).sendKeys(Id) }
Burada, kullanıcı tarafından ana test durumundan girdi gönderileceği için Id, yöntemde bir parametre olarak geçirilir.
Not :Sürücü örneğini Test Katmanındaki Main sınıfından almak ve ayrıca PageFactory.InitElement () kullanarak sayfa sınıfında bildirilen WebElements'i (Sayfa Nesneleri) başlatmak için Sayfa Katmanındaki her bir sınıfta bir kurucu oluşturulması gerekir. .
Sürücüyü burada başlatmayız, bunun yerine Örneği, Sayfa Katmanı sınıfının nesnesi oluşturulduğunda Ana Sınıftan alınır.
InitElement () - ana sınıftan sürücü örneğini kullanarak bildirilen WebElements öğesini başlatmak için kullanılır. Diğer bir deyişle, WebElements, sürücü örneği kullanılarak oluşturulur. Yalnızca WebElementler başlatıldıktan sonra, eylemleri gerçekleştirmek için yöntemlerde kullanılabilirler.
Aşağıda gösterildiği gibi her sayfa için iki Java Sınıfı oluşturulur:
Ana Sayfa.java
//package com.automation.pages; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; public class HomePage { WebDriver driver; // Locator for Email Address @FindBy(how=How.ID,using='EmailId') private WebElement EmailIdAddress; // Locator for Password field @FindBy(how=How.ID,using='Password ') private WebElement Password; // Locator for SignIn Button @FindBy(how=How.ID,using='SignInButton') private WebElement SignInButton; // Method to type EmailId public void typeEmailId(String Id){ driver.findElement(EmailAddress).sendKeys(Id) } // Method to type Password public void typePassword(String PasswordValue){ driver.findElement(Password).sendKeys(PasswordValue) } // Method to click SignIn Button public void clickSignIn(){ driver.findElement(SignInButton).click() } // Constructor // Gets called when object of this page is created in MainClass.java public HomePage(WebDriver driver) { // 'this' keyword is used here to distinguish global and local variable 'driver' //gets driver as parameter from MainClass.java and assigns to the driver instance in this class this.driver=driver; PageFactory.initElements(driver,this); // Initialises WebElements declared in this class using driver instance. } }
SearchPage.Java
//package com.automation.pages; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; public class SearchPage{ WebDriver driver; // Locator for Success Message @FindBy(how=How.ID,using='Message') private WebElement SuccessMessage; // Method that return True or False depending on whether the message is displayed public Boolean MessageDisplayed(){ Boolean status = driver.findElement(SuccessMessage).isDisplayed(); return status; } // Constructor // This constructor is invoked when object of this page is created in MainClass.java public SearchPage(WebDriver driver) { // 'this' keyword is used here to distinguish global and local variable 'driver' //gets driver as parameter from MainClass.java and assigns to the driver instance in this class this.driver=driver; PageFactory.initElements(driver,this); // Initialises WebElements declared in this class using driver instance. } }
Test Katmanı
Bu sınıfta Test Durumları uygulanır. Ayrı bir paket oluşturuyoruz, örneğin com.automation.test ve sonra burada bir Java Sınıfı oluşturuyoruz (MainClass.java)
Test Senaryosu Oluşturma Adımları:
- Sürücüyü başlatın ve uygulamayı açın.
- PageLayer Sınıfının bir nesnesini oluşturun (her web sayfası için) ve sürücü örneğini bir parametre olarak iletin.
- Oluşturulan nesneyi kullanarak, eylemleri / doğrulamayı gerçekleştirmek için PageLayer Sınıfındaki (her web sayfası için) yöntemlere bir çağrı yapın.
- Tüm eylemler gerçekleştirilene kadar 3. adımı tekrarlayın ve ardından sürücüyü kapatın.
//package com.automation.test; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; public class MainClass { public static void main(String() args) { System.setProperty('webdriver.chrome.driver','./exefiles/chromedriver.exe'); WebDriver driver= new ChromeDriver(); driver.manage().window().maximize(); driver.get('URL mentioned here'); // Creating object of HomePage and driver instance is passed as parameter to constructor of Homepage.Java HomePage homePage= new HomePage(driver); // Type EmailAddress homePage.typeEmailId('abc@ymail.com'); // EmailId value is passed as paramter which in turn will be assigned to the method in HomePage.Java // Type Password Value homePage.typePassword('password123'); // Password value is passed as paramter which in turn will be assigned to the method in HomePage.Java // Click on SignIn Button homePage.clickSignIn(); // Creating an object of LoginPage and driver instance is passed as parameter to constructor of SearchPage.Java SearchPage searchPage= new SearchPage(driver); //Verify that Success Message is displayed Assert.assertTrue(searchPage.MessageDisplayed()); //Quit browser driver.quit(); } }
Web Öğelerini Bildirmek İçin Kullanılan Ek Açıklama Türü Hiyerarşisi
Ek açıklamalar, UI Öğeleri için bir konum stratejisi oluşturmaya yardımcı olmak için kullanılır.
# 1) @FindBy
Pagefactory söz konusu olduğunda, @FindBy sihirli bir değnek görevi görür. Konsepte tüm gücü ekler. Artık, Pagefactory'deki @FindBy ek açıklamasının, normal sayfa nesnesi modelindeki driver.findElement () ile aynı performansı gösterdiğini biliyorsunuz. WebElement / WebElements'i bulmak için kullanılır tek kriterle .
# 2) @FindBys
WebElement'i bulmak için kullanılır birden fazla kriter ve verilen kriterlerin tümüne uyması gerekir. Bu kriterler bir ebeveyn-çocuk ilişkisinde belirtilmelidir. Başka bir deyişle, bu, belirtilen ölçütleri kullanarak WebElement'leri bulmak için AND koşullu ilişkisini kullanır. Her kriteri tanımlamak için birden çok @FindBy kullanır.
Örneğin:
Bir WebElement'in HTML kaynak kodu:
POM'da:
@FindBys({ @FindBy(id = 'searchId_1'), @FindBy(name = 'search_field') }) WebElementSearchButton;
Yukarıdaki örnekte, WebElement 'SearchButton' yalnızca ikisiyle de eşleşir id değeri 'searchId_1' ve ad değeri 'search_field' olan ölçütler. Lütfen ilk ölçütün bir ana etikete ait olduğunu ve bir alt etiket için ikinci ölçüt olduğunu unutmayın.
# 3) @FindAll
WebElement'i bulmak için kullanılır birden fazla kriter ve verilen kriterlerden en az birine uyması gerekir. Bu, WebElements'i bulmak için OR koşullu ilişkilerini kullanır. Tüm kriterleri tanımlamak için birden fazla @FindBy kullanır.
Örneğin:
HTML SourceCode:
POM'da:
@FindBys({ @FindBy(id = 'UsernameNameField_1'), // doesn’t match @FindBy(name = 'User_Id') //matches @FindBy(className = “UserName_r”) //matches }) WebElementUserName;
Yukarıdaki örnekte, WebElement ‘Kullanıcı Adı, eğer en az biriyle eşleşir belirtilen kriterlerin.
# 4) @CacheLookUp
WebElement test senaryolarında daha sık kullanıldığında, Selenium test komut dosyası her çalıştırıldığında WebElement'i arar. Belirli Web Öğelerinin global olarak tüm TC için kullanıldığı bu durumlarda ( Örneğin, Oturum açma senaryosu her TC için gerçekleşir), bu açıklama, ilk kez okunduktan sonra bu Web Elemanlarını önbellekte tutmak için kullanılabilir.
Bu da, kodun daha hızlı çalışmasına yardımcı olur çünkü her seferinde sayfada WebElement'i aramak zorunda değildir, bunun yerine referansını bellekten alabilir.
Bu, @FindBy, @FindBys ve @FindAll özelliklerinden herhangi biri ile önek olabilir.
Örneğin:
@CacheLookUp @FindBys({ @FindBy(id = 'UsernameNameField_1'), @FindBy(name = 'User_Id') @FindBy(className = “UserName_r”) }) WebElementUserName;
Ayrıca, bu ek açıklamanın yalnızca öznitelik değeri (xpath, id adı, sınıf adı vb.) Çok sık değişmeyen WebElements için kullanılması gerektiğini unutmayın. WebElement ilk kez bulunduğunda, referansını önbellekte tutar.
Bu nedenle, birkaç gün sonra WebElement’in özniteliğinde bir değişiklik olur, Selenium, önbellekte eski referansına sahip olduğundan ve WebElement’teki son değişikliği dikkate almayacağından, öğeyi bulamayacaktır.
PageFactory.initElements Hakkında Daha Fazla Bilgi ()
Artık Pagefactory'nin InitElements () kullanarak web öğelerini başlatma stratejisini anladığımıza göre, yöntemin farklı sürümlerini anlamaya çalışalım.
Bildiğimiz yöntem, sürücü nesnesini ve geçerli sınıf nesnesini girdi parametreleri olarak alır ve sayfadaki tüm öğeleri örtük ve proaktif olarak başlatarak sayfa nesnesini döndürür.
Uygulamada, yukarıdaki bölümde gösterildiği gibi yapıcının kullanımı, diğer kullanım yollarına göre daha çok tercih edilir.
Yöntemi Çağırmanın Alternatif Yolları:
# 1) 'Bu' işaretçiyi kullanmak yerine, geçerli sınıf nesnesini oluşturabilir, sürücü örneğini ona iletebilir ve parametrelerle, yani sürücü nesnesi ve yeni oluşturulan sınıf nesnesi ile initElements statik yöntemini çağırabilirsiniz.
public PagefactoryClass(WebDriver driver) { //version 2 PagefactoryClass page=new PagefactoryClass(driver); PageFactory.initElements(driver, page); }
#iki) Pagefactory sınıfını kullanarak öğeleri başlatmanın üçüncü yolu, 'yansıma' adı verilen api'yi kullanmaktır. Evet, 'yeni' anahtar kelimeli bir sınıf nesnesi oluşturmak yerine, sınıfadı.class, initElements () girdi parametresinin bir parçası olarak iletilebilir.
public PagefactoryClass(WebDriver driver) { //version 3 PagefactoryClass page=PageFactory.initElements(driver, PagefactoryClass.class); }
Sıkça Sorulan Sorular
S # 1) @FindBy için kullanılan farklı konum belirleme stratejileri nelerdir?
Cevap: Bunun basit cevabı, @ FindBy için kullanılan farklı konum belirleme stratejilerinin olmamasıdır.
Normal POM'daki findElement () yönteminin kullandığı aynı 8 konum belirleme stratejisini kullanırlar:
- İD
- isim
- sınıf adı
- xpath
- css
- etiket adı
- linkText
- kısmiLinkText
S # 2) @FindBy ek açıklamalarının kullanımının da farklı sürümleri var mı?
Cevap: Aranacak bir web öğesi olduğunda, @FindBy notunu kullanırız. Farklı konum belirleme stratejilerinin yanı sıra @FindBy'yi kullanmanın alternatif yollarını da ayrıntılı olarak inceleyeceğiz.
@FindBy'nin 1. sürümünü nasıl kullanacağımızı zaten görmüştük:
@FindBy(id = 'cidkeyword') WebElement Symbol;
@FindBy'nin 2. sürümü, giriş parametresini Nasıl ve Kullanma .
Nasıl Web elemanının tanımlanacağı yer belirleme stratejisini arar. Anahtar kelime kullanma yer belirleyici değerini tanımlar.
Daha iyi anlamak için aşağıya bakın,
- How.ID, kullanarak öğeyi arar İD strateji ve tanımlamaya çalıştığı öğenin id = cidkeyword.
@FindBy(how = How.ID, using = ' cidkeyword') WebElement Symbol;
- How.CLASS_NAME, kullanarak öğeyi arar sınıf adı strateji ve tanımlamaya çalıştığı öğenin sınıfı = yeni sınıf.
@FindBy(how = How.CLASS_NAME, using = 'newclass') WebElement Symbol;
S # 3) @ FindBy'nin iki sürümü arasında bir fark var mı?
Cevap: Cevap Hayır, iki versiyon arasında fark yok. Sadece ilk versiyon, ikinci versiyona kıyasla daha kısa ve daha kolay.
S # 4) Bulunacak web öğelerinin bir listesi olması durumunda sayfa fabrikasında ne kullanırım?
Cevap: Her zamanki sayfa nesnesi tasarım modelinde, aynı sınıfa veya etiket adına ait birden çok öğeyi bulmak için driver.findElements () var, ancak Pagefactory ile sayfa nesnesi modeli durumunda bu tür öğeleri nasıl buluruz? Bu tür öğeleri elde etmenin en kolay yolu, aynı ek açıklamayı @FindBy kullanmaktır.
Bu satırın çoğunuz için bir kafa karıştırıcı gibi göründüğünü anlıyorum. Ama evet, sorunun cevabı bu.
Aşağıdaki örneğe bakalım:
Pagefactory olmadan normal sayfa nesnesi modelini kullanarak, aşağıda gösterildiği gibi birden çok öğeyi bulmak için driver.findElements öğesini kullanırsınız:
private List multipleelements_driver_findelements = driver.findElements (By.class(“last”));
Aynısı, aşağıda verildiği gibi Pagefactory ile sayfa nesne modeli kullanılarak da elde edilebilir:
@FindBy (how = How.CLASS_NAME, using = 'last') private List multipleelements_FindBy;
Temel olarak, öğeleri WebElement türündeki bir listeye atamak, öğeleri tanımlarken ve yerleştirirken Pagefactory kullanılıp kullanılmadığına bakılmaksızın hile yapar.
S # 5) Hem pagefactory olmadan hem de Pagefactory ile Sayfa nesnesi tasarımı aynı programda kullanılabilir mi?
Cevap: Evet, hem Pagefactory olmadan hem de Pagefactory ile sayfa nesnesi tasarımı aynı programda kullanılabilir. Aşağıda verilen programı aşağıdaki bölümde inceleyebilirsiniz. 6. Soru için Cevap programda her ikisinin de nasıl kullanıldığını görmek için.
Hatırlanması gereken bir şey, önbelleğe alınmış özelliğe sahip Pagefactory konseptinin dinamik öğelerde kaçınılması gerektiğidir, oysa sayfa nesnesi tasarımı dinamik öğeler için iyi çalışır. Ancak, Pagefactory yalnızca statik öğelere uygundur.
S # 6) Öğeleri birden çok kritere göre tanımlamanın alternatif yolları var mı?
hangi müzik indirici en iyisidir
Cevap: Öğeleri birden çok kritere göre tanımlamanın alternatifi, @FindAll ve @FindBys ek açıklamalarını kullanmaktır. Bu ek açıklamalar, içinde geçirilen kriterlerden getirilen değerlere bağlı olarak tekli veya çoklu öğelerin tanımlanmasına yardımcı olur.
# 1) @FindAll:
@FindAll birden fazla @FindBy içerebilir ve herhangi bir @FindBy ile eşleşen tüm öğeleri tek bir listede döndürür. @FindAll, aramanın bir dizi @FindBy etiketi kullanması gerektiğini belirtmek için Sayfa Nesnesi üzerindeki bir alanı işaretlemek için kullanılır. Daha sonra FindBy kriterlerinden herhangi biriyle eşleşen tüm öğeleri arayacaktır.
Unsurların belge düzeninde olmasının garanti edilmediğini unutmayın.
@FindAll kullanmak için sözdizimi aşağıdaki gibidir:
@FindAll( { @FindBy(how = How.ID, using = 'foo'), @FindBy(className = 'bar') } )
Açıklama: @FindAll, @FindBy kriterlerinin her birine uyan ayrı öğeleri arayacak ve tanımlayacak ve bunları listeleyecektir. Yukarıdaki örnekte, önce id = ”foo” olan bir öğeyi arayacak ve ardından ikinci öğeyi className = ”bar” ile tanımlayacaktır.
Her bir FindBy kriteri için tanımlanmış bir öğe olduğu varsayıldığında, @FindAll, sırasıyla 2 öğenin listelenmesiyle sonuçlanacaktır. Unutmayın, her kriter için birden fazla unsur tanımlanabilir. Böylece, basit bir deyişle, @ Hepsini bul eşdeğer davranır VEYA @FindBy kriterindeki işleci geçti.
# 2) @FindBys:
FindBys, aramanın ByChained'da açıklandığı gibi bir zincirde bir dizi @FindBy etiketi kullanması gerektiğini belirtmek için Sayfa Nesnesi üzerindeki bir alanı işaretlemek için kullanılır. Gerekli WebElement nesnelerinin verilen kriterlerin tümüne uyması gerektiğinde @ FindBys ek açıklamasını kullanın.
@FindBys kullanmak için sözdizimi aşağıdaki gibidir:
@FindBys( { @FindBy(name=”foo”) @FindBy(className = 'bar') } )
Açıklama: @FindBys, tüm @FindBy kriterlerine uyan öğeleri arayacak ve tanımlayacak ve bunları listeleyecektir. Yukarıdaki örnekte, name = ”foo” ve className = ”bar” olan öğeleri arayacaktır.
@FindAll, verilen kriterlerde ad ve sınıfAdı ile tanımlanmış bir öğe olduğunu varsayarsak, 1 öğeyi listelemeyle sonuçlanacaktır.
Geçilen tüm FindBy koşullarını karşılayan bir öğe yoksa, @FindBys'in sonucu sıfır öğe olacaktır. Tüm koşullar birden fazla unsuru karşılıyorsa, tanımlanmış web öğelerinin bir listesi olabilir. Basit bir deyişle, @ FindBys eşdeğer davranır VE @FindBy kriterindeki işleci geçti.
Yukarıdaki açıklamaların hepsinin uygulanmasını ayrıntılı bir program aracılığıyla görelim:
@FindBy, @FindBys ve @FindAll ek açıklamalarının uygulanmasını anlamak için önceki bölümde verilen www.nseindia.com programını değiştireceğiz.
# 1) PagefactoryClass'ın nesne deposu aşağıdaki gibi güncellenmiştir:
List newlist = driver.findElements (By.tagName ('a'));
@Findby (nasıl = Nasıl. ETİKET ADI , = 'a' kullanarak)
özel Bulma değerini listeleyin;
@Hepsini bul ({ @Findby (className = 'sel'), @Findby (xpath = ”// a (@ id =’ tab5 ′) ”)})
özel Findall değerini listeleyin;
@Filmdenkare ({ @Findby (className = 'sel'), @Findby (xpath = ”// a (@ id =’ tab5 ′) ”)})
özel Findbysvalue'yu listeleyin;
# 2) Yeni bir yöntem olan seeHowFindWorks (), PagefactoryClass'a yazılır ve Main sınıfındaki son yöntem olarak çağrılır.
Yöntem aşağıdaki gibidir:
private void seeHowFindWorks() { System.out.println('driver.findElements(By.tagName()) '+newlist.size()); System.out.println('count of @FindBy- list elements '+findbyvalue.size()); System.out.println('count of @FindAll elements '+findallvalue.size()); for(int i=0;i Aşağıda verilen sonuç, programın çalıştırılmasının ardından konsol penceresinde gösterilen sonuçtur:

Şimdi kodu ayrıntılı olarak anlamaya çalışalım:
# 1) Sayfa nesnesi tasarım kalıbı aracılığıyla 'yeni liste' öğesi, 'a' çapasına sahip tüm etiketleri tanımlar. Başka bir deyişle, sayfadaki tüm bağlantıların bir sayısını alıyoruz.
Pagefactory @FindBy'nin driver.findElement () ile aynı işi yaptığını öğrendik. Findbyvalue öğesi, pagefactory konseptine sahip bir arama stratejisi aracılığıyla sayfadaki tüm bağlantıların sayısını elde etmek için oluşturulur.
Hem driver.findElement () hem de @FindBy'nin aynı işi yaptığı ve aynı öğeleri tanımladığı doğru ispatlar. Yukarıdaki sonuç konsol penceresinin ekran görüntüsüne bakarsanız, yeni liste öğesi ile tanımlanan bağlantıların sayısı ve bulma değerinin sayısı eşittir, yani. 299 sayfada bulunan bağlantılar.
Sonuç aşağıdaki gibi gösterildi:
driver.findElements(By.tagName()) 299 count of @FindBy- list elements 299
#iki) Burada findallvalue adıyla web öğelerinin listesine ilişkin @FindAll ek açıklamasının çalışmasını ayrıntılı olarak ele alacağız.
@FindAll ek açıklamasındaki her @FindBy ölçütüne keskin bir şekilde bakıldığında, ilk @FindBy ölçütü className = 'sel' olan öğeleri arar ve ikinci @FindBy ölçütü XPath = '// a (@ id = ile belirli bir öğeyi arar 'tab5')
Şimdi nseindia.com sayfasındaki öğeleri incelemek ve @FindBy kriterlerine karşılık gelen öğeler hakkında belirli netlikler elde etmek için F12'ye basalım.
Sayfada className = ”sel” e karşılık gelen iki öğe vardır:
için) 'Temel Bilgiler' öğesi liste etiketine, yani
className = ”sel” ile. Aşağıdaki Anlık Görüntüye Bakın

b) Başka bir 'Sipariş Kitabı' öğesi, 'sel' olarak sınıf adına sahip bir bağlantı etiketine sahip bir XPath'e sahiptir.

c) XPath içeren ikinci @FindBy, İD dır-dir ' tab5 ”. Aramaya yanıt olarak tanımlanan tek bir unsur vardır: Temeller.
Aşağıdaki Anlık Görüntüye Bakın:

Nseindia.com testi yürütüldüğünde, aranan öğelerin sayısını aldık.
@FindAll as 3. Görüntülendiğinde findallvalue için öğeler şunlardı: 0 olarak Temellerincidizin öğesi, 1 olarak Sipariş Defteristdizin öğesi ve yine 2 olarak Temellernddizin öğesi. @FindAll'ın her @FindBy ölçütü için öğeleri ayrı ayrı tanımladığını zaten öğrendik.
Aynı protokole göre, birinci kriter araması için, yani className = 'sel' koşulu karşılayan iki öğe belirledi ve 'Temel Bilgiler' ve 'Sipariş Defteri' ni getirdi.
Ardından sonraki @FindBy ölçütüne taşındı ve ikinci @FindBy için verilen xpath başına 'Temel Bilgiler' öğesini getirebilir. Bu nedenle, sonunda sırasıyla 3 element belirledi.
Bu nedenle, @FindBy koşullarından herhangi birini karşılayan öğeleri elde etmez, ancak her @FindBy ile ayrı ayrı ilgilenir ve öğeleri aynı şekilde tanımlar. Ek olarak, mevcut örnekte, öğelerin benzersiz olup olmadığını izlemediğini de gördük ( Örneğin. Bu durumda, iki @FindBy ölçütünün sonucunun bir parçası olarak iki kez görüntülenen 'Temel Bilgiler' öğesi)
# 3) Burada findbysvalue adıyla web öğelerinin listesine ilişkin @FindBys ek açıklamasının çalışmasını ayrıntılı olarak ele alacağız. Burada da birinci @FindBy ölçütü, className = 'sel' olan öğeleri arar ve ikinci @FindBy ölçütü, xpath = '// a (@ id =' tab5 'ile belirli bir öğeyi arar).
Artık ilk @FindBy koşulu için tanımlanan unsurların 'Temeller' ve 'Sipariş Defteri' olduğunu ve ikinci @FindBy ölçütünün 'Temeller' olduğunu biliyoruz.
Öyleyse, @FindBys sonucu, @FindAll'dan nasıl farklı olacak? Önceki bölümde @FindBys'in AND koşullu operatörüne eşdeğer olduğunu ve bu nedenle tüm @FindBy koşulunu karşılayan bir öğeyi veya öğelerin listesini aradığını öğrendik.
Mevcut örneğimize göre, 'Temeller' değeri, sınıf = 'sel' ve id = 'tab5' olan ve dolayısıyla her iki koşulu sağlayan tek öğedir. Bu nedenle @FindBys boyutu test senaryosu 1'dir ve değeri 'Temel Bilgiler' olarak görüntüler.
Pagefactory'deki Öğeleri Önbelleğe Alma
Bir sayfa her yüklendiğinde, @FindBy veya driver.findElement () aracılığıyla bir çağrı başlatılarak sayfadaki tüm öğeler yeniden aranır ve sayfadaki öğeler için yeni bir arama yapılır.
Öğeler dinamik olduğunda veya çalışma süresi boyunca değişmeye devam ettiğinde çoğu zaman, özellikle AJAX öğeleriyse, her sayfa yüklemesinde sayfadaki tüm öğeler için yeni bir arama olması kesinlikle mantıklıdır.
Web sayfası statik öğeler içerdiğinde, öğenin önbelleğe alınması çeşitli şekillerde yardımcı olabilir. Öğeler önbelleğe alındığında, sayfayı yüklerken öğeleri yeniden bulması gerekmez, bunun yerine önbelleğe alınan öğe havuzuna başvurabilir. Bu, çok zaman kazandırır ve daha iyi performansı artırır.
Pagefactory, bir açıklama kullanarak öğeleri önbelleğe alma özelliğini sağlar @CacheLookUp .
Ek açıklama, sürücüye, öğeler için DOM'dan bulucunun aynı örneğini kullanmasını ve pagefactory initElements yöntemi önbelleğe alınan statik öğenin depolanmasına belirgin bir şekilde katkıda bulunurken bunları tekrar aramamasını söyler. İnitElements, öğelerin önbelleğe alma işini yapar.
Bu, sayfa fabrikası konseptini normal sayfa nesnesi tasarım modeline göre özel kılar. Biraz sonra tartışacağımız kendi artıları ve eksileri ile birlikte gelir. Örneğin, Facebook ana sayfasındaki oturum açma düğmesi, önbelleğe alınabilen ve önbelleğe alınması için ideal bir öğe olan statik bir öğedir.
Şimdi @CacheLookUp ek açıklamasının nasıl uygulanacağına bakalım.
Öncelikle aşağıdaki gibi Önbelleğe Alma için bir paketi içe aktarmanız gerekir:
import org.openqa.selenium.support.CacheLookup
Aşağıda, @CacheLookUp kullanarak bir öğenin tanımını gösteren pasaj bulunmaktadır. UniqueElement ilk kez arandığında, initElement () öğenin önbelleğe alınmış sürümünü depolar, böylece bir dahaki sefere sürücü öğeyi aramaz, bunun yerine aynı önbelleğe başvurur ve eylemi sağ öğede gerçekleştirir. uzakta.
@FindBy(id = 'unique') @CacheLookup private WebElement UniqueElement;
Şimdi, önbelleğe alınmış web öğesindeki eylemlerin, önbelleğe alınmamış web öğesindekinden daha hızlı olduğunu gösteren gerçek bir programa bakalım:
Nseindia.com programını daha da geliştirmek, içinde Arama kutusu için önbelleğe alınmış bir öğe ve aynı Arama Kutusu için önbelleğe alınmamış bir öğe oluşturduğum başka bir yeni yöntem monitorPerformance () yazdım.
Daha sonra hem önbelleğe alınan hem de önbelleğe alınmayan eleman için öğenin etiket adını 3000 kez almaya ve hem önbelleğe alınmış hem de önbelleğe alınmamış eleman tarafından görevi tamamlamak için geçen süreyi ölçmeye çalışıyorum.
3000 kez düşündüm, böylece ikisinin zamanlamasında gözle görülür bir fark görebiliyoruz. Önbelleğe alınan öğenin, önbelleğe alınmamış öğeninkine kıyasla daha az zamanda 3000 kat daha az sürede tagname almayı tamamlamasını bekliyorum.
Artık önbelleğe alınan öğenin neden daha hızlı çalışması gerektiğini biliyoruz, yani sürücüye ilk aramadan sonra öğeyi aramaması, doğrudan üzerinde çalışmaya devam etmesi talimatı verildi ve öğe aramasının yapıldığı önbelleğe alınmamış öğe için durum böyle değil tüm 3000 kez ve ardından eylem gerçekleştirilir.
MonitorPerformance () yönteminin kodu aşağıdadır:
private void monitorPerformance() { //non cached element long NoCache_StartTime = System.currentTimeMillis(); for(int i = 0; i <3000; i ++) { Searchbox.getTagName(); } long NoCache_EndTime = System.currentTimeMillis(); long NoCache_TotalTime=(NoCache_EndTime-NoCache_StartTime)/1000; System.out.println('Response time without caching Searchbox ' + NoCache_TotalTime+ ' seconds'); //cached element long Cached_StartTime = System.currentTimeMillis(); for(int i = 0; i < 3000; i ++) { cachedSearchbox.getTagName(); } long Cached_EndTime = System.currentTimeMillis(); long Cached_TotalTime=(Cached_EndTime - Cached_StartTime)/1000; System.out.println('Response time by caching Searchbox ' + Cached_TotalTime+ ' seconds'); }
Yürütme sırasında, konsol penceresinde aşağıdaki sonucu göreceğiz:
Sonuç olarak, önbelleğe alınmamış öğe üzerindeki görev, 82 önbelleğe alınan öğedeki görevi tamamlamak için geçen süre yalnızca saniye 37 saniye. Bu aslında hem önbelleğe alınan hem de önbelleğe alınmayan öğenin yanıt süresinde gözle görülür bir farktır.

S # 7) Pagefactory konseptinde @CacheLookUp ek açıklamasının Artıları ve Eksileri nelerdir?
Cevap:
Artıları @CacheLookUp ve kullanımı için uygun durumlar:
@CacheLookUp, öğeler statik olduğunda veya sayfa yüklenirken hiç değişmediğinde uygulanabilir. Bu tür öğeler çalışma süresini değiştirmez. Bu gibi durumlarda, test yürütmenin genel hızını artırmak için açıklamanın kullanılması tavsiye edilir.
@CacheLookUp ek açıklamasının eksileri:
Ek açıklama ile önbelleğe alınan öğelere sahip olmanın en büyük dezavantajı, StaleElementReferenceExceptions'ı sık sık alma korkusudur.
Dinamik öğeler, birkaç saniye veya zaman aralığının birkaç dakikasında hızlı bir şekilde değişmeye yatkın olanlarla oldukça sık yenilenir.
Aşağıda, dinamik öğelerin bu tür birkaç örneği verilmiştir:
- Web sayfasında, zamanlayıcıyı her saniye güncelleyen bir kronometreye sahip olmak.
- Hava durumu raporunu sürekli güncelleyen bir çerçeve.
- Canlı Sensex güncellemelerini bildiren bir sayfa.
Bunlar, @CacheLookUp ek açıklamasının kullanımı için ideal veya uygulanabilir değildir. Bunu yaparsanız, StaleElementReferenceExceptions istisnası alma riskiyle karşı karşıya kalırsınız.
Bu tür öğelerin önbelleğe alınmasında, test yürütme sırasında öğelerin DOM'u değiştirilir ancak sürücü, önbelleğe alma sırasında önceden depolanan DOM sürümünü arar. Bu, artık web sayfasında bulunmayan eski öğenin sürücü tarafından aranmasını sağlar. StaleElementReferenceException olmasının nedeni budur.
Fabrika Sınıfları:
Pagefactory, birden çok fabrika sınıfı ve arabirimi üzerine kurulmuş bir kavramdır. Bu bölümde burada birkaç fabrika sınıfı ve arayüz hakkında bilgi edineceğiz. Bakacağımız birkaç tanesi AjaxElementLocatorFactory , ElementLocatorFactory ve DefaultElementFactory.
Pagefactory'nin, belirli bir koşul yerine getirilene kadar öğeyi Örtük veya Açıkça beklemek için herhangi bir yol sağlayıp sağlamadığını hiç merak ettik mi ( Misal: Bir öğe görünür, etkinleştirilebilir, tıklanabilir vb. Olana kadar)? Cevabınız evet ise, işte buna uygun bir cevap.
AjaxElementLocatorFactory tüm fabrika sınıfları arasında önemli katkı sağlayanlardan biridir. AjaxElementLocatorFactory'nin avantajı, Web öğesi için Nesne sayfası sınıfına bir zaman aşımı değeri atayabilmenizdir.
Pagefactory, açık bir bekleme özelliği sağlamasa da, sınıfı kullanarak örtük beklemek için bir varyant vardır. AjaxElementLocatorFactory . Bu sınıf, uygulama Ajax bileşenlerini ve öğelerini kullandığında dahil edilebilir.
İşte bunu kodda nasıl uygulayacağınız. Yapıcı içinde, initElements () yöntemini kullandığımızda, öğeler üzerinde örtük bir bekleme sağlamak için AjaxElementLocatorFactory'yi kullanabiliriz.
PageFactory.initElements(driver, this); can be replaced with PageFactory.initElements( new AjaxElementLocatorFactory(driver, 20), this);
Kodun yukarıdaki ikinci satırı, sürücünün her bir yüklendiğinde sayfadaki tüm öğeler için 20 saniyelik bir zaman aşımı ayarlayacağını ve 20 saniyelik bir beklemeden sonra herhangi bir öğe bulunamadığında 'NoSuchElementException' atıldığını ifade eder. bu eksik eleman için.
Beklemeyi aşağıdaki gibi de tanımlayabilirsiniz:
public pageFactoryClass(WebDriver driver) { ElementLocatorFactory locateMe = new AjaxElementLocatorFactory(driver, 30); PageFactory.initElements(locateMe, this); this.driver = driver; }
Yukarıdaki kod, AjaxElementLocatorFactory sınıfı ElementLocatorFactory arayüzünü uyguladığından mükemmel çalışır.
Burada, üst arabirim (ElementLocatorFactory), alt sınıfın (AjaxElementLocatorFactory) nesnesini ifade eder. Bu nedenle, AjaxElementLocatorFactory kullanılarak bir zaman aşımı atanırken Java 'yukarı yayınlama' veya 'çalışma zamanı polimorfizmi' kavramı kullanılır.
Teknik olarak nasıl çalıştığıyla ilgili olarak, AjaxElementLocatorFactory ilk olarak, load () döndüğünde yüklemesi bitmemiş olabilecek bir SlowLoadableComponent kullanarak bir AjaxElementLocator oluşturur. Load () çağrısından sonra, isLoaded () yöntemi bileşen tam olarak yüklenene kadar başarısız olmaya devam etmelidir.
Başka bir deyişle, AjaxElementLocator sınıfından locator.findElement () 'e bir çağrı çağırarak koddaki bir öğeye her erişildiğinde tüm öğeler yeni bir şekilde aranacaktır ve bu daha sonra SlowLoadableComponent sınıfı üzerinden yüklenene kadar bir zaman aşımı uygulayacaktır.
Ek olarak, AjaxElementLocatorFactory aracılığıyla zaman aşımı atandıktan sonra, @CacheLookUp ek açıklamasına sahip öğeler artık ek açıklama yok sayılacağından önbelleğe alınmayacaktır.
Nasıl yapılacağına dair de bir değişiklik var yapabilirsin ara initElements () yöntemi ve nasıl yapmamalı ara AjaxElementLocatorFactory bir öğeye zaman aşımı atamak için.
# 1) Aşağıda initElements () yönteminde gösterildiği gibi sürücü nesnesi yerine bir öğe adı da belirtebilirsiniz:
PageFactory.initElements( , this);
Yukarıdaki varyanttaki initElements () yöntemi dahili olarak DefaultElementFactory sınıfına yapılan bir çağrıyı çağırır ve DefaultElementFactory'nin yapıcısı SearchContext arabirim nesnesini bir giriş parametresi olarak kabul eder. Web sürücüsü nesnesi ve bir web öğesinin her ikisi de SearchContext arayüzüne aittir.
Bu durumda, initElements () yöntemi yalnızca belirtilen öğe için önceden başlatılacak ve web sayfasındaki tüm öğeler başlatılmayacaktır.
#iki) Ancak, AjaxElementLocatorFactory nesnesini belirli bir şekilde nasıl çağırmamanız gerektiğini belirten bu gerçeğe ilginç bir dönüş burada. AjaxElementLocatorFactory ile birlikte yukarıdaki initElements () varyantını kullanırsam, başarısız olur.
Misal: Aşağıdaki kod, yani AjaxElementLocatorFactory tanımına sürücü nesnesi yerine öğe adını iletmek, AjaxElementLocatorFactory sınıfının yapıcısı olarak yalnızca Web sürücüsü nesnesini girdi parametresi olarak aldığından ve bu nedenle web öğesi içeren SearchContext nesnesi bunun için çalışmayacaktır.
PageFactory.initElements(new AjaxElementLocatorFactory(, 10), this);
S # 8) Sayfa fabrikasını kullanmak, normal sayfa nesnesi tasarım desenine göre uygun bir seçenek mi?
Cevap: Bu, insanların sahip olduğu en önemli soru ve bu yüzden eğitimin sonunda buna değinmeyi düşündüm. Artık Pagefactory hakkında kavramlarından, kullanılan ek açıklamalarından, desteklediği ek özelliklerden, kod yoluyla uygulamadan, artılarından ve eksilerinden başlayarak 'giriş ve çıkış' bilgilerini biliyoruz.
Yine de, sayfa fabrikası bu kadar çok iyi şeye sahipse, neden kullanımına bağlı kalmayalım?
Pagefactory, sık sık güncellenen öğenin değerleri gibi dinamik öğeler için uygun olmadığını gördüğümüz CacheLookUp konseptiyle birlikte gelir. Öyleyse, CacheLookUp içermeyen pagefactory, gitmek için iyi bir seçenek mi? Evet, xpath'ler statikse.
Bununla birlikte, çöküş, modern çağ uygulamasının, sayfa faktörü olmadan sayfa nesnesi tasarımının sonuçta iyi çalıştığını bildiğimiz, ancak pagefactory konseptinin dinamik xpaths ile eşit derecede iyi çalıştığı ağır dinamik öğelerle dolu olmasıdır? Belki değil. İşte hızlı bir örnek:
Nseindia.com web sayfasında aşağıdaki gibi bir tablo görüyoruz.

Tablonun xpath'i
'//*(@id='tab9Content')/table/tbody/tr(+count+)/td(1)'
Her satırdan ilk sütun 'Miktar Satın Al' için değerler almak istiyoruz. Bunu yapmak için satır sayacını artırmamız gerekecek ancak sütun dizini 1 olarak kalacaktır. Ek açıklama statik olan değerleri kabul ettiğinden ve hiçbir değişken aktarılamayacağından, bu dinamik XPath'i @FindBy ek açıklamasında geçirebilmemiz mümkün değildir. o.
Her zamanki POM bununla harika çalışırken sayfa fabrikasının tamamen başarısız olduğu yer burasıdır. Driver.findElement () yönteminde bu tür dinamik xpath'leri kullanarak satır dizinini artırmak için kolayca bir for döngüsü kullanabilirsiniz.
Sonuç
Sayfa Nesne Modeli, Selenium otomasyon çerçevesinde kullanılan bir tasarım kavramı veya modelidir.
Yöntemlerin isimlendirilmesi konveksiyonu Sayfa Nesne Modeli'nde kullanıcı dostudur. POM'daki Kodun anlaşılması kolaydır, yeniden kullanılabilir ve bakımı yapılabilir. POM'da, web elemanında herhangi bir değişiklik olması durumunda, tüm sınıfları düzenlemek yerine, ilgili sınıfta değişiklik yapmak yeterlidir.
Her zamanki POM gibi Pagefactory, uygulamak için harika bir konsepttir. Ancak, her zamanki POM'un nerede uygulanabilir olduğunu ve Pagefactory'nin nereye uygun olduğunu bilmemiz gerekir. Statik uygulamalarda (hem XPath hem de öğelerin statik olduğu), Pagefactory daha iyi performansın ek faydaları ile serbestçe uygulanabilir.
Alternatif olarak, uygulama hem dinamik hem de statik öğeler içerdiğinde, pomun her bir web öğesinin fizibilitesine göre Pagefactory ve Pagefactory olmadan karışık bir uygulamasına sahip olabilirsiniz.
Yazar: Bu eğitici Shobha D tarafından yazılmıştır.Proje Lideri olarak çalışır ve manuel, otomasyon (Selenium, IBM Rational Functional Tester, Java) ve API Testlerinde (SOAPUI ve Java'da Rest garantili) 9 yıldan fazla deneyime sahiptir. .
Şimdi, Pagefactory'nin daha fazla uygulanması için size.
Mutlu Keşfetmek !!!
=> Sıfırdan Selenyum Öğrenmek İçin Burayı Ziyaret Edin.
Önerilen Kaynaklar
- 30+ En İyi Selenyum Öğreticisi: Gerçek Örneklerle Selenyum Öğrenin
- Etkili Selenium Komut Dosyası Oluşturma ve Sorun Giderme Senaryoları - Selenium Eğitimi # 27
- Günlüklerle Selenium Komut Dosyalarında Hata Ayıklama (Log4j Eğitimi) - Selenium Eğitimi # 26
- JUnit Framework'e Giriş ve Selenium Script'te Kullanımı - Selenium Tutorial # 11
- Selenium Otomasyon Projesinin Test Tahminini Etkileyen 7 Faktör - Selenium Eğitimi # 32
- Junit ve TestNG Çerçevelerini Kullanan Selenium'daki İddialar
- Selenium Komut Dosyaları Oluşturmak için TestNG Framework Nasıl Kullanılır - TestNG Selenium Tutorial # 12
- Selenyumda TestNG Ek Açıklamalarının Nasıl Kullanılacağını Öğrenin (Örneklerle)