Enes Pekkaya
Enes Pekkaya

Reputation: 304

General solution for ajax request in Protractor

I want to wait until ajax call complete. Below I wrote general method. But It seems that is not work.

When I ran call function every afterajax request , isLoaded always to be true.

In protractor, Is there any solution? Or where have I made mistake?

Thank you

    module.waitUntilJqueryLoad = async function (timeout) {
    var isDone = false;

    timeout = timeout || 60;

    await browser.sleep(1000);
    //Wait for jQuery to load
    var isLoaded = await browser.driver.executeScript("return jQuery.active == 0;");

    if(isLoaded) {
        console.log("JQuery is Ready!");

        return await browser;
    }

    //This loop will rotate for 60 times to check If page Is ready after every 1 second.
    //You can replace your value with 60 If you wants to Increase or decrease wait time.
    for (var i = 0; i < timeout; i++) {
        try {
            await browser.sleep(1000);
        } catch (err) {}

        //To check page ready state.
        var isLoaded = await browser.driver.executeScript("return jQuery.active == 0;");
        console.log(isLoaded);

        if(isLoaded) {
            console.log("JQuery is Ready");
            isDone = true;
        } else {
            console.log("JQuery is NOT Ready !!");
        }

        if(isDone)
            break;
    }

    return browser;
};

Upvotes: 0

Views: 354

Answers (1)

Enes Pekkaya
Enes Pekkaya

Reputation: 304

I have a work around for that. If your loading popup added display style, it will work.

This is not a general solution but other posted solution has not worked even below code.

await browser.wait(until.invisibilityOf(element(by.id('loadingPanel'))), 60000);

Example Usage :

element(by.id('selectPerson')).waitForInvisibilityOf(10000); // wait 10 seconds

Here is my solution;

protractor.ElementFinder.prototype.waitForInvisibilityOf = async function (timeout) {
var _debug = true;
var isDone = false;
timeout = timeout || 60000;
var seconds = timeout / 1000;

if(await !this.isPresent())
    return this;

//This loop will rotate for 60 times to check If page Is ready after every 1 second.
//You can replace your value with 60 If you wants to Increase or decrease wait time.
for (var i = 1; i <= seconds; i++) {
    await browser.sleep(1000);

    var style = await this.getAttribute('style');
    var insibilityOf = await style.includes('display: none;');
    var visibilityOf = await style.includes('display: block;');

    if(insibilityOf) {
        if(_debug)
            console.log(i + " second: Element invisible!");
        isDone = true;
    }
    else {
        if(_debug)
            console.log(i + " second: Element NOT invisible!");
    }

    if(seconds === i)
        throw "Element invisibility timed out after "+ timeout +" milliseconds";

    if(!insibilityOf && !visibilityOf && i > 10) // break for paging is loaded
        break;

    if(isDone) // If element is invisible
        break;
}

return await this; };

Upvotes: 1

Related Questions