Search code examples
c#seleniumselenium-webdrivercoded-ui-tests

Selenium Waits Logic


I am building a testing framework for my website I want to fully separate the framework away from test the issue is when I write a test sometimes the Assert needs time until it can be true, for example if I am on Upload file page and when the file is uploaded the website should display File uploaded successfully page but it will need to much time until the browser reaches this page

How should I force the Assert to wait sometime before it returns result?

some code that might explain my current way of work:

Upload Page Class

Public class UploadPage
{
 [FindsBy(How = How.Name, Using = "upload-button")]
 public IWebElement BtnUpload { get; set; }

  public UploadPage()
  {
   PageFactory.InitElements(Driver, this);
  }

 public void UploadFile(string path)
  {
    //select file
    BtnUpload.Click();
  }
}

Successful Upload Page:

 Public class UploadSuccessfulPage
   {
     [FindsBy(How = How.Name, Using = "success-message")]
     public IWebElement LblSuccessMessage{ get; set; }

     public UploadSuccessfulPage()
     {
       PageFactory.InitElements(Driver, this);
     }
     public bool IsAt()
     {
      Driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(60))
      return Driver.url==configurations.UploadSuccessfulPageURL;
     }
   } 

Test Method:

public void TestUpload()
{
 UploadPage uploadPage= new UploadPage ();
 uploadPage.UploadFile(path);
 UploadSuccessfulPage successPage= new UploadSuccessfulPage();
 Assert.IsTrue(successPage.IsAt());
}

when I write my tests this way the assert do not wait despite that IsAt() contains implicit wait

P.S: I am not intending to use Thread.Sleep();


Solution

  • The method bool IsAt() should be implemented like:

    public bool IsAt()
    {
      Driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(60));
      try {
         return driver.FindElement(By.Name("success-message").Displayed;
      } catch (WebDriverException e) {
        return false;
      }
    }
    

    Or using explicit wait:

    public bool IsAt()
    {
      try {
        WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(60));
         wait.Until(ExpectedConditions.ElementIsVisible(By.Name("success-message")));
        return true;
      } catch (TimeoutException e){
        return false;
      }
    }
    

    Update: If you want to verify by url, the bool IsAt() should look like:

    public bool IsAt()
        {
          try {
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(60));
             wait.Until(ExpectedConditions.UrlToBe(configurations.UploadSuccessfulPageURL));
            return true;
          } catch (TimeoutException e){
            return false;
          }
        }
    

    Look at the class ExpectedConditions to find a condition suitable to your require