-1

I need to test an AngularJS website with Selenium, I read in a blog that due to angular directive it's tough to test angular website with selenium. Though I tried with Selenium and I got success to run the cases but it's not stable some time it fails and throw "unable to locate Element" "No such element" or like "Null pointer exceptions". Is there any way something I'm missing here to run it with selenium successfully. I also read about ProtectorJS as well but selenium is on priority for test run.

Thanks in advance.

promitheus
  • 67
  • 2
  • 13
  • Possible duplicate of [Can angularjs apps be automated with selenium? if yes, why should we use protractor?](http://stackoverflow.com/questions/27380994/can-angularjs-apps-be-automated-with-selenium-if-yes-why-should-we-use-protrac) – Ramesh Rajendran Jan 11 '17 at 12:14
  • 1
    What you are describing is a challenge faced by all selenium automation experts all over the world (including me). That's just the way it is - you're not alone. – Happy Bird Jan 11 '17 at 15:33

3 Answers3

1

I had the same problem. The implicit selenium waits didn't work with angular and I didn't want to mess my tests up with explicit waits tremendously increasing test duration.

I found this: https://github.com/paul-hammant/ngWebDriver

It is a webDriver derived from Protractor which can be used in Selenium.

I wrote an actions class in which I waited for Angular before carrying out the actions (click, fill, check etc.). For the code snippet see my answer to this question.

Community
  • 1
  • 1
74nine
  • 838
  • 7
  • 13
  • @promitheus good to hear that my answer solved your problem. You can accept the answer by clicking the green checkmark. – 74nine Jan 20 '17 at 07:52
0

This problem is because this fields that you are trying to get are not yet there.

Unfortunately there is no a possible an automatic fix, but what you can do is add a piece of code to wait until this attribute is there

WebDriverWait.until(findElement(By.xpath("//[@id='id']"));

other option is add a wait(ms) function in your code and call it.

the problem of both of them is that you need to write lot of lines for this reason.

TiGreX
  • 1,602
  • 3
  • 26
  • 41
0

In order to wait for Angular processed elements, you can wait until all Angular requests are finished.

Selenium provides Explicit Waits to perform such tasks with ExpectedCondition

Example of Expected Condition:

 public static ExpectedCondition<Boolean> angularHasFinishedProcessing() {
return new ExpectedCondition<Boolean>() {
    @Override
    public Boolean apply(WebDriver driver) {
        return Boolean.valueOf(((JavascriptExecutor) driver).executeScript("return (window.angular !== undefined) && (angular.element(document).injector() !== undefined) && (angular.element(document).injector().get('$http').pendingRequests.length === 0)").toString());
    }
};

}

After that, we can just use our code to wait for all AJAX requests to complete We provide ExpectedCondition in Explicit Waits which is implemented with WebDriverWait

WebDriverWait wait = new WebDriverWait(driver, 15, 100);
wait.until(AdditionalConditions. angularHasFinishedProcessing()));

What we did here is, we used JavascriptExecutor and executed javascript to get pending requests. If there is no pending request we can use this element.

Fenio
  • 3,528
  • 1
  • 13
  • 27