[Collapse]TestComplete FAQ
 [Collapse]Writing Automated Test Script Code
   How do I call procedures or variables declared in another unit?/support/viewarticle.aspx?aid=8921
   How can I close a modal dialog which was invoked by a method called from a script?/support/viewarticle.aspx?aid=8922
   How can I pass function parameters by reference in JScript (C++Script, C#Script)?/support/viewarticle.aspx?aid=8923
   I can use the same name for two procedures that are in different units. Is this correct?/support/viewarticle.aspx?aid=8924
   I cannot find functions to deal with time. Where should I search for them?/support/viewarticle.aspx?aid=8925
   Is there a way to call routines defined in another project?/support/viewarticle.aspx?aid=8926
 [Expand]Working With Files, Databases and Excel Sheets
 [Expand]Web Testing - Functional Testing of Web Pages
 [Expand]TestComplete Trial Version Questions
 [Expand]Test Log and Results
 [Expand]Supported Applications, Operating Systems and Development Tools
 [Expand]Recording, Running and Debugging Automated Tests
 [Expand]Objects, Files and Images Comparison
 [Expand]Miscellaneous
 [Expand]Load Testing of Web Servers
 [Expand]Licensing Questions
 [Expand]General Questions About Automated Testing
 [Expand]Automated Testing Tasks - Basic
 [Expand]Automated Testing Tasks - Advanced
 [Expand]Accessing Application's Internal Objects, Methods and Properties
Updated: 7/26/2010 Applies To: TestComplete
Rating: No votes
Click to rate:
PoorNot badAverageGoodExcellent
Q.: How can I close a modal dialog which was invoked by a method called from a script?

A.: Generally a script instruction is not executed until the previous instruction is finished. This behavior causes unexpected pauses in test execution since routines that invoke modal dialogs return the resulting value only when the corresponding dialog is closed.

To solve this issue the Runner.CallObjectMethodAsync method was introduced in TestComplete ver. 4.2. It calls the specified object method asynchronously. That is, it does not wait for the method to complete, but proceeds to the next code instruction. Thus the further instructions can simulate the actions needed to close the dialog (typically press OK or Close button). To find out whether the previously called method had finished, the CallObjectMethodAsync returns an especial CallObjectMethodAsyncResult object. See the "Testing Modal Windows" help topic for details.

Below is an example that calls a dialog of an Open application and then closes it via user interface actions.

VBScriptCopy Code

Sub Test
    Dim p, w, ResObject
    ...
    ' Calls the method that displays a modal dialog
    Set ResObject = Runner.CallObjectMethodAsync(p.VCLObject("MainForm")._
                                            VCLObject("ADialog"), "Execute")
    ' Simulates user actions over the dialog and closes it  
    Set w = p.WaitWindow("*", " ADialogCaption ", -1, 1000)
    If w.Exists Then
       w.Window("Button", "*Ok*").ClickButton()
    Else
       Log.Message("The window was not found.")  
    End  If
    ' Waits for method completion
    ResObject.WaitForCompletion(5000)
    ' Processes the result
    If ResObject.Completed Then
       Log.Message("Success, Return Value: " + CStr(ResObject.ReturnValue))
    Else
       Log.Message("Failure, Return Value: " + CStr(ResObject.ReturnValue))
    End  If
    ...
End  Sub

JScriptCopy Code

function Test()
{
     var p, w, ResObject;
      ...
      // Calls the method that displays a modal dialog
      ResObject = Runner.CallObjectMethodAsync(p.VCLObject("MainForm").
                                    VCLObject("ADialog "), "Execute");
     // Simulates user actions over the dialog and closes it
      w = p.WaitWindow("*", " ADialogCaption", -1, 1000);
      if (w.Exists) 
        w.Window("Button", "*Ok*").ClickButton();
      else  
        Log.Message("The window was not found.")  
      // Waits for method completion
      ResObject.WaitForCompletion(5000);
      // Processes the result
      if (ResObject.Completed)
        Log.Message("Success, Return Value: " + ResObject.ReturnValue);
      else
        Log.Message("Failure, Return Value: " + ResObject.ReturnValue);
    ...
}

DelphiScriptCopy Code

procedure Test();
var p, w, ResObject: OleVariant;
begin
  ...
  // Calls the method that displays a modal dialog
  ResObject := Runner.CallObjectMethodAsync(p.VCLObject('MainForm').
                                    VCLObject('ADialog'), 'Execute');
  // Simulates user actions over the dialog and closes it 
  w := p.WaitWindow('*', 'ADialogCaption', -1, 1000); 
  if w.Exists then
      w.Window("Button", '*Ok*').ClickButton()
  else
    Log.Message('The window was not found.'); 
  // Waits for method completion
  ResObject.WaitForCompletion(5000);
  // Processes the result
  if ResObject.Completed then
      Log.Message('Success, Return Value: ' + VarToStr(ResObject.ReturnValue))
  else
      Log.Message('Failure, Return Value: ' + VarToStr(ResObject.ReturnValue));
  ...
end;

C++Script, C#ScriptCopy Code

function Test()
{
      var p, w, ResObject;
      ...
      // Calls the method that displays a modal dialog
      ResObject = Runner["CallObjectMethodAsync"](p["VCLObject"]("MainForm")
                                        ["VCLObject"]("ADialog"), "Execute");
      // Simulates user actions over the dialog and closes it  
      w = p["WaitWindow"]("*", "ADialogCaption", -1, 1000);
      if (w["Exists"]) 
          w["Window"]("Button", "*Ok*")["ClickButton"]();
      else
        Log["Message"]("The window was not found.")   
      // Waits for method completion
      ResObject["WaitForCompletion"](5000);
      // Processes the result
      if (ResObject["Completed"])
          Log["Message"]("Success, Return Value: " + ResObject["ReturnValue"]);
      else
          Log["Message"]("Failure, Return Value: " + ResObject["ReturnValue"]);    
      ...
}

However, it is not recommended to use the Runner.CallObjectMethodAsync method to perform asynchronous calls to methods provided by TestComplete. Some of the built-in methods may operate normally, while the others may cause problems when they are called asynchronously. Therefore certain TestComplete methods cannot be launched via CallObjectMethodAsync. An example of such a method is the BuiltIn.SendMAPIMail routine. It often invokes a security warning dialog displayed by Outlook / Outlook Express which cannot be closed by TestComplete.

The only solution is to close the dialog from another process, namely, via the Windows Script Host. This is a language-independent utility that introduces wide capabilities for automation. The helper script we are interested in should focus the dialog window and perform the actions needed to close the dialog.

Here is the code of a script that closes the Outlook Express security dialog. The code should be placed in a text file named CloseSecurityDialog.vbs

VBScriptCopy Code

WindowCaption = "Outlook Express"
Set WshShell = WScript.CreateObject("WScript.Shell")
' Focus the dialog window
a = WshShell.AppActivate(WindowCaption)  
While Not a
   WScript.Sleep(100)
   a = WshShell.AppActivate(WindowCaption) 
WEnd
WScript.Sleep(600)  
' Simulate the ALT+S keystroke that is an accelerator For the "Send" button
WshShell.SendKeys("%S")

Once the helper Windows Script is created, you can call it from TestComplete right before the instruction that invokes the modal dialog. The following code snippet demonstrates how to do this:

VBScriptCopy Code

Dim  WshShell
  ...
  ' Obtain the OLE object of Windows Script Host 
  Set WshShell = Sys.OleObject("WScript.Shell")
  ' Launch the script at specified path
  WshShell.Run("C:\Work\CloseSecurityDialog.vbs")
  ' Call the routine invoking a modal dialog
  If SendMAPIMail("John Smith", "jsmith@domain.com", "MessageSubject", "MessageBody") Then
      Log.Message("Mail was sent")
  Else
      Log.Warning("Mail was not sent")
  End If
  ...
End  Sub

JScriptCopy Code

function  ModalMessager()
{
  var WshShell;
  ...
  // Obtain the OLE object of Windows Script Host
  WshShell = Sys.OleObject("WScript.Shell");
  // Launch the script at specified path
  WshShell.Run("C:\\Work\\CloseSecurityDialog.vbs");
  // Call the routine invoking a modal dialog
  if (SendMAPIMail("John Smith", "jsmith@domain.com", "MessageSubject", "MessageBody"))
      Log.Message("Mail was sent");
  else
      Log.Warning("Mail was not sent");
  ...
}

DelphiScriptCopy Code

function ModalMessager();
    var  WshShell : OleVariant;
begin
    ...
    // Obtain the OLE object of Windows Script Host
    WshShell := Sys.OleObject('WScript.Shell');
    // Launch the script at specified path
    WshShell.Run('C:\Work\CloseSecurityDialog.vbs');
    // Call the routine invoking a modal dialog
    if (SendMAPIMail('John Smith', 'jsmith@domain.com', 'MessageSubject', 'MessageBody')) then
        Log.Message('Mail was sent.')
    else
        Log.Warning('Mail was not sent.');
    ...
end;

C++Script, C#ScriptCopy Code

function  ModalMessager()
{
    var  WshShell;
    ...
    // Obtain the OLE object of Windows Script Host
    WshShell = Sys["OleObject"]("WScript.Shell");
    // Launch the script at specified path
    WshShell["Run"]("C:\\Work\\CloseSecurityDialog.vbs");
    // Call the routine invoking a modal dialog
    if  (SendMAPIMail("John Smith", "jsmith@domain.com", "MessageSubject", "MessageBody"))
        Log["Message"]("Mail was sent");
    else
        Log["Warning"]("Mail was not sent"); 
    ...
}


© 2010 AutomatedQA Corp.
Email Send feedback on this document
 
© 2010 SmartBear Software. All rights reserved.
Home | Privacy | Terms of Use | About | Contact Us | Site Map | Print