Is there something like jQuery.active in angularjs?

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><!--My Angular Scripts--></head>
<body ng-app="MyApp">
<!--Your Html -->
<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")
    //any other properties you need
   }

   [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();//see extension below
      //test whatever result you want after ajax request has come back
     }
}

Here is the WaitForAjax extension

public static class WebDriverExtensions
{
  public static void WaitForAjax(this IWebDriver webDriver)
        {
            while (true)
            {
                //Note: FindElement is another extension that uses a timer to look for an element
                //It is NOT the one that selenium uses - the selenium extension throws exceptions on a null element
                var ajaxIsComplete = webDriver.FindElement(By.Id("http-status"), 5);
                if (ajaxIsComplete != null && ajaxIsComplete.Text.Equals("0"))
                {
                    //optional wait for angularjs digest or compile if data is returned in ajax call
                    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.

+4
source share
3

. , - :

angular.module('myApp',[])
.value('httpStatus',{arc:0})
.factory('activeHttpIntercepotrs',function(httpStatus,$q,$rootScope){
    //link up $rootScope and httpStatus
    $rootScope.httpStatus = httpStatus;
    return {
        'request': function(config){
            httpStatus.arc++; return config || $q.when(config);
        },
        'response': function(config){
            httpStatus.arc--; return config || $q.when(config);
        }
    }

})
.config(function($httpProvider){
    $httpProvider.interceptors.push('activeHttpIntercepotrs');
});

DOM -... - :

<span class="dontDisplayMe">{{httpStatus.arc}}</span>

- , , . , DOM - , $http

+5

, , , angular. Ruby. . 30 , Requests.length 0. "0", .

Watir::Wait.until(30) {
@browser.execute_script("return angular.element(document.body).injector().get(\'$http\').pendingRequests.length;") == "0"
}
+10

Capybara Capybara-Webkit Ruby:

def wait_for_ajax
  Timeout.timeout(Capybara.default_max_wait_time) do
    loop until finished_all_ajax_requests?
  end
end

def finished_all_ajax_requests?
  pending_requests = page.evaluate_script('angular.element(document.body).injector().get("$http").pendingRequests.length')
  pending_requests && pending_requests.zero?
end
+1

Source: https://habr.com/ru/post/1528218/


All Articles