I use selenium to test my application. I have many ajax calls that use $ resource or $ http. It would be nice if there was a way to query any active ajax requests in angular so that selenium can wait for these requests to complete.
I suggested that I could place an element on the page (to search for selenium) and connect it to some flag that gets success, but it can get pretty dirty.
There is a very effective way to do this when using jQuery, as described here.
Or does selenium have a way to do this that I have not found?
Could not find anything in the documents? Any suggestions? Thanks.
EDIT:
Caleb Boyd's answer is correct and an excellent solution to the problem of detecting angular ajax calls when using the selenium web driver. Here is a brief implementation of how I use it. I actually used a variation of the caleb code from this link , which included ajax errors. However, this is essentially the same thing. Thanks Caleb.
Add this script and element to the bottom of the page. Just uninstall before deploying:
<html>
<head></head>
<body ng-app="MyApp">
<script>
MyApp.config(function($httpProvider) {
$httpProvider.interceptors.push('requestInterceptor');
})
.factory('requestInterceptor', function($q, $rootScope) {
$rootScope.pendingRequests = 0;
return {
'request': function(config) {
$rootScope.pendingRequests++;
return config || $q.when(config);
},
'requestError': function(rejection) {
$rootScope.pendingRequests--;
return $q.reject(rejection);
},
'response': function(response) {
$rootScope.pendingRequests--;
return response || $q.when(response);
},
'responseError': function(rejection) {
$rootScope.pendingRequests--;
return $q.reject(rejection);
}
};
});
</script>
<span id="http-status">{{pendingRequests}}</span>
</body>
</html>
I am using NUnit for my testing platform.
[TestFixture]
public class MyTestClass
{
[Setup}
public void Setup()
{
_webDriver = new ChromeDriver(@"...path to chromedriver.exe")
}
[TearDown]
public void TearDown()
{
if(_webDriver == null)
return;
_webDriver.Quit();
_webDriver.Dispose();
}
[Test]
public void Test_my_page_functionality()
{
var pageBtn = _webDriver.FindElement(By.Id("my-btn-id"));
pageBtn.Click();
_webDriver.WaitForAjax();
}
}
Here is the WaitForAjax extension
public static class WebDriverExtensions
{
public static void WaitForAjax(this IWebDriver webDriver)
{
while (true)
{
var ajaxIsComplete = webDriver.FindElement(By.Id("http-status"), 5);
if (ajaxIsComplete != null && ajaxIsComplete.Text.Equals("0"))
{
Thread.Sleep(1000);
break;
}
Thread.Sleep(100);
}
}
}
Try testing the WaitForAjax extension by placing Thread.Sleep (5000) at the bottom of your controller method. Hope this helps someone. Thanks again to Caleb.