TestComplete 6 FAQ - Testing Tasks - Part 2
This page contains answers to frequently asked questions about TestComplete ver. 4 - 6. For answers to questions on TestComplete 3, see TestComplete 3 FAQ.
Q.: How can I run and close my application via the TestedApp object?
A.: Here is a sample routine in VBScript -
Sub Test
' Launches the first application in
' the tested applications list
Set app = TestedApps.Items(0)
app.Run
' Performing tests
Set p = Sys.Process("MyApplication")
Set w = p.Window("MainFormClass", "MainFormCaption", 1)
w.Window("Button1", "*").Click
Log.Picture w, w.FullName
' Closes the application
app.Close
BuiltIn.Delay 3000 ' Waits until the application is closed
If p.Exists Then app.Terminate
End Sub
Q.: How can I set the Clipboard content from TestComplete?
A.: If you need to place text in the Clipboard, you can
use the Sys.Clipboard property:
[VBScript]
Sys.Clipboard = "My text"'
Also, you can select the desired text or image and simulate the Ctrl-C keystroke, for instance:
Sys.Keys "^C"
To save a picture to the Clipboard, you can either select it
and then simulate the Ctrl-C key press, or you can call the Regions.GetPicture(item).SaveToClipboard
Set w = p.Window("WindowClassName",
"WindowCaption", 1)
Regions.AddPicture(w, "MyAppWnd")
Regions.GetPicture("MyAppWnd").SaveToClipboard
Note: If the TestComplete 3 Compatibility plug-in is installed, use the
Regions.SaveToClipboard method:
Set w = p.Window("WindowClassName",
"WindowCaption", 1)
Regions.SaveToClipboard w
Q.: How can I run a script routine from an external application?
A.: If you want to run the script in TestComplete, you
must connect to TestComplete via COM and then call the RunRoutine or RunRoutineEx methods of the Integration object. The Integration object is available from any Connected Application. The difference between the methods are that RunRoutineEx lets you call routines containing parameters, while RunRoutine can only call script functions that do not use parameters. Both functions do not pause the program execution until the run of the specified script routine is over. To obtain the routine result, use the Integration.RoutineResult property.
Visual Basic Application
Set ProjectSuiteName = "C:\Work\TestComplete Project\MySuite.pjs"
Set ProjectName = "MyProject"
Set UnitName = "Unit1"
Set RoutineName = "SayHello"
' Creates the application object
Set TestCompleteApp = CreateObject("TestComplete.TestCompleteApplication")
' Obtains the integration object
Set IntegrationObject = TestCompleteApp.Integration
' Opens the project suite
IntegrationObject.OpenProjectSuite (ProjectSuiteName)
' Runs the routine
IntegrationObject.RunRoutine (ProjectName, UnitName, RoutineName)
Delphi Application
ProjectSuiteName := 'C:\Work\TestComplete Project\MySuite.pjs';
ProjectName := 'MyProject';
UnitName := 'Unit1';
RoutineName := 'SayHello';
// Creates the application object
TestCompleteApp := CreateOleObject('TestComplete.TestCompleteApplication');
// Obtains the integration object
IntegrationObject := TestCompleteApp.Integration;
// Opens the project suite
IntegrationObject.OpenProjectSuite(ProjectSuiteName);
// Runs the routine
IntegrationObject.RunRoutine(ProjectName, UnitName, RoutineName);
C# Application
// Add the following lines to your unit
using System.Runtime.InteropServices;
using TestComplete;
...
public class Form1 : System.Windows.Forms.Form
{
// Defines functions needed to obtain a reference to TestComplete
[DllImport("Ole32.dll", PreserveSig = false, EntryPoint = "CoCreateInstance")]
[return: MarshalAs(UnmanagedType.IUnknown)]
private static extern object CoCreateInstance([In] ref Guid clsid, [MarshalAs(UnmanagedType.IUnknown)]
Object punkOuter, int context, [In] ref Guid iid);
[DllImport("oleaut32.dll", PreserveSig = false, EntryPoint = "GetActiveObject")]
[return: MarshalAs(UnmanagedType.IUnknown)]
private static extern object GetActiveObject([In] ref Guid clsid, int reserved);
// Defines helper constants
private const int INPROC_SERVER = 1;
private const int LOCAL_SERVER = 4;
private void TestFunc()
{
var ProjectSuiteName, ProjectName, UnitName, RoutineName;
ProjectSuiteName = "C:\\Work\\TestComplete Project\\MySuite.pjs";
ProjectName = "MyProject";
UnitName = "Unit1";
RoutineName = "SayHello"
Guid CLSID_TestComplete = new Guid("6C8DF45D-C28E-4139-9068-B2B8EDC1E66D");
Guid IID_TestComplete = new Guid("148F5A09-EB10-48f9-8229-44D9B6D62007");
object TestCompleteObject = null;
// Obtains access to TestComplete
try
{
TestCompleteObject = GetActiveObject(ref CLSID_TestComplete, 0);
}
catch
{
try
{
TestCompleteObject = CoCreateInstance(ref CLSID_TestComplete, null,
INPROC_SERVER | LOCAL_SERVER, ref IID_TestComplete);
}
catch
{
}
}
if (TestCompleteObject == null) return;
// Obtains ITestCompleteCOMManager
TestComplete.ITestCompleteCOMManager TestCompleteManager =
(TestComplete.ITestCompleteCOMManager) TestCompleteObject;
// Obtains Integration object
TestComplete.ItcIntegration IntegrationObject = TestCompleteManager.Integration;
//Opens the project suite
IntegrationObject.OpenProjectSuite(ProjectSuiteName);
try
{
// Runs the routine
IntegrationObject.RunRoutine(ProjectName, UnitName, RoutineName);
}
catch(System.Runtime.InteropServices.COMException ex)
{
System.Windows.Forms.MessageBox.Show("An exception occurred: " + ex.Message);
}
finally
{
// Closes TestComplete
TestCompleteManager.Quit();
// Releases COM objects
Marshal.ReleaseComObject(IntegrationObject);
Marshal.ReleaseComObject(TestCompleteManager);
Marshal.ReleaseComObject(TestCompleteObject);
}
}
Q.: How do I work with results from an external application? For example, how can I check if the last test was successful?
A.: To check whether the last test run finished successfully, while your application is connected to TestComplete via COM, call the GetLastResultDescription method of the Integration object. This method returns the IntegrationResultDescription object whose properties provide descriptions of the test result. To get the full list of properties see
the “IntegrationResultDescription Object” help topic. Here are some of the most useful properties for this problem:
IsTestCompleted- Specifies whether the test execution was completed (return value: True) or if it was interrupted (return value: False).Status- Provides information on test results: whether the test execution was successful (return value: 0), has warnings (return value: 1) or error messages posted to the log (return value: 2).
Visual Basic Application
Set ProjectSuiteName = "C:\Work\TestComplete Project\MySuite.pjs"
Set ProjectName = "MyProject"
Set UnitName = "Unit1"
Set RoutineName = "SayHello"
' Creates the application object
Set TestCompleteApp = CreateObject("TestComplete.TestCompleteApplication")
' Obtains the integration object
Set IntegrationObject = TestCompleteApp.Integration
' Opens the project suite
IntegrationObject.OpenProjectSuite (ProjectSuiteName)
' Runs the routine
IntegrationObject.RunRoutine (ProjectName, UnitName, RoutineName)
While IntegrationObject.IsRunning
DoEvents
Wend
' Obtains the result
Set LastResult = IntegrationObject.GetLastResultDescription
Select Case LastResult.Status
Case 0: MsgBox "The test run finished successfully."
Case 1: MsgBox "Warning messages were posted to the test log."
Case 2: MsgBox "Error messages were posted to the test log."
End Select
Delphi Application
ProjectSuiteName := 'C:\Work\TestComplete Project\MySuite.pjs';
ProjectName := 'MyProject';
UnitName := 'Unit1';
RoutineName := 'SayHello';
// Creates the application object
TestCompleteApp := CreateOleObject('TestComplete.TestCompleteApplication');
// Obtains the integration object
IntegrationObject := TestCompleteApp.Integration;
// Opens the project suite
IntegrationObject.OpenProjectSuite(ProjectSuiteName);
// Runs the routine
IntegrationObject.RunRoutine(ProjectName, UnitName, RoutineName);
while IntegrationObject.IsRuning do sleep(500);
// Obtains the result
LastResult := IntegrationObject.GetLastResultDescription;
case LastResult.Status of
1: ShowMessage('The test run finished successfully.');
2: ShowMessage('Warning messages were posted to the test log.');
3: ShowMessage('Error messages were posted to the test log.');
end;
C# Application
// Add the following lines to your unit
using System.Runtime.InteropServices;
using TestComplete;
...
public class Form1 : System.Windows.Forms.Form
{
// Defines functions needed to obtain a reference to TestComplete
[DllImport("Ole32.dll", PreserveSig = false, EntryPoint = "CoCreateInstance")]
[return: MarshalAs(UnmanagedType.IUnknown)]
private static extern object CoCreateInstance([In] ref Guid clsid, [MarshalAs(UnmanagedType.IUnknown)]
Object punkOuter, int context, [In] ref Guid iid);
[DllImport("oleaut32.dll", PreserveSig = false, EntryPoint = "GetActiveObject")]
[return: MarshalAs(UnmanagedType.IUnknown)]
private static extern object GetActiveObject([In] ref Guid clsid, int reserved);
// Defines helper constants
private const int INPROC_SERVER = 1;
private const int LOCAL_SERVER = 4;
private void TestFunc()
{
var ProjectSuiteName, ProjectName, UnitName, RoutineName;
ProjectSuiteName = "C:\\Work\\TestComplete Project\\MySuite.pjs";
ProjectName = "MyProject";
UnitName = "Unit1";
RoutineName = "SayHello"
Guid CLSID_TestComplete = new Guid("6C8DF45D-C28E-4139-9068-B2B8EDC1E66D");
Guid IID_TestComplete = new Guid("148F5A09-EB10-48f9-8229-44D9B6D62007");
object TestCompleteObject = null;
// Obtains access to TestComplete
try
{
TestCompleteObject = GetActiveObject(ref CLSID_TestComplete, 0);
}
catch
{
try
{
TestCompleteObject = CoCreateInstance(ref CLSID_TestComplete, null,
INPROC_SERVER | LOCAL_SERVER, ref IID_TestComplete);
}
catch
{
}
}
if (TestCompleteObject == null) return;
// Obtains ITestCompleteCOMManager
TestComplete.ITestCompleteCOMManager TestCompleteManager =
(TestComplete.ITestCompleteCOMManager) TestCompleteObject;
// Obtains Integration object
TestComplete.ItcIntegration IntegrationObject = TestCompleteManager.Integration;
// Opens the project suite
IntegrationObject.OpenProjectSuite(ProjectSuiteName);
try
{
// Runs the routine
IntegrationObject.RunRoutine(ProjectName, UnitName, RoutineName);
while (IntegrationObject.IsRunning())
Application.DoEvents();
// Obtains the result
switch(IntegrationObject.GetLastResultDescription().Status)
{
case TestComplete.TC_LOG_STATUS.lsOk :
System.Windows.Forms.MessageBox.Show("The test run finished successfully.");
break;
case TestComplete.TC_LOG_STATUS.lsWarning :
System.Windows.Forms.MessageBox.Show("Warning messages were posted to the test log.");
break;
case TestComplete.TC_LOG_STATUS.lsError :
System.Windows.Forms.MessageBox.Show("Error messages were posted to the test log.");
break;
}
}
catch(System.Runtime.InteropServices.COMException ex)
{
System.Windows.Forms.MessageBox.Show("An exception occurred: " + ex.Message);
}
finally
{
// Closes TestComplete
TestCompleteManager.Quit();
// Releases COM objects
Marshal.ReleaseComObject(IntegrationObject);
Marshal.ReleaseComObject(TestCompleteManager);
Marshal.ReleaseComObject(TestCompleteObject);
}
}
Q.: How do I create a script that will simulate the uninstall of my tested application?
A.: Typically, applications are uninstalled through the Add/Remove Programs window. However, it is difficult to create a stable script for this window.
If you just want to uninstall software without testing the installer
GUI, you can using the Win32_Product WMI object. This object only works with products
installed by the Windows Installer. For more information on this object, please refer to MSDN:
The following script demonstrates how you can use the object in your script. Please note that applications are removed silently when this approach is used.
[VBScript]
Sub Main
PostInstalledAppsInfo
UninstallApplication "NUnit-Net-2.0 2.2.7"
End Sub
' Posts information on installed applications to the test log
Sub PostInstalledAppsInfo
Dim WMIService, ObjectsList, CurrentObject
Set WMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set ObjectsList = WMIService.ExecQuery("Select * From Win32_Product")
Log.AppendFolder("Installed Applications")
For Each CurrentObject In ObjectsList
Log.AppendFolder(CurrentObject.Caption)
Log.Message "Vendor: " & CurrentObject.Vendor
Log.Message "Version: " & CurrentObject.Version
Log.Message "Description: " & CurrentObject.Description
Log.Message "Location: " & CurrentObject.InstallLocation
Log.PopLogFolder
Next
Log.PopLogFolder
End Sub
' Uninstalls the specified application
Sub UninstallApplication (AppName)
Dim WMIService, ObjectsList, CurrentObject
Set WMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set ObjectsList = WMIService.ExecQuery("Select * From Win32_Product Where Caption=""" & AppName & """")
If ObjectsList.Count > 0 Then
For Each CurrentObject In ObjectsList
CurrentObject.Uninstall
Log.Message "The '" & AppName & "' program is uninstalled."
Next
Else
Log.Error "The '" & AppName & "' program is not found."
End If
End Sub
[JScript]
function Main()
{
PostInstalledAppsInfo();
UninstallApplication("NUnit-Net-2.0 2.2.7");
}
// Posts information on installed applications to the test log
function PostInstalledAppsInfo()
{
var WMIService, ObjectsList, ObjectsEnum, CurrentObject;
Log.AppendFolder("Installed Applications");
WMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!//./root/cimv2");
ObjectsList = WMIService.ExecQuery("Select * From Win32_Product");
ObjectsEnum = new Enumerator (ObjectsList);
for ( ; !ObjectsEnum.atEnd(); ObjectsEnum.moveNext())
{
CurrentObject = ObjectsEnum.item();
Log.AppendFolder(CurrentObject.Caption);
Log.Message ("Vendor: " + CurrentObject.Vendor);
Log.Message ("Version: " + CurrentObject.Version);
Log.Message ("Description: " + CurrentObject.Description);
Log.Message ("Location: " + CurrentObject.InstallLocation);
Log.PopLogFolder();
}
Log.PopLogFolder();
}
// Uninstalls the specified application
function UninstallApplication (AppName)
{
var WMIService, ObjectsList, ObjectsEnum, CurrentObject;
WMIService = GetObject("winmgmts://./root/cimv2");
ObjectsList = WMIService.ExecQuery("Select * From Win32_Product Where Caption=\"" + AppName + "\"")
if (ObjectsList.Count > 0)
{
ObjectsEnum = new Enumerator (ObjectsList);
for ( ; !ObjectsEnum.atEnd(); ObjectsEnum.moveNext())
{
CurrentObject = ObjectsEnum.item();
CurrentObject.Uninstall();
Log.Message ("The '" + AppName + "' program is uninstalled.");
}
}
else
Log.Error ("The '" + AppName + "' program is not found.");
}
[DelphiScript]
A DelphiScript example is not available, because DelphiScript does not have built-in support for enumertions.
[C++Script, C#Script]
function Main()
{
PostInstalledAppsInfo();
UninstallApplication("NUnit-Net-2.0 2.2.7");
}
// Posts information on installed applications to the test log
function PostInstalledAppsInfo()
{
var WMIService, ObjectsList, ObjectsEnum, CurrentObject;
Log["AppendFolder"]("Installed Applications");
WMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!//./root/cimv2");
ObjectsList = WMIService["ExecQuery"]("Select * From Win32_Product");
ObjectsEnum = new Enumerator (ObjectsList);
for ( ; !ObjectsEnum["atEnd"](); ObjectsEnum["moveNext"]())
{
CurrentObject = ObjectsEnum["item"]();
Log["AppendFolder"](CurrentObject["Caption"]);
Log["Message"]("Vendor: " + CurrentObject["Vendor"]);
Log["Message"]("Version: " + CurrentObject["Version"]);
Log["Message"]("Description: " + CurrentObject["Description"]);
Log["Message"]("Location: " + CurrentObject["InstallLocation"]);
Log["PopLogFolder"]();
}
Log["PopLogFolder"]();
}
// Uninstalls the specified application
function UninstallApplication (AppName)
{
var WMIService, ObjectsList, ObjectsEnum, CurrentObject;
WMIService = GetObject("winmgmts://./root/cimv2");
ObjectsList = WMIService["ExecQuery"]("Select * From Win32_Product Where Caption=\"" + AppName + "\"")
if (ObjectsList["Count"] > 0)
{
ObjectsEnum = new Enumerator (ObjectsList);
for ( ; !ObjectsEnum["atEnd"](); ObjectsEnum["moveNext"]())
{
CurrentObject = ObjectsEnum["item"]();
CurrentObject["Uninstall"]();
Log["Message"]("The '" + AppName + "' program is uninstalled.");
}
}
else
Log["Error"]("The '" + AppName + "' program is not found.");
}
The other way to uninstall an application is by reading the UninstallString value from the Windows Registry. The UninstallString value contains a command line string that is run to launch the uninstallation program for an application. Once you get the UninstallString data, you will be able to execute the command line via a TestComplete script.
You need to find the registry key that corresponds to your tested application. To do this, run the Registry Editor (regedit) and explore the keys under the following node:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
As soon as you know the key name, you can read the data from the UninstallString entry. To learn how you can work with the registry from TestComplete script, see the “Storages.Registry” help topic in TestComplete.
To execute the command line string from a TestComplete script, you can use the following code:
[VBScript]
Dim WshShell
Set WshShell = Sys.OleObject("WScript.Shell")
Call WshShell.Exec ("Your_command_line")
[JScript]
var WshShell = Sys.OleObject("WScript.Shell");
WshShell.Exec ("Your_command_line");
[JScript]
var WshShell : OleVariant;
...
WshShell := Sys.OleObject('WScript.Shell');
WshShell.Exec ('Your_command_line');
[C++Script, C#Script]
var WshShell = Sys["OleObject"]("WScript.Shell");
WshShell["Exec"]("Your_command_line");
Q.: How can I measure the time passed between events?
A.: There are several ways to measure time intervals:
- Use the
StopWatchobject provided by the HISUtils plug-in (this plug-in is available in TestComplete 5 and later). - Use the
Win32API.GetTickCountfunction. - Use the
Utilities.Nowfunction.
Below are examples that demonstrate these approaches:
[VBScript]
Sub CheckTime1
Dim StopWatchObj
Set StopWatchObj = HISUtils.StopWatch
StopWatchObj.Start
Call BuiltIn.Delay (1500)
StopWatchObj.Stop
Call Log.Message (StopWatchObj.ToString)
End Sub
SubCheckTime2
t1 = Win32API.GetTickCount
Call BuiltIn.Delay (1500)
t2 = Win32API.GetTickCount
Call Log.Message( (t2 - t1)/1000 & " sec")
End Sub
Sub CheckTime3
t1 = Utilities.Now
Call BuiltIn.Delay(1500)
t2 = Utilities.Now
Call Log.Message(Utilities.FormatDateTime("nn:ss:zzz", t2-t1))
End Sub
[JScript]
function Test()
{
var StopWatchObj = HISUtils.StopWatch;
StopWatchObj.Start();
BuiltIn.Delay(1500);
StopWatchObj.Stop();
Log.Message(StopWatchObj.ToString());
}
function CheckTime2()
{
var t1 = Win32API.GetTickCount();
BuiltIn.Delay(1500);
var t2 = Win32API.GetTickCount();
Log.Message( (t2 - t1)/1000 + " sec");
}
function CheckTime3()
{
var t1 = Utilities.Now();
BuiltIn.Delay(1500);
var t2 = Utilities.Now();
Log.Message(Utilities.FormatDateTime("nn:ss:zzz", t2-t1));
}
[DelphiScript]
procedure CheckTime1;
var StopWatchObj : OleVariant;
begin
StopWatchObj := HISUtils.StopWatch;
StopWatchObj.Start;
BuiltIn.Delay(1500);
StopWatchObj.Stop;
Log.Message(StopWatchObj.ToString);
end;
procedure CheckTime2;
var t1, t2: OleVariant;
begin
t1 := Win32API.GetTickCount;
BuiltIn.Delay(1500);
t2 := Win32API.GetTickCount;
Log.Message(VarToStr((t2 - t1)/1000) + ' sec');
end;
procedure CheckTime3;
var t1, t2: OleVariant;
begin
t1 := Utilities.Now;
BuiltIn.Delay(1500);
t2 := Utilities.Now;
Log.Message(Utilities.FormatDateTime('nn:ss:zzz', t2-t1));
end;
[C++Script, C#Script]
function Test()
{
var StopWatchObj = HISUtils["StopWatch"];
StopWatchObj["Start"]();
BuiltIn["Delay"](1500);
StopWatchObj["Stop"]();
Log["Message"](StopWatchObj["ToString"]());
}
function CheckTime2()
{
var t1 = Win32API["GetTickCount"]();
BuiltIn["Delay"](1500);
var t2 = Win32API["GetTickCount"]();
Log["Message"]( (t2 - t1)/1000 + " sec");
}
function CheckTime3()
{
var t1 = Utilities["Now"]();
BuiltIn["Delay"](1500);
var t2 = Utilities["Now"]();
Log["Message"](Utilities["FormatDateTime"]("nn:ss:zzz", t2-t1));
}
Q.: How do I minimize TestComplete after running a script?
A.: There is a special option that allows you to minimize TestComplete when you run a script. To reach it, double-click the project in the Project Explorer panel. TestComplete will display the project editor in the Workspace panel. Click Properties at the bottom of the project editor and then choose Playback in the list on the left of the page. In the Runtime options group verify the Minimize TestComplete checkbox.
Q.: How do I create a COM object via scripts?
A.: Use the Sys.OleObject property and pass the name of the desired OLE object to it. If you use VBScript, JScript, C++Script or C#Script, you can also create COM objects using “native” functions of these languages: In VBScript, you can use the CreateObject and GetObject functions; in JScript
use the new ActiveXObject(…) statement. C++Script and C#Script are based on JScript, so you can use the JScript functions in these languages as well.
Below is an example that creates a new Microsoft Word document via COM:
[VBScript]
Sub Main
Set ComObjWrd = Sys.OleObject("Word.Application") ' Creates MS Word
' You can also create MS Word in the following way --
' Set ComWordObj = CreateObject("Word.Application")
ComObjWrd.Visible = True
ComObjWrd.Documents.Add ' Creates a new document
...
End Sub
[JScript]
function Main()
{
var ComObjWrd = Sys.OleObject("Word.Application"); // Creates MS Word
// You can also create MS Word in the following way --
// var ComWordObj = new ActiveXObject("Word.Application")
ComObjWrd.Visible = true;
ComObjWrd.Documents.Add(); // Creates a new document
...
}
[DelphiScript] procedure Main; var ComObjWrd : OleVariant; begin ComObjWrd := Sys.OleObject['Word.Application']; // Creates MS Word ComObjWrd.Visible := true; ComObjWrd.Documents.Add; // Creates a new document ... end;
[C++Script, C#Script]
function Main()
{
var ComObjWrd = Sys["OleObject"]("Word.Application"); // Creates MS Word
// You can also create MS Word in the following way --
// var ComWordObj = new ActiveXObject("Word.Application")
ComObjWrd["Visible"] = true;
ComObjWrd["Documents"]["Add"](); // Creates a new document
...
}
Note: If the TestComplete 3 Compatibility plug-in is installed, TestComplete emulates functionality of the earlier versions of the product. In this case use
the Sys.GetOleObject method instead of Sys.OleObject.
Q.: How can I read REG_MULTI_SZ values from the Registry?
A.: You can use the WScript.Shell object or the StdRegProv WMI class. Using the WMI class you can read and write values to the Registry, however, it only works in VBScript. You can find more information on these object and class on MSDN:
WScript.Shell: http://msdn.microsoft.com/library/en-us/script56/html/7b956233-c1aa-4b59-b36d-f3e97a9b02f0.asp
StdRegProv WMI class:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/stdregprov.asp
The following code demonstrates the use of the WScript.Shell object:
[VBScript]
Sub ReadMString
Dim WSObj, vals
Set WSObj = Sys.OleObject("WScript.Shell")
vals = WSObj.RegRead("HKEY_CURRENT_USER\Software\Automated QA\TestValue")
For i = 0 To UBound(vals)
Call Log.Message(vals(i))
Next
End Sub
[JScript]
function ReadMString()
{
var WSObj = Sys.OleObject("WScript.Shell");
var value = WSObj.RegRead("HKEY_CURRENT_USER\\Software\\Automated QA\\TestValue");
var vals = VBArray(value).toArray();
for (i = 0; i < vals.length; i++)
Log.Message(vals[i]);
}
[DelphiScript]
procedure ReadMString;
var WSObj, value, i : OleVariant;
begin
WSObj := Sys.OleObject['WScript.Shell'];
value := WSObj.RegRead('HKEY_CURRENT_USER\Software\Automated QA\TestValue');
for i := 0 to BuiltIn.VarArrayHighBound(value, 1) do
Log.Message(value[i]);
end;
[JScript]
function ReadMString()
{
var WSObj = Sys.OleObject("WScript.Shell");
var value = WSObj["RegRead"]("HKEY_CURRENT_USER\\Software\\Automated QA\\TestValue");
var vals = VBArray(value)["toArray"]();
for (i = 0; i < vals["length"]; i++)
Log["Message"](vals[i]);
}
The following code demonstrates the usage of the WMI StdRegProv class:
[VBScript]
Sub Main
Dim strKeyPath, strValName, MultiStrVal
strKeyPath = "Software\Automated QA"
strValName = "TestValue"
MultiStrVal = GetMultiStringValue(HKEY_CURRENT_USER, strKeyPath, strValName)
If IsNull(MultiStrVal) Then
Log.Error("Value not found")
Else
Log.AppendFolder("Before")
For i = 0 To UBound(MultiStrVal)
Log.Message MultiStrVal(i)
Next
Log.PopLogFolder
End If
NewVal = Array("Test1", "Test2")
Call SetMultiStringValue(HKEY_CURRENT_USER, strKeyPath, strValName, NewVal)
MultiStrVal = GetMultiStringValue(HKEY_CURRENT_USER, strKeyPath, strValName)
If IsNull(MultiStrVal) Then
Log.Error("Value not found")
Else
Log.AppendFolder("After")
For i = 0 To UBound(MultiStrVal)
Log.Message MultiStrVal(i)
Next
Log.PopLogFolder
End If
End Sub
Function GetMultiStringValue(RootPath, strKeyPath, strValName)
Dim Value, oReg
Set oReg=GetObject("winmgmts:\\.\root\default:StdRegProv")
Call oReg.GetMultiStringValue(RootPath, strKeyPath, strValName, Value)
GetMultiStringValue = Value
End Function
Function SetMultiStringValue(RootPath, strKeyPath, strValName, arrValue)
Dim oReg
Set oReg=GetObject("winmgmts:\\.\root\default:StdRegProv")
Call oReg.SetMultiStringValue(RootPath, strKeyPath, strValName, arrValue)
End Function
A.: To time the execution of script code, you need to set and compare two time stamps: before the desired statements execute and right after the execution is over. To get the time stamps you can use the StopWatch object that is provided by the HISUtils plug-in (the plug-in is available in TestComplete 5 and later), the Win32 API GetTickCount function, or the Unilities.Now function.
The following code snippet demonstrates the usage of the StopWatch object.
[VBScript]
Sub GetTest1Time
Dim StopWatchObj
Set StopWatchObj = HISUtils.StopWatch
StopWatchObj.Start
' Do something
...
StopWatchObj.Stop
Log.Message("The execution time is: " & StopWatchObj.ToString)
End Sub
[JScript]
function GetTest1Time()
{
var StopWatchObj = HISUtils.StopWatch;
StopWatchObj.Start();
// Do something
...
StopWatchObj.Stop();
Log.Message("The execution time is: " + StopWatchObj.ToString());
}
[DelphiScript]
procedure GetTest1Time;
var StopWatchObj : OleVariant;
begin
StopWatchObj := HISUtils.StopWatch;
StopWatchObj.Start;
// Do something
...
StopWatchObj.Stop;
Log.Message('The execution time is: ' + StopWatchObj.ToString);
end;
[C++Script, C#Script]
function GetTest1Time()
{
var StopWatchObj = HISUtils["StopWatch"];
StopWatchObj["Start"]();
// Do something
...
StopWatchObj["Stop"]();
Log["Message"]("The execution time is: " + StopWatchObj["ToString"]());
}
Below is an example that uses the Win32API.GetTickCount function:
[VBScript]
Sub GetTest2Time()
Dim startTime, endTime
startTime = Win32API.GetTickCount
' Do something
...
endTime = Win32API.GetTickCount
Call Log.Message("The execution time is: " & (endTime - startTime)/1000 & " sec")
End Sub
[JScript]
function GetTest2Time()
{
var startTime = Win32API.GetTickCount();
// Do something
...
var endTime = Win32API.GetTickCount();
Log.Message("The execution time is: " + (endTime - startTime)/1000 + " seconds");
}
[DelphiScript]
procedure GetTest2Time();
var startTime, endTime : OleVariant;
begin
startTime := Win32API.GetTickCount();
// Do something
...
endTime := Win32API.GetTickCount();
Log.Message('The execution time is ' + VarToStr( (endTime - startTime)/1000 ) + ' seconds');
end;
[C++Script, C#Script]
function GetTest2Time()
{
var startTime = Win32API["GetTickCount"]();
// Do something
...
var endTime = Win32API["GetTickCount"]();
Log["Message"]("The execution time is: " + (endTime - startTime)/1000 + " seconds");
}
Here is the Utilities.Now function usage example:
[VBScript]
Sub GetTest3Time()
Dim startTime, endTime
startTime = Utilities.Now
' Do something
...
endTime = Utilities.Now
Call Log.Message("The execution time is: " & Utilities.FormatDateTime("nn:ss:zzz", endTime-startTime))
End Sub
[JScript]
function GetTest3Time()
{
var startTime = Utilities.Now();
// Do something
...
var endTime = Utilities.Now();
Log.Message("The execution time is: " + Utilities.FormatDateTime("nn:ss:zzz", endTime-startTime));
}
[DelphiScript]
procedure GetTest3Time();
var startTime, endTime : OleVariant;
begin
startTime := Utilities.Now();
// Do something
...
endTime := Utilities.Now();
Log.Message('The execution time is ' + Utilities.FormatDateTime('nn:ss:zzz', endTime-startTime));
end;
[C++Script, C#Script]
function GetTest3Time()
{
var startTime = Utilities["Now"]();
// Do something
...
var endTime = Utilities["Now"]();
Log["Message"]("The execution time is: " + Utilities["FormatDateTime"]("nn:ss:zzz", endTime-startTime));
}
Q.: How can I obtain the name of the user account that TestComplete is running under?
A.: Use the Sys.UserName property.
Q.: How do I know the domain that the current user is in?
A.: The Sys.UserName property returns the name of the current user. To determine the domain groups to which the user belongs, you can use the ADSystemInfo object. For more information on this object, please refer to MSDN:
[VBScript]
Sub Main
Dim objADSysInfo, strUser, objUser, ObjGroup, Obj
Set objADSysInfo = CreateObject("ADSystemInfo")
Call Log.AppendFolder("Current User Info")
strUser = objADSysInfo.UserName
Call OutputDelimitedString(strUser)
Log.PopLogFolder
Set objUser = GetObject("LDAP://" & strUser)
Call Log.AppendFolder("Member Of")
ObjGroup = objUser.memberOf
If BuiltIn.VarType(ObjGroup) = varOleStr Then
Call OutputDelimitedString(ObjGroup)
Else
For Each Obj In ObjGroup
Call Log.AppendFolder("Group")
Call OutputDelimitedString(Obj)
Log.PopLogFolder
Next
End If
Log.PopLogFolder
End Sub
Function OutputDelimitedString(strOut)
Dim ArrayOfItems, i
ArrayOfItems = Split(strOut, ",")
For i = 0 To UBound(ArrayOfItems)
Call Log.Message (ArrayOfItems(i))
Next
End Function
[JScript]
function Main()
{
var objADSysInfo, strUser, objUser, ObjGroup, i, Obj;
objADSysInfo = new ActiveXObject("ADSystemInfo");
Log.AppendFolder("Current User Info");
strUser = objADSysInfo.UserName;
OutputDelimitedString(strUser);
Log.PopLogFolder();
objUser = GetObject("LDAP://" + strUser);
Log.AppendFolder("Member Of");
ObjGroup = objUser.memberOf;
if (BuiltIn.VarType(ObjGroup) == varOleStr)
OutputDelimitedString(ObjGroup);
else
{
ObjGroup = ObjGroup.toArray();
for (i = 0; i < ObjGroup.length; i++)
{
Obj = ObjGroup[i];
Log.AppendFolder("Group");
OutputDelimitedString(Obj);
Log.PopLogFolder();
}
}
Log.PopLogFolder();
}
function OutputDelimitedString(strOut)
{
var ArrayOfItems = strOut.split("",")
for (var i = 0; i < ArrayOfItems.length; i++)
Log.Message(ArrayOfItems[i]);
}
[DelphiScript] A DelphiScript example is not available.
[C++Script, C#Script]
function Main()
{
var objADSysInfo, strUser, objUser, ObjGroup, i, Obj;
objADSysInfo = new ActiveXObject("ADSystemInfo");
Log["AppendFolder"]("Current User Info");
strUser = objADSysInfo["UserName"];
OutputDelimitedString(strUser);
Log["PopLogFolder"]();
objUser = GetObject("LDAP://" + strUser);
Log["AppendFolder"]("Member Of");
ObjGroup = objUser["memberOf"];
if (BuiltIn["VarType"](ObjGroup) == varOleStr)
OutputDelimitedString(ObjGroup);
else
{
ObjGroup = ObjGroup["toArray"]();
for (i = 0; i < ObjGroup["length"]; i++)
{
Obj = ObjGroup[i];
Log["AppendFolder"]("Group");
OutputDelimitedString(Obj);
Log["PopLogFolder"]();
}
}
Log["PopLogFolder"]();
}
function OutputDelimitedString(strOut)
{
var ArrayOfItems = strOut["split"](",")
for (var i = 0; i < ArrayOfItems["length"]; i++)
Log["Message"](ArrayOfItems[i]);
}
Q.: How do I know the operating system’s language?
A.: You can obtain the language by using the Microsoft WMI Win32_OperatingSystem class. For more information on this class, see:
[VBScript]
Sub Main
Dim strComputer, objWMIService, colOperatingSystemsList, colOperatingSystems, objOperatingSystem
strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colOperatingSystems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
For Each objOperatingSystem In colOperatingSystems
Call Log.Message ("OS: " & objOperatingSystem.Name)
Call Log.Message ("OS Language: " & objOperatingSystem.OSLanguage)
Next
End Sub
[JScript]
function Main ()
{
var strComputer, objWMIService, colOperatingSystemsList, colOperatingSystems, objOperatingSystem;
strComputer = ".";
objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!//" + strComputer + "/root/cimv2");
colOperatingSystemsList = objWMIService.ExecQuery("Select * from Win32_OperatingSystem");
colOperatingSystems = new Enumerator(colOperatingSystemsList);
for ( ; !colOperatingSystems.atEnd(); colOperatingSystems.moveNext() )
{
objOperatingSystem = colOperatingSystems.item();
Log.Message("OS: " + objOperatingSystem.Name);
Log.Message("OS Language: " + objOperatingSystem.OSLanguage);
}
}
[DelphiScript] A DelphiScript sample is not available, because DelphiScript does not have built-in support for enumerations.
[C++Script, C#Script]
function Main ()
{
var strComputer, objWMIService, colOperatingSystemsList, colOperatingSystems, objOperatingSystem;
strComputer = ".";
objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!//" + strComputer + "/root/cimv2");
colOperatingSystemsList = objWMIService["ExecQuery"]("Select * from Win32_OperatingSystem");
colOperatingSystems = new Enumerator(colOperatingSystemsList);
for ( ; !colOperatingSystems["atEnd"](); colOperatingSystems["moveNext"]() )
{
objOperatingSystem = colOperatingSystems["item"]();
Log["Message"]("OS: " + objOperatingSystem["Name"]);
Log["Message"]("OS Language: " + objOperatingSystem["OSLanguage"]);
}
}
Q.: How do I check if the file that is associated with a shortcut exists?
A.: Below is a sample script that demonstrates this:
[VBScript]
Sub Main
Dim WshShell, strDesktop, fileName, oShellLink
Set WshShell = CreateObject("WScript.Shell")
strDesktop = WshShell.SpecialFolders("Desktop")
fileName = strDesktop & "\My Application.lnk"
If Utilities.FileExists(fileName) Then
Set oShellLink = WshShell.CreateShortcut(fileName)
If Utilities.FileExists(oShellLink.TargetPath) Then
Call Log.Message ("The target file exists (" & oShellLink.TargetPath & ").")
Else
Call Log.Error ("The target file does not exist (" & oShellLink.TargetPath & ").")
End If
Else
Call Log.Error ("The specified LNK file does not exist.")
End If
End Sub
[JScript]
function Main()
{
var WshShell, strDesktop, fileName, oShellLink;
WshShell = new ActiveXObject("WScript.Shell");
strDesktop = WshShell.SpecialFolders("Desktop");
fileName = strDesktop + "\\GridMainDemo.lnk";
if (Utilities.FileExists(fileName))
{
oShellLink = WshShell.CreateShortcut(fileName);
if (Utilities.FileExists(oShellLink.TargetPath))
Log.Message("The target file exists (" + oShellLink.TargetPath + ").");
else
Log.Error("The target file does not exist (" + oShellLink.TargetPath + ").");
}
else
Log.Error("The specified LNK file does not exist.");
}
[DelphiScript]
procedure Main;
var
WshShell, strDesktop, fileName, oShellLink : OleVariant;
begin
WshShell := Sys.OleObject['WScript.Shell'];
strDesktop := WshShell.SpecialFolders('Desktop');
fileName := strDesktop + '\\My Application.lnk';
if Utilities.FileExists(fileName) then
begin
oShellLink := WshShell.CreateShortcut(fileName);
if Utilities.FileExists(oShellLink.TargetPath) then
Log.Message('The target file exists (' + oShellLink.TargetPath + ').')
else
Log.Error('The target file does not exist (' + oShellLink.TargetPath + ').');
end
else
Log.Error('The specified LNK file does not exist.');
end;
[C++Script, C#Script]
function Main()
{
var WshShell, strDesktop, fileName, oShellLink;
WshShell = new ActiveXObject("WScript.Shell");
strDesktop = WshShell["SpecialFolders"]("Desktop");
fileName = strDesktop + "\\GridMainDemo.lnk";
if (Utilities["FileExists"](fileName))
{
oShellLink = WshShell["CreateShortcut"](fileName);
if (Utilities["FileExists"](oShellLink["TargetPath"]))
Log["Message"]("The target file exists (" + oShellLink["TargetPath"] + ").");
else
Log["Error"]("The target file does not exist (" + oShellLink["TargetPath"] + ").");
}
else
Log["Error"]("The specified LNK file does not exist.");
}
Q.: How do I obtain the text from the console application’s window?
A.: TestComplete does not include special methods to obtain text from console application’s windows. As
a workaround, you can copy the console contents to the clipboard and then obtain it using the Sys.Clipboard property:
[VBScript]
Function GetTextFromConsole()
' Obtain the process and window of the console application
Set Proc = Sys.Process("cmd")
Set Wnd = Proc.Window("ConsoleWindowClass", "*")
' Simulate the keystrokes: Alt+Space, E, S, Enter
' (Call system menu, select Edit | Select All,
' press Enter to copy the selected text to the clipboard)
Wnd.Keys("~ ES[Enter]")
' Return the result
GetTextFromConsole = Sys.Clipboard
End Function
[JScript]
function GetTextFromConsole()
{
var Proc, Wnd;
// Obtain the process and window of the console application
Proc = Sys.Process("cmd");
Wnd = Proc.Window("ConsoleWindowClass", "*");
// Simulate the keystrokes: Alt+Space, E, S, Enter
// (Call system menu, select Edit | Select All,
// press Enter to copy the selected text to the clipboard)
Wnd.Keys("~ ES[Enter]");
// Return the result
return Sys.Clipboard
}
[DelphiScript]
function GetTextFromConsole();
var
Proc, Wnd : OleVariant;
begin
// Obtain the process and window of the console application
Proc := Sys.Process('cmd');
Wnd := Proc.Window('ConsoleWindowClass', '*');
// Simulate the keystrokes: Alt+Space, E, S, Enter
// (Call system menu, select Edit | Select All,
// press Enter to copy the selected text to the clipboard)
Wnd.Keys('~ ES[Enter]');
// Return the result
Result := Sys.Clipboard;
end;
[C++Script, C#Script]
function GetTextFromConsole()
{
var Proc, Wnd;
// Obtain the process and window of the console application
Proc = Sys["Process"]("cmd");
Wnd = Proc["Window"]("ConsoleWindowClass", "*");
// Simulate the keystrokes: Alt+Space, E, S, Enter
// (Call system menu, select Edit | Select All,
// press Enter to copy the selected text to the clipboard)
Wnd["Keys"]("~ ES[Enter]");
// Return the result
return Sys["Clipboard"];
}
One more variant is to launch the application and to use methods of the WScript.Shell object to read data from the standard output stream:
[VBScript]
Sub Test
' The name of the application to be run
CommandLine = "c:\My File.bat"
' Create the WScript.Shell object and launch the application
Set WshShell = CreateObject("WScript.Shell")
Set oExec = WshShell.Exec(CommandLine)
' Parse the standard output
txt = ""
Do While Not oExec.StdOut.AtEndOfStream
txt = txt + oExec.StdOut.Read(1)
If InStr(txt, "Press any key") <> 0 Then Exit Do
Loop
' Post the result to the test log
Log.Message txt
End Sub
[JScript]
function Test()
{
var CommandLine, WshShell, oExec, txt;
// The name of the application to be run
CommandLine = "c:\\MyFile.bat";
// Create the WScript.Shell object and launch the application
WshShell = new ActiveXObject("WScript.Shell");
oExec = WshShell.Exec(CommandLine);
// Parse the standard output
txt = "";
while(! oExec.StdOut.AtEndOfStream)
{
txt = txt + oExec.StdOut.Read(1);
if (txt.indexOf("Press any key") >= 0)
break;
}
// Post the result to the test log
Log.Message(txt);
}
[DelphiScript]
procedure Test;
var
CommandLine, WshShell, oExec, txt : OleVariant;
begin
// The name of the application to be run
CommandLine := 'c:\MyFile.bat';
// Create the WScript.Shell object and launch the application
WshShell := Sys.OleObject['WScript.Shell'];
oExec := WshShell.Exec(CommandLine);
// Parse the standard output
txt := '';
while not oExec.StdOut.AtEndOfStream do
begin
txt := txt + oExec.StdOut.Read(1);
if Pos('Press any key', txt) > 0 then
Break;
end;
// Post the result to the test log
Log.Message(txt);
end;
[C++Script, C#Script]
function Test()
{
var CommandLine, WshShell, oExec, txt;
// The name of the application to be run
CommandLine = "c:\\MyFile.bat";
// Create the WScript.Shell object and launch the application
WshShell = new ActiveXObject("WScript.Shell");
oExec = WshShell["Exec"](CommandLine);
// Parse the standard output
txt = "";
while(! oExec["StdOut"]["AtEndOfStream"])
{
txt = txt + oExec["StdOut"]["Read"](1);
if (txt.indexOf("Press any key") >= 0)
break;
}
// Post the result to the test log
Log["Message"](txt);
}
