ALM Defect Customization

45
Application Lifecycle Management Defect Customizations SSBS Prepared for Defect Module customization Materials June 2012 Document Version 1.0

description

HP alm admin

Transcript of ALM Defect Customization

Page 1: ALM Defect Customization

Application Lifecycle Management Defect Customizations

SSBS Prepared for Defect Module customization Materials

June 2012Document Version 1.0

Page 2: ALM Defect Customization

Document Controls – Change Record

Date Author Version Change Reference

06/17/2012 Joseph Inbaraj 1.0

Contributors

Name Title

Joseph Inbaraj Automation Tester

Application Lifecycle Management Defect CustomerPage 2

Page 3: ALM Defect Customization

Table of ContentsOverview......................................................................................................................4Quality Center Defect Moudle Customizations........................................................4

1. Project Users………………………………………………………………………………………………………..

2. Groups and Permissions3. Module Access4. Project Entities – Defect – User Fields5. Auto Mail and Mail configurations in Site Administrator6. Alert Rules For Auto Email7. Workflow8. Enable PPM field values in Defect Module9. Script Generator – Add Defect field customization

Script Generator –Defect details field customization

Application Lifecycle Management Defect CustomerPage 3

Page 4: ALM Defect Customization

Overview

This document provides Defect Module with a comprehensive description of ALM Defect Center Workflow customizations and Site Administrator.

This plan will describe the customizations necessary to support the ALM quality processes.

Application Lifecycle Management CustomizationsThe following list contains ALM Defect Workflow customizations and Site

Administration requirements:

I. ITC Project Code

A. Assigned To and Assigned Team field Customizations

The Assigned To list box should only display Users who belong to the Team that was selected in the Assigned Team list box. To do this, a number of things must be considered:

1. Each Team must be its own separate list. This is because it is impossible to hide list items from users. We have removed the original ASSIGNED TO lookup list and created a lookup list for each individual Team, containing its users. When you need to add or delete users to the project, make sure you add/delete the users from the Team in the Customize Project List section.

2. When a user changes the Assigned Team field, the Assigned To field will be blanked out so the user will be forced to enter a valid user that belongs to the new Team.

3. Since the Assigned To needs to be a lookup list, the original Assigned To field (BG_RESPONSIBLE), which is a USER LIST, has been hidden from users. However, we need to synch the value between the two Assigned To fields because the User List is needed for the Defect Automatic Mail feature.

Fields Involved:Assigned To – BG_USER_18Assigned Team – BG_USER_01AssignedTo (original field, hidden) – BG_RESPONSIBLE

Code:

Defects Module:

Application Lifecycle Management Defect CustomerPage 4

Page 5: ALM Defect Customization

Sub Bug_MoveTo On Error Resume Next

'Change the Assigned To list to the respective Team based on the Assigned Team field Bug_Fields("BG_USER_18").List = Lists(Bug_Fields("BG_USER_01").Value)

On Error Goto 0End Sub

Sub Bug_FieldChange(FieldName)

'Synch the Assigned To Lookup List with the AssignedTo User Listif FieldName = "BG_USER_18" then Bug_Fields("BG_RESPONSIBLE").Value = Bug_Fields("BG_USER_18").Value

elseif FieldName = "BG_USER_01" then 'If Assigned Team has changed, change the Assigned To list accordingly Bug_Fields("BG_USER_18").List = Lists(Bug_Fields("BG_USER_01").Value)

'Blank out Assigned To if Assigned Team changes to a group user doesn't belong to if VerifyUserExistsInGroup("BG_USER_01", "BG_USER_18") = 0 then Bug_Fields("BG_USER_18").Value = "" Bug_Fields("BG_RESPONSIBLE").Value = ""

Application Lifecycle Management Defect CustomerPage 5

Page 6: ALM Defect Customization

end ifend if

End Sub

Function Bug_FieldCanChange(FieldName, NewValue) On Error Resume Next

'Prevent modification of Assigned To if Assigned Team is blank If FieldName = "BG_USER_18" and Bug_Fields("BG_USER_01").IsNull then Msgbox "Please fill out the Assigned Team field first." Bug_FieldCanChange = false else Bug_FieldCanChange = DefaultRes end if

On Error GoTo 0End Function

Function VerifyUserExistsInGroup(Field1, Field2) On Error Resume Next‘This Function verifies whether the User exists in a Team.‘Field1 is the Team Field (Assigned Team, Detected by Team)‘Field 2 is the User Field (Assigned To, Detected By)

Application Lifecycle Management Defect CustomerPage 6

Page 7: ALM Defect Customization

‘Return values: 0 if user is not found in Team, non-zero if found

dim com 'As Command dim rec 'As RecordSet

set com = TDConnection.Command SQL = "select * from all_lists where al_father_id in (select al_item_id from all_lists where al_description='" & _ Bug_Fields(Field1).Value & "') and al_description='" & Bug_Fields(Field2).Value & "'" com.CommandText = SQL set rec = com.Execute

VerifyUserExistsInGroup = rec.RecordCount

set rec = nothing set com = nothing

On Error GoTo 0End Function

B. Detected By and Detected By Team Customizations

When adding a new Defect, the Detected by field is automatically filled in by Quality Center. We need to automatically fill in the Detected By Team with the team the user belongs to. Below are some considerations:

1. Make sure all Users in the Project belongs to a Team in the Customize Project List section, else, the user cannot select a Detected By Team.

Application Lifecycle Management Defect CustomerPage 7

Page 8: ALM Defect Customization

2. When the user changes the Detected By Team field to a Team he/she does not belongs to, the Detected By field should be blanked out.

3. When the user changes the Detected By, the Detected By Team should be automatically switched to the Team the user belongs to.

Fields Involved:Detected By – BG_DETECTED_BYDetected By Team – BG_USER_02

Code:

Defects Module:

Sub Bug_NewOn Error Resume Next WizardFieldCust_Add ' Added by wizard

'Auto populate Detected By Team Bug_Fields("BG_USER_02").Value = FindUserGroup(Bug_Fields("BG_DETECTED_BY").Value)

On Error Goto 0End Sub

Application Lifecycle Management Defect CustomerPage 8

Page 9: ALM Defect Customization

Sub Bug_FieldChange(FieldName)

'Blank out Detected By if Detected By Team changes to a group user doesn't belong toif FieldName = "BG_USER_02" then if VerifyUserExistsInGroup("BG_USER_02", "BG_DETECTED_BY") = 0 then Bug_Fields("BG_DETECTED_BY").Value = "" end if

'Auto populated Detected By Teamelseif FieldName = "BG_DETECTED_BY" then Bug_Fields("BG_USER_02").Value = FindUserGroup(Bug_Fields("BG_DETECTED_BY").Value)end if

End Sub

Function VerifyUserExistsInGroup(Field1, Field2) On Error Resume Next‘This Function verifies whether the User exists in a Team.‘Field1 is the Team Field (Assigned Team, Detected by Team)‘Field 2 is the User Field (Assigned To, Detected By)‘Return values: 0 if user is not found in Team, non-zero if found

dim com 'As Command dim rec 'As RecordSet

Application Lifecycle Management Defect CustomerPage 9

Page 10: ALM Defect Customization

set com = TDConnection.Command SQL = "select * from all_lists where al_father_id in (select al_item_id from all_lists where al_description='" & _ Bug_Fields(Field1).Value & "') and al_description='" & Bug_Fields(Field2).Value & "'" com.CommandText = SQL set rec = com.Execute

VerifyUserExistsInGroup = rec.RecordCount

set rec = nothing set com = nothing

On Error GoTo 0End Function

Function FindUserGroup(UserName) On Error Resume next'This Function finds the user's Team'userName is the name of the User in Detected By field'Return value: the Team name the User belongs to

dim com 'As Command dim rec 'As RecordSet

Application Lifecycle Management Defect CustomerPage 10

Page 11: ALM Defect Customization

set com = TDConnection.Command SQL = "select al_description from all_lists where al_item_id in (select al_father_id from all_lists where al_description='" & _ UserName & "')" com.CommandText = SQL set rec = com.Execute

FindUserGroup = rec.FieldValue("al_description")

set rec = nothing set com = nothing

On Error Goto 0End Function

C. Retest_QA Customizations

Whenever the Defect Status changes to Retest_QA, both the Detected By and Detected By Team fields should be copied to the Assigned To and Assigned Team fields, respectively.

Fields Involved:Assigned To – BG_USER_18Assigned Team – BG_USER_01AssignedTo (original field, hidden) – BG_RESPONSIBLEDetected By – BG_DETECTED_BY

Application Lifecycle Management Defect CustomerPage 11

Page 12: ALM Defect Customization

Detected By Team – BG_USER_02Status – BG_STATUS

Code:

Defects Module:

Sub Bug_FieldChange(FieldName)

'If Status changes to ReTest_QA, copy the Detected By (Team) to Assigned To (Team)If FieldName = "BG_STATUS" and Bug_Fields("BG_STATUS").Value = "ReTest_QA" then Bug_Fields("BG_USER_18").Value = Bug_Fields("BG_DETECTED_BY").Value Bug_Fields("BG_USER_01").Value = Bug_Fields("BG_USER_02").Value Bug_Fields("BG_RESPONSIBLE").Value = Bug_Fields("BG_USER_18").Valueend if

End Sub

D. Disable Add Defect Button

To prevent users from adding Defects directly from the Defects module, we need to disable the Add Defect button there. We need to force users to only use the Add Defect button when running a Manual Test. This way, traceability is enforced.

NOTE: User’s still will be able to Add Defects from the following locations: Add Defect button when running a Manual Test Linked Defects dialog box From the main Tools menu

Application Lifecycle Management Defect CustomerPage 12

Page 13: ALM Defect Customization

Code:

Common Module:

Sub EnterModule 'Use ActiveModule and ActiveDialogName to get 'the current context. On Error Resume Next

'Disable the Add Defect button in the Defects module if not an Admin If ActiveModule = "Defects" and Not(User.IsInGroup("ADMIN")) then Actions.Action("BugAddAction1").Visible = false end if

On Error GoTo 0End Sub

E. Copy KPC and Test Name from Test Lab to Defects

The Key Process Chain field and Test Name in Test Lab should be copied to the Defect that user adds. The Workflow code requires that we pass data from one module to another (Test Lab to Defects). However, Quality Center’s Workflow module does not have this capability. To get around this problem, we have to have the Test Lab module write temporary data to a file, which the Defects module will read and delete after use. The file will be written on one of the following locations, depending on the Client machine’s Operating System:

C:\WinNT\Temp\QC_KCS.txt C:\Windows\Temp\QC_KCS.txt

Application Lifecycle Management Defect CustomerPage 13

Page 14: ALM Defect Customization

This would mean that the code will fail if the user does not have adequate permissions in the directories specified.

Fields Involved:Test Plan KEY PROCESS CHAIN – TS_USER_07Test Plan Test Name – TS_NAMEDefects KEY PROCESS CHAIN – BG_USER_16Defects Test Name – BG_USER_17

Code:

Common Module:

Function ActionCanExecute(ActionName) 'Use ActiveModule and ActiveDialogName to get 'the current context. On Error Resume Next dim flib

Application Lifecycle Management Defect CustomerPage 14

Page 15: ALM Defect Customization

'Delete KPC cache file if user adds Defect from Linked Defects tab if ActionName = "actAssNewDefect" then set flib = CreateObject("Scripting.FileSystemObject") if flib.FileExists("C:\WinNT\Temp\QC_KCS.txt") then set myf = flib.DeleteFile("C:\WinNT\Temp\QC_KCS.txt", True) elseif flib.FileExists("C:\Windows\Temp\QC_KCS.txt") then set myf = flib.DeleteFile("C:\Windows\Temp\QC_KCS.txt", True) end if set flib = nothing end if

ActionCanExecute = DefaultRes On Error GoTo 0End Function

ManualRun Module:

Sub Run_MoveTo On Error Resume Next dim flib, myf

'Record Test ID in a file on the Client so we can pass the KPC to Defects. 'We use a file because Workflow cannot pass data between modules. set flib = CreateObject("Scripting.FileSystemObject")

Application Lifecycle Management Defect CustomerPage 15

Page 16: ALM Defect Customization

if flib.FolderExists("C:\WinNT\Temp") then set myf = flib.OpenTextFile("C:\WinNT\Temp\QC_KCS.txt", 2, True) elseif flib.FolderExists("C:\Windows\Temp") then set myf = flib.OpenTextFile("C:\Windows\Temp\QC_KCS.txt", 2, True) end if myf.Write Run_Fields("RN_TEST_ID").Value

set myf = nothing set flib = nothing

On Error GoTo 0End Sub

Defects Module:

Sub Bug_NewOn Error Resume Next WizardFieldCust_Add ' Added by wizard

dim tsf, ts, flib, myf dim tsID, KPC, tsName

Application Lifecycle Management Defect CustomerPage 16

Page 17: ALM Defect Customization

tsID = 0 KPC = "" tsName = ""

'Read the Test ID from the temporary file created from the ManualRun module set flib = CreateObject("Scripting.FileSystemObject") if flib.FileExists("C:\WinNT\Temp\QC_KCS.txt") then set myf = flib.OpenTextFile("C:\WinNT\Temp\QC_KCS.txt", 1, False) elseif flib.FileExists("C:\Windows\Temp\QC_KCS.txt") then set myf = flib.OpenTextFile("C:\Windows\Temp\QC_KCS.txt", 1, False) end if tsID = CLng(Trim(myf.ReadAll)) 'Use TestFactory and Test objects to grab the KPC set tsf = TDConnection.TestFactory set ts = tsf.Item(tsID) KPC = ts.Field("TS_USER_07") tsName = ts.Name set ts = nothing set tsf = nothing set myf = nothing set flib = nothing

'Pass TestLab KPC and Test Name to Defects Bug_Fields("BG_USER_16").Value = KPC Bug_Fields("BG_USER_17").Value = tsName

On Error Goto 0End Sub

F. Run Manually and Continue Manual Run Customizations

The Run Manually and Continue Manual Run buttons should be enabled or disabled depending on the current Status of the Test highlighted in the Test Lab Execution Grid. The following are the rules:

Test Status Run Manually Continue Manual RunNo Run Yes NoNot Completed No YesPassed Yes YesFailed No Yes

Application Lifecycle Management Defect CustomerPage 17

Page 18: ALM Defect Customization

NOTE: There is a bug in the QC Workflow wherein disabling either the Run or Continue Run button doesn’t work, when you either first enter the Test Lab module, or when you press the Refresh All button in the Test Set Tree area. So we have to add a Message to the User to prevent them from pressing the wrong button in these cases.

Fields Involved:Status – TC_STATUSCode:

Common Module:

Application Lifecycle Management Defect CustomerPage 18

Page 19: ALM Defect Customization

Function ActionCanExecute(ActionName) 'Use ActiveModule and ActiveDialogName to get 'the current context. On Error Resume Next

'Prevent people from executing New Run when status is Not Completed or Failed If ActionName = "act_run" or ActionName = "act_run_manually" then if TestSetTest_Fields("TC_STATUS").Value = "Not Completed" or _ TestSetTest_Fields("TC_STATUS").Value = "Failed" then Msgbox "This test is in progress. Please select the Continue Manual Run from the drop-down." ActionCanExecute = false else ActionCanExecute = DefaultRes end if else ActionCanExecute = DefaultRes end if

On Error GoTo 0End Function

TestLab Module:

Sub TestSetTests_MoveTo

Application Lifecycle Management Defect CustomerPage 19

Page 20: ALM Defect Customization

On Error Resume Next

'Disable New Run/Continue Manual Run buttons based on Test Status Select Case TestSetTest_Fields("TC_STATUS").Value 'Allow only New Run for No Run Case "No Run" Actions.Action("act_run").Enabled = true Actions.Action("act_run_manually").Enabled = true Actions.Action("act_continue_man_run").Enabled = false 'Allow only Continue Run for Not Completed Case "Not Completed" Actions.Action("act_run").Enabled = false Actions.Action("act_run_manually").Enabled = false Actions.Action("act_continue_man_run").Enabled = true 'Allow both Continue and New Run for Passed Case "Passed" Actions.Action("act_run").Enabled = true Actions.Action("act_run_manually").Enabled = true Actions.Action("act_continue_man_run").Enabled = true 'Allow only Continue Run for Failed Case "Failed" Actions.Action("act_run").Enabled = false Actions.Action("act_run_manually").Enabled = false Actions.Action("act_continue_man_run").Enabled = true

Application Lifecycle Management Defect CustomerPage 20

Page 21: ALM Defect Customization

End Select

On Error GoTo 0End Sub

G. Consolidated ITC Code

Common Modules:

Sub EnterModule 'Use ActiveModule and ActiveDialogName to get 'the current context. On Error Resume Next

'Disable the Add Defect button in the Defects module if not an Admin If ActiveModule = "Defects" and Not(User.IsInGroup("ADMIN")) then Actions.Action("BugAddAction1").Visible = false end if

On Error GoTo 0End Sub

Function ActionCanExecute(ActionName) 'Use ActiveModule and ActiveDialogName to get 'the current context.

Application Lifecycle Management Defect CustomerPage 21

Page 22: ALM Defect Customization

On Error Resume Next dim flib

'Prevent people from executing New Run when status is Not Completed or Failed If ActionName = "act_run" or ActionName = "act_run_manually" then if TestSetTest_Fields("TC_STATUS").Value = "Not Completed" or _ TestSetTest_Fields("TC_STATUS").Value = "Failed" then Msgbox "This test is in progress. Please select the Continue Manual Run from the drop-down." ActionCanExecute = false else ActionCanExecute = DefaultRes end if 'Delete KPC cache file if user adds Defect from Linked Defects tab elseif ActionName = "actAssNewDefect" then set flib = CreateObject("Scripting.FileSystemObject") if flib.FileExists("C:\WinNT\Temp\QC_KCS.txt") then set myf = flib.DeleteFile("C:\WinNT\Temp\QC_KCS.txt", True) elseif flib.FileExists("C:\Windows\Temp\QC_KCS.txt") then set myf = flib.DeleteFile("C:\Windows\Temp\QC_KCS.txt", True) end if set flib = nothing ActionCanExecute = DefaultRes else ActionCanExecute = DefaultRes

Application Lifecycle Management Defect CustomerPage 22

Page 23: ALM Defect Customization

end if

On Error GoTo 0End Function

TestLab Module:

Sub TestSetTests_MoveTo On Error Resume Next

'Disable New Run/Continue Manual Run buttons based on Test Status Select Case TestSetTest_Fields("TC_STATUS").Value 'Allow only New Run for No Run Case "No Run" Actions.Action("act_run").Enabled = true Actions.Action("act_run_manually").Enabled = true

Application Lifecycle Management Defect CustomerPage 23

Page 24: ALM Defect Customization

Actions.Action("act_continue_man_run").Enabled = false 'Allow only Continue Run for Not Completed Case "Not Completed" Actions.Action("act_run").Enabled = false Actions.Action("act_run_manually").Enabled = false Actions.Action("act_continue_man_run").Enabled = true 'Allow both Continue and New Run for Passed Case "Passed" Actions.Action("act_run").Enabled = true Actions.Action("act_run_manually").Enabled = true Actions.Action("act_continue_man_run").Enabled = true 'Allow only Continue Run for Failed Case "Failed" Actions.Action("act_run").Enabled = false Actions.Action("act_run_manually").Enabled = false Actions.Action("act_continue_man_run").Enabled = true End Select

On Error GoTo 0End Sub

ManualRun Module:

Sub Run_MoveTo

Application Lifecycle Management Defect CustomerPage 24

Page 25: ALM Defect Customization

On Error Resume Next dim flib, myf

'Record Test ID in a file on the Client so we can pass the KPC to Defects. 'We use a file because Workflow cannot pass data between modules. set flib = CreateObject("Scripting.FileSystemObject") if flib.FolderExists("C:\WinNT\Temp") then set myf = flib.OpenTextFile("C:\WinNT\Temp\QC_KCS.txt", 2, True) elseif flib.FolderExists("C:\Windows\Temp") then set myf = flib.OpenTextFile("C:\Windows\Temp\QC_KCS.txt", 2, True) end if myf.Write Run_Fields("RN_TEST_ID").Value

set myf = nothing set flib = nothing

On Error GoTo 0End Sub

Defects Module:

Application Lifecycle Management Defect CustomerPage 25

Page 26: ALM Defect Customization

Sub Bug_NewOn Error Resume Next WizardFieldCust_Add ' Added by wizard

dim tsf, ts, flib, myf dim tsID, KPC, tsName

tsID = 0 KPC = "" tsName = ""

'Read the Test ID from the temporary file created from the ManualRun module set flib = CreateObject("Scripting.FileSystemObject") if flib.FileExists("C:\WinNT\Temp\QC_KCS.txt") then set myf = flib.OpenTextFile("C:\WinNT\Temp\QC_KCS.txt", 1, False) elseif flib.FileExists("C:\Windows\Temp\QC_KCS.txt") then set myf = flib.OpenTextFile("C:\Windows\Temp\QC_KCS.txt", 1, False) end if tsID = CLng(Trim(myf.ReadAll)) 'Use TestFactory and Test objects to grab the KPC set tsf = TDConnection.TestFactory set ts = tsf.Item(tsID) KPC = ts.Field("TS_USER_07")

Application Lifecycle Management Defect CustomerPage 26

Page 27: ALM Defect Customization

tsName = ts.Name set ts = nothing set tsf = nothing set myf = nothing set flib = nothing

'Pass TestLab KPC and Test Name to Defects Bug_Fields("BG_USER_16").Value = KPC Bug_Fields("BG_USER_17").Value = tsName

'Auto populate Detected By Team Bug_Fields("BG_USER_02").Value = FindUserGroup(Bug_Fields("BG_DETECTED_BY").Value)

On Error Goto 0End Sub

Sub Bug_MoveTo On Error Resume Next

WizardFieldCust_Details ' Added by wizard WizardListCust ' Added by wizard

'Change the Assigned To list to the respective Team based on the Assigned Team field Bug_Fields("BG_USER_18").List = Lists(Bug_Fields("BG_USER_01").Value)

Application Lifecycle Management Defect CustomerPage 27

Page 28: ALM Defect Customization

On Error Goto 0End Sub

Sub Bug_FieldChange(FieldName) WizardListCust ' Added by wizard

'If Status changes to ReTest_QA, copy the Detected By (Team) to Assigned To (Team)If FieldName = "BG_STATUS" and Bug_Fields("BG_STATUS").Value = "ReTest_QA" then Bug_Fields("BG_USER_18").Value = Bug_Fields("BG_DETECTED_BY").Value Bug_Fields("BG_USER_01").Value = Bug_Fields("BG_USER_02").Value Bug_Fields("BG_RESPONSIBLE").Value = Bug_Fields("BG_USER_18").Value'Synch the Assigned To Lookup List with the AssignedTo User Listelseif FieldName = "BG_USER_18" then Bug_Fields("BG_RESPONSIBLE").Value = Bug_Fields("BG_USER_18").Valueelseif FieldName = "BG_USER_01" then 'If Assigned Team has changed, change the Assigned To list accordingly Bug_Fields("BG_USER_18").List = Lists(Bug_Fields("BG_USER_01").Value)

Application Lifecycle Management Defect CustomerPage 28

Page 29: ALM Defect Customization

'Blank out Assigned To if Assigned Team changes to a group user doesn't belong to if VerifyUserExistsInGroup("BG_USER_01", "BG_USER_18") = 0 then Bug_Fields("BG_USER_18").Value = "" Bug_Fields("BG_RESPONSIBLE").Value = "" end if'Blank out Detected By if Detected By Team changes to a group user doesn't belong toelseif FieldName = "BG_USER_02" then if VerifyUserExistsInGroup("BG_USER_02", "BG_DETECTED_BY") = 0 then Bug_Fields("BG_DETECTED_BY").Value = "" end if'Auto populated Detected By Teamelseif FieldName = "BG_DETECTED_BY" then Bug_Fields("BG_USER_02").Value = FindUserGroup(Bug_Fields("BG_DETECTED_BY").Value)end if

End Sub

Function Bug_FieldCanChange(FieldName, NewValue) On Error Resume Next

'Prevent modification of Assigned To if Assigned Team is blank If FieldName = "BG_USER_18" and Bug_Fields("BG_USER_01").IsNull then Msgbox "Please fill out the Assigned Team field first." Bug_FieldCanChange = false

Application Lifecycle Management Defect CustomerPage 29

Page 30: ALM Defect Customization

else Bug_FieldCanChange = DefaultRes end if

On Error GoTo 0End Function

Function FindUserGroup(UserName) On Error Resume next'This Function finds the user's Team'userName is the name of the User in Detected By field'Return value: the Team name the User ble

dim com dim rec

set com = TDConnection.Command SQL = "select al_description from all_lists where al_item_id in (select al_father_id from all_lists where al_description='" & _ UserName & "')" com.CommandText = SQL set rec = com.Execute

FindUserGroup = rec.FieldValue("al_description")

Application Lifecycle Management Defect CustomerPage 30

Page 31: ALM Defect Customization

set rec = nothing set com = nothing

On Error Goto 0End Function

Function VerifyUserExistsInGroup(Field1, Field2) On Error Resume Next‘This Function verifies whether the User exists in a Team.‘Field1 is the Team Field (Assigned Team, Detected by Team)‘Field 2 is the User Field (Assigned To, Detected By)‘Return values: 0 if user is not found in Team, non-zero if found

dim com 'As Command dim rec 'As RecordSet

set com = TDConnection.Command SQL = "select * from all_lists where al_father_id in (select al_item_id from all_lists where al_description='" & _ Bug_Fields(Field1).Value & "') and al_description='" & Bug_Fields(Field2).Value & "'" com.CommandText = SQL set rec = com.Execute

VerifyUserExistsInGroup = rec.RecordCount

set rec = nothing set com = nothing

On Error GoTo 0End Function

Application Lifecycle Management Defect CustomerPage 31

Page 32: ALM Defect Customization

II. FUT Project Code

A. Assigned To and Assigned Team field Customizations

The Assigned To list box should only display Users who belong to the Team that was selected in the Assigned Team list box. To do this, a number of things must be considered:

1. Each Team must be its own separate list. This is because it is impossible to hide list items from users. We have removed the original ASSIGNED TO lookup list and created a lookup list for each individual Team, containing its users. When you need to add or delete users to the project, make sure you add/delete the users from the Team in the Customize Project List section.

2. When a user changes the Assigned Team field, the Assigned To field will be blanked out so the user will be forced to enter a valid user that belongs to the new Team.

3. Since the Assigned To needs to be a lookup list, the original Assigned To field (BG_RESPONSIBLE), which is a USER LIST, has been hidden from users. However, we need to synch the value between the two Assigned To fields because the User List is needed for the Defect Automatic Mail feature.

Fields Involved:Assigned To – BG_USER_14Assigned Team – BG_USER_01AssignedTo (original field, hidden) – BG_RESPONSIBLE

Code:

Defects Module:

Sub WizardListCust' This subroutine had been automatically generated by "Script Generator - List Customization".' Any modification you make will be overwritten next time you use the generator.    ' BEGIN: When primary Assigned Team value is changed, Assigned To's selection list will change.    Select Case Bug_Fields("BG_USER_01").Value        Case "AGSP"            Bug_Fields("BG_USER_14").List = Lists("TEAM-AGSP")        Case "AGSP-Logistics"            Bug_Fields("BG_USER_14").List = Lists("AGSP-Logistics")        Case "AGSP-Order Management"            Bug_Fields("BG_USER_14").List = Lists("AGSP-Order Management")        Case "AGSP-Planning"            Bug_Fields("BG_USER_14").List = Lists("AGSP-Planning")        Case "AGSP-Pricing"            Bug_Fields("BG_USER_14").List = Lists("AGSP-Pricing")        Case "AGSS"            Bug_Fields("BG_USER_14").List = Lists("TEAM-AGSS")        Case "AGSS-Contract and Warranty"            Bug_Fields("BG_USER_14").List = Lists("AGSS-Contract & Warrenty")        Case "AGSS-Installed Base"            Bug_Fields("BG_USER_14").List = Lists("AGSS-Installed Base")        Case "AGSS-Service Delivery"

Application Lifecycle Management Defect CustomerPage 32

Page 33: ALM Defect Customization

            Bug_Fields("BG_USER_14").List = Lists("AGSS-Service Delivery")        Case "AGSS-Workforce Planning"            Bug_Fields("BG_USER_14").List = Lists("AGSS-Workforce Planning")        Case "AI"            Bug_Fields("BG_USER_14").List = Lists("AI-Development")        Case "AI-Data Conversion"            Bug_Fields("BG_USER_14").List = Lists("AI-Data Conversion")        Case "AI-Project Focals"            Bug_Fields("BG_USER_14").List = Lists("AI-Development")        Case "AI-Tech Testing"            Bug_Fields("BG_USER_14").List = Lists("AI-Tech Testing")        Case "AI-Technical"            Bug_Fields("BG_USER_14").List = Lists("AI-Development")        Case "BI"            Bug_Fields("BG_USER_14").List = Lists("TEAM-BI")        Case "BI-Functional"            Bug_Fields("BG_USER_14").List = Lists("BI-AGS Parts")        Case "BI-Technical"            Bug_Fields("BG_USER_14").List = Lists("BI-Technical")        Case "CT"            Bug_Fields("BG_USER_14").List = Lists("TEAM-CT")        Case "CT-Basis"            Bug_Fields("BG_USER_14").List = Lists("CT-Basis")        Case "CT-Infrastructure"            Bug_Fields("BG_USER_14").List = Lists("CT-Infrastructure")        Case "CT-Tools"            Bug_Fields("BG_USER_14").List = Lists("CT-Tools")        Case "EDM"            Bug_Fields("BG_USER_14").List = Lists("TEAM-EDM")        Case "EDM-Cross Domain"            Bug_Fields("BG_USER_14").List = Lists("EDM-Cross Domain")        Case "EDM-Customer"            Bug_Fields("BG_USER_14").List = Lists("EDM-Customer")        Case "EDM-Material"            Bug_Fields("BG_USER_14").List = Lists("EDM-Material")        Case "EDM-Product"            Bug_Fields("BG_USER_14").List = Lists("EDM-Product")        Case "EDM-Technical"            Bug_Fields("BG_USER_14").List = Lists("EDM-Technical")        Case "EDM-Vendor"            Bug_Fields("BG_USER_14").List = Lists("EDM-Vendor")        Case "Finance"            Bug_Fields("BG_USER_14").List = Lists("TEAM-Finance")        Case "FINANCE-AP,Assets"            Bug_Fields("BG_USER_14").List = Lists("FINANCE-Accounts Payable")        Case "FINANCE-BI"            Bug_Fields("BG_USER_14").List = Lists("FINANCE-BI")        Case "FINANCE-BTC"            Bug_Fields("BG_USER_14").List = Lists("FINANCE-BTC")        Case "FINANCE-Costing"            Bug_Fields("BG_USER_14").List = Lists("FINANCE-Costing")        Case "FINANCE-EDM"            Bug_Fields("BG_USER_14").List = Lists("FINANCE-EDM")        Case "FINANCE-GL"            Bug_Fields("BG_USER_14").List = Lists("FINANCE-GL")

Application Lifecycle Management Defect CustomerPage 33

Page 34: ALM Defect Customization

        Case "FINANCE-Projects"            Bug_Fields("BG_USER_14").List = Lists("FINANCE-Projects")        Case "FINANCE-Services"            Bug_Fields("BG_USER_14").List = Lists("FINANCE-Services")        Case "FINANCE-Spares"            Bug_Fields("BG_USER_14").List = Lists("FINANCE-Spares")        Case "FINANCE-Tax"            Bug_Fields("BG_USER_14").List = Lists("FINANCE-Tax")        Case "FINANCE-Time,Workflow"            Bug_Fields("BG_USER_14").List = Lists("FINANCE-Workflow")        Case "GBLOPS"            Bug_Fields("BG_USER_14").List = Lists("TEAM-GBLOPS")        Case "GBLOPS-AMJ CES"            Bug_Fields("BG_USER_14").List = Lists("GBLOPS-AMJ CES")        Case "GBLOPS-E2Open Procure to Invoice"            Bug_Fields("BG_USER_14").List = Lists("GBLOPS-E2Open Procure to Invoice")        Case "GBLOPS-ECC AGS Procurement"            Bug_Fields("BG_USER_14").List = Lists("GBLOPS-ECC AGS Procurement")        Case "GBLOPS-ECC SRM"            Bug_Fields("BG_USER_14").List = Lists("GBLOPS-ECC SRM")        Case "GBLOPS-SRM REL1"            Bug_Fields("BG_USER_14").List = Lists("TEAM-GBLOPS")        Case "GBLOPS-SRM REL2"            Bug_Fields("BG_USER_14").List = Lists("TEAM-GBLOPS")        Case "HRM"            Bug_Fields("BG_USER_14").List = Lists("HRM")        Case "HR Management"            Bug_Fields("BG_USER_14").List = Lists("HRM")        Case "OR"            Bug_Fields("BG_USER_14").List = Lists("TEAM-OR")        Case "OR-Change Management"            Bug_Fields("BG_USER_14").List = Lists("OR-Change Management")        Case "OR-Communication"            Bug_Fields("BG_USER_14").List = Lists("OR-Change Management")        Case "OR-Training"            Bug_Fields("BG_USER_14").List = Lists("OR-Change Management")        Case "QA"            Bug_Fields("BG_USER_14").List = Lists("TEAM-QA")        Case "QA-Audit"            Bug_Fields("BG_USER_14").List = Lists("QA-Audit")        Case "QA-Issue Management"            Bug_Fields("BG_USER_14").List = Lists("QA-Risk Management")        Case "QA-Risk Management"            Bug_Fields("BG_USER_14").List = Lists("QA-Risk Management")        Case "QA-Test"            Bug_Fields("BG_USER_14").List = Lists("QA-Test")        Case "S&C"            Bug_Fields("BG_USER_14").List = Lists("TEAM-S&C")        Case "S&C-IBC"            Bug_Fields("BG_USER_14").List = Lists("S&C-IBC")        Case "S&C-Privacy"            Bug_Fields("BG_USER_14").List = Lists("S&C-Security")        Case "S&C-Security"            Bug_Fields("BG_USER_14").List = Lists("S&C-Security")        Case "VC"

Application Lifecycle Management Defect CustomerPage 34

Page 35: ALM Defect Customization

            Bug_Fields("BG_USER_14").List = Lists("TEAM-VC")        Case "VC FEP"            Bug_Fields("BG_USER_14").List = Lists("VC Operations")        Case "VC Lead"            Bug_Fields("BG_USER_14").List = Lists("VC Operations")        Case "VC Operations"            Bug_Fields("BG_USER_14").List = Lists("VC Operations")        Case "VC Sales"            Bug_Fields("BG_USER_14").List = Lists("VC Operations")        Case "VC TFG"            Bug_Fields("BG_USER_14").List = Lists("VC Operations")        Case "VC-ABC"            Bug_Fields("BG_USER_14").List = Lists("TEAM-VC")        Case "VC-ABC FEP"            Bug_Fields("BG_USER_14").List = Lists("TEAM-VC")        Case "VC-ABC TFG"            Bug_Fields("BG_USER_14").List = Lists("TEAM-VC")        Case "VC-UN"            Bug_Fields("BG_USER_14").List = Lists("TEAM-VC")        Case "FINANCE-Fixed Assets"            Bug_Fields("BG_USER_14").List = Lists("FINANCE-Fixed Assets")        Case "FINANCE-Global Trade"            Bug_Fields("BG_USER_14").List = Lists("FINANCE-Global Trade")        Case "AGSS-Portal"            Bug_Fields("BG_USER_14").List = Lists("AGSS-Portal")        Case "AGSS-Projects Systems"            Bug_Fields("BG_USER_14").List = Lists("AGSS-Projects Systems")        Case "FINANCE-Accounts Payable"            Bug_Fields("BG_USER_14").List = Lists("FINANCE-Accounts Payable")        Case "FINANCE-Workflow"            Bug_Fields("BG_USER_14").List = Lists("FINANCE-Workflow")        Case "BI-AGS Parts"            Bug_Fields("BG_USER_14").List = Lists("BI-AGS Parts")        Case "BI-AGS Service"            Bug_Fields("BG_USER_14").List = Lists("BI-AGS Service")        Case "BI-Finance"            Bug_Fields("BG_USER_14").List = Lists("BI-Finance")        Case "BI-Global Operations"            Bug_Fields("BG_USER_14").List = Lists("BI-Global Operations")        Case "BI-Technical"            Bug_Fields("BG_USER_14").List = Lists("BI-Technical")        Case "AI - Data Conversion"            Bug_Fields("BG_USER_14").List = Lists("AI-Data Conversion")        Case "AI-Interface"            Bug_Fields("BG_USER_14").List = Lists("AI-Interface")        Case "AI-Development"            Bug_Fields("BG_USER_14").List = Lists("AI-Development")        Case "FINANCE-COPA"            Bug_Fields("BG_USER_14").List = Lists("FINANCE-COPA")        Case "AI-Portal"            Bug_Fields("BG_USER_14").List = Lists("AI-Portal")        Case Else            Bug_Fields("BG_USER_14").List = Lists("AGSP-Logistics")    End Select

Application Lifecycle Management Defect CustomerPage 35

Page 36: ALM Defect Customization

    ' END: When primary Assigned Team value is changed, Assigned To's selection list will change.End Sub

Sub Bug_FieldChange(FieldName)  WizardListCust ' Added by wizardif FieldName = "BG_USER_01" then   'Blank out Assigned To if Assigned Team changes to a group user doesn't belong to   if VerifyUserExistsInGroup("BG_USER_01", "BG_USER_14") = 0 then      Bug_Fields("BG_USER_14").Value = ""      Bug_Fields("BG_RESPONSIBLE").Value = ""   end if‘Sync BG_USER_14 and BG_RESPONSIBLEelseif FieldName = “BG_USER_14” then Bug_Fields(“BG_RESPONSIBLE”).Value = Bug_Fields(“BG_USER_14”).Valueend ifEnd Sub

Function Bug_FieldCanChange(FieldName, NewValue)  On Error Resume Next  'Prevent modification of Assigned To if Assigned Team is blank  If FieldName = "BG_USER_14" and Bug_Fields("BG_USER_01").IsNull then     Msgbox "Please fill out the Assigned Team field first."     Bug_FieldCanChange = false  else     Bug_FieldCanChange = DefaultRes  end if  Bug_FieldCanChange = DefaultRes  On Error GoTo 0End Function

Function VerifyUserExistsInGroup(Field1, Field2)  On Error Resume Next'This Function verifies whether the User exists in a Team.'Field1 is the Team Field (Assigned Team, Detected by Team)'Field 2 is the User Field (Assigned To, Detected By)'Return values: 0 if user is not found in Team, non-zero if found  dim com 'As Command  dim rec 'As RecordSet   set com = TDConnection.Command   SQL = "select * from all_lists where al_father_id in (select al_item_id from all_lists where al_description='" & _     Bug_Fields(Field1).Value & "') and al_description='" & Bug_Fields(Field2).Value & "'"   com.CommandText = SQL   set rec = com.Execute   VerifyUserExistsInGroup = rec.RecordCount   set rec = nothing   set com = nothing  On Error GoTo 0End Function

Application Lifecycle Management Defect CustomerPage 36

Page 37: ALM Defect Customization

III. Administrator Lockout CodeThe purpose of this code is to enable Administrator to prevent users from logging in

during a maintenance period. The following are the requirements:1. Create a file called “AllowedUsers.txt” in the Project Repository. To find the Project Repository: a. Login to Site Administrator and go to the Site Projects tab. b. Highlight the project you want to lock down. On the right, you will see an edit box called Project Directory. This is where you need to create the file. 2. Copy and Paste the Workflow code below in the Customization area of the project that you wish to lock down.3. The following are the rules that the code will follow: a. If the file is empty, all users can log in. b. If the file contains Quality Center usernames, each of which are separated by New Lines, only those users are allowed to log in. For example, the following entries will allow only alex_qc and alice_qc to log in:

alex_qcalice_qc

Code: Common_Module:

Function CanLogin(DomainName, ProjectName, UserName)  On Error Resume Next   dim ext 'As ExtendedStorage   dim flib, myf

Application Lifecycle Management Defect CustomerPage 37

Page 38: ALM Defect Customization

   dim clntPath   dim allowedUsers()   dim userAllowed   Redim allowedUsers(0)   userAllowed = False   set flib = CreateObject("Scripting.FileSystemObject")   if flib.FolderExists("C:\WinNT\Temp") then      clntPath = "C:\WinNT\Temp"   elseif flib.FolderExists("C:\Windows\Temp") then      clntPath = "C:\Windows\Temp"   else      clntPath = "C:\"   end if   set ext = TDConnection.ExtendedStorage   ext.ServerPath = TDConnection.DirectoryPath(0)   ext.ClientPath = clntPath   ext.Load "AllowedUsers.txt", True   set myf = flib.OpenTextFile(clntPath & "\AllowedUsers.txt", 1)   do while myf.AtEndOfStream <> true      allowedUsers(UBound(allowedUsers)) = myf.ReadLine      Redim Preserve allowedUsers(UBound(allowedUsers) + 1)   loop   if UBound(allowedUsers) > 0 then      Redim Preserve allowedUsers(UBound(allowedUsers) - 1)   end if   if UBound(allowedUsers) = 0 and allowedUsers(0) = "" then      CanLogin = true   else      for i = 0 to UBound(allowedUsers)         if Trim(UCase(User.UserName)) = Trim(UCase(allowedUsers(i))) then            userAllowed = True         end if      next      if userAllowed then         CanLogin = true      else         CanLogin = false      end if   end if   set myf = nothing   set flib = nothing   set ext = nothing  On Error GoTo 0End Function

Application Lifecycle Management Defect CustomerPage 38

Page 39: ALM Defect Customization

IV. Site Administrator Usage queriesThe following SQL queries can be ran in TOAD against the QCSiteAdmin_DB Schema to

get usage statistics

A. List of users who have not logged in within a certain date range:

select user_name from users where user_name not in

(select distinct(user_name) from sessions_history

where start_time>=to_date('08/06/2007', 'mm/dd/yyyy') and

start_time<=to_date('08/09/2007', 'mm/dd/yyyy'));

The first date is the “From” date, while the second is the “To” date.

B. List of idle sessions at a specified amount of time (hours):

select p.ps_domain_name, p.ps_project_name, l.ls_login_time,

l.ls_last_action_time, l.ls_client_type

from login_sessions l, project_sessions p

where (((select sysdate from dual)-ls_last_action_time) * 24 > 1) and

Application Lifecycle Management Defect CustomerPage 39

Page 40: ALM Defect Customization

l.ls_id = p.ps_ls_id

The 1 after the > symbol is 1 hour.

V. Next Responsible Workflow Code:

A. Next Responsible Rules and Challenges:1. NextResponsible code should work when a Step is Passed or Deferred.2. NextResponsible code should not work if any of the Steps are Failed.3. It should no work if the next TESTER is already the same as the Next Responsible. This is because making an unneeded change will trigger a mail to the Next Responsible person.5. When all Steps are Passed, or when the Pass All button is pressed, the Next Responsible field will have the value of "Test Passed". 6. To find the next Step, we use a SQL Statement that orders the Steps for that Run according to ST_STEP_ORDER. However, we do not assume that the next Step is ST_STEP_ORDER + 1. This is because users have the capability of deleting Steps. Thus, you may have an order of 1, 2, 3, 5, where Step of Order 4 was deleted. To make sure we have the correct Step, we use a SQL Statement ordered on the said field, and get the next Record in line.7. We need to make sure that we post the NextResponsible field only if the user presses End Run button. If the User presses the x button to close the Manual Runner window, then a dialog appears that asks the User whether he wants to post the Run. We need to run the code, only if a Yes was pressed. To do this, the Actual posting of data occurs in the ManualRun_Run_AferPost event.8. If the Step's Status was changed to No Run, and the previous Step shows Passed or Deferred, the Next Responsible should change to this current Step's Tester.9. If the Step's TESTER field was changed, this Step's Status is No Run, and the previous Step is Passed or Deferred, the Next Responsible field should also change.10. Step deletion - When a user Deletes a Step during the Run, and if the Step before that deleted Step has a Status of either Passed or Deferred, the Next Responsible should change to the Tester of the Step that comes After it.Challenge: Workflow doesn't catch whether the User pressed Yes or No on the Delete Step Confirmation dialog box. In order to detect this, we use the following methodology:

a. Use a Public variable to switch on when the Delete Step action is executed. Also record the Step ID of the step highlighted when the button was pressed.

b. In the Event immediately after this action (occurs after confirmation message), which is the Step_MoveTo, if the flag is True, find out if the Step still exists. then the user pressed "No", we do nothing. Otherwise, we assign the Next Responsible.

B. Recommendations:

Application Lifecycle Management Defect CustomerPage 40

Page 41: ALM Defect Customization

1. The code is not completely tested for freedom from bugs. Therefore, do not use without extensive testing.2. This code is complex, and has coded around limitations due to the behavior and design of the Quality Center User Interface. This may pose a problem when upgrading to next versions of Quality Center, as the User Interface changes. Therefore, I recommend either of the following before such a time arises:

a. I recommend the Services of HP Professional Services Organization before upgrading to a new version, to properly test and make modifications to the code as necessary.

b. Consider not using the code at all, and try restructuring the Test Cases in a way where each Tester is responsible for their own Tests instead of Testers sharing Tests and owning separate Steps within the same Test Cases. I recommend this because with the latter structure, the capabilities Applied Materials is looking for is already built-in to Quality Center. I also recommend a discussion between Applied Materials and an HP Consultant around customer Test Design and Execution processes to see if the recommended structure can be applied to AMAT at all.

Application Lifecycle Management Defect CustomerPage 41

Page 42: ALM Defect Customization

C. Code:

Common Script: Public KPC 'Variable for passing KPC from Test Lab to Defect Public isPassed 'Boolean, switches when Pass Selected button is pressed Public isPassAll 'Boolean, switches when Pass All button is pressed Public isDelStep 'Boolean, switches when Delete Step button is pressed Public deletedStep 'Long, records Step ID being deleted by Delete Step action Public prevStep 'Long, records the Step ID of the Step before the Deleted one Public deletedStatus 'String, records the Status of the deleted Step Public prevStatus 'String, records the Status of the Step before the deleted one Public postNextResponsible 'Boolean, switch to signal posting of Next Responsible Public NextResponsible 'String, Next Responsible User Public TestID 'Long, records Test ID for Next Responsbile Public NextStep 'String, the name of the Step to be executed by Next Responsible Public TestSetName 'String, records Test Set for Next Responsible

Function ActionCanExecute(ActionName)   'Use ActiveModule and ActiveDialogName to get   'the current context.   On Error Resume Next

  dim rnf 'As RunFactory  dim rn 'As Run  dim stf 'As StepFactory  dim stl 'As List  dim st 'As Step  dim prevst 'As Step

'(Re)-Initialize variables  isPassed = false   isPassAll = false   isDelStep = false   deletedStep = 0   prevStep = 0   deletedStatus = ""   prevStatus = ""

     'Record Pass Selected, Pass All, Delete Step action for Next Responsible code If ActionName = "act_pass_selected" then         isPassed = True      elseif ActionName = "act_pass_all" then         isPassAll = True      elseif ActionName = "act_del" then 'Record also ST_ID and ST_STATUS when Delete Step button is pressed,

Application Lifecycle Management Defect CustomerPage 42

Page 43: ALM Defect Customization

' in able to deal with users pressing No in Confirmation message.        deletedStep = Step_Fields("ST_ID").Value         deletedStatus = Step_Fields("ST_STATUS").Value         isDelStep = True

'Also for the same purpose, find the ST_ID and ST_STATUS of the Step previous to it.        set rnf = TDConnection.RunFactory         set rn = rnf.Item(Step_Fields("ST_RUN_ID").Value)         set stf = rn.StepFactory         set stl = stf.NewList("select * from step where st_run_id=" & Step_Fields("ST_RUN_ID").Value & " order by st_step_order")         for i = 1 to stl.Count            set st = stl.Item(i)            if st.ID = deletedStep then               set prevst = stl.Item(i - 1)               prevStep = prevst.ID               prevStatus = prevst.Status            end if         next      end if

     ActionCanExecute = DefaultRes

'Cleanup  set prevst = nothing   set st = nothing   set stl = nothing   set stf = nothing   set rn = nothing   set rnf = nothing

  On Error GoTo 0 End Function

Sub AssignNextResponsible(Step_ID, Run_ID)  On Error Resume Next 'This subroutine copies the TESTER field of the Step passed to it to the NEXT RESPONSIBLE field.' Parameters: Step_ID: The Step ID of the previous Step where the TESTER field will be copied From.

Application Lifecycle Management Defect CustomerPage 43

Page 44: ALM Defect Customization

' Run_ID: The Run ID of the current Run.dim com 'As Command dim rec 'As RecordSet dim tsf 'As TestFactory dim ts 'As Test dim rnf 'As RunFactory dim rn 'As Run dim stf 'As StepFactory dim st 'As Step dim nextst 'As Step dim lastst 'As Step dim stl 'As List dim allPassed 'As Boolean dim isFailed 'As Boolean dim tsetf 'As TestSetFactory dim tset 'As TestSet

allPassed = True isFailed = False

'Create necessary objects: Test Object, Run Object, TestSet Object   set com = TDConnection.Command    com.CommandText = "select * from step where st_id = " & Step_ID    set rec = com.Execute    set tsf = TDConnection.TestFactory    set ts = tsf.Item(rec.FieldValue("ST_TEST_ID"))    set rnf = TDConnection.RunFactory    set rn = rnf.Item(Run_ID)    set tsetf = TDConnection.TestSetFactory    set tset = tsetf.Item(rn.Field("RN_CYCLE_ID")) 'Get the last Step ID for the Test   set stf = rn.StepFactory    set stl = stf.NewList("select * from step where st_run_id=" & Run_ID & " order by st_step_order desc")    set lastst = stl.Item(1)

'If the Step is not the Last Step, and the Pass All button was not pressed…   If (lastst.ID > Step_ID) and not isPassAll then       com.CommandText = "select * from step where st_run_id=" & Run_ID & " order by st_step_order"       set rec = com.Execute

Application Lifecycle Management Defect CustomerPage 44

Page 45: ALM Defect Customization

'Determine if any of the Steps if Failed. If any steps are Failed, switch the isFailed flag to True.       for i = 1 to rec.RecordCount          if rec.FieldValue("ST_STATUS") = "Failed" then             isFailed = True             exit For          end if          rec.Next       next

'Get the Step Object for the next Step.       set stl = stf.NewList("select * from step where st_run_id=" & Run_ID & " order by st_step_order")       for i = 1 to stl.Count          set st = stl.Item(i)          if st.ID = Step_ID then             set nextst = stl.Item(i + 1)             exit for          end if       next

'If the next Step’s TESTER field is not the same as the NEXT RESPONSIBLE FIELD, and ' none of the steps are Failed…      If ts.Field("TS_USER_16") <> nextst.Field("ST_USER_09") and not isFailed then 'Switch the posting flag to True, and record relevant data for posting and emailing.         postNextResponsible = true          NextResponsible = nextst.Field("ST_USER_09")          TestID = ts.ID          NextStep = nextst.Name          TestSetName = tset.Name 'If NextResponsible variable already has data, do not extract again. ' See Step_FieldChange function for explanation.      elseif Len(NextResponsible) > 0 then          postNextResponsible = true          TestID = ts.ID          NextStep = nextst.Name          TestSetName = tset.Name       end if 'If all Steps are Passed, or the Pass All button was pressed, change NEXT RESPONSIBLE to

Application Lifecycle Management Defect CustomerPage 45

Page 46: ALM Defect Customization

' “Test Passed”.   else       com.CommandText = "select * from step where st_run_id=" & Run_ID & " order by st_step_order desc"       set rec = com.Execute       while not rec.EOR          if rec.FieldValue("ST_STATUS") <> "Passed" then             if not(rec.Position = 0 and isPassed) then                allPassed = false             end if          end if          rec.Next       wend

      if allPassed or isPassAll then          postNextResponsible = true          NextResponsible = "Test Passed"          TestID = ts.ID          NextStep = ""          TestSetName = ""       end if    End If

'Cleanupset tset = nothing set tsetf = nothing set stl = nothing set lastst = nothing set nextst = nothing set st = nothing set stf = nothing set rn = nothing set rnf = nothing set ts = nothing set tsf = nothing set rec = nothing set com = nothing

    PrintError "Step_FieldChange"  On Error GoTo 0 End Sub

Application Lifecycle Management Defect CustomerPage 46

Page 47: ALM Defect Customization

ManualRun Module:

Sub Step_MoveTo  On Error Resume Next

dim rnf 'As RunFactorydim rn 'As Rundim stf 'As StepFactorydim stl 'As Listdim st 'As Stepdim deletedFound 'As Boolean

deletedFound = false

 'If the Delete Step button was pressed, find the Deleted Step. This will tell us whether the User ' confirmed the deletion or not. if isDelStep then      set rnf = TDConnection.RunFactory      set rn = rnf.Item(Step_Fields("ST_RUN_ID").Value)      set stf = rn.StepFactory      set stl = stf.NewList("")      for each st in stl         if st.ID = deletedStep then            deletedFound = true            exit for         end if      next

'If the Deleted Step was not Found, then run the Next Responsible code.     if not deletedFound then         set prevst = stf.Item(prevStep)         if deletedStatus = "No Run" and (prevStatus = "Passed" or prevStatus = "Deferred") then            AssignNextResponsible prevStep, Step_Fields("ST_RUN_ID").Value         end if      end if

     isDelStep = false   end if

Application Lifecycle Management Defect CustomerPage 47

Page 48: ALM Defect Customization

'Cleanup  set st = nothing   set stl = nothing   set stf = nothing   set rn = nothing   set rnf = nothing

 On Error GoTo 0 End Sub

Sub Step_FieldChange(FieldName)  On Error Resume Next

dim rnf 'As RunFactorydim rn 'As Rundim stf 'As StepFactorydim stl 'As Listdim st 'As Stepdim prevst 'As Step

'If the Status has been changed to Passed or Deferred through one of multiple ways…If FieldName = "ST_STATUS" and ((Step_Fields("ST_STATUS").Value = "Passed" or _    Step_Fields("ST_STATUS").Value = "Deferred") or isPassed or isPassAll) then 'Run Next Responsible code.      AssignNextResponsible Step_Fields("ST_ID").Value, Step_Fields("ST_RUN_ID").Value 'If the Status was changed to No Run, or the TESTER field was modified while the current' Step’s Status is No Run…elseif (FieldName = "ST_STATUS" and Step_Fields("ST_STATUS").Value = "No Run") or _   (FieldName = "ST_USER_09" and Step_Fields("ST_STATUS").Value = "No Run") then

'Get the Step object for the previous Step   set rnf = TDConnection.RunFactory    set rn = rnf.Item(Step_Fields("ST_RUN_ID").Value)    set stf = rn.StepFactory    set stl = stf.NewList("select * from step where st_run_id=" & Step_Fields("ST_RUN_ID").Value & " order by st_step_order")    for i = 1 to stl.Count       set st = stl.Item(i)       if st.ID = Step_Fields("ST_ID").Value then          set prevst = stl.Item(i - 1)          exit for       end if    next

Application Lifecycle Management Defect CustomerPage 48

Page 49: ALM Defect Customization

'If the TESTER field was changed, record the value prematurely, because the data is not posted ' in the Database yet.   if FieldName = "ST_USER_09" then       NextResponsible = Step_Fields("ST_USER_09").Value    end if

'If the Status of the previous Step is either Passed or Deferred, run Next Responsible code.   if prevst.Status = "Passed" or prevst.Status = "Deferred" then       AssignNextResponsible prevst.ID, Step_Fields("ST_RUN_ID").Value    end if End If

'Cleanupset prevst = nothing set st = nothing set stl = nothing set stf = nothing set rn = nothing set rnf = nothing

    PrintError "Step_FieldChange"  On Error GoTo 0 End Sub

Sub ManualRun_Run_AfterPost  On Error Resume Next

  dim tsf 'As TestFactory  dim ts 'As Test

'If the user either pressed the End Run button or said Yes in the confirmation dialog after pressing the x ' button of the Manual Runner window, change the NEXT RESPONSIBLE field.  if postNextResponsible then      set tsf = TDConnection.TestFactory      set ts = tsf.Item(TestID)      ts.Field("TS_USER_16") = NextResponsible      ts.Post 'If there is a Next Step to be executed, send an email to the Next Responsible person.     if Len(NextStep) > 0 then         EmailNextResponsible NextResponsible, TestSetName, ts.Name, NextStep      end if   end if

'Cleanup

Application Lifecycle Management Defect CustomerPage 49

Page 50: ALM Defect Customization

  set ts = nothing   set tsf = nothing

  On Error GoTo 0 End Sub

Sub EmailNextResponsible(nextresp, tsetname, tstname, stpname)  On Error Resume Next 'This function sends an email to the Next Responsible tester.'Parameters: nextresp – Next Responsible Tester’s Username' tsetname – TestSet where the Test to be executed is located.' tstname – The name of the Test that needs to be executed.' stpname – The name of the Step that needs to be executed.dim MessageSubject dim MessageBody

  MessageSubject = "Please execute the following step"   MessageBody = "You are the Next Responsible for the following Step. Please execute it: " & vbcrlf & vbcrlf   MessageBody = MessageBody & "Test Set: " & tsetname & vbcrlf   MessageBody = MessageBody & "Test Name: " & tstname & vbcrlf   MessageBody = MessageBody & "Step Name: " & stpname   'TDConnection.SendMail nextresp, User.UserName, MessageSubject, MessageBody, nothing, "Text"

 On Error GoTo 0 End Sub

Application Lifecycle Management Defect CustomerPage 50