1

I am using the PageFactory with PageObject pattern.

In one of the websites (heavy jQuery) some pages slow to load especially first time page is called. I get "Element is not displayed" or "NoSuchElementException", etc. Dropdowns same thing.

So because when I do myproperty.Click() I get an error my FindsBy goes out of the Windows I start calling my "WaitElementVisible" extensionMethod instead, get an element back and then click which makes my property with attribute pointless .Am I missing the obvious?

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

   public void DoSomething()
   {
        txtPassword.Click // Error Element is not displayed" or "NoSuchElementException"

        //So FindsBy pointless And I need todo
        var myElement=myDriver.WaitElementVisible(by.Id( "user_password"),30));
        myElement.Click()

   }

Questions:

  1. Should the constructor BasePage implement a "WaitForPageToLoad" kind of method Looking for an element to be displayed? Would this resolve the problem?

  2. Does the PageInitElement just initialize the properties and if not found set it to null .Is this correct?

  3. Am I better off just forget "[FindsBy (etc.]" and do everything in a method?

  4. Is it possible to write your own "FindsByWithWait"attribute and how you do that and avoid writing an extensionMethod like below:

Sample code:

    //Ideally I would like to implement a FindsByWithWait that does below       
    public static IWebElement WaitElementVisible(this IWebDriver driver, By by, int timeout = 10) 
    {
        return new WebDriverWait(driver, TimeSpan.FromSeconds(timeout)).Until((drv) => {
            try 
            {
                var ele = drv.FindElement(by);
                return ele.Displayed ? ele : null;
            } 
            catch (StaleElementReferenceException){return null;} 
            catch (NotFoundException){return null;}
        });
    }

   public abstract class BasePage
   {
    protected BasePage
    {
        WaitForPageToLoad();
    }

     protected void WaitForPageToLoad()
     {
            var wait = new WebDriverWait(myDriver, TimeSpan.FromSeconds(30));

            try
            {
                wait.Until(p => p.Title == PageTitle);
            }
            catch (Exception e)
            {
                //log etc...
            }

    }
  }

    public class LoginPage : BasePage
    {
        [FindsBy(How = How.Id, Using = "user_login")]
        public IWebElement txtUserName { get; set; }

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

        [FindsBy(How = How.Name, Using = "commit")]
        public IWebElement btnLogin { get; set; }


        public void Logon(string userName, string password)
        {
            txtUserName.Clear();
            txtUserName.SendKeys(userName);// sometimes will fail (specially site loaded for first time)

            txtPassword.Clear();
            txtPassword.SendKeys(password); //(fails specially site loaded for first time)

            btnLogin.Click();//THIS MIGHT FAIL             
        }   

    }


    I hope you can clarify and answer some of the questions above,that will help me greatly with my Selenium learning curve.

    Thanks a lot
approxiblue
  • 6,982
  • 16
  • 51
  • 59
developer9969
  • 4,628
  • 6
  • 40
  • 88

1 Answers1

0
  1. Selenium already waits for the initial web page to load, but from there you are on your own.
  2. I do believe that init just initializes the properties.
  3. PageFactory can be troublesome with C# right now I have found and it was best for me to create By vars and pagefactory elements. example:

    public string login = "user_login";
    
     By user_login = new By.Id(login);
    
     [FindsBy(How = How.Id, Using = login)]
     public IWebElement txtUserName { get; set; }
    
  4. You can write your own wait methods. Examples: WaitForElementsOnPage

Community
  • 1
  • 1
RockinWatson
  • 111
  • 6