Sep
23
2008
--

Implementing Callback in VBScript

Callback is a function which is executed on completion of a registered event. VBScript is not a event driven language, which means we are limited in terms of events for which callback can be implemented.

This article will demonstrate how to implement a callback on finish/terminate event. This finish/terminate event could be one of the following

  • The script finishes/terminates
  • A function finishes/terminates
  • A class finishes/terminates

CallBack implementation

We will create a special CallBack class for this

Class Callback
	'The object which called
	Dim Caller
 
	'Code to be executed during callback
	Dim CallBackCode
 
	'When the class ends execute the callback code
	Sub Class_Terminate()
		Execute CallBackCode
	End Sub
End Class

Executing code when script ends
If we want a Finalize function to be called when the script ends we can use the below code

Dim OC
Set OC = New Callback
OC.CallBackCode = "Call Finalize(0)"
 
Function Finalize(ByVal ExitCode)
	Msgbox "The code end with exit code - "  & ExitCode
End Function
 
Msgbox "Script ends here"

Executing code when a function ends

Function Test()
	Dim OC
	Set OC = New CallBack
	OC.CallBackCode = "Msgbox ""Function Test ended"""
 
	x = 2/0
	Msgbox "Unreachable code"
End Function
 
Call Test()

The advantage of implementing this call back is that they are guaranteed to be executed even in case the script end with a error or the function ends with an error. In QTP we can similarly execute a code at the end of the Test by declaring the variable in one of the associate global libraries.

Note: The approach works on the concept that all variables are destroyed once the scope in which they exist ends. It is important to make sure the CallBack object is always taken in a variable declared (as shown in code “Dim OC”)

Executing the Callback on a Class method

In case we want a class method to be called on a class object we can use the caller property

Class Test
     Function CallMe()
            Msgbox "You called me"
     End Function
End Class
 
Dim oTest
Set oTest = new Test
 
Dim OC
Set OC = New CallBack
Set OC.Caller = oTest
OC.CallBackCode = "Call Caller.CallMe"
Rating: 7.2/10 (6 votes cast)
Written by Tarun Lalwani in: VBScript | Tags: , , , , , , , , , , , ,
Sep
21
2008
0

DP Part 4 - Common mistakes

This article would go over some common mistakes people make while using Descriptive Programming (DP) in QTP.

Using strings with Pattern

Let’s assume we want to click a link “Logout (Tarun)” on my web page. Two possible methods that can be used are

Method 1

Browser("miccclass:=Browser").Page("micclass:=Page").Link("text:=Logout (Tarun)").Click

Method 2

Set oDesc = Description.Create
oDesc("text").Value = "Logout (Tarun)"
Browser("miccclass:=Browser").Page("micclass:=Page").Link(oDesc).Click

Now both the above methods will fail giving below mentioned error

Cannot identify the object “[ Link ]” (of class Link). Verify that this object’s properties match an object currently displayed in your application.

Cannot identify the link object

Cannot identify the link object

Looking through the naked eyes on the web page the link does exist indeed

So what went wrong? The problem was with the characters “(” and “)” present in the text of the link we used. By default QTP treats all DP properties as regular expression (r.e.) patterns and “(xxx)” is considered as a group of patter xxx. The text “Logout (Tarun)” when treated as a r.e. gets a literal meaning of “Logout Tarun”, and since there is no such link on the web page QTP throws an error. To avoid such situations we need to escape the regular expression characters using the escape character “\”. Now we have three different solutions to correct the problem

Method 1

Browser("miccclass:=Browser").Page("micclass:=Page").Link("text:=Logout \(Tarun\)").Click

Method 2

Set oDesc = Description.Create
oDesc("text").Value = "Logout \(Tarun\)"
Browser("miccclass:=Browser").Page("micclass:=Page").Link(oDesc).Click

Method 3

Set oDesc = Description.Create
oDesc("text").Value = "Logout (Tarun)"
'Do not treat the value as regular expression.
oDesc("text").RegularExpression = False

Browser(”miccclass:=Browser”).Page(”micclass:=Page”).Link(oDesc).Click

IMO Method 3 should be preferred for a neater coding as we are using the actual text of the link.

Overpopulated description while identifying objects

An overpopulated description does not help in recognizing the object. We should use minimum no. of properties which are stable enough to recognize the object on every single run. Consider the below overpopulated description

Set oDesc = Description.Create
oDesc("html tag").Value = "TABLE"
oDesc("micclass").Value = "WebTable"
oDesc("innertext").Value = "abcde"
oDesc("outertext").Value = "abcde"
oDesc("innerhtml").Value = "<TR><TD>abcde</TD></TR>"
oDesc("outerhtml").Value = "<TABLE><TR><TD>abcde</TD></TR><TABLE>"
oDesc("rows").Value = 1
oDesc("cols").Value = 1

Consider the following advices while create such a description

  • rows and cols are dynamic properties which might change if the table gets updated. These properties should be avoided
  • Only one of the properties from innertext, outertext, outerhtml and innerhtml should be used
  • outerhtml and innerhtml properties should be avoided as they contains various tags and difficult to express
  • When using Browser().Page().WebTable(oDesc) we can skip specifying the micclass and html tag properties also because as soon as we enclose oDesc with the WebTable() test object these two properties are mostly implied.

Considering the above points we can reduce our description to just

Set oDesc = Description.Create
oDesc("outertext").Value = "abcde"

Underpopulated description while using ChildObjects

Though we reduced the no. of properties in the description object when identified a table in the last section but while using ChildObjects method we should make sure the following

  • Maximum description properties should be used to reduce the final result set. Though we should still follow the advices specified in earlier section of overpopulated descriptions except the last one (Where we ignore micclass and HTML tag).
  • When using ChildObjects to find WebElements, “html tag” should always be provided to avoid errors.
  • Property names used in description should be as the same case provided in the QTP help file. IMO changing the case sometimes causes general run error during script run. Though there is no documentation proving that description names are case sensitive

Using “Class Name” instead of “micclass”

Don’t know why by Mercury/HP preferred to show micclass as “Class Name” in the object spy. This misleads many DP user to create a description with non-existent property class name

Class Name shown in object spy

Class Name shown in object spy

'Below is the wrong way
Browser("Class Name:=Browser")
 
'Below is the right way
Browser("micclass:=Browser")
 
'Below is the wrong way
Set oDesc = Description.Create
oDesc("Class Name").Value = "Browser"
oDesc("title").Value = "My title"
 
'Below is the right way
Set oDesc = Description.Create
oDesc("micclass").Value = "Browser"
oDesc("title").Value = "My title"
Rating: 9.5/10 (6 votes cast)