Best way to find out if jqGrid is loaded and ready with Selenium
Asked Answered
B

3

5

How are you finding out if jqGrid is loaded and ready to be used, via selenium.

Some details :

  • Im using C# driver
  • I have a method : new WebDriverWait(driver, new TimeSpan(0, 0, 0, 30)).Until(x => loadingdissapearedcondition) which im using to wait until Loading.. element is gone.
  • I also sometimes use this script :

private const string script = @"return ($('#{0}').jqGrid('getGridParam', 'reccount') !=x undefined) && ($('#{0}').jqGrid('getGridParam', 'reccount') != 0) && (!$('#load_{0}').is(':visible')) && (!$('#busyIcon').is(':visible'))";

private readonly string waitScript;

waitScript = string.Format(script, jqGridId);

public void WaitUntilLoadIconDissappears()
{
    driver.WaitUntil(MAXWAIT, Wait);
}

public bool Wait()
{
    var executeScript = ((IJavaScriptExecutor) driver).ExecuteScript(waitScript);
    bool result;
    bool tryParse = bool.TryParse(executeScript.SafeToString(), out result);
    return tryParse && result;
}

to find if jqGrid has records and loading done.

I require something better - as even the above two does not make driver wait until load finishes, if we are using local data for jqGrid. Im also curious what is the best way, or at the minimum, how others are dealing with this problem.

Benbena answered 1/8, 2012 at 10:46 Comment(0)
A
14

I never used Selenium before, so I'm not sure that I understood your problem correctly. jqGrid will be first initialized and then (optionally) the data can be loaded from the server. During the initializing stage the original <table id="grid"></table> element will be converted to relatively complex HTML fragment which is the grid. At the end of the initialization the DOM element of the table (the $("#grid")[0]) will get the expando grid.

So you can use the test like

if ($("#grid")[0].grid) {
    // grid is initialized
}

to determine that the grid is already initialized. jqGrid uses the same test internally (see here for example).

Artificer answered 1/8, 2012 at 11:22 Comment(8)
After grid is initialized, It will make an ajax call to get data from server. Later on whenever ppl do a refresh grid also, it will make calls to get data. I basically want a script that returns 'true' when jqGrid is Loading, and 'false' when it is idle. -If i can get such a script I can execute it from within selenium.Benbena
@Zasz: Request to the server to fill the data exists only if datatype: "json" or datatype: "xml". It depends on other settings like (loadonce: true). The grid can be refilled from the server depends on the user's activity. For example if the user sort by the column, click on the next page and so on the new request will be send to the server and the content of the grid will be refreshed. You can use beforeRequest, beforeProcessing and loadComplete or loadError callbacks to control when the request to the server will be started and when it will be ended.Artificer
Yep these callbacks are most close to what I need - but i have no control over when they are executed. I will be polling using selenium to know when jqgrid is loaded (polling = just executing script at 500 ms intervals). While callbacks tell me the status of jqGrid - i need a script to use while polling that tell me the status of jqGrid. Thanks for taking the time to help me out.Benbena
@Zasz: You are welcome! You can just define a variable like var inLoading; in the outer scope and set it to true in beforeRequest and reset it to false inside of loadComplete or loadError. You can define the variable in the scope (for example as global variable) which you can easy access using Selenium.Artificer
I ended up using a input hidden instead of a variable, just like you described...Benbena
@willsteel: Not a problem!Artificer
@Oleg..Each and every answer has been very useful to me.. thanks you very much :)Cabinetwork
@Avinash: You are welcome! I'm glad to read that you find my posts good. Thanks!Artificer
B
0

Here is solution for Java and jqgrid. If grid data is not loaded yet then right pager has no value, so simply check its length. Methods such as isElementPresent, isDisplayed etc. seems not to work for grid right pager object. It's always present in page code while ajax, but text value is set when dynamic data is loaded.

public void waitForGridPagerRight(String gridName) throws Exception {

    for (int second = 0;; second++) {
        if (second >= 15) {
            fail("Timeout.");
        }
        try {
            if (driver
                    .findElement(By.id("pager_" + gridName + "_right"))
                    .getText().length() > 2)
                break;
        } catch (Exception e) {
        }
        Thread.sleep(1000);
    }
}
Bothersome answered 9/4, 2014 at 10:8 Comment(0)
R
0

Not sure why @Oleg's answer didn't work for me. It seemed like grid was being populated even before the ajax call was being made. It appears there's some change in newer versions maybe. It look like the last thing to happen in the ajax call is that the "loading" block is hidden, so instead I find that element and check it's display attribute a la:

  def wait_for_jqgrid(self, t=20):
    def check_jqgrid(driver):
      #the last thing jqgrid does after the ajax call is to turn off the loading div
      #so we find it and check to see if its display attribute is no longer set to 'none'
      script = 'pid = $.jgrid.jqID($(".ui-jqgrid-btable").get(0).p.id); return $("#load_"+pid).get(0).style.display == "none";'
      return driver.execute_script(script)
    WebDriverWait(self.driver, t).until(check_jqgrid)

When the loading div is hidden, we are done. This is python but the same javascript bit should work in Java or whatever.

Revue answered 13/3, 2020 at 21:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.