Monday, March 17, 2014

Script to upload attachment in QC test lab

Dim oCurrentTest,oAttachment
Set oCurrentTest = QCUtil.CurrentTest.Attachments
Set oAttachment = oCurrentTest.AddItem(Null)
oAttachment.FileName = “C:Results.xls”
oAttachment.Type = 1 oAttachment.Post
oAttachment.Refresh Set
oAttachment =Nothing
Set oCurrentTest =Nothing

4 Different Ways to Associate Function Libraries to your QTP Scripts

Most of the times, when you are creating test scripts or are designing a new QTP Framework, you would be trying to come up with reusable functions which you would have to store in the function library. Now, in order to use this function library with multiple test cases, you need to associate this function library with your scripts. This article explains the 4 methods that will help you in associating the function libraries in QTP Test Cases.
Based on the type of framework you are using, you can use any of the following methods to associate function libraries to your QTP Script -
  • 1) By using ‘File > Settings > Resources > Associate Function Library’ option in QTP.
  • 2) By using Automation Object Model (AOM).
  • 3) By using ExecuteFile method.
  • 4) using LoadFunctionLibrary method.
Let’s see in detail how each of these methods can be used to map function libraries to your test scripts.

1. Using ‘File > Settings > Resources > Associate Function Library’ option from the Menu bar

This is the most common method used to associate a function library to a test case. To use this method, select File > Settings option from the Menu bar. This will display the ‘Test Settings’ window. Click on Resources from the left hand side pane. From the right hand side pane, click on the ‘+’ button and select the function library that needs to be associated with the test case.
Associate function Library to QTPAssociate function Library to QTP

2. Using AOM (Automation Object Model)

QTP AOM is a mechanism using which you can control various QTP operations from outside QTP. Using QTP Automation Object Model, you can write a code which would open a QTP test and associate a function library to that test.
Example: Using the below code, you can open QTP, then open any test case and associate a required function library to that test case. To do so, copy paste the below code in a notepad and save it with a .vbs extension.
1
2
3
4
5
6
7
8
9
10
11
12
13
'Open QTP
Set objQTP = CreateObject("QuickTest.Application")
objQTP.Launch
objQTP.Visible = True
'Open a test and associate a function library to the test
objQTP.Open "C:AutomationSampleTest", False, False
Set objLib = objQTP.Test.Settings.Resources.Libraries
'If the library is not already associated with the test case, associate it..
If objLib.Find("C:SampleFunctionLibrary.vbs") = -1 Then ' If library is not already added
  objLib.Add "C:SampleFunctionLibrary.vbs", 1 ' Associate the library to the test case
End

3. Using ExecuteFile Method

ExecuteFile statement executes all the VBScript statements in a specified file. After the file has been executed, all the functions, subroutines and other elements from the file (function library) are available to the action as global entities. Simply put, once the file is executed, its functions can be used by the action. You can use the below mentioned logic to use ExecuteFile method to associate function libraries to your script.
1
2
3
4
5
'Action begins
ExecuteFile "C:YourFunctionLibrary.vbs"
'Other logic for your action would come here
'.....

4. Using LoadFunctionLibrary Method

LoadFunctionLibrary, a new method introduced in QTP 11 allows you to load a function library when a step runs. You can load multiple function libraries from a single line by using a comma delimiter.
1
2
3
4
5
6
7
8
'Some code from the action
'.....
LoadFunctionLibrary "C:YourFunctionLibrary_1.vbs" 'Associate a single function library
LoadFunctionLibrary "C:FuncLib_1.vbs", "C:FuncLib_2.vbs" 'Associate more than 1 function libraries
'Other logic for your action would come here
'.....
This was all about the different ways using which you can associate function libraries to QTP Scripts. What are your views on this article? Can you think of any other points which I have missed and can be added here? Please let us know your views using the comments section. Happy Reading.. :–)
Reference: http://www.automationrepository.com/2011/09/associate-function-library-to-qtp-script/

ALM/QC – How to Update a Test Plan Field using OTA

 Is it possible to use OTA to update a Test Plan Field in ALM/QC?
Since writing my posts “How to Update a Defect using OTA” and “How to Update a Test Set Field Using OTA” I’ve received a few emails inquiring if it’s possible to also update information for an ALM Test Plan using HP’s Open Test Architecture (OTA).

The quick answer is “Yes” but rather than answer each one individual, I thought it would be better to frame my replay in the form of a quick post.
How to get the QC/ALM field name
In order to update a field in ALM using OTA you will need to know the backend name that ALM assigns to the field. This name is normally different than the label name that you might see in the ALM Test Lab section.
If you don’t know what the actual field names are, you can easily find them by going into QC’s Tools>Customize.
In the Project Customization section and go into the “Project Entities” section.


Under the Project Entities Tree view click expand Defect and click on your System Folder or User Fields. Clicking on a field will reveal the field name that you will need to use.
For this example I want to find the System Field > Status and get the name value for it (TS_STATUS)


QTP OTA Code to Update a Test Plan Field in an ALM/QC Test Lab
 
The following example updates the ‘Test Plan’ that has the ‘Test Set ID’ of 6 and changes the ‘Status’ field to Ready.

The code is pretty straight forward and uses the OTA’s TestFactory object to accomplish our goal.
  • Creating an instance of the TestFactory object allows us to access all the services needed to manage tests.
  • Next you set the Filter property to set the ID for the test set that you want to update.
  • Finally use the TestFactory’s NewList method to create a list of object that matches your specified filter.
  • Make sure to use the Post method to actually write the changed values to your ALM database
'=========================================
set tdc = createobject("TDApiOle80.TDConnection")
tdc.InitConnectionEx "http://yourURL/qcbin"
tdc.Login "yourName","yourPassword"
tdc.Connect "yourDomain","yourProject"
'=========================================
testPlanID = 6
Set TestList = tdc.TestFactory
Set TestPlanFilter = TestList.Filter
TestPlanFilter.Filter("TS_STATUS") = testPlanID

Set TestPlanList = TestList.NewList("")
Set myTestPlan = TestPlanList.Item(testPlanID)
myTestPlan.Field("TS_STATUS") = "Ready"
myTestPlan.Post

Set TestPlanFilter = Nothing
Set myTestPlan = Nothing
Set TestList = Nothing
Set TestPlanFilter = Nothing

How Update All Tests
There might be times when you need to update the same field for all the tests in your test plan. To update the same field for all your tests you could create code that loops thru all the tests:
'=========================================
set tdc = createobject("TDApiOle80.TDConnection")
tdc.InitConnectionEx "http://yourURL/qcbin"
tdc.Login "yourName","yourPassword"
tdc.Connect "yourDomain","yourProject"
'=========================================
Set TestList = tdc.TestFactory
Set TestPlanFilter = TestList.Filter
Set TestPlanList = TestList.NewList("")
For each tpTest in TestPlanList
 Set myTestPlan = TestPlanList.Item(tpTest.ID)
 myTestPlan.Field("TS_STATUS") = "Ready"
 myTestPlan.Post
Next 
Set TestPlanFilter = Nothing
Set myTestPlan = Nothing
Set TestList = Nothing
Set TestPlanFilter = Nothing


How to run the code



To run the defect code you can either place it in QTP and run as a script or place the code in a text file and save as a .VBS vbscript file.


Automatic TestSet Execution via Script

 
User's Requirement
 
Need to execute a QTP TestSet without using Quality Center GUI
 
 
Proposal Solution
 
The solution is to have a script that accepts 2 input parameters that are:
  • Path TestLab
  • TestSet Name
 
Once the connection to QC has been done, through interaction with the user, selection of Domain and Project from combo, etc, it will be launch the execution of the TestSet on a Remote Machine.

 
 
_________________________________________________________________________
 
Script Implementation
 
Considerations:
this would be only an example, a case study, on how to work and manage with the TSScheduler OTA Object.
I think this type of implementation could have sense only in particular context, those whom who execs the testset doesn't know anything about Quality Center, how to move inside it and doesn't have any permission to access it (user and password could be retrieve from somewhere else instead of how has been developed here).
 
 
How this script works.
The script has been written starting from the example found in the OTA help for the TSScheduler object description and remanaged.
 
This script must be launched from DOS Command Prompt passing 2 parameters that rappresents the Path and the TestSet Name.
In the case the 2 parameters have some spaces those strings must be written between the char " .
For example: myScript.vbs "Root\Fld1\Sub Folder1_1\Other Folder" "My TestSet"
 
This is the code:
 
'This version consists on call the script passing 2 parameters that are:
'
' - Path TestLab (where the TestSet is located)
' - TestSet Name


'*******************************************************
'Constants to set where to run the entire TestSet or the single TSTest
'*******************************************************
Const RUN_LOCAL  = 0
Const RUN_REMOTE = 2
Const RUN_PLANNED_HOST = 8
Const REMOTE_MACHINE = "REMOTE.MACHINE.ON.SOME.DOMAIN"

'Constants for log file.
'*******************************************************
Const PathLogFile = "d:\LogSched\"   'The location of the file is out of scope
Const LogFile = "logSched.txt"          'for this task.
Const FOR_WRITING = 2
'*******************************************************
'Variables
'*******************************************************
Dim tdc, fso, fOut
Dim QC_ADDRESS
Dim DOMAIN
Dim PROJECT
Dim USER
Dim PASSWORD
Dim PathTestLab
Dim TestSetName
'*******************************************************
 
'*******************************************************
'*******************************************************
'            M  A  I  N
'*******************************************************
'*******************************************************
'Check the Arguments passed to the script
if wscript.arguments.count <> 2 then
 Msgbox "Arguments Number Error! I need 2 informations: " & vbNewLine & _
     "- TestSet Folder" & vbNewLine & _
     "- TestSet Name" & vbNewLine & vbNewLine & _
     "Thank you. End of Program", vbCritical + vbSystemModal, "Arguments Error!!!"
 wscript.quit  
end if
PathTestLab = wscript.Arguments(0)
TestSetName = wscript.Arguments(1)
 
'Log File
set fso = CreateObject("Scripting.FileSystemObject")
if Not(fso.FolderExists(PathLogFile)) then
 msgbox "Log Path " & PathLogFile & " Not Found! End of Program!!", vbSystemModal + vbCritical, "Log Path Error!"
 set fso = nothing
 wscript.quit
end if
set fOut = fso.OpenTextFile(PathLogFile & LogFile, FOR_WRITING, True)
fOut.WriteLine "Date/Hour: " & Now & " - Start TestSet Execution Procedure"  & vbNewLine & vbNewLine
 
'Create the TDConnection Object
set tdc = CreateObject("tdapiole80.tdconnection.1")

'    Ask user for QC Coordinates
QC_ADDRESS = ""
USER = ""
PASSWORD = ""
QC_ADDRESS = InputBox("Insert the QC Site in th form http://qcaddress/qcbin", "QC Address", "http://10.10.10.10/qcbin")
if QC_ADDRESS = "" then
 set tdc = Nothing
 fOut.Close
 set fOut = Nothing
 set fso = Nothing
 wscript.quit
end if
'   Retrieve User Credential
Dim strUC
strUC = getUserInfo     
'getUserInfo returns a string
'if it contains the sequence of chars "@||@" it means that user infos have been correctly retrieved.
if instr(strUC,"@||@") = 0 then
 set tdc = Nothing
 fOut.Close
 set fOut = Nothing
 set fso = Nothing
 wscript.quit
end if
USER = split(strUC,"@||@")(0)
'next if because many times no password is set.
if right(strUC,4) <> "@||@" then
 PASSWORD = split(strUC,"@||@")(1)
end if
'Try to estabilished the Connection to QC Project. If it's ok, do the RunTestSet!
if QCConnect(QC_ADDRESS, USER, PASSWORD) then
 'Call the Sub to Run the TestSet on Remote Machine
 RunTestSet PathTestLab, TestSetName, REMOTE_MACHINE, RUN_REMOTE

 else

    fOut.WriteLine "Date/Hour: " & Now & " - QC Connection Error"
  
end if
if tdc.Connected then
 tdc.Disconnect
end if

fOut.WriteLine "Date/Hour: " & Now & " - END of PROGRAM"
fOut.close
set tdc = nothing
set fOut = nothing
set fso = nothing
MSGBOX "END OF PROGRAM", vbSystemModal + vbInformation, "End Program"
wscript.quit
'*******************************************************
'*******************************************************
'       E  N  D     M  A  I  N
'*******************************************************
'*******************************************************
 
 
'*******************************************************  
'            F U N C T I O N S
'*******************************************************
'Function to Retrieve UserInfo
Public Function getUserInfo()
'   Creation of the form to insert user and password
' Create an IE object
Dim res
res = ""
Set objIE = CreateObject( "InternetExplorer.Application" )
' specify some of the IE window's settings
objIE.Navigate "about:blank"
objIE.Document.title = "User and Password" & String( 80, "=" )
objIE.ToolBar        = False
objIE.Resizable      = False
objIE.StatusBar      = False
objIE.Width          = 400
objIE.Height         = 240
' Center the dialog window on the screen
With objIE.Document.parentWindow.screen
     objIE.Left = (.availWidth  - objIE.Width ) \ 2
     objIE.Top  = (.availHeight - objIE.Height) \ 2
End With
' Wait till IE is ready
Do While objIE.Busy
    WScript.Sleep 200
Loop
' Insert the HTML code to prompt for user input
objIE.Document.body.innerHTML = "<div align=""center""><table cellspacing=""5"">" _
                                  & "<tr nowrap><th colspan=""2"">Insert User and Password " _
                                  & ":</th></tr><tr nowrap><td>User :" _
                                  & "</td><td><input type=""text"" size=""20"" id=" _
                                  & """User""></td></tr><tr nowrap><td>Password :" _
                                  & "</td><td><input type=""password"" size=""20"" id=" _
                                  & """Password""></td></tr></table>" _
                                  & "<p><input type=""hidden"" id=""OK"" name=""OK"" " _
                                  & "value=""0""><input type=""submit"" value="" OK "" " _
                                  & "onclick=""VBScript:OK.value=1""></p></div>"
' Hide the scrollbars
objIE.Document.body.style.overflow = "auto"
' Make the window visible
objIE.Visible = True
' Set focus on User input field
objIE.Document.all.User.focus

' Wait till the OK button has been clicked
On Error Resume Next
Do While objIE.Document.all.OK.value = 0
    WScript.Sleep 200

    If Err Then    'user clicked red X (or alt-F4) to close IE window    
    exit do
    End if

Loop

' Read the user input from the dialog window
if not(Err) then
 res = objIE.Document.all.User.value & "@||@" & objIE.Document.all.Password.value
end if

'Close and release the object
objIE.Quit
Set objIE = Nothing
 
getUserInfo = res
On Error Goto 0
End Function
 
'Boolean Function that Check the Connection to the Project.
Public Function QCConnect(addr, usr, pwd)
Dim Res, dom, prj
Res = True
On Error Resume Next
tdc.InitConnectionEx addr
if err.number <> 0 then
 Res = False
 msgbox "QC Error in method InitConnectionEx", vbSystemModal + vbCritical, "InitConnectionEx ERROR!!!!"
end if
if Res then
 err.clear
 tdc.login usr, pwd
 if err.number <> 0 then
  Res = False
  msgbox "QC Error in method Login", vbSystemModal + vbCritical, "Login ERROR!!!!"
 end if
end if
strDomAndPrj = getDomPrjInfo   'call the function to retrieve Domain and Project Selections
if instr(strDomAndPrj, "@||@") > 0 then
 dom = split(strDomAndPrj,"@||@")(0)
 prj = split(strDomAndPrj,"@||@")(1)

 if Res then
  err.clear
  tdc.Connect dom, prj
  if err.number <> 0 then
   Res = False
   msgbox "QC Error in method Connect, check the Domain, Project and if user " & usr & " is allowed to the Project", vbSystemModal + vbCritical, "Connect ERROR!!!!"
  end if
 end if
 else
    Res = False
end if
QCConnect = Res
On error Goto 0
End Function

'Function that retrieve the Domain and Project Selection
Public Function getDomPrjInfo
Dim Res
Res = ""
set DomLst = tdc.VisibleDomains
optDomStr = ""
if DomLst.Count > 0 then
  for each dm in DomLst
 optDomStr = optDomStr & " <option value=" & chr(34) & dm & chr(34) & ">" & dm & "</option> " & vbNewLine
  next
end if
set DomLst = Nothing
optPrjStr = ""
' Form to select Domain and Project
' Create an IE object
Set objIE = CreateObject( "InternetExplorer.Application" )
' specify some of the IE window's settings
objIE.Navigate "about:blank"
objIE.Document.title = "Domain and Project" & String( 80, "=" )
objIE.ToolBar        = False
objIE.Resizable      = False
objIE.StatusBar      = False
objIE.Width          = 400
objIE.Height         = 240
' Center the dialog window on the screen
With objIE.Document.parentWindow.screen
     objIE.Left = (.availWidth  - objIE.Width ) \ 2
     objIE.Top  = (.availHeight - objIE.Height) \ 2
End With
' Wait till IE is ready
Do While objIE.Busy
    WScript.Sleep 200
Loop
' Insert the HTML code to prompt for user input
objIE.Document.body.innerHTML = "<div align=""center""><table cellspacing=""5"">" _
                                  & "<tr nowrap><th colspan=""2"">Select Domain and Project " _
                                  & ":</th></tr>" _       
          & "<label>Domain:<br>" _
          & "<select name=""Domain""> " _
          & optDomStr _
          & "</select> " _        
          & "</label></br>" _                  
          & "</table>" _       
                                  & "<p><input type=""hidden"" id=""OK"" name=""OK"" " _
                                  & "value=""0""><input type=""submit"" value="" OK "" " _
                                  & "onclick=""VBScript:OK.value=1""></p></div>"
' Hide the scrollbars
objIE.Document.body.style.overflow = "auto"
' Make the window visible
objIE.Visible = True
' Set focus on Domain input field
objIE.Document.all.Domain.focus

' Wait till the OK button has been clicked
Do While objIE.Document.all.OK.value = 0
    WScript.Sleep 200
 If Err Then    'user clicked red X (or alt-F4) to close IE window    
    exit do
    End if
Loop

if Not(Err) then
 ' Read the user input from the dialog window
 Res = objIE.Document.all.Domain.Value
 set PrjLst = tdc.VisibleProjects(Res)
 optPrjStr = ""
 for each pj in PrjLst
  optPrjStr = optPrjStr & " <option value=" & chr(34) & pj & chr(34) & ">" & pj & "</option> " & vbNewLine
 next
 ' Insert the HTML code to prompt for user input
 objIE.Document.body.innerHTML = "<div align=""center""><table cellspacing=""5"">" _
           & "<tr nowrap><th colspan=""2"">Select Domain and Project " _
           & ":</th></tr>" _       
           & "<label>Domain: " & Res & " <br>" _             
           & "</label></br>" _                  
           & "<label>Project:<br>" _
           & "<select name=""Project"" > " _
           & optPrjStr _
           & "</select> " _        
           & "</label></br>" _
           & "</table>" _       
           & "<p><input type=""hidden"" id=""OK"" name=""OK"" " _
           & "value=""0""><input type=""submit"" value="" OK "" " _
           & "onclick=""VBScript:OK.value=1""></p></div>"

 ' Hide the scrollbars
 objIE.Document.body.style.overflow = "auto"
 ' Make the window visible
 objIE.Visible = True
 ' Set focus on Project input field
 objIE.Document.all.Project.focus
 ' Wait till the OK button has been clicked
 Do While objIE.Document.all.OK.value = 0
  WScript.Sleep 200
  If Err Then    'user clicked red X (or alt-F4) to close IE window    
   exit do
  End if
 Loop
 
 ' Read the user input from the dialog window
 if Not(Err) then
  Res = Res & "@||@" & objIE.Document.all.Project.Value
 end if
end if
'Close and release the object
objIE.Quit
Set objIE = Nothing
getDomPrjInfo = Res
End Function
 
'This Sub is take from the example on OTA API TSScheduler Object description
Public Sub RunTestSet(tsFolderName, tSetName, _
           HostName, runWhere)
' This example show how to run a test set in three different ways:
' * Run all tests on the local machine (where this code runs).
' * Run the tests on a specified remote machine.
' * Run the tests on the hosts as planned in the test set.
    Dim TSetFact 'As TestSetFactory
 Dim tsList 'As List
    Dim theTestSet 'As TestSet
    Dim tsTreeMgr 'As TestSetTreeManager
    Dim tsFolder 'As TestSetFolder
    Dim Scheduler 'As TSScheduler
    Dim execStatus 'As ExecutionStatus

 On Error Resume Next    'my code

    'On Error GoTo RunTestSetErr
    'errmsg = "RunTestSet"

 ' Get the test set tree manager from the test set factory.
    'tdc is the global TDConnection object.
    Set TSetFact = tdc.TestSetFactory
    Set tsTreeMgr = tdc.TestSetTreeManager

 ' Get the test set folder passed as an argument to the example code. 
 'Dim nPath$
    'nPath = "Root\" & Trim(tsFolderName)
 '===> In this script the path has been passed as the 1st argument so nPath will be set directly to tsFolderName
 Dim nPath
 nPath = tsFolderName

 
 err.clear   'my add
    Set tsFolder = tsTreeMgr.NodeByPath(nPath)

 'my code
 if err.number <> 0 then
  msgbox "Error during the creation of the SysTreeNode for the path " & nPath, vbSystemModal + vbCritical, "QC Critical Error - Cannot Continue!!!"
  exit sub
 end if
 
 'If tsFolder Is Nothing Then
    '    err.Raise vbObjectError + 1, "RunTestSet", "Could not find folder " & nPath
    '    GoTo RunTestSetErr
    'End If
    'On Error GoTo RunTestSetErr

 ' Search for the test set passed as second argument to the example code.
    Set tsList = tsFolder.FindTestSets(tSetName)

 'I prefer the "Select case" statement instead of innested if
 Select case tsList.Count
   case 0: fOut.WriteLine "Date/Hour: " & Now & " -  TestSet " & tSetName & " not found under " & nPath & " !!!"
     exit Sub
   case 1: set theTestSet = tsList.Item(1)
   case else: fOut.WriteLine "Date/Hour: " & Now & " - Found more than one TestSet with the name & " & tSetName & " under " & nPath & " !!!"
        exit Sub
 End Select
    'If tsList.Count > 1 Then
    '    MsgBox "FindTestSets found more than one test set: refine search"
    'ElseIf tsList.Count < 1 Then
    '    MsgBox "FindTestSets: test set not found"
    'End If
    'Set theTestSet = tsList.Item(1)
    'Debug.Print theTestSet.ID
 
  '*******************************************************
  '      Start the scheduler on the local machine.
  '*******************************************************
    Set Scheduler = theTestSet.StartExecution("")
 'Set up for the run depending on where the test instances
 'are to execute.
    Select Case runWhere
        Case RUN_LOCAL
   ' Run all tests on the local machine.
            Scheduler.RunAllLocally = True
        Case RUN_REMOTE
   ' Run tests on a specified remote machine.
   ' ===> This set the HostName for the Scheduler Object <===
            Scheduler.TdHostName = HostName
            ' RunAllLocally must not be set for
            ' remote invocation of tests.
            ' Do not do this:
            ' Scheduler.RunAllLocally = False
        Case RUN_PLANNED_HOST
   ' Run on the hosts as planned in the test set.
            Dim TSTestFact 'As TSTestFactory
   Dim testList 'As List
            Dim tsFilter 'As TDFilter
            Dim TSTst 'As TSTest
   ' Get the test instances from the test set.
            Set TSTestFact = theTestSet.TSTestFactory
            Set tsFilter = TSTestFact.Filter
            tsFilter.Filter("TC_CYCLE_ID") = theTestSet.ID
            Set testList = TSTestFact.NewList(tsFilter.Text)
            'Debug.Print "Test instances and planned hosts:"
   ' For each test instance, set the host to run depending
   ' on the planning in the test set.
   ' It retrieves the HostName indicating into the TestInstance
            For Each TSTst In testList
                'Debug.Print "Name: " & TSTst.Name & " ID: " & TSTst.ID & " Planned Host: " & TSTst.HostName
                Scheduler.RunOnHost(TSTst.ID) = TSTst.HostName
            Next
            Scheduler.RunAllLocally = False
 
    End Select
 ' Run the tests.
 ' This is the same as RunTestSet
    Scheduler.Run
  '*******************************************************
  '     Get the execution status object.
  '*******************************************************
     Set execStatus = Scheduler.ExecutionStatus

 ' Track the events and statuses.
    Dim RunFinished 'As Boolean,
 Dim iter 'As Integer,   'I think this is not necessary
 Dim i 'As Integer
    Dim ExecEventInfoObj 'As ExecEventInfo,
 Dim EventsList 'As List
    Dim TestExecStatusObj 'As TestExecStatus

    'While ((RunFinished = False) And (iter < 100))
 Do While Not(RunFinished) '===> Change in a Do While statement
        'iter = iter + 1
        execStatus.RefreshExecStatusInfo "all", True   '===> Force the Refresh of all the test status!
        RunFinished = execStatus.Finished      '===> Checks if execution is finished or still in progress
        Set EventsList = execStatus.EventsList     '===> Retrieve the List of Execution Events that are ExecEventInfo Objects
        For Each ExecEventInfoObj In EventsList
            fOut.WriteLine "Event: " & ExecEventInfoObj.EventDate & " " & ExecEventInfoObj.EventTime & " " & vbNewLine & _
                    "Event Type: " & ExecEventInfoObj.EventType & vbNewLine & _
     "[Event types: 1-fail, 2-finished, 3-env fail, 4-timeout, 5-manual]"
        Next
        'Debug.Print Tab; execStatus.Count & " exec status"
        For i = 1 To execStatus.Count
            Set TestExecStatusObj = execStatus.Item(i)
            fOut.WriteLine "Date/Hour: " & Now & " - Status: " & vbNewLine & _
                        "Test ID (the ID of the Test in TestPlan):   " & TestExecStatusObj.TestID & vbNewLine & _
      "Test instance (the ID of the TestInstance): " & TestExecStatusObj.TSTestID & " " & vbNewLine & _
                        "Order:                                      " & TestExecStatusObj.TestInstance & vbNewLine & _                     
                        "Message:                                    " & TestExecStatusObj.Message & vbNewLine & _
      "Status:                                     " & TestExecStatusObj.Status & vbNewLine & _
      "=====================================================" & vbNewLine
        Next 'i

  'This part is for visualbasic code
        'Sleep() has to be declared before it can be used.
        'This is the module level declaration of Sleep():
        'Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
        'Sleep (5000)

  Wscript.Sleep (60000)  'wait 1 minute before next iteration.
  
 Loop
 'Wend 'Loop While execStatus.Finished = False
    'Debug.Print "Scheduler finished around " & CStr(Now)
    'Debug.Print
 On error Goto 0

'RunTestSetErr:
'    ErrHandler err, err.Description, errmsg, NON_FATAL_ERROR
End Sub
'*******************************************************

Friday, March 14, 2014

Quality Center : Recover lost password..... That's not hacking!!!

Question:
Hi ,
I have lost my QC password and dont want to ask my client to reset it 
Can we do something to recover it?
In a trouble right now. Please help.
Thanks
XXXX
Solution:

1. Open the C:\Program Files\HP\QuickTest Professional\bin\mic.ini file using notepad.

2.  Go to  [TestDirector] section (usually at the bottom ) .

3. Copy the encrypted password corresponding to your QC UserID.

To decrypt it run the following code in QTP:

'Open Google page and set password in the search box
systemutil.Run "C:\Program Files\Internet Explorer\IEXPLORE.EXE", "www.google.com"
Browser("title:=Google").Sync
Browser("title:=Google").Page("title:=Google").WebEdit("name:=q","type:=text").SetSecure <Encrypted Password From mic.ini>

QTP : Read PDF file even without buying PDF Writer or converting into text file

Often while automating manual test cases, we come across the scenarios of validating PDF data.
But we don't have any direct way of doing so.
The two  most common ways are :
1. Install PDF writer and use its API's to read data from PDF file.
    This would cost us the license for PDF writer

2. Convert the PDF file into text file using some tool and then do the validation .
    This would add a new layer of file conversion and also create dependency.

Considering the above shortcomings we were able to have a workaround for that.
This involves moving the PDF data into system clipboard and then extracting the value from clipboard..
''This Function takes file path as input and return the PDF data 
Function ReadPDF(Filename)
Set oShell = CreateObject("wscript.shell")
        'Open the PDF file
oShell.run Filename
wait(4)
        
        '' Select all data from PDF file using 'Control + a ' keys
oShell.Sendkeys "^a"
wait(2)
        '' Move data from PDF file to clipboard using 'Control + c ' keys
oShell.Sendkeys "^c"
wait(2)
       'Fetching data from clipboard
Set oClipboard = CreateObject("htmlfile")
strClipboard = objClipboard.ParentWindow.ClipboardData.GetData("Text")
       'Close the PDF File
Call terminateProcess("AcroRd32.exe")
       'Return the value of clipboard data
ReadPDF= strClipboard
End Function
'This function takes the name of the process to be terminated
Function terminateProcess(name)
   Dim objWMIService, objProcess, colProcess
Dim strComputer, strProcessKill 
strComputer = "."
Set objWMIService = GetObject("winMgmts:\\localhost") 
Set oNetwork =Createobject("Wscript.Network")
usrname = oNetwork.UserName
Set colProcess = objWMIService.ExecQuery _
("Select * from Win32_Process Where Name = '" & name &"'")
For Each objProcess in colProcess
objProcess.GetOwner strNameOfUser,strUserDomain
If  strNameOfUser=usrname Then
objProcess.Terminate()
End If 
Next 
End Function

QTP: Recording To Descriptive Programing Converter


The “Descriptive Programming Converter” utility as the name suggests , converts the recorded code into Descriptive Programming code.

It also gives you a proper commenting for each line of the recorded code and that too at click of a button.

Interesting....... ??

Find out how to do that:

It consist of two parts:


1. QTP script (This script is to be kept on C:\Converter of the machine : Currently Hard-coded , you may change it)
This script parses the recorded code and converts it into descriptive programming.

2. Initiate.Vbs (This file could be kept anywhere. It’s better to keep it on the Quick launch)
User is supposed to run this file after recording and script in QTP.
It will automatically ‘Print’ the recorded steps in descriptive programming.

Setup:

QTP Script
''''' Save the following script at C:\Converter with name Rec2Des using QTP

Set objFSO = CreateObject("Scripting.FileSystemObject") 
Const ForReading = 1 
Set objFile = objFSO.OpenTextFile ("C:\Converter\Script.mts", ForReading) 

Quote  =""""

'Parses the code present in the MTS file
Do Until objFile.AtEndOfStream 
strNextLine = objFile.Readline 
b=""
Obj= Split(strNextLine," @@")
'ObjInt=Split(Obj(0),"")
Act=Split(Obj(0),".")
Action=Act(Ubound(Act))

Obj1=Split(Obj(0),".")
For i=0 to Ubound(Obj1)-1
a=Obj1(i)
If b="" Then
b=a
Else 
b=b&"."& a
End If

Next
fobj=Split(b,".")
Object=fobj(Ubound(fobj))

If instr(b,"") Then
CleanRow=Split(b,"")
b=CleanRow(1)
End If
'Print  b

Sloop=Split (b,".")

For i=0 to Ubound(Sloop)
For j=0 to Ubound(Sloop)-i
If ObjPart="" Then
ObjPart=ObjPart&Sloop(j)
Else
ObjPart=ObjPart&"."&Sloop(j)
End If
Next
ClassObj=Split(Sloop(Ubound(Sloop)-i),"(")

'Getting class of fragmented object
CObj=ClassObj(0)
ObjPass=ObjPart
ObjPart =""

Execute("Set theTestObject = " &ObjPass)

Set Props = theTestObject.GetTOProperties
PropsCount = Props.Count
For k = 0 To PropsCount -1
PropName = Props(k).Name
PropValue = Props(k).Value

If  CompletProp=""  Then
CompletProp=Quote & PropName & ":=" & PropValue & Quote
Else
CompletProp=CompletProp &","&Quote & PropName & ":=" & PropValue & Quote
End If

Next
'Print CompletProp
If FragElement="" Then
FragElement=CObj&"("&CompletProp&")"
Else   
FragElement=FragElement &"."&CObj&"("&CompletProp&")"
End If
If CompElem="" Then
CompElem=FragElement 
Else
CompElem=FragElement &"." &CompElem
End If
FragElement=""
CompletProp=""
Next
Print  "'"  &Action &" action applied on "& Object & " object"
Print CompElem&"."&Action
Print vbcrlf
CompElem =""

Loop 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Keep the following code as Initiate.Vbs (You can keep it on quick Launch for ease of use)

'Create the QTP App object
Set qtApp = CreateObject("QuickTest.Application") Loc = qtApp.Test.Location Loc1=Loc&"\Action1\Script.mts" Loc2=Loc&"\Action1\Resource.mtr" Loc3=Loc&"\Action1\ObjectRepository.bdb" set filesys=CreateObject("Scripting.FileSystemObject")
'Perform the file Copy filesys.CopyFile Loc1, "C:\Converter\" filesys.CopyFile Loc2, "C:\Converter\Rec2Des\Action1\" filesys.CopyFile Loc3, "C:\Converter\Rec2Des\Action1\" 'Open the test in read-only mode qtApp.Open "C:\Converter\Rec2Des", True 'Get the instance of the openedtest Set qtTest = qtApp.Test 'Run the test qtTest.Run

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Steps:
  1. Open QTP and start recording a script.
  2. Save the above recorded script at any desired location (Do not close it)
  3. Run Initiate.vbs File