1

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.

Blaise
  • 21,314
  • 28
  • 108
  • 169
  • Sounds like the class takes time before it's removed, so wait for it: `WebDriverWait wait = new WebDriverWait(); wait.Until(d => !SelectById(elementId).GetAttribute("class").Contains("ng-hide"))` – Arran Aug 05 '14 at 15:21
  • Thanks for the input. Are you using `seleno` or something? There is no parameterless constructor for `WebDriverWait`. It asks for `WebDriverWait(IWebDriver driver, TimeSpan timeout)`. – Blaise Aug 05 '14 at 15:32
  • It was pseudo code. However, yes, it'll want access to the driver and how long to wait for it. No idea if Seleno has anything to give you direct access to the driver, but you'll need it. – Arran Aug 05 '14 at 15:34
  • Thank you. You certainly have pointed us to the right direction. We now have the solution. – Blaise Aug 05 '14 at 15:47

2 Answers2

1

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;
    }
}
Blaise
  • 21,314
  • 28
  • 108
  • 169
0

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.

ABucin
  • 936
  • 1
  • 7
  • 18
  • Yes, I thought that was what I did. Can you please tell me how to "wait for the class to be toggled off"? – Blaise Aug 05 '14 at 15:01
  • 1
    In Java, I did something like: WebElement myDynamicElement = (new WebDriverWait(driver, 10)) .until(ExpectedConditions.presenceOfElementLocated(By.class("myDynamicElement"))); – ABucin Aug 05 '14 at 15:03
  • LATER EDIT: This might work: http://stackoverflow.com/questions/16882860/selenium-webdriver-js-explicit-wait – ABucin Aug 05 '14 at 15:09
  • Something like this should to the trick: var driver = new webdriver.Builder(). usingServer(server.address()). withCapabilities(webdriver.Capabilities.firefox()). build(); For more info, you can see: https://code.google.com/p/selenium/wiki/WebDriverJs#Understanding_the_API – ABucin Aug 05 '14 at 18:31