Applies to TestComplete 14.20, last modified on September 11, 2019

Complex dynamic web pages may take a few seconds to load, and the web page scripts can also load additional content after the page has been loaded. As a result, the web page load time may be longer during test playback than during recording. To avoid test failures due to timing issues, you can make your tests wait until a web page or element is completely loaded.

This topic describes various approaches to waiting for web pages.

Waiting for Web Pages in Scripts

In scripts, you can wait until a web page is loaded completely using the following approaches:

Waiting for a Test Object to Appear

The WaitPage method lets you pause the test execution until the Page object that contains the specified URL becomes accessible or until the specified time period elapses. Note that the method does not wait until a web page is loaded completely, it only waits for the corresponding Page object and returns the object as the result.

You can use the Exists property to determine whether a new page has been loaded successfully (see below).

Using Hard-Coded Delays

To wait until a web page is loaded completely, you can use the Wait or ToUrl method. The Wait method returns the page's URL, frame or resource that was loaded last. On a failure, the method returns an empty string. The ToUrl method returns the Page object that corresponds to the newly loaded web page.

You can specify the waiting timeout for the Wait and ToUrl methods using their WaitTime parameter. If the parameter is specified, the script execution is paused until the browser loads the page and becomes ready to accept user input or until the specified timeout is reached. If the parameter is omitted or equal to -1, the waiting timeout is specified by the project's Web page loading timeout option.

The Wait and ToUrl methods check whether the loading process has been finished and the next test command is executed after the specified page has been loaded completely. This works for simple pages and is acceptable in most situations. However, for complex (especially dynamic) pages these methods may return a value earlier than the page is loaded completely.

The issue is that the process may report that the page has been loaded, while some elements of the page are still being loaded or created. This happens, for instance, when the page contains frames or script code that performs additional processing upon loading the page. To wait until a page is loaded, you can call the aqUtils.Delay method after instructing the browser to navigate to the page:

JavaScript, JScript

function useDelay()
{
  var page;

  // Run Internet Explorer and open a page
  Browsers.Item(btIExplorer).Run("http://smartbear.com/");

  // Wait for 10 seconds until the page is loaded
  aqUtils.Delay(10000);

  // Get a page object
  page = Sys.Browser().Page("*");

  ...

}

Python

def useDelay():
  # Run Internet Explorer and open a page
  Browsers.Item[btIExplorer].Run("http://smartbear.com/");

  # Wait for 10 seconds until the page is loaded
  aqUtils.Delay(10000);

  # Get a page object
  page = Sys.Browser().Page("*");

  # ...

VBScript

Sub useDelay
Dim page

  ' Run Internet Explorer and open a page
  Browsers.Item(btIExplorer).Run("http://smartbear.com/")

  ' Wait for 10 seconds until the page is loaded
  aqUtils.Delay 10000

  ' Get a page object
  Set page = Sys.Browser.Page("*")

  ...

End Sub

DelphiScript

procedure useDelay();
var page : OleVariant;
begin

  // Run Internet Explorer and open a page
  Browsers.Item[btIExplorer].Run('http://smartbear.com/');

  // Wait for 10 seconds until the page is loaded
  aqUtils.Delay(10000);

  // Get a page object
  page := Sys.Browser.Page('*');

   ...

end;

C++Script, C#Script

function useDelay()
{
  var page;

  // Run Internet Explorer and open a page
  Browsers["Item"](btIExplorer)["Run"]("http://smartbear.com/");

  // Wait for 10 seconds until the page is loaded
  aqUtils["Delay"](10000);

  // Get a page object
  page = Sys["Browser"]()["Page"]("*");

   ...

}

Note, however, that using hard-coded delays has a few disadvantages. For example, the test will be paused even if the page is already loaded. Also, the test might fail if the web page has not been loaded during the delay.

Checking if a Page Is Fully Loaded

To ensure that a web page has been loaded, you can wait until the “problematic” elements are loaded.

For instance, if you are testing a page with frames, you can wait until the page obtains the collection of frames and then use the contentDocument.readyState property of the frames to check whether their content is fully loaded.

Note: Before you check the contentDocument.readyState property of the “problematic” elements, always make sure that the elements already exist on the page and they can be obtained as child objects of the corresponding page object in your tests.

The following code demonstrates this approach:

JavaScript

function Main()
{
  let URL = "http://smartbear.com/";
  
  // Run Internet Explorer and open a page
  Browsers.Item(btIExplorer).Run(URL);
  let page = Sys.Browser().Page("*");

  let stopTime = GetTickCount() + 10000;
  while (GetTickCount() < stopTime)
  {
    frames = page.FindAllChildren("ObjectType", "Frame", 5, true);
    if (frames.length > 0)
    {
      var waitFrame = false;
      for (i in frames)
      {
        let frame = frames[i];
        if (frame.Exists && (frame.contentDocument.readyState != "complete"))
        {
          waitFrame = true;
          break;
        }
      }
      if (! waitFrame)
        break;
      aqUtils.Delay(100);
    }
  }

}

JScript

function Main()
{
  var URL = "http://smartbear.com/";
  
  // Run Internet Explorer and open a page
  Browsers.Item(btIExplorer).Run(URL);
  var page = Sys.Browser().Page("*");

  var stopTime = GetTickCount() + 10000;
  while (GetTickCount() < stopTime)
  {
    frames = page.FindAllChildren("ObjectType", "Frame", 5, true).toArray();
    if (frames.length > 0)
    {
      var waitFrame = false;
      for (var i = 0; i < frames.length; i++)
      {
        var frame = frames[i];
        if (frame.Exists && (frame.contentDocument.readyState != "complete"))
        {
          waitFrame = true;
          break;
        }
      }
      if (! waitFrame)
        break;
      aqUtils.Delay(100);
    }
  }

}

Python

def WaitPage():
  URL = "http://smartbear.com/";

  # Run Internet Explorer and open a page
  Browsers.Item[btIExplorer].Run(URL);
  page = Sys.Browser().Page("*");

  stopTime = GetTickCount() + 10000;
  while (GetTickCount() < stopTime):
    frames = page.FindAllChildren("ObjectType", "Frame", 5, True);
    if VarArrayHighBound(frames, 1) >= 0:
      waitFrame = False;
      for i in range (0, VarArrayHighBound(frames, 1)-1):
        frame = frames[i];
        if ((frame.Exists) and (frame.contentDocument.readyState != "complete")):
          waitFrame = True;
          break;
      if not waitFrame:
        break;
      aqUtils.Delay(100);

VBScript

Sub Main

  URL = "http://smartbear.com/"

  ' Run Internet Explorer and open a page
  Browsers.Item(btIExplorer).Run(URL)
  Set page = Sys.Browser().Page("*")

  stopTime = GetTickCount() + 10000
  Do While GetTickCount() < stopTime

    frames = page.FindAllChildren("ObjectType", "Frame", 5, True)
    If UBound(frames) >= 0 Then

      waitFrame = False
      For i = 0 To UBound(frames)
        Set frame = frames(i)
        If frame.Exists And frame.contentDocument.readyState <> "complete" Then
          waitFrame = true
          Exit For
        End If
      Next
      If Not waitFrame Then
        Exit Do
      End If
      aqUtils.Delay(100)
    End If
  Loop

End Sub

DelphiScript

procedure Main;
var
  URL, page, stopTime, waitFrame, frames, frame, i : OleVariant;
begin

  URL := 'http://smartbear.com/';

  // Run Internet Explorer and open a page
  Browsers.Item(btIExplorer).Run(URL);
  page := Sys.Browser().Page('*');

  stopTime := GetTickCount() + 10000;
  while (GetTickCount() < stopTime) Do
  begin
    frames := page.FindAllChildren('ObjectType', 'Frame', 5, true);
    if VarArrayHighBound(frames, 1) >= 0 then
    begin
      waitFrame := false;
      for i := 0 to VarArrayHighBound(frames, 1) do
      begin
        frame := frames[i];
        if ((frame.Exists) and (frame.contentDocument.readyState <> 'complete')) then
        begin
          waitFrame := true;
          break;
        end;
      end;
      if not waitFrame then
        break;
      aqUtils.Delay(100);
    end;
  end;

end;

C++Script, C#Script

function Main()
{
  var URL = "http://smartbear.com/";
  
  // Run Internet Explorer and open a page
  Browsers["Item"](btIExplorer)["Run"](URL);
  var page = Sys["Browser"]()["Page"]("*");

  var stopTime = GetTickCount() + 10000;
  while (GetTickCount() < stopTime)
  {
    frames = page["FindAllChildren"]("ObjectType", "Frame", 5, true)["toArray"]();
    if (frames["length"] > 0)
    {
      var waitFrame = false;
      for (var i = 0; i < frames["length"]; i++)
      {
        var frame = frames[i];
        if (frame["Exists"] && (frame["contentDocument"]["readyState"] != "complete"))
        {
          waitFrame = true;
          break;
        }
      }
      if (! waitFrame)
        break;
      aqUtils["Delay"](100);
    }
  }

}

The general approach is to wait until the desired web page element becomes available or until it contains the correct values. For instance, if you know that the page script adds HTML tags at the end of the page or modifies text at the end of the page, you can create a test that will wait until the element is available (or until the content is changed). The following code snippets wait until the tested web page contains an element whose contentText attribute equals TestComplete:

JavaScript, JScript

var page;

   // Run Internet Explorer and open a page
   Browsers.Item(btIExplorer).Run("http://smartbear.com/");
   page = Sys.Browser().Page("*");

  // Waiting for the object
  do
  {
    aqUtils.Delay(100);
    obj = page.NativeWebObject.Find("contentText", "TestComplete");
  }
  while (! obj.Exists)
  ...

Python

# Run Internet Explorer and open a page
Browsers.Item[btIExplorer].Run("http://smartbear.com/");
page = Sys.Browser().Page("*");

# Waiting for the object
while True:
  aqUtils.Delay(100);
  obj = page.NativeWebObject.Find("contentText", "TestComplete");
  if obj.Exists:
    break;
  
# ...

VBScript

Dim page

   ' Run Internet Explorer and open a page
   Browsers.Item(btIExplorer).Run("http://smartbear.com/")
   Set page = Sys.Browser.Page("*")

  ' Wait for the object
  Do
    aqUtils.Delay 100
    Set obj = page.NativeWebObject.Find("contentText", "TestComplete")
  Loop Until obj.Exists

  ...

DelphiScript

var page, obj : OleVariant;
begin
  // Run Internet Explorer and open a page
   Browsers.Item[btIExplorer].Run('http://smartbear.com/');
   page := Sys.Browser.Page('*');

  // Wait for the object
  repeat
    aqUtils.Delay(100);
    obj := page.NativeWebObject.Find('contentText', 'TestComplete');
  until obj.Exists;
  ...
end;

C++Script, C#Script

var page;

   // Run Internet Explorer and open a page
  Browsers["Item"](btIExplorer)["Run"]("http://smartbear.com/");
  page = Sys["Browser"]()["Page"]("*");

  // Waiting for the object
  do
  {
    aqUtils["Delay"](100);
    obj = page["NativeWebObject"]["Find"]("contentText", "TestComplete");
  }
  while (! obj["Exists"])
  ...

Waiting for Web Pages in Keyword Tests

To open a web page from keyword tests in TestComplete, you use the Navigate operation. The operation waits until the web page is downloaded completely for the period of time specified by its WaitTime parameter. If the parameter is omitted, the waiting time is specified by the project's Web page loading timeout option. However, the operation may report that the page has been loaded while it is still being loaded (for example, scripts of dynamic web pages may load additional content or modify the existing content after the page has been loaded).

To work around the problem you can specify an additional wait timeout using the Delay operation. This operation pauses your test for the specified time period.

You can also call any of the methods described above from your keyword tests. To do this, use the Call Object Method or Run Code Snippet operation. For a detailed description of how to call methods from your keyword tests, see the Calling Object Methods topic.

See Also

Testing Web Applications
Common Tasks for Web Testing
Finding Objects on Web Pages
Testing Dynamic Web Pages

Highlight search results