Kategorier
Test and Q&A

Selenium C# Page Object Model utan PageFactory

PageFactory för Selenium C# har from. version 3.11 utgått. Det har under en övergångsperiod gått att använda med ett tilläggspaket (NuGet) som heter DotNetSeleniumExtras.PageObjects men från version 4 av Selenium stöds inte heller det.

PageFactory anses av flera inom Selenium-community inte vara ett bra stöd i konceptet Page Object Model (POM), även om jag själv inte haft några problem med det. Längst ner i detta inlägg finns några länkar till anledningen bakom att sluta stödja PageFactory, om du vill veta mer.

Vad är då PageFactory? Jo det används för att initiera webbelement i POM-classen och elementen får därför en funktion som liknar cachning. Denna bild från guru99.com visar bra hur man definierar webbelement med PageFactory:

Från guru99.com

Om man vill uppgradera sitt Selenium-projekt till version 4, vilket är bra för att få nya funktioner och eventuella säkerhetspatchar, krävs det att man konverterar @FindBy till FindElement vilket får till följd att webbelementen letas upp under runtime när testet körs. Det är egentligen ganska lätt att konvertera men kan ta lite tid. I det projekt jag jobbar med nu var det ca. 700 webbelement som fick konverteras manuellt, men egentligen utan några större problem.

Om ett element i PageFactory ”hittades” så här:

        [FindsBy(How = How.Id, Using = "account")]
        public IWebElement MyAccount { get; set; }

Så får man konvertera det till:

public IWebElement MyAccount => _driver.FindElement(By.Id("account"));

Och sen får man ta bort initieringen av PageFactory och till slut avinstallera NuGet-paketet DotNetSeleniumExtras.PageObjects.

Det jag upptäckt efter konverteringen är att vissa delar av testerna har varit anpassad för PageFactory och beter sig nu lite annorlunda. Ett exempel är om man vill kolla om ett webbelement finns på sidan (i DOM:en), tex. om en knapp ska synas eller inte. Beroende på vilket front-end ramverk som används kanske elementet bara är ”hidden” eller ”not enabled” men det kan även vara så att det inte finns alls. Just det fallet kan man lösa genom följande:

Skapa en generell metod (här i classen BasePage.cs) som sätter ner tiden (här till 5 sekunder) hur länge Seleniums webdriver ska vänta på ett element är tillgängligt i DOM:en. Om du inte sätter ner tiden får du vänta i den tid som gäller generellt för ImplicitWait, i mitt fall 30 sekunder (timeSpan).
Om elementet sedan är tillgängligt returneras true, annars false eftersom ett NoSuchElement-exception kan kastas och det tas hand om med catch.
Observera att ImplicitWait sätts tillbaka till 30 sekunder när resultatet returneras vilket innebär att resten av testmetoden som exekveras åter har webdrivern med sitt ursprungsvärde.

        public bool IsElementDisplayed(string elementToCheck, int time = 5)
        {           
            Driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(time);
           
            var present = false;
            try
            {
                IWebElement element = Driver.FindElement(By.Id(elementToCheck));
                present = element.Displayed;
            }
            catch (Exception)
            {
                            
               //Set back ImplicitWait to default 
                Driver.Manage().Timeouts().ImplicitWait = timeSpan;
                return present;
            }
            //Set back ImplicitWait to default 
            Driver.Manage().Timeouts().ImplicitWait = timeSpan;
            return present;
        }

Och i din testmetod, anropa metoden med webbelementet som en textsträng. Då får du en snygg assert som du kan hantera som du vill:

Assert.IsTrue(BasePage.IsElementDisplayed("sitelogo"), "Site logo not visible");

Det finns många olika sätt att hantera liknande fall och det aktuella behovet får avgöra hur du väljer att implementera. I mitt projekt var det enklast att göra på detta vis då vi har många tester om element syns (finns) eller inte i DOMen.

Om du överväger att komma bort från PageFactory för att kunna uppgradera till Selenium 4 hoppas jag att du fått lite ideer av mitt inlägg. Till slut kommer här ett antal länkar om du vill läsa mer om bakgrunden till PageFactory och varför den supporten nu upphör.

Lars Thunberg – Q&A-konsult inom testledning, systemtestning och testautomatisering

Lämna ett svar

Din e-postadress kommer inte publiceras.