Calling Methods Asynchronously

Applies to TestComplete 15.47, last modified on January 20, 2023

When executing a script, the script engine goes through the script code line by line. The execution of the next statement or method call is only possible after the execution of the previous statement (or method) is completed. That is, if you call a method in your script code the script execution will not continue until the method returns the execution control.

However, in some situations consecutive execution may cause problems. For instance, you may need to simulate user actions over a modal dialog box, which you call with an internal method of the tested Open Application. Typically, these methods only return the execution control after the modal dialog box is closed. So, you will not be able to simulate user actions over the dialog since the script is paused by the method waiting for the dialog to be closed. A similar situation occurs with web pages that display Login dialogs or Information bars. The TestComplete ToUrl method that can be used to open web pages does not return the execution control until the page is loaded and the page is not treated as loaded until the Login dialog or Information bar is closed.

To work around the described problem, you can open a web page or a modal dialog box another way. For instance, you can open the dialog by simulating user actions over the application under test (selecting a menu item or clicking a button on another form). To open a web page, you can simulate typing the page’s URL into the Address bar of your web browser.

An alternative approach is to call the method or property that pauses the script execution asynchronously. This means that after a call to the method (property) the script engine continues executing further script statements and does not wait until this method returns the execution control (or until the get or set methods of the property return).

To call a method or obtain a property’s value asynchronously, you should use the Runner.CallObjectMethodAsync method. It has the following syntax:

Runner.CallObjectMethodAsync(Obj, MethodName, Param1, Param2, Param3, ...)

The method uses the following parameters:

  • Obj specifies the object, whose method you are calling.
  • MethodName specifies the name of the method to be called or the name of the property, whose value is obtained.
  • Param1, Param2, Param3 and others are optional parameters. They specify the value to be passed to the called method as parameters. If you obtain the value of an indexed property, these parameters specify the indexes.

To set a property value asynchronously, use the Runner.SetObjectPropertyAsync method:

Runner.SetObjectPropertyAsync(Obj, PropertyName, Param1, Param2, ..., Value)

The method’s parameters are similar to parameters of the CallObjectMethodAsync method:

  • Obj specifies the object, whose property you set.
  • PropertyName specifies the desired property.
  • Param1, Param2, Param3 and other parameters are used if you set an indexed property. In this case, these parameters specify the indexes.
  • Value specifies the value to be assigned to the property.

Both methods return the CallObjectMethodAsyncResult object with methods and properties that let you:

  • Wait until the asynchronous call is over (the WaitForCompletion method).
  • Determine whether the called method returns the execution control (the Completed property).
  • Obtain the result value of the called method (the ReturnValue property). Note that this property only supports ordinary values (integers, strings, boolean, dates and others) and does not support object references. That is, if the called method returns an object, the ReturnValue property will not hold a reference to this object. It will hold an empty value.

The following code demonstrates the typical use of the CallObjectMethodAsync method:

JavaScript, JScript

...
// The following method calls the ShowModal method asynchronously.
// Obj is a variable that holds a reference to an object of an Open Application.
// This object contains the ShowModal method
CallResultObj = Runner.CallObjectMethodAsync(Obj, "ShowModal", "Caption", "Title", 10, 10);

// Simulate user actions over the modal dialog
// ...

// Wait 10 seconds until the asynchronous call is over
CallResultObj.WaitForCompletion(10000);
 
// Check the results
Res = CallResultObj.ReturnValue;
...

Python

...
# The following method calls the ShowModal method asynchronously.
# Obj is a variable that holds a reference to an object of an Open Application.
# This object contains the ShowModal method
CallResultObj = Runner.CallObjectMethodAsync(Obj, "ShowModal", "Caption", "Title", 10, 10)

# Simulate user actions over the modal dialog
# ...

# Wait 10 seconds until the asynchronous call is over
CallResultObj.WaitForCompletion(10000)
 
# Check the results
Res = CallResultObj.ReturnValue
...

VBScript

...
' The following method calls the ShowModal method asynchronously.
' Obj is a variable that holds a reference to an object of an Open Application.
' This object contains the ShowModal method
Set CallResultObj = Runner.CallObjectMethodAsync(Obj, "ShowModal", "Caption", "Title", 10, 10)
 
' Simulate user actions over the modal dialog
' ...
 
' Wait 10 seconds until the asynchronous call is over
CallResultObj.WaitForCompletion 10000

' Check the results
Res = CallResultObj.ReturnValue
...

DelphiScript

var
  CallResultObj, Res : OleVariant;
begin
  ...
  // The following method calls the ShowModal method asynchronously.
  // Obj is a variable that holds a reference to an object of an Open Application.
  // This object contains the ShowModal method
  CallResultObj := Runner.CallObjectMethodAsync(Obj, 'ShowModal', 'Caption', 'Title', 10, 10);
  
  // Simulate user actions over the modal dialog
  // ...
  
  // Wait 10 seconds until the asynchronous call is over
  CallResultObj.WaitForCompletion(10000);
  
  // Check the results
  Res := CallResultObj.ReturnValue;
...
end;

C++Script, C#Script

...
// The following method calls the ShowModal method asynchronously.
// Obj is a variable that holds a reference to an object of an Open Application.
// This object contains the ShowModal method
CallResultObj = Runner["CallObjectMethodAsync"](Obj, "ShowModal", "Caption", "Title", 10, 10);

// Simulate user actions over the modal dialog
// ...

// Wait 10 seconds until the asynchronous call is over
CallResultObj["WaitForCompletion"](10000);

// Check the results
MethodResult = CallResultObj["ReturnValue"];
...

The following code demonstrates a typical call to the Runner.SetObjectPropertyAsync method. The sample code uses this method to assign a value to the indexed property; MyProperty[index]of the Obj object. In the following code snippet, 1 is the index value and the string My Value is the assigned value:

JavaScript, JScript

...
CallResultObj = Runner.SetObjectPropertyAsync(Obj, "MyProperty", 1, "MyValue");
CallResultObj.WaitForCompletion(1000);
...

Python

...
CallResultObj = Runner.SetObjectPropertyAsync(Obj, "MyProperty", 1, "MyValue")
CallResultObj.WaitForCompletion(1000)
...

VBScript

...
Set CallResultObj = Runner.SetObjectPropertyAsync(Obj, "MyProperty", 1, "MyValue")
Call CallResultObj.WaitForCompletion(1000)
...

DelphiScript

var
  CallResultObj, Res : OleVariant;
begin
  ...
  CallResultObj := Runner.SetObjectPropertyAsync(Obj, 'MyProperty', 1, 'MyValue');
  CallResultObj.WaitForCompletion(1000);
...
end;

C++Script, C#Script

...
CallResultObj = Runner["SetObjectPropertyAsync"](Obj, "MyProperty", 1, "MyValue");
CallResultObj["WaitForCompletion"](1000);
...

Though the described functionality was developed for calling internal methods of Open Applications, you can also use it to call methods provided by TestComplete (that is, methods that TestComplete adds to internal objects of Open Applications, or methods of TestComplete scripting objects). However, there is one specific character: if you call a TestComplete method, you should not use the WaitForCompletion method to pause the script execution until the method returns. To pause the script, use the while statement checking the state of the Completed property, that is --

JavaScript, JScript

...
// Call method asynchronously
CallResultObj = Runner.CallObjectMethodAsync(Obj, "MethodName", "Param1", "Param2");
 
// Perform the desired user actions
// ...
 
// Wait until the asynchronous call is over
while(! CallResultObj.Completed)
  aqUtils.Delay(100)
 
// Check the results
MethodResult = CallResultObj.ReturnValue;
...

Python

...
# Call method asynchronously
CallResultObj = Runner.CallObjectMethodAsync(Obj, "MethodName", "Param1", "Param2")
 
# Perform the desired user actions
# ...
 
# Wait until the asynchronous call is over
while not CallResultObj.Completed:
  aqUtils.Delay(100)
 
# Check the results
MethodResult = CallResultObj.ReturnValue
...

VBScript

...
' Call method asynchronously
Set CallResultObj = Runner.CallObjectMethodAsync(Obj, "MethodName", "Param1", "Param2")
 
' Perform the desired user actions
' ...
 
' Wait until the asynchronous call is over
While Not CallResultObj.Completed
  aqUtils.Delay 100
WEnd
 
' Check the results
MethodResult = CallResultObj.ReturnValue
...

DelphiScript

var
  CallResultObj, MethodResult : OleVariant;
begin
  ...
  // Call method asynchronously
  CallResultObj := Runner.CallObjectMethodAsync(Obj, 'MethodName', 'Param1', 'Param2');
 
  // Perform the desired user actions
  // ...
 
  // Wait until the asynchronous call is over
  while CallResultObj.Completed = False do
    aqUtils.Delay(100);
 
  // Check the results
  MethodResult := CallResultObj.ReturnValue;
  ...
end;

C++Script, C#Script

...
// Call method asynchronously
CallResultObj = Runner["CallObjectMethodAsync"](Obj, "MethodName", "Param1", "Param2");
 
// Perform the desired user actions
// ...
 
// Wait until the asynchronous call is over
while (! CallResultObj["Completed"])
  aqUtils["Delay"](100);
 
// Check the results
MethodResult = CallResultObj["ReturnValue"];
...

See Also

Testing Modal Windows
Diagnosing Application Freezes

Highlight search results