Blaise
Blaise

Reputation: 22212

How to use Selenium (or Seleno) to detect if a DOM element is displayed by Angular

When my button is clicked, the ng-hide directive will turn a hidden div to be visible on page. I am using Seleno to write UI test for an Angular application.

I have checked the display css value on that element:

var cssValue = SelectById(elementId).GetCssValue("display");

This cssValue always returns a none.

Also checked is the class attribute.

var cls = SelectById(elementId).GetAttribute("class");

I am expecting ng-hide should be removed from the classes of this element.

return !SelectById(elementId).GetAttribute("class").Contains("ng-hide");

But every time the class still contains ng-hide!


In case someone may ask, here is my SelectById. Just to return a Web Element on the Selenium Page Object.

    protected IWebElement SelectById(string id)
    {
        return Find.Element(By.Id(id));
    }

As mentioned in the answer section, I probably did not wait out the class update by Angular in a correct way. What I did is just let the Thread Sleep a while.

    public static void Pause(int durationInMilisecond = 2000)
    {
        if (SelenoSettings.EnablePausing) 
            Thread.Sleep(durationInMilisecond);
    }

Anyone can give me some advice? Thanks.

Upvotes: 1

Views: 4593

Answers (2)

Blaise
Blaise

Reputation: 22212

Here is our solution, thanks to the input from ABucin and Arran. Thank you for pointing to the right direction for us. WebDriverWait is the thing we should look into in this case.

public bool Displayed(string elementId)
{
    try
    {
    var wait=new WebDriverWait(BrowserFactory.Chrome(),new TimeSpan(0,2,0));
    wait.Until(d => !SelectById(elementId).GetAttribute("class").Contains("ng-hide"));

    // then there is all types of checking start to work:
    var bySelenoDisplayed =SelectById(elementId).Displayed;
    return bySelenoDisplayed;

    var byCss = SelectById(elementId).GetCssValue("display");
    return !byCss.Equals("hidden");

    var byClass = SelectById(elementId).GetAttribute("class");
    return !byClass.Contains("ng-hide");
    }

    catch (Exception)
    {
        // 2min timeout reached.
        return false;
    }
}

Upvotes: 1

ABucin
ABucin

Reputation: 956

According to the Angular ngHide documentation (https://docs.angularjs.org/api/ng/directive/ngHide), "The element is shown or hidden by removing or adding the ng-hide CSS class onto the element.". So your best way of approaching this, is to:

  • click on button
  • wait for the class to be toggled off
  • check that class is not present

I believe your problem is that the class removal does not happen immediately, but after a certain period of time. I have had several issues regarding this with Selenium on Java, and I assume this is the problem in your case, as well.

Upvotes: 0

Related Questions