Forum Discussion

nish_b's avatar
nish_b
Contributor
5 years ago

setInterval is not defined: Suggestion for best wait method during page loads

Hi,   ISSUE:  ReferenceError: setInterval is not defined   DESCRIPTION: I am trying to write a pure JavaScript function for the webpage to fully load before proceeding with my test script. I am u...
  • AlexKaras's avatar
    5 years ago

    Hi,

     

    function for the webpage to fully load

    Definition of the fully loaded page depends on how the given tested page is implemented.

    The generic process is like this:

    -- Browser sends request for the page to the server and waits for the response;

    -- When the response is fully received, browser starts to render it. This is the moment that page.Wait waits for;

    -- Page may contain script functions that modify DOM structure. These might be jQuery, Angular, regular script function or something else. jQuery and Angular provide internal ways to determine if they finished their current activities or not. This can be used to delay test execution until jQuery and/or Angular finish their current activities. Regular script functions are not predictable. They can provide some heavy processing that takes a lot of time without any indication whether or not the processing has completed;

    -- Finally, page may contain some Ajax calls that are executed asynchronously. Depending on their nature, these calls may get data and change page DOM structure in a way that you are interested in. In this case your code must postpone until the required web element appears on the page. Otherwise, such calls may be ignored and test code may proceed.

     

    So, your approach to wait for the page load may depend on the page design and implementation.

     

    As for the setInterval() / clearInterval() functions - what these functions are provided by? They are not built-in TestComplete functions. If JavaScript provides these functions, then they should be accessible from JavaScript-based test project. If this is something provided by DOM/jQuery/etc. then these functions must be called from within page context. Check https://support.smartbear.com/articles/testcomplete/embedding-scripts-into-web-pages/ and "Run JavaScript on Web Pages" TestComplete's help topic for more details on how to call script function from the page context.

     

    Your polling function provided in code snippet #2:

    It will not work as you probably expect it to function. The reason is that this function checks if the object provided as a parameter exists. If the object does not exist, then the code waits in a loop until object's .Exists property becomes True. This will never happen. If the object did not exist when it was obtained, then this means that TestComplete's stub object was returned. And even if/when the sought for object appears, this will in no way be reflected on the stub object. The approach in this case must be not to wait for .Exists to become true, but search in a loop for the object (via .FindXXX() ) and check its .Exists property.

     

  • nish_b's avatar
    nish_b
    5 years ago

    Hi Alex,

     

    I tried your suggestion for 2. i modified the function to loop and keep searching for webelement and then check Exists property. But at 2nd iteration (when i =1)  , when it tries to find the webelement again, it is throwing "Unspecified Error". Could you help here?

     

    Below is the rewritten function:

     

    isElementPresent(webpage,xpath,timeout,pollingTime,frequency) {
    let flag=false;
    let webObj;
    Log.Message("Timeout starting");
    aqUtils.Delay(timeout);
    Log.Message("Timeout stopped");
    for(let i=0;i<frequency;i++){
    webObj=webpage.FindChildByXPath(xpath);
    Log.Message("webobj is: "+webObj);
    if(webObj!==null){
    Log.Message("webObj is not null, checking its existence");
    if(webObj.Exists===true){
    Log.Message("Element exists at iteration: "+i);
    flag=true;
    break;
    }
    else
    {
    Log.Message("Waiting for element at iteration: "+i);
    aqUtils.Delay(pollingTime);
    }
    }
    else {
    Log.Message("WebObj is null/Undefined. Waiting for element at iteration: "+i);
    aqUtils.Delay(pollingTime);
    }
    }
    return flag;
    }

  • AlexKaras's avatar
    AlexKaras
    5 years ago

    Hi,

     

    .FindChildByXPath() should work. I expect the problem is within the getOpenBrowserPage() method. Can you provide it?

    What happens between two subsequent calls to getOpenBrowserPage()? If the page or its content changes somehow then test code must wait at least until the page is reloaded (via <page>.Wait() method) and only then proceed.