Perfecto Mobile Native Automation Bridge for Micro Focus ALM
Many organizations require the ability to create mobile tests in Perfecto Mobile's Native Automation interface and manage those tests, executions, and results in Micro Focus ALM. This reference architecture describes a method of configuring Micro Focus ALM to accomplish this goal.
On this page:
Prerequisites
- Micro Focus ALM 11.0+
- Tests written in Perfecto Mobile Native Automation
Implementation overview
Micro Focus ALM provides the following extensible APIs for integrating external tools:
- OTA (Open Test Architecture)
- VAPI-XP tests
This implementation uses a standard VAPI-XP test in Micro Focus ALM. When the test is executed, parameters are first passed into the test, then the Perfecto API is called to initiate the execution of a mobile test. Once the execution has completed, the VAPI-XP test collects the Perfecto execution report and attaches it to the run.
This article describes the method for customizing Micro Focus ALM to work with the supplied VAPI-XP script. Minor customizations are also required in the VAPI-XP script. When completed, the VAPI-XP script should be used as a template for future test creation. Copying and pasting the test is the recommended way of duplicating the test.
Step-by-step instructions
Click a step to view details.
Follow the below steps to configure your HP ALM/Quality Center instance.
- In the ALM/QC project, open the project customization.
- Open the Project Lists category.
- Select New List and name the list
Perfecto Mobile
. -
Create the following Items/Sub-Items:
Item Sub-Item Value Cloud URL The hostname in the format: mycompany.perfectomobile.com
Password The password to the Perfecto Mobile username that will be used for automation. Username The Perfecto Mobile username of the user that will be used to execute the automated script - Save the Project Lists category.
- Open the Project Entities category and expand the Test entity.
-
Create a new User Field named
MobileCloud Script Path
and provide the following configuration options.Type String Length 255 Sanitazation Type (HP ALM 12+) Text Masked Off Take note of the Name field. It will contain a value in the format
TS_USER_XX
where XX is a two digit integer. - Save the customization changes and return to the project.
- Open the Test Plan module and create a new test. Choose VAPI-XP as the Test Type. This test will become the template for new Native Automation tests going forward.
- Open the Script tab of the newly created test case and copy the below script into the editor.
- Edit the Const values
SCRIPT_PATH_FIELD
to reflect the field name that was added in step 7. - Open the Parameters tab and create a new parameter named
DeviceID
.
- Create new Native Automation tests in the Perfecto Mobile cloud
- Copy the VAPI-XP template test in HP ALM/Quality Center and name it appropriately.
- Provide the path to the MobileCloud script in the MobileCloud Script Path field of your test. Examples:
PRIVATE:ALM\ALM Test
GROUP:Login Tests\Valid Login
PUBLIC:Req Processing\New Functionality\Reject Req - Open the Test Configurations tab and create a configuration for each device you wish to run the test on. In the Data tab of the configuration, provide the Perfecto Mobile Device ID in the Actual Value field.
- Add the Tests or Test Configurations to a Test Set. They are now ready for execution. All test results will be attached to the Run for each Test Instance.
ALM_Native_Automation_Bridge.zip
' Perfecto Mobile [VBScript]
' Created by Application Lifecycle Management
' 9/29/2014 10:30:10 AM
' ====================================================
' ----------------------------------------------------
' Main Test Function
' Debug - Boolean. Equals to false if running in [Test Mode] : reporting to Application Lifecycle Management
' CurrentTestSet - [OTA COM Library].TestSet.
' CurrentTSTest - [OTA COM Library].TSTest.
' CurrentRun - [OTA COM Library].Run.
' ----------------------------------------------------
Option explicit
'If the custom script path has been added to the Test Plan entity, provide the field name and set USE_CUSTOM_SCRIPT_FIELD = True
'If the script path is being provided in the VAPI-XP script, set USE_CUSTOM_SCRIPT_FIELD = False and set the script path in SCRIPT_PATH
'
'If the ALM/QC project has been configured to have the username, password, and cloud URL stored in a project list, provide the list name in PERFECTO_CONFIG and set
'USE CUSTOM_CONFIG_LIST = True
'If these parameters are being provided in the VAPI-XP script, set USE_CUSTOM_CONFIG_LIST = False and provide the values in CONFIG_USERNAME, CONFIG_PASSWORD, AND CONFIG_CLOUD_URL
Const SCRIPT_PATH_FIELD = "TS_USER_01"Const PERFECTO_CONFIG = "Perfecto Mobile"Const DEBUG_SCRIPT = "PRIVATE:ALM\ALM%20Test.xml"Const USE_CUSTOM_SCRIPT_FIELD = True
Const USE_CUSTOM_CONFIG_LIST = True
Const SCRIPT_PATH = ""Const CONFIG_USERNAME = ""Const CONFIG_PASSWORD = ""Const CONFIG_CLOUD_URL = ""Sub Test_Main(Debug, CurrentTestSet, CurrentTSTest, CurrentRun)
' *** VBScript Limitation ! ***
' "On Error Resume Next" statement suppresses run-time script errors.
' To handle run-time error in a right way, you need to put "If Err.Number <> 0 Then" ' after each line of code that can cause such a run-time error.
On Error Resume Next
' clear output window
TDOutput.Clear
' TODO: put your code here
dim restReq, xmlResponse
set restReq = CreateObject("MSXML2.ServerXMLHTTP.6.0")
Set xmlResponse = CreateObject("MSXML2.DOMDocument.6.0")
Dim username, password, cloudURL
Dim executionId, reportKey, errorMessage
Dim flowEndCode, executionStatus, progressPercentage, completionDescription
If USE_CUSTOM_CONFIG_LIST Then
'Grab the username, password, and cloud URL from the customization list
username = TDConnection.Customization.Lists.List(PERFECTO_CONFIG).RootNode.Child("Username").Children.Item(1).Name
password = TDConnection.Customization.Lists.List(PERFECTO_CONFIG).RootNode.Child("Password").Children.Item(1).Name
cloudURL = TDConnection.Customization.Lists.List(PERFECTO_CONFIG).RootNode.Child("Cloud URL").Children.Item(1).Name
Else
username = CONFIG_USERNAME
password = CONFIG_PASSWORD
cloudURL = CONFIG_CLOUD_URL
End If
'Grab the script path from the custom field and normalize it
Dim scriptPath
If Not Debug And USE_CUSTOM_SCRIPT_FIELD Then
scriptPath = TDConnection.TestFactory.Item(CurrentRun.TestId).Field(SCRIPT_PATH_FIELD)
ElseIf Not Debug And Not USE_CUSTOM_SCRIPT_FIELD Then
scriptPath = SCRIPT_PATH
Else
scriptPath = DEBUG_SCRIPT
End If
'If the user didn't put the XML extension on the script, fix that
If InStr(scriptPath, ".xml") <> Len(scriptPath) - 3 Then
scriptPath = scriptPath & ".xml" End If
scriptPath = URLEncode(scriptPath)
TDOutput.Print "Script Path: " & scriptPath
'Grab the device ID from the actual value of the Test Configuration DeviceID parameter
Dim paramValueFct, paramList, deviceID
Set paramValueFct = CurrentTSTest.ParameterValueFactory
Set paramList = paramValueFct.NewList("")
deviceID = Trim(RemoveHTML(paramList.Item(1).ActualValue))
deviceID = Replace(deviceID, vbCrLf, "")
TDOutput.Print "Using Device ID: " & deviceID
'Assemble and send the execution command
Dim reqURL
reqURL = "https://" & cloudURL & "/services/executions?operation=execute&scriptKey=" & scriptPath & "&user=" & username & "&password=" & password & "&responseFormat=xml¶m.DUT=" & deviceID
TDOutput.Print reqURL
restReq.open "GET", reqURL
restReq.send
xmlResponse.loadXML restReq.responseText
'WScript.Echo restReq.responseText
TDOutput.Print xmlResponse.xml
On Error Resume Next
errorMessage = xmlResponse.selectSingleNode ("/response/errorMessage").text
executionId = xmlResponse.selectSingleNode ("/response/executionId").text
reportKey = xmlResponse.selectSingleNode ("/response/reportKey").text
Err.Clear
TDOutput.Print "Error Message: " & errorMessage
TDOutput.Print "Execution ID: " & executionId
TDOutput.Print "Report Key: " & reportKey
On Error Goto 0
If Not Debug Then
If Len(errorMessage) > 0 Then
TDHelper.AddStepToRun "Connect to MobileCloud", , , errorMessage, "Failed" CurrentRun.Status = "Failed" CurrentTSTest.Status = "Failed" Else
TDHelper.AddStepToRun "Connect to MobileCloud", , , , "Passed" End If
End If
'If the execution started successfully, begin checking the execution status
If Len(errorMessage) = 0 Then
Do
XTools.Sleep 5000
restReq.open "GET", "https://" & cloudURL & "/services/executions/" & executionId & "?operation=status&user=" & username & "&password=" & password & "&responseFormat=xml" restReq.send
xmlResponse.loadXML restReq.responseText
On Error Resume Next
flowEndCode = xmlResponse.selectSingleNode ("/response/flowEndCode").text
executionStatus = xmlResponse.selectSingleNode ("/response/status").text
progressPercentage = xmlResponse.selectSingleNode ("/response/progressPercentage").text
completionDescription = xmlResponse.selectSingleNode ("/response/completionDescription").text
Err.Clear
On Error Goto 0
If Not Debug Then
'If the device is in use, it'll fail here
If progressPercentage = 0.0 And flowEndCode = "Failed" Then
TDHelper.AddStepToRun "Initialization", , , completionDescription, "Failed" End If
End If
'WScript.Echo "Execution Status: " & executionStatus & " | " & progressPercentage
TDOutput.Print "Execution Status: " & executionStatus & " | " & progressPercentage & " | Flow End Code: " & flowEndCode
Loop While executionStatus <> "Completed"
If Not Debug Then
If flowEndCode = "Success" Then
CurrentRun.Status = "Passed" CurrentTSTest.Status = "Passed" Else
CurrentRun.Status = "Failed" CurrentTSTest.Status = "Failed" End If
'Download the execution report and attach it to the run
restReq.open "GET", "https://" & cloudURL & "/services/reports/" & reportKey & "?operation=download&user=" & username & "&password=" & password & "&format=html" restReq.send
Dim fso, file, path
Set fso = CreateObject("Scripting.FileSystemObject")
path = fso.GetSpecialFolder(2)
path = path & "\" & Replace(Replace(Replace(reportKey, "xml", "html"), "/", "_"), ":", "_")
Set file = fso.CreateTextFile( path, True)
file.Write restReq.responseText
file.Close
Dim objRunAttach, newAttach
Set objRunAttach = CurrentRun.Attachments
Set newAttach = objRunAttach.AddItem (Null)
newAttach.FileName = path
newAttach.Type = 1
newAttach.Post
'Download the execution XML report, parse it, and add the steps to the run report
' WScript.Echo "https://" & cloudURL & "/services/reports/" & reportKey & "?operation=download&user=" & username & "&password=" & password & "&format=xml" restReq.open "GET", "https://" & cloudURL & "/services/reports/" & reportKey & "?operation=download&user=" & username & "&password=" & password & "&format=xml" restReq.send
' WScript.Echo restReq.responseText
xmlResponse.loadXML restReq.responseText
xmlResponse.setProperty "SelectionLanguage", "XPath"
Dim actionList
Set actionList = xmlResponse.selectNodes ("//action")
Dim action, status
For Each action In actionList
'WScript.Echo action.childNodes.item(0).firstChild.attributes.getNamedItem("displayName").text
If action.childNodes.item(1).firstChild.firstChild.text Then
status = "Passed" Else
status = "Failed" End If
TDHelper.AddStepToRun action.childNodes.item(0).firstChild.attributes.getNamedItem("displayName").text, , , , status
Next
End If
End If
Set restReq = Nothing
Set xmlResponse = Nothing
Set paramValueFct = Nothing
Set paramList = Nothing
Set fso = Nothing
Set file = Nothing
Set objRunAttach = Nothing
Set newAttach = Nothing
Set actionList = Nothing
Set action = Nothing
If Not Debug Then
End If
' handle run-time errors
If Err.Number <> 0 Then
TDOutput.Print "Run-time error [" & Err.Number & "] : " & Err.Description
' update execution status in "Test" mode
If Not Debug Then
CurrentRun.Status = "Failed" CurrentTSTest.Status = "Failed" End If
End If
End Sub
function URLEncode (sInput)
On Error Resume Next
if IsNull(sInput) then
URLEncode = "" exit function
end if
URLEncode = sInput
URLEncode = Replace(URLEncode, chr(0), "")
URLEncode = Replace(URLEncode, "%", "%25")
URLEncode = Replace(URLEncode, " ", "%20")
URLEncode = Replace(URLEncode, """", "%22")
URLEncode = Replace(URLEncode, "&", "%26")
URLEncode = Replace(URLEncode, "'", "%27")
URLEncode = Replace(URLEncode, "/", "%2F")
URLEncode = Replace(URLEncode, "?", "%3F")
URLEncode = Replace(URLEncode, "\", "%5C")
On Error Goto 0
end function
Function RemoveHTML( strText )
On Error Resume Next
Dim TAGLIST
TAGLIST = ";!--;!DOCTYPE;A;ACRONYM;ADDRESS;APPLET;AREA;B;BASE;BASEFONT;" &_
"BGSOUND;BIG;BLOCKQUOTE;BODY;BR;BUTTON;CAPTION;CENTER;CITE;CODE;" &_
"COL;COLGROUP;COMMENT;DD;DEL;DFN;DIR;DIV;DL;DT;EM;EMBED;FIELDSET;" &_
"FONT;FORM;FRAME;FRAMESET;HEAD;H1;H2;H3;H4;H5;H6;HR;HTML;I;IFRAME;IMG;" &_
"INPUT;INS;ISINDEX;KBD;LABEL;LAYER;LAGEND;LI;LINK;LISTING;MAP;MARQUEE;" &_
"MENU;META;NOBR;NOFRAMES;NOSCRIPT;OBJECT;OL;OPTION;P;PARAM;PLAINTEXT;" &_
"PRE;Q;S;SAMP;SCRIPT;SELECT;SMALL;SPAN;STRIKE;STRONG;STYLE;SUB;SUP;" &_
"TABLE;TBODY;TD;TEXTAREA;TFOOT;TH;THEAD;TITLE;TR;TT;U;UL;VAR;WBR;XMP;" Const BLOCKTAGLIST = ";APPLET;EMBED;FRAMESET;HEAD;NOFRAMES;NOSCRIPT;OBJECT;SCRIPT;STYLE;"
Dim nPos1
Dim nPos2
Dim nPos3
Dim strResult
Dim strTagName
Dim bRemove
Dim bSearchForBlock
nPos1 = InStr(strText, "<")
Do While nPos1 > 0
nPos2 = InStr(nPos1 + 1, strText, ">")
If nPos2 > 0 Then
strTagName = Mid(strText, nPos1 + 1, nPos2 - nPos1 - 1)
strTagName = Replace(Replace(strTagName, vbCr, " "), vbLf, " ")
nPos3 = InStr(strTagName, " ")
If nPos3 > 0 Then
strTagName = Left(strTagName, nPos3 - 1)
End If
If Left(strTagName, 1) = "/" Then
strTagName = Mid(strTagName, 2)
bSearchForBlock = False
Else
bSearchForBlock = True
End If
If InStr(1, TAGLIST, ";" & strTagName & ";", vbTextCompare) > 0 Then
bRemove = True
If bSearchForBlock Then
If InStr(1, BLOCKTAGLIST, ";" & strTagName & ";", vbTextCompare) > 0 Then
nPos2 = Len(strText)
nPos3 = InStr(nPos1 + 1, strText, "</" & strTagName, vbTextCompare)
If nPos3 > 0 Then
nPos3 = InStr(nPos3 + 1, strText, ">")
End If
If nPos3 > 0 Then
nPos2 = nPos3
End If
End If
End If
Else
bRemove = False
End If
If bRemove Then
strResult = strResult & Left(strText, nPos1 - 1)
strText = Mid(strText, nPos2 + 1)
Else
strResult = strResult & Left(strText, nPos1)
strText = Mid(strText, nPos1 + 1)
End If
Else
strResult = strResult & strText
strText = "" End If
nPos1 = InStr(strText, "<")
Loop
strResult = strResult & strText
RemoveHTML = strResult
On Error Goto 0
End Function