15

I'm using Selenium webdriver to interact with some website.
If the website is using jQuery we can get the pending AJAX request by using jQuery.active:

 JavascriptExecutor jsx = (JavascriptExecutor) driver;

Int totAjaxRequest = (Int)jsx.executeScript("jQuery.active");

Int totAjaxRequest = (Int)jsx.executeScript("return jQuery.active");

In case if the website is not using jQuery, how could we count the number of XMLHttpRequest requests?

Sergey Gubarev
  • 777
  • 3
  • 11
  • 29
शेखर
  • 16,910
  • 12
  • 52
  • 105

2 Answers2

1

Keep this in your website, and call it from selenium. I think there is no any similar built in js function. I don't think this is the answer you are looking for, but as I said above javascript does not have such a function itself.

If you can not edit or add new script to your website, you can still run the script.

Int totAjaxRequest = (Int)jsx.executeScript("
    (function(){
        var count = 0;
        XMLHttpRequest.prototype.nativeSend = XMLHttpRequest.prototype.send;
        XMLHttpRequest.prototype.send = function(body) {

            this.onreadystatechange  = function(){
               switch(this.readyState){
                   case 2: count++; break
                   case 4: count--; break
               }
            };
            this.nativeSend(body);
        };

        return count;
    })()

");
Void Spirit
  • 789
  • 5
  • 17
  • The website does not belongs to me. So I can not add some code there. Is there any way in selenium by which I can inject some function/script in the website. – शेखर Oct 03 '18 at 06:02
  • just wrap that script only function part to Int totAjaxRequest = (Int)jsx.executeScript("{{here}}"); Answer is updated – Void Spirit Oct 03 '18 at 16:53
  • it's difficult to use.the above function because it reinitize the counter every time – शेखर Oct 07 '18 at 01:54
1

Here an example how the waiting for AJAX requests can be done with nightwatch custom commands.

One command to init the counter. on every send if will increase the counter and on ever open it will decrease it customCommands/initAjaxCounters.js:

exports.command = function () {
  this.execute(function () {
    window.sumStartedAjaxRequests = 0
    window.activeAjaxCount = 0

    function isAllXhrComplete () {
      window.activeAjaxCount--
    }

    (function (open) {
      XMLHttpRequest.prototype.open = function () {
        this.addEventListener('loadend', isAllXhrComplete)
        return open.apply(this, arguments)
      }
    })(XMLHttpRequest.prototype.open)
  })
  this.execute(function () {
    (function (send) {
      XMLHttpRequest.prototype.send = function () {
        window.activeAjaxCount++
        window.sumStartedAjaxRequests++
        return send.apply(this, arguments)
      }
    })(XMLHttpRequest.prototype.send)
  })
  return this
}

and then an other custom command to wait

const sleepWhenOutstandingAjaxCalls = function (result) {
  if (result.value > 0) {
    this.pause(this.globals.waitForConditionPollInterval)
    this.waitForOutstandingAjaxCalls()
  }
}

exports.command = function () {
  // init the ajax counter if it hasn't been initialized yet
  this.execute('return (typeof window.activeAjaxCount === "undefined")', [], function (result) {
    if (result.value === true) {
      throw Error('checking outstanding Ajax calls will not work without calling initAjaxCounter() first')
    }
  })

  this.execute(
    'return window.activeAjaxCount', [], sleepWhenOutstandingAjaxCalls
  )
  return this
}
INDIVIDUAL-IT
  • 386
  • 2
  • 10