Showing posts with label Programming Help. Show all posts
Showing posts with label Programming Help. Show all posts

Tuesday, June 10, 2014

Automation of Silverlight application using QTP - typical object identification issue

I am trying to consolidate the typical issues I have faced during Microsoft Silverlight v5.1 using QTP 11. I have tried to write generic functions so that it can be used as part of automation framework.

1. Scenario: Dropdown list having checkboxex in it is defined in usign SLVTable object where rows of the table contains the checkboxes and the name of the checkbox in the row. This object is not directly being identified by the tool. To handle this issue I wrote the following function and register it with SlvTable object to select specific check box:

'desc: it is the parameter which contains name of the checkbox. In my application name is given in second column. Index can be updated based on the application.

Sub ClickSLVTableDropDown(obj, desc)
rows=obj.RowCount
index=0
For cnt=0 to rows-1
var=obj.GetCellData(cnt,1)
If strcomp(var,desc,1)=0 Then
index=cnt
Exit for
End If
Next

set obj=obj.GetCellChildObjects(index,0)
obj(0).click
End Sub

RegisterUserFunc "SlvTable", "ClickSLVTableDropDown", "ClickSLVTableDropDown"




2. Scenario: SlvTable is used to have values in the dropdown but does not have checkboxes. Apart from only the values in the dropdown visible on the screen are counted as number of rows in the SlvTable not all the values it contains. So if you want to loop in the table, the option is not a feasible option.

Organization of the object: Dropdown object is defined as combination of textbox and a button. Clicking on either of these two objects individually the dropdown will come up from which values needs to be selected. Directly entering the value in the text box does not help as the object is organized in such a ways that the value needs to be selected from the table values.

Solution: Click on the SlvTextbox object which would open the drop down. Then use the below code for clicking on the specific value from the dropdown:

Sub SelectValueFromDowpdown(obj, desc)
obj.Click
wait 2
set wsh=createobject("WScript.Shell")
wsh.SendKeys desc
wait 1
wsh.SendKeys "{ENTER}"
End Sub

RegisterUserFunc "SlvEdit", "SelectValueFromDowpdown", "SelectValueFromDowpdown"




3. Scenario:On the page in for navigation to different options for a the navigation options are organized in the way that SlvObject element is embedded in SlvTable object. The scenario may be in such a way that based on certain previous selection the order of appearance of SlvObject may change.

Solution: Get the rows from the SlvTable and find out the order of SlvObject appearance in the table and click the object accordingly.

Sub SelectValue(obj, val)
rows= obj.GetItemsCount
For counter=0 to rows-1
set child=obj.GetItemChildObjects(counter)
child_name=child(0).getRoproperty("text")
If strcomp(child_name,val,1)=0 Then
obj.Select counter
Exit for
End If
Next
End Sub

RegisterUserFunc "SlvList", "SelectValue", "SelectValue"




4. Scenario: Item needs to be selected from SlvComboBox but items are not added to Item property and hence 'Select' method does not work.

Solution: In this scenario loop thru all the elements in the combo box and find out the index of the item you want to select. Then based on this index select the item from the combo box. 

Sub SelectComboOption(obj, combo_option)
total_items=obj.GetItemsCount
For counter=0 to total_items-1
set child= obj.GetItemChildObjects(counter)
item_name=child(0).getRoproperty("text")
If strcomp(item_name,combo_option,1)=0 Then
obj.Select counter
Exit for
End If
Next
End Sub

RegisterUserFunc "SlvComboBox", "SelectComboOption", "SelectComboOption"



5. Scenario: In SLVComboBox select method is able to select the items from the combo box but accordingly changes are not getting reflected. However, while performing similar action manually or using the sendkeys function, the functionality was working. While doing the root cause analysis I found out that in the items collection the items were not added by their name and only class of the item was added in the array.

Solution:  While using object spy I noticed that the dropdown options were being displayed as text block and as child object of the SlvComboBox. Below code shows how the problem is being solved using descriptive programming. A description object is created which represents the item to be selected from the combo box and using childobjects method of the combobox the reference to that object is used to click and select the required item in the combo box.

Browser("").Page("").SlvWindow("").SlvComboBox("").Click
Set  childObj=Description.Create
childObj("classname").value="System.Windows.Controls.TextBlock"
childObj("parent text").value="Filter Name"
set cObj=Browser("").Page("").SlvWindow("").SlvComboBox("").ChildObjects(childObj)
cObj(0).click



Please share if you have alternate ways to resolve these object identification problems. Thanks.

Saturday, October 19, 2013

Automating SAP portal based application automation issues and possible resolutions

Few challenges which I have encountered while automating the SAP portal based applications and I am trying to put them below hoping it would help someone like me (or probably me in future looking for help :-) about code) :

Before going to the specific challenges I would like to write about what I have understood about the SAP NetWeaver portal. They have tried to standardize the controls by clubbing basic HTML web elements in a specific order and then come up with a framework for the portal. So basically at the core it is web add in which helps to identify the objects on the application. Since the portal is relatively new (compared to ECC), it is not as stable as ECC is when it comes to automating the UI using QTP. In this context few of the challenges which I am trying to document below:

1. SAPCombo: It is recorded by the tool but when you try to play back the script the control is not identified by the tool. How it actually works is that when you spy the object you will find that it is a WebEdit and on its click event a webtable opens up which contains the elements of the combo box. To handle this there may be two ways:

a. First add the WebEdit to your object repository-> click on WebEdit in the code-> create a description of the web element from the table you want to click-> add web table to the repository-> use child item method of the WebTable to click on the element you want to click

objDesc=Description.create
objDesc("micClass").value="WebElement"
objDesc("name").value="One"

Browser("Browser").Page("Page").WebEdit("EditBox").click
set childobj=Browser("Browser").Page("Page").WebTable("Table").childobjects(objDesc)
childobj(0).click  (Just find out which native method this object support and invoke that method)

b. Create a Wscript.Shell object and use the sendkey method to perform the action. There may be issues while using this method and I prefer the above method, but in some case when you are not able to figure out the unique identification properties or the placement of the WebEdit(required for childitem method) object in the table cell, it is the method left to go with and works well.

2. SAPEdit: I have noticed that qtp tries to identify the SapEdit using html id property to identify the object, but every time you login a new id is assigned to the object and the script fails. I try to solve this problem is by going by regular expression and index property. Mostly the id is represented something like: WD78DA, where initial WD is constant and remaining string keeps changing. To address this issue what I do is put it as a regular expression- WD.*, and then find out the index of the edit box on the screen and use this property. I have not see this index changing and it helps me to solve this issue. Don't forget to remove the "sapattachedtext" property if that is being used by the tool

3. SAPEdit inside a WebTable: In such case apart from going by indexes and regular expression, you can use childitem method to enter the value in a particular SAPEdit box embedded inside the WebTable.

Browser().Page().WebTable().childItem(1,2, "WebEdit",0).set "Value"

4.SAPButton: Sometimes I have experienced that when you are adding and SAPButton using add button in the object repository, you will find two SAPButton objects at the bottom in the object hierarchy which QTP is showing, in that case you just go ahead and check the second last object in the hierarchy as I have experienced that it had the name property which helped tool to identify the object while execution whereas tool faced difficulty when I added the last object in the hierarchy as it did not have fixed recognition properties associated with the object.

Please post other issues as well if you have faced while automating SAP netweaver portal and how you resolved those. That would help. Thanks.

Tuesday, October 8, 2013

Some Custom functions in QTP

I am placing few of the custom function which I have written, below. These can be reused in the same form without changes and will try to add more here.

'***************************************************************************
Function current_date(date_format)
dim c_date
   Select Case date_format
  Case "dd.mm.yyyy"
c_date=Day(now())&"."&Month(Now())&"."&Year(Now())

Case "dd/mm/yyyy"
c_date=Day(now())&"/"&Month(Now())&"/"&Year(Now())
   End Select

   current_date=c_date
End Function

'***************************************************************************
Sub sap_exit()
SAPGuiSession("type:=GuiSession","name:=ses.0.").Reset " "
SAPGuiSession("type:=GuiSession","name:=ses.0.").Reset "ex"
End Sub

'***************************************************************************
'This function returns arrays of dates from_date to to_date
Function middle_dates(from_date, to_date)
f_date=getdate(from_date)
t_date=getdate(to_date)

'msgbox "start:"&f_date &"/n End:" & t_date
diff=datediff("d",f_date,t_date)
num_elements=CInt(diff)
dim arr_date()
ReDim arr_date(num_elements)
arr_date(0)=format_date(f_date,"dd.mm.yyyy")
For counter=1 to diff
d_var=dateadd("d", counter,f_date)
arr_date(counter)=format_date(d_var, "dd.mm.yyyy")
Next
middle_dates=arr_date
End Function
'***************************************************************************
' This function takes date in dd.mm.yyyy format and convert it to the system date format to be processed
function getdate(d)
str=Split(d,".")
str_day=str(0)
str_month=str(1)
str_year=str(2)
d=dateserial(str_year,str_month,str_day)
'msgbox d
getdate=d
end function
'***************************************************************************
'This cuntion converts date to the required format
Function format_date(dt, format)
return_date=""
  d=CInt(day(dt))
If d<10 Then
d="0"&cstr(d)
End If

m=cint(month(dt))
If m<10 Then
m="0" & cstr(m)
End If

y=year(dt)

Select Case (format)
Case "dd.mm.yyyy"
 return_date=d &"." & m & "." & y 

End Select
format_date=return_date
End Function
'***************************************************************************
'get temp file path
Function getTempFilePath(fileName)
Set objShell = CreateObject("WScript.Shell")
Set colEnvironment = objShell.Environment("PROCESS")
objPath = colEnvironment("temp")
getTempFilePath=objPath&"\"&fileName
End Function
'***************************************************************************
'Generic function to capture screenshot
'Funciton to capture the screenshot
Function CaptureScreenshot(obj)
obj.capturebitmap gettempfilepath("screenshot.png"), true
    CaptureScreenshot=gettempfilepath("screenshot.png")
End Function

'***************************************************************************
'Function Name:current_time
'Function returns current time in HH:MM:SS format
'******************************************************************************************************************
Function current_time()
   current_time=hour(now())&":"&minute(now())&":"&second(now())
End Function
'***************************************************************************
'This subroutine logs SAP status bar event
Sub ReportStatusBarEvent_Desc(obj,desc, screenshot)
   text=obj.getROProperty("text")
   msgtype=obj.getROProperty("messagetype")
If Strcomp(msgtype,"S",1)=0 Then
reporter.ReportEvent  micPass,desc, text, screenshot
else
reporter.ReportEvent  micFail,desc, text, screenshot
End If
End Sub


'******************************************************************************************************************
'Function Name:CustomWait
'Description:This function is written to have custom wait on object
'******************************************************************************************************************
Sub CustomWait(obj, MaxWaitTime)
flag=true
counter=0
While (flag AND counter<=MaxWaitTime)
If obj.exist Then
'If obj.getroproperty("enabled") Then
flag=false
wait 3
'End If
else
wait 3
counter=counter+3
End If
Wend
End Sub

'*****************************************************************************************************************
'Function Name:CustomSendKeys
'Description:Function to use sendkeys operation
'******************************************************************************************************************
Sub CustomSendKeys(obj, desc)
    set wsh=createobject("WScript.Shell")
wsh.SendKeys desc
Set wsh=nothing
End Sub
'******************************************************************************************************************

'You can register these functions with multiple object using registeruserfunc .