4

I'm stuck with this problem:

Our test page will show a spinner while loading data. To solve this problem I added the following lines in a method to make sure the spinner was not present before resuming:

IWebDriver driver = SeleniumHelper.GetWebDriver();
WebDriverWait wait = new WebDriverWait(SeleniumHelper.GetWebDriver(), TimeSpan.FromSeconds(10));
wait.Until(ExpectedConditions.InvisibilityOfElementLocated(By.Id("dvLoading")));

However I would like to create a method that will always be executed before each other method so I wouldn't need to add this lines to the already created methods.

4

Safest is checking for presence of elements (in a loop). It does not wait, but will return list of element present (matching the locator). Returned list will be empty if spinners is not found. If still present, wait for a second or few, and loop back.

I use this trick in many places, and wrapped it to our own custom helper library. Rock solid.

More fancy way is to locate the spinner, and wait until it vanishes (using Expected Condition helper class)

| improve this answer | |
3

You could also use Threading. I don't have the code with me. The first thread executed steps in the test suite/script. the second thread simply looked for the spinner icon. When the spinner appeared it suspended the execution of the Main thread. This reduces the overhead of having to insert checks every step of the way.

| improve this answer | |
2

To call same method every time before other methods, you can use SetUp method from NUnit unit testing framework. Put your spinner checking method in SetUp. This method will be called before each method.

Sample code:

using System;
using NUnit.Framework;

[TestFixture]
public class MyTests
{
  [SetUp] 
  public void Init()
  {
    checkSpinnerNotPresent();  // This'll be called before each test method
  }

  [TearDown] 
  public void Dispose()
  {
    /* Codes for running after each test method */ 
  }

  [Test] 
  public void test()
  { /* ... */ }
}

The is according to NUnit 2. Look there, if you want to use NUnit 3 or higher.

| improve this answer | |
0

You can customize the below methods according to your requirement. Method 1:

    public bool IsElementVisible(IWebElement element)
    {
        return element.Displayed && element.Enabled;
    }

or Method 2:

  public bool TryFindElement(By by, IWebElement element)
    {
        try
        {
            element = driver.FindElement(by);
            bool getelement = element.Displayed;
            return getelement;
        }
        catch
        {
            return false;
        }
    }
| improve this answer | |
  • You can also use thread.sleep() before calling the above methods. – Zain Farooq Mar 8 '18 at 11:17
0

An ideal solution would have you build a class for that page. So any time you want to interact with that page you could have finding and waiting for the spinner as a required action before you look for any other elements on the page.

| improve this answer | |
0

To Handle Spinner in Selenium. We have to use Explicit wait-
1- WebdriverWait
2- FluientWait

As Spinner has two states 1- style.display="block and 2-style.display="none"

style.display="block" : Indicates Spinner is running. Below code will return true if spinner is disappear else timeout exception

 public static boolean waitTillSpinnerDisable(WebDriver driver, By by)
 {
   FluentWait<WebDriver> fWait = new FluentWait<WebDriver>(driver);
   fWait.withTimeout(10, TimeUnit.SECONDS);
   fWait.pollingEvery(250, TimeUnit.MILLISECONDS);
   fWait.ignoring(NoSuchElementException.class);

    Function<WebDriver, Boolean> func = new Function<WebDriver, Boolean>() 
    {
      @Override
     public Boolean apply(WebDriver driver) 
     {
       WebElement element = driver.findElement(by);
       System.out.println(element.getCssValue("display"));         
       if(element.getCssValue("display").equalsIgnoreCase("none")) 
        {
          return true;
        }
       return false;
     }
  };
 return fWait.until(func);
}

By: pass the spinner locator (e.g. By.Id, By.css, By.xpath) etc..
For Complete demo How handle Spinner in Selenium visit on : Handling Spinner in Selenium

| improve this answer | |
0

Here is what I am using in TypeScript with NodeJS. It waits for all spinners on the page by looking at the name of the alt attribute and the src attribute.

public async WaitForAllSpinners(): Promise<void> {
const elements = await this.driver.findElements(By.css("img"));
const keywords = ["loading", "loader", "spinner"];

for (const element of elements) {
    let altText = "";
    let srcText = "";

    //Element may be stale by the time we check it
    try {
        altText = await element.getAttribute("alt");
    } catch (error) {}

    //Element may be stale by the time we check it
    try {
        srcText = await element.getAttribute("src");
    } catch (error) {}

    let identifiedByAltText = false;
    let identifiedBySrcText = false;

    for (const keyword of keywords) {
        if (altText && altText.toLowerCase().indexOf(keyword) >= 0) {
            identifiedByAltText = true;
            break;
        }
        if (srcText && srcText.toLocaleLowerCase().indexOf(keyword) >= 0) {
            identifiedBySrcText = true;
            break;
        }
    }

    if (identifiedByAltText || identifiedBySrcText) {
        //Element may be stale by the time we wait for it
        try {
            await this.driver.wait(until.elementIsNotVisible(element), this._testConfig.DefaultElementTimeout);
        } catch (error) {}
    }
}

}

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.