Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get webDriver to wait for page to load (C# Selenium project)

I've started a Selenium project in C#. Trying to wait for page to finish loading up and only afterwards proceed to next action.

My code looks like this:

 loginPage.GoToLoginPage();         loginPage.LoginAs(TestCase.Username, TestCase.Password);         loginPage.SelectRole(TestCase.Orgunit);         loginPage.AcceptRole(); 

inside loginPage.SelectRole(TestCase.Orgunit):

 RoleHierachyLabel = CommonsBasePage.Driver.FindElement(By.XPath("//span[contains(text(), " + role + ")]"));  RoleHierachyLabel.Click();  RoleLoginButton.Click(); 

I search for element RoleHierachyLabel. I've been trying to use multiple ways to wait for page to load or search for an element property allowing for some timeout:

1. _browserInstance.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5)); 

2. public static bool WaitUntilElementIsPresent(RemoteWebDriver driver, By by, int timeout = 5)     {         for (var i = 0; i < timeout; i++)         {             if (driver.ElementExists(by)) return true;         }         return false;     } 

How would you tackle this obstacle?

like image 396
clau84 Avatar asked Apr 04 '17 09:04

clau84


People also ask

How Use wait in Selenium C#?

We can wait until an element is present in Selenium webdriver using the explicit wait. It is mainly used whenever there is a synchronization issue for an element to be available on page. The WebDriverWait and the ExpectedCondition classes are used for an explicit wait implementation.

What would you do to make the WebDriver wait for a page to refresh before executing the test?

until(conditionToCheck); This way you can wait for your element to be present before executing your test2.


1 Answers

I've been searching for alternatives and I've settled for the following versions. All use explicit wait with a defined timeout and are based on element properties in the first case and on element staleness in the second case.

First choice would be checking element properties until a timeout is reached. I've arrived to the following properties that confirm it is available on the page:

Existence - An expectation for checking that an element is present on the DOM of a page. This does not necessarily mean that the element is visible.

//this will not wait for page to load Assert.True(Driver.FindElement(By elementLocator).Enabled)  //this will search for the element until a timeout is reached public static IWebElement WaitUntilElementExists(By elementLocator, int timeout = 10)     {         try         {             var wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(timeout));             return wait.Until(ExpectedConditions.ElementExists(elementLocator));         }         catch (NoSuchElementException)         {             Console.WriteLine("Element with locator: '" + elementLocator + "' was not found in current context page.");             throw;         }     } 

Visibility - An expectation for checking that an element is present on the DOM of a page and visible. Visibility means that the element is not only displayed but also has a height and width that is greater than 0.

//this will not wait for page to load Assert.True(Driver.FindElement(By elementLocator).Displayed)  //this will search for the element until a timeout is reached public static IWebElement WaitUntilElementVisible(By elementLocator, int timeout = 10)     {         try         {             var wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(timeout));             return wait.Until(ExpectedConditions.ElementIsVisible(elementLocator));         }         catch (NoSuchElementException)         {             Console.WriteLine("Element with locator: '" + elementLocator + "' was not found.");             throw;         }     } 

Clickable - An expectation for checking an element is visible and enabled such that you can click it.

//this will not wait for page to load //both properties need to be true in order for element to be clickable Assert.True(Driver.FindElement(By elementLocator).Enabled) Assert.True(Driver.FindElement(By elementLocator).Displayed)  //this will search for the element until a timeout is reached public static IWebElement WaitUntilElementClickable(By elementLocator, int timeout = 10)     {         try         {             var wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(timeout));             return wait.Until(ExpectedConditions.ElementToBeClickable(elementLocator));         }         catch (NoSuchElementException)         {             Console.WriteLine("Element with locator: '" + elementLocator + "' was not found in current context page.");             throw;         }     } 

Second choice applies when the trigger object, for example a menu item, is no longer attached to the DOM after it is clicked. This is ususally the case when click action on the element will trigger a redirect to another page. In this case it's usefull to check StalenessOf(element) where element is the item that was clicked to trigger the redirect to the new page.

public static void ClickAndWaitForPageToLoad(By elementLocator, int timeout = 10)     {         try         {             var wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(timeout));             var element = Driver.FindElement(elementLocator);             element.Click();             wait.Until(ExpectedConditions.StalenessOf(element));         }         catch (NoSuchElementException)         {             Console.WriteLine("Element with locator: '" + elementLocator + "' was not found in current context page.");             throw;         }     } 
like image 126
clau84 Avatar answered Sep 18 '22 13:09

clau84