Waiting for Web Pages in Hybrid Mobile Applications

Applies to TestComplete 14.30, last modified on November 21, 2019

Hybrid mobile applications can load pages from the Internet. These pages may take several seconds to load, and web page scripts may also load additional content after that. As a result, the web page load time may be longer during test run than during recording. To avoid test failures due to timing issues, you can make your tests wait until a web page or element is loaded completely.

This topic explains how to wait until a web page is loaded in a hybrid mobile application.

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 WebView.WaitPage method lets you pause the test run until the Page object that contains the specified URL becomes accessible or until the specified period elapses. 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.

Waiting for Simple Web Pages

To wait until a web page is loaded completely, you can use the Wait, WebView.ToUrl or Page.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 parameters. If the parameter is specified, the script execution is paused until the WebView control loads the page and becomes ready to accept user input or until the specified timeout is reached. If the parameter is omitted or equals -1, the waiting timeout is specified by the project's Web page loading timeout option.

JavaScript, JScript

function WebTest()
{
  // Select the mobile device
  Mobile.SetCurrent("MyDevice");

  // Run the hybrid application
  TestedApps.WebViewSample.Run();

  // Obtain the WebView object
  // On Android devices
  var p = Mobile.Device().Process("smartbear.webview_sample");
  var webview = p.RootLayout("").WebView("mainWebView");
  // On iOS devices
  // var p = Mobile.Device().Process("SampleWebViewApp");
  // var webview = p.Window(0).WebView(0);

  // Open a page and wait until it is loaded
  var page = webview.ToUrl("http://support.smartbear.com/");
  // Work with the page
  …
}

Python

def WebTest():
  # Select the mobile device
  Mobile.SetCurrent("MyDevice");

  # Run the hybrid application
  TestedApps.WebViewSample.Run();

  # Obtain the WebView object
  # On Android devices
  p = Mobile.Device().Process("smartbear.webview_sample");
  webview = p.RootLayout("").WebView("mainWebView");
  # On iOS devices
  # p = Mobile.Device().Process("SampleWebViewApp");
  # webview = p.Window(0).WebView(0);

  # Open a page and wait until it is loaded
  page = webview.ToUrl("http://support.smartbear.com/");
  # Work with the page
  # ...

VBScript

Sub WebTest()
  Dim p, webview, page
  ' Select the mobile device
  Mobile.SetCurrent("MyDevice")

  ' Obtain the WebView object
  ' On Android devices
  Set p = Mobile.Device.Process("smartbear.webview_sample")
  Set webview = p.RootLayout("").WebView("mainWebView")
  ' On iOS devices
  ' Set p = Mobile.Device.Process("SampleWebViewApp")
  ' Set webview = p.Window(0).WebView(0)

  ' Open a page and wait until it is loaded
  Set page = webview.ToUrl("http://support.smartbear.com/")
  ' Work with the page
  …
End Sub

DelphiScript

function WebTest();
var
  p, webview, page: OleVariant;
begin
  // Select the mobile device
  Mobile.SetCurrent('MyDevice');

  // Run the hybrid application
  TestedApps.WebViewSample.Run;

  // Obtain the WebView object
  // On Android devices
  p := Mobile.Device.Process('smartbear.webview_sample');
  webview := p.RootLayout('').WebView('mainWebView');
  // On iOS devices
  // p := Mobile.Device.Process('SampleWebViewApp');
  // webview := p.Window(0).WebView(0);

  // Open a page and wait until it is loaded
  page := webview.ToUrl('http://support.smartbear.com/');
  // Work with the page
  …
end;

C++Script, C#Script

function WebTest()
{
  // Select the mobile device
  Mobile["SetCurrent"]("MyDevice");

  // Run the hybrid application
  TestedApps["WebViewSample"]["Run"]();

  // Obtain the WebView object
  // On Android devices
  var p = Mobile["Device"]["Process"]("smartbear.webview_sample");
  var webview = p["RootLayout"]("")["WebView"]("mainWebView");
  // On iOS devices
  // var p = Mobile["Device"]["Process"]("SampleWebViewApp");
  // var webview = p["Window"](0)["WebView"](0);

  // Open a page and wait until it is loaded
  var page = webview["ToUrl"]("http://support.smartbear.com/");
  // Work with the page
  …
}

To detect that a web page has loaded completely on the Android device, the Wait and ToUrl methods use the WebWiew.getProgress() and WebViewClient.onPageFinished() native methods. On iOS devices, TestComplete waits until the document.readyState property returns complete. This works for simple pages and is acceptable in most situations. However, for complex (especially dynamic) pages, the property may return the value earlier than the page is loaded completely.

The issue is that the WebView control 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 for complex pages, you can use hard-coded delays or wait until specific web page elements are loaded.

Using Hard-Coded Delays

To wait until a complex page is loaded, you can call the aqUtils.Delay method after instructing the WebView control to navigate to the page:

JavaScript, JScript

function WebTestDelayed()
{
  // Select the mobile device
  Mobile.SetCurrent("MyDevice");

  // Run the hybrid application
  TestedApps.WebViewSample.Run();

  // Obtain the WebView object
  // On Android devices
  var p = Mobile.Device().Process("smartbear.webview_sample");
  var webview = p.RootLayout("").WebView("mainWebView");
  // On iOS devices
  // var p = Mobile.Device().Process("SampleWebViewApp");
  // var webview = p.Window(0).WebView(0);

  // Open a page
  var page = webview.ToUrl("http://support.smartbear.com/");
  // Wait for post-processing
  aqUtils.Delay(10000);
  // Work with the page
  …
}

Python

def WebTestDelayed():
  # Select the mobile device
  Mobile.SetCurrent("MyDevice");

  # Run the hybrid application
  TestedApps.WebViewSample.Run();

  # Obtain the WebView object
  # On Android devices
  p = Mobile.Device().Process("smartbear.webview_sample");
  webview = p.RootLayout("").WebView("mainWebView");
  # On iOS devices
  # p = Mobile.Device().Process("SampleWebViewApp");
  # webview = p.Window(0).WebView(0);

  # Open a page
  page = webview.ToUrl("http://support.smartbear.com/");
  # Wait for post-processing
  aqUtils.Delay(10000);
  # Work with the page

VBScript

Sub WebTestDelayed()
  Dim p, webview, page
  ' Select the mobile device
  Mobile.SetCurrent("MyDevice")

  ' Obtain the WebView object
  ' On Android devices
  Set p = Mobile.Device.Process("smartbear.webview_sample")
  Set webview = p.RootLayout("").WebView("mainWebView")
  ' On iOS devices
  ' Set p = Mobile.Device.Process("SampleWebViewApp")
  ' Set webview = p.Window(0).WebView(0)

  ' Open a page
  Set page = webview.ToUrl("http://support.smartbear.com/")
  ' Wait for post-processing
  aqUtils.Delay(10000)
  ' Work with the page
  …
End Sub

DelphiScript

function WebTestDelayed();
var
  p, webview, page: OleVariant;
begin
  // Select the mobile device
  Mobile.SetCurrent('MyDevice');

  // Run the hybrid application
  TestedApps.WebViewSample.Run;

  // Obtain the WebView object
  // On Android devices
  p := Mobile.Device.Process('smartbear.webview_sample');
  webview := p.RootLayout('').WebView('mainWebView');
  // On iOS devices
  // p := Mobile.Device.Process('SampleWebViewApp');
  // webview := p.Window(0).WebView(0);

  // Open a page
  page := webview.ToUrl('http://support.smartbear.com/');
  // Wait for post-processing
  aqUtils.Delay(10000);
  // Work with the page
  …
end;

C++Script, C#Script

function WebTestDelayed()
{
  // Select the mobile device
  Mobile["SetCurrent"]("MyDevice");

  // Run the hybrid application
  TestedApps["WebViewSample"]["Run"]();

  // Obtain the WebView object
  // On Android devices
  var p = Mobile["Device"]["Process"]("smartbear.webview_sample");
  var webview = p["RootLayout"]("")["WebView"]("mainWebView");
  // On iOS devices
  // var p = Mobile["Device"]["Process"]("SampleWebViewApp");
  // var webview = p["Window"](0)["WebView"](0);

  // Open a page
  var page = webview["ToUrl"]("http://support.smartbear.com/");
  // Wait for post-processing
  aqUtils["ToUrl"](10000);
  // Work with the page
  …
}

Using hard-coded delays has a few disadvantages. One of them is the fixed wait time. The test will be paused for the specified period even if a page has been loaded completely. And if you specify too short time period, the test might fail if the page is not loaded during that time.

Waiting for Web Page Elements

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

The general approach is to wait until the 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, you can create a test that will wait until the element is available. The following code snippets wait until the tested web page contains an element whose contentText attribute equals TestComplete:

JavaScript, JScript

function WaitForElement()
{
  // Select the mobile device
  Mobile.SetCurrent("MyDevice");

  // Run the hybrid application
  TestedApps.WebViewSample.Run();

  // Obtain the WebView object
  // On Android devices
  var p = Mobile.Device().Process("smartbear.webview_sample");
  var webview = p.RootLayout("").WebView("mainWebView");
  // On iOS devices
  // var p = Mobile.Device().Process("SampleWebViewApp");
  // var webview = p.Window(0).WebView(0);

  // Open a page
  var page = webview.ToUrl("http://support.smartbear.com/");
  // Waiting for the object
  do
  {
    aqUtils.Delay(100);
    obj = page.FindChild("contentText", "TestComplete",10);
  }
  while (! obj.Exists)
  // Work with the page
  …
}

Python

def WaitForElement():
  # Select the mobile device
  Mobile.SetCurrent("MyDevice");

  # Run the hybrid application
  TestedApps.WebViewSample.Run();

  # Obtain the WebView object
  # On Android devices
  p = Mobile.Device().Process("smartbear.webview_sample");
  webview = p.RootLayout("").WebView("mainWebView");
  # On iOS devices
  # p = Mobile.Device().Process("SampleWebViewApp");
  # webview = p.Window(0).WebView(0);

  # Open a page
  page = webview.ToUrl("http://support.smartbear.com/");
  # Waiting for the object
  while True:
    aqUtils.Delay(100);
    obj = page.FindChild("contentText", "TestComplete",10);
    if not obj.Exists:
      break;
    # Work with the page

VBScript

Sub WaitForElement()
  Dim p, webview, page
  ' Select the mobile device
  Mobile.SetCurrent("MyDevice")

  ' Obtain the WebView object
  ' On Android devices
  Set p = Mobile.Device.Process("smartbear.webview_sample")
  Set webview = p.RootLayout("").WebView("mainWebView")
  ' On iOS devices
  ' Set p = Mobile.Device.Process("SampleWebViewApp")
  ' Set webview = p.Window(0).WebView(0)

  ' Open a page
  Set page = webview.ToUrl("http://support.smartbear.com/")
  ' Wait for the object
  Do
    aqUtils.Delay 100
    Set obj = page.FindChild("contentText", "TestComplete",10)
  Loop Until obj.Exists
  ' Work with the page
  …
End Sub

DelphiScript

function WaitForElement();
var
  p, webview, page: OleVariant;
begin
  // Select the mobile device
  Mobile.SetCurrent('MyDevice');

  // Run the hybrid application
  TestedApps.WebViewSample.Run;

  // Obtain the WebView object
  // On Android devices
  p := Mobile.Device.Process('smartbear.webview_sample');
  webview := p.RootLayout('').WebView('mainWebView');
  // On iOS devices
  // p := Mobile.Device.Process('SampleWebViewApp');
  // webview := p.Window(0).WebView(0);

  // Open a page
  page := webview.ToUrl('http://support.smartbear.com/');
  // Wait for the object
  repeat
    aqUtils.Delay(100);
    obj := page.FindChild('contentText', 'TestComplete',10);
  until obj.Exists;
  // Work with the page
  …
end;

C++Script, C#Script

function WaitForElement()
{
  // Select the mobile device
  Mobile["SetCurrent"]("MyDevice");

  // Run the hybrid application
  TestedApps["WebViewSample"]["Run"]();

  // Obtain the WebView object
  // On Android devices
  var p = Mobile["Device"]["Process"]("smartbear.webview_sample");
  var webview = p["RootLayout"]("")["WebView"]("mainWebView");
  // On iOS devices
  // var p = Mobile["Device"]["Process"]("SampleWebViewApp");
  // var webview = p["Window"](0)["WebView"](0);

  // Open a page
  var page = webview["ToUrl"]("http://support.smartbear.com/");
  // Waiting for the object
  do
  {
    aqUtils["Delay"](100);
    obj = page["FindChild"]("contentText", "TestComplete",10);
  }
  while (! obj["Exists"])
  // Work with the page
  …
}

Waiting for Web Pages in Keyword Tests

You can 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 Hybrid Mobile Applications - Overview
Common Tasks for Hybrid Mobile Application Testing
Finding Objects on Web Pages in Hybrid Applications

Highlight search results