Oct
26
2008
--

Difference between IE6 and IE7

This article will take you over various differences between Internet Explorer 6 (IE6) and Internet Explorer 7 (IE7). These difference would be from QTP automation perspective

Difference #1 - Alert dialog title

IE6 alert dialog title is “Microsoft Internet Explorer” and for IE7 the alert dialog title is “Windows Internet explorer”

IE7 Alert dialog

IE7 Alert dialog


IE6 Alert dialog

IE6 Alert dialog

Both windows can be easily supported at the same time in QTP by using regular expression “(Windows|Microsoft) Internet Explorer”. The statement is true whether we use object repository or descriptive programming.

Difference #2 - Multiple Tab windows

IE7 supports multiple tabs. QTP 9.2 supports IE7 but with tabs setting disabled, QTP 9.5 supports testing IE7 with tabs also. So is there any other difference because of these tabs? Because if IE7 tabs QTP now identifies the each tab as a Browser and not the whole window as a Browser. The statement would become clear when we look at the below code

Maximizing IE6 Browser

Dim hwndBrw
hwndBrw = Browser("Browser").GetROProperty("hwnd")
Window("hwnd:=" & hwndBrw).Maximize

But when we run the same code in IE7 QTP throws below error

The operation cannot be performed error

The operation cannot be performed error

The reason for this error is that the handle of the window that we receive is not the main browser window handle but the sub window handle (TAB) which cannot be maximized. To receive the main window handle we would need to use Windows API

Dim hwndBrw, hwndWindow
hwndBrw = Browser("Browser").GetROProperty("hwnd")
 
Const GA_ROOT = 2
'Declare Function GetAncestor Lib "user32.dll" (ByVal hwnd As Long, ByVal gaFlags As Long) As Long
Extern.Declare micLong, "GetMainWindow", "user32" ,"GetAncestor",micLong, micLong
 
'Get the main IE window handle
hwndWindow = Extern.GetMainWindow(hwndBrw, GA_ROOT)
Window("hwnd:=" & hwndWindow).Maximize

Note: Above code will work on IE6 as well

Difference #3 - Certificate Security error

The way IE7 present certificate error is completely different from way IE6 does it

IE6 Certificate security error

IE6 Certificate security error


IE7 Certificate security error

IE7 Certificate security error

Handling the IE7 security error is as easy as it gets

If Browser("KnowledgeInbox").Page("IE7").Link("text:=Continue to this website \(not recommended\)\.").Exist Then
     Browser("KnowledgeInbox").Page("IE7").Link("text:=Continue to this website \(not recommended\)\.").Click
End If

or

If Browser("KnowledgeInbox").Page("IE7").Link("html id:=overridelink").Exist Then
    Browser("KnowledgeInbox").Page("IE7").Link("html id:=overridelink").Click
End If

These are 3 key differences IMO which needs to taken care of in case both IE6 and IE7 needs to be supported by QTP scripts.

Rating: 0.0/10 (0 votes cast)
Oct
25
2008
--

When to change QTP Web ReplayType Setting?

What is ReplayType?

ReplayType is QTP Web Add-in setting. It can be used to change how the events are replayed on the browser. There are two modes of ReplayType

  • Events (1) - Replay of events using the Browser methods (something similar to DOM).
  • Mouse (2) - Replay of events using the mouse and keyboard simulation.

When to change ReplayType?

Use of ReplayType can be best explained by a below example. In below sample textbox we need to type in any value and see that the button gets enabled when there some text in the textbox and disabled when there is not text. Click on the button will display the values inside the textbox.

Scenario #1

Type in textbox and enable the button:

Now when we record using QTP on this page we would get the below code

Browser("KnowledgeInbox").Page("ReplayType").WebEdit("txtReplayType").Set "KnowledgeInbox"
Browser("KnowledgeInbox").Page("ReplayType").WebButton("Type and enable me").Click

But on replay QTP will throw a “Object is disabled” error as shown in below image

Object is disabled error during replay

Object is disabled error during replay

QTP throws above error as the ReplayType of the Web Add-in is set to 1 (Events). Let’s look at the HTML code related to the text box

<input onkeyup="EnableThis(this, document.getElementsByName('btnReplayType')[0])" name="txtReplayType" size="20" type="text" />

The input text box has a handler for onkeyup event. Now with ReplayType as 1 (events) QTP just goes and sets the value of textbox which means non of the events get fired. Now there are two possible solutions for the same. We will look at each of them one by one

Solution #1
Firing the handled event manually using FireEvent. In this approach we need to look into the HTML and see which event has a handler and fire the same after changing the value of the textbox

Browser("KnowledgeInbox").Page("ReplayType").WebEdit("txtReplayType").Set "KnowledgeInbox"
Browser("KnowledgeInbox").Page("ReplayType").WebEdit("txtReplayType").FireEvent "onkeyup"
Browser("KnowledgeInbox").Page("ReplayType").WebButton("Type and enable me").Click

Solution #2
Changing ReplayType to 2 (Mouse) will instruct QTP to replay the Set method using Keyboard and mouse simulation. This would simulate a actual user typing into the browser

Setting.WebPackage("ReplayType") = 2 'Mouse
Browser("KnowledgeInbox").Page("ReplayType").WebEdit("txtReplayType").Set "KnowledgeInbox"
Browser("KnowledgeInbox").Page("ReplayType").WebButton("Type and enable me").Click
Setting.WebPackage("ReplayType") = 1 'Events

We saw two of the few possible solutions. Which one should be used then? IMO we should first go for Solution #1 and if that does not work then for Solution #2. The reason behind that opinion is that ReplayType=2 means that your workstation needs unlocked when QTP replays the script.

Scenario #2
I won’t demonstrate the 2nd scenario but would just give overview of the same. For some links which opens popups, when clicked manually popup would open. But when we do the same thing through QTP it IE popup blocker would show a popup blocked message. IE popup blocker is said to be smart enough to determine if a user clicked a link or it was done through code and based on the same the popup is blocked or shown. Changing ReplayType to 2 (Mouse) would simulate a user click and not give the popup bar.

Rating: 0.0/10 (0 votes cast)
Oct
20
2008
--

How to check for error pages (Page cannot be displayed)?

This is the first article in my “How to?” series and i hope there would be many more that i would be able to write in future.

While testing any web application there can be instances where the application is not available or you get a page cannot be displayed, internal server error etc and need to take some action based on the same. I present a very generic function which returns True/False whether there is an error on the page or not. The best part about this function is that it is compatible with both IE and FF

'Author: Tarun Lalwani
'Website: www.KnowledgeInbox.com
 
'Function: IsPageCannotBeDisplayed
'Comments: To check if a Page cannot be displayed or some other keyword is present on the page
'Input:
'@Brw - QTP Browser Test object
'@PCD_Keyword - Keywords to be used for checking a page cannot
'				be displayed error.
'Return: True/False in case error has occurred
Public Function IsPageCannotBeDisplayed(oBrw, PCD_Keywords)
	Dim sUrl, sPageText, oPg
 
	IsPageCannotBeDisplayed = False
 
	If Not oBrw.Exist(0) Then Exit Function
 
	'Get the page object
	Set oPg = oBrw.Page("micclass:=Page")
 
	'A page might not exist when the dialog modal is present
	'in the browser
	If Not oPg.Exist(0) Then Exit Function
 
	sURL = oBrw.Page("micclass:=Page").GetROProperty("URL")
 
	'Special check for IE and FF URL checks
	If InStr(1, sURL, "shdoclc.dll", vbTextCompare) <> 0 or _
		InStr(1, sURL, "about:neterror?", vbTextCompare) <> 0 Then
		IsPageCannotBeDisplayed = True
	'IF IE then we will use HTML DOM to get the whole page text
	ElseIf InStr(1, oBrw.GetROProperty("version"),"internet explorer", vbTextCompare) Then
		sPageText = oPg.Object.documentElement.outerText
	Else
		'We now assume it is Firefox. So object property is not available
		'This approach won't work on IE
		sPageText = oPg.GetROProperty("outertext")
	End If
 
	Dim sKeyword
 
	For each sKeyword in PCD_Keywords
		'Check if our keyword exist on the page
		If InStr(1, sPageText , sKeyword, vbTextCompare) Then
			IsPageCannotBeDisplayed = True
			Exit Function
		End if
	Next
End Function
 
'Keywords for page cannot be displayed. Different application have different pages for
'page cannot be displayed. Make sure you a unique keyword is picked from the page
Dim PCD_Keywords
PCD_Keywords = Array("The page cannot be displayed", "Sorry page is not found", "Internal server error")
 
'Usage
'Msgbox IsPageCannotBeDisplayed(Browser("Mozilla Firefox Start"), PCD_Keywords)
Rating: 6.0/10 (6 votes cast)
Oct
12
2008
--

“The parameter is incorrect” error when typing into a WebEdit

Sometimes QTP throws a “The parameter is incorrect” error when setting a text in a WebEdit

The parameter is incorrect error

The parameter is incorrect error

Below is a test textbox to reproduce the issue

WebEdit with Max Length 4:

The error can be reproduced using below code

'Will work fine
Browser("KnowledgeInbox").Page("KnowledgeInbox").WebEdit("txtMaxTest").Set "1234"
 
'Will throw a parameter is incorrect error
Browser("KnowledgeInbox").Page("KnowledgeInbox").WebEdit("txtMaxTest").Set "12345"

There are two root causes of this issue

Root Cause #1
Trying to set a text in a textbox greater than it’s max length would raise the error. The sample textbox shown in this article has Max length of 4. That is the reason why the 2nd line of the code shown above throws an error

Root Cause #2
This root cause is specific to firefox browser. If ReplayType (in Tools->Options->Web (Tab) -> Advacned…(button)) is set to Mouse then an set operation on a WebEdit in Firefox will produce this error. The code below can be used to reproduce the error

'Will work fine
Setting.WebPackage("ReplayType") = 1 'Browser
Browser("KnowledgeInbox").Page("KnowledgeInbox").WebEdit("txtMaxTest").Set "1234"
 
Setting.WebPackage("ReplayType") = 2 'Mouse
'Will throw a parameter is incorrect error even when we type the same text
Browser("KnowledgeInbox").Page("KnowledgeInbox").WebEdit("txtMaxTest").Set "1234"
Rating: 8.9/10 (15 votes cast)
Sep
26
2008
--

DP Part 1 - Overview

Introduction

This document demonstrates the usage of Descriptive programming in QTP 8.20. It also discusses situations where Descriptive programming can be used. Using Descriptive Programming automation scripts can be created even if the application has not been developed.

Descriptive Programming

Whenever QTP records any action on any object of an application, it adds some description on how to recognize that object to a repository of objects called object repository. QTP cannot take action on an object until unless its object description is in the Object Repository. But descriptive programming provides a way to perform action on objects which are not in Object repository

Object Identification:

To identify an object during the play back of the scripts QTP stores some properties which helps QTP to uniquely identify the object on a page. Below screen shots shows an example Object repository:

Sample object repository

Sample object repository

Now to recognize a radio button on a page QTP had added 2 properties the name of the radio button and the html tag for it. The name the left tree view is the logical name given by QTP for the object. This can be changed as per the convenience of the person writing the test case. QTP only allows UNIQUE logical name under same level of hierarchy. As we see in the snapshot the two objects in Browser->Page node are “WebTable” and “testPath”, they cannot have the same logical name. But an object under some other node can have the same name. Now with the current repository that we have, we can only write operation on objects which are in the repository. Some of the example operations are given below

Browser("Browser").Page("Page").WebRadioGroup ("testPath").Select "2"
cellData = Browser("Browser").Page("Page").WebTable ("WebTable").GetCellData (1,1)
Browser("Example2").Page("Page").WebEdit("testPath").Set "Test text"

When and Why to use Descriptive programming?

Below are some of the situations when Descriptive Programming can be considered useful:

  1. The objects in the application are dynamic in nature and need special handling to identify the object. The best example would be of clicking a link which changes according to the user of the application, Ex. “Logout <>”.
  2. When object repository is getting huge due to the no. of objects being added. If the size of Object repository increases too much then it decreases the performance of QTP while recognizing a object.
  3. 3. When you don’t want to use object repository at all. Well the first question would be why not Object repository? Consider the following scenario which would help understand why not Object repositoryScenario 1: Suppose we have a web application that has not been developed yet. Now QTP for recording the script and adding the objects to repository needs the application to be up, that would mean waiting for the application to be deployed before we can start of with making QTP scripts. But if we know the descriptions of the objects that will be created then we can still start off with the script writing for testing

    Scenario 2: Suppose an application has 3 navigation buttons on each and every page. Let the buttons be “Cancel”, “Back” and “Next”. Now recording action on these buttons would add 3 objects per page in the repository. For a 10 page flow this would mean 30 objects which could have been represented just by using 3 objects. So instead of adding these 30 objects to the repository we can just write 3 descriptions for the object and use it on any page.

  4. Modification to a test case is needed but the Object repository for the same is Read only or in shared mode i.e. changes may affect other scripts as well.
  5. When you want to take action on similar type of object i.e. suppose we have 20 textboxes on the page and there names are in the form txt_1, txt_2, txt_3 and so on. Now adding all 20 the Object repository would not be a good programming approach.

How to use Descriptive programming?

There are two ways in which descriptive programming can be used

  1. By creating properties collection object for the description.
  2. By giving the description in form of the string arguments.

By creating properties collection object for the description.

To use this method you need first to create an empty description

Dim obj_Desc 'Not necessary to declare
Set obj_Desc = Description.Create

Now we have a blank description in “obj_Desc”. Each description has 3 properties “Name”, “Value” and “Regular Expression”.

obj_Desc("html tag").value= "INPUT"

When you use a property name for the first time the property is added to the collection and when you use it again the property is modified. By default each property that is defined is a regular expression. Suppose if we have the following description

obj_Desc("html tag").value= "INPUT"
obj_Desc("name").value= "txt.*"

This would mean an object with html tag as INPUT and name starting with txt. Now actually that “.*” was considered as regular expression. So, if you want the property “name” not to be recognized as a regular expression then you need to set the “regularexpression” property as FALSE

obj_Desc("html tag").value= "INPUT"
obj_Desc("name").value= "txt.*"
obj_Desc("name").regularexpression= "txt.*"

This is how of we create a description. Now below is the way we can use it

Browser("Browser").Page("Page").WebEdit(obj_Desc).set "Test"

When we say .WebEdit(obj_Desc) we define one more property for our description that was not earlier defined that is it’s a text box (because QTPs WebEdit boxes map to text boxes in a web page).

If we know that we have more than 1 element with same description on the page then we must define “index” property for the that description

Consider the HTML code given below

<input name="txt_Name" type="textbox" />
<input name="txt_Name" type="textbox" />

Now the html code has two objects with same description. So distinguish between these 2 objects we will use the “index” property. Here is the description for both the object

For 1st textbox:

obj_Desc("html tag").value= "INPUT"
obj_Desc("name").value= "txt_Name"
obj_Desc("index").value= "0"

For 2nd textbox:

obj_Desc("html tag").value= "INPUT"
obj_Desc("name").value= "txt_Name"
obj_Desc("index").value= "1"

Consider the HTML Code given below:

<input name="txt_Name" type="textbox" />
<input name="txt_Name" type="radio" />

We can use the same description for both the objects and still distinguish between both of them

obj_Desc("html tag").value= "INPUT"
obj_Desc("name").value= "txt_Name"

When I want to refer to the textbox then I will use the inside a WebEdit object and to refer to the radio button I will use the description object with the WebRadioGroup object.

Browser("Browser").Page("Page").WebEdit(obj_Desc).set "Test" 'Refers to the text box
Browser("Browser").Page("Page").WebRadioGroup(obj_Desc).set "Test" 'Refers to the radio button

But if we use WebElement object for the description then we must define the “index” property because for a webelement the current description would return two objects.

Hierarchy of test description

When using programmatic descriptions from a specific point within a test object hierarchy, you must continue to use programmatic descriptions
from that point onward within the same statement. If you specify a test object by its object repository name after other objects in the hierarchy have
been described using programmatic descriptions, QuickTest cannot identify the object.

For example, you can use Browser(Desc1).Page(Desc1).Link(desc3), since it uses programmatic descriptions throughout the entire test object hierarchy.
You can also use Browser(”Index”).Page(Desc1).Link(desc3), since it uses programmatic descriptions from a certain point in the description (starting
from the Page object description).

However, you cannot use Browser(Desc1).Page(Desc1).Link(”Example1″), since it uses programmatic descriptions for the Browser and Page objects but
then attempts to use an object repository name for the Link test object (QuickTest tries to locate the Link object based on its name, but cannot
locate it in the repository because the parent objects were specified using programmatic descriptions).

Getting Child Object

We can use description object to get all the objects on the page that matches that specific description. Suppose we have to check all the checkboxes present on a web page. So we will first create an object description for a checkboxe and then get all the checkboxes from the page

Dim obj_ChkDesc
 
Set obj_ChkDesc=Description.Create
obj_ChkDesc("html tag").value = "INPUT"
obj_ChkDesc("type").value = "checkbox"
 
Dim allCheckboxes, singleCheckBox
Set  allCheckboxes = Browse("Browser").Page("Page").ChildObjects(obj_ChkDesc)
 
dim i
For i = 0 to allCheckboxes.Count - 1
	singleCheckBox(i).Set "ON"
Next

The above code will check all the check boxes present on the page. To get all the child objects we need to specify an object description i.e. we can’t use the string arguments that will be discussed later in the 2nd way of using the programming description.

Possible Operation on Description Object

Consider the below code for all the solutions

Dim obj_ChkDesc
 
Set obj_ChkDesc=Description.Create
obj_ChkDesc("html tag").value = "INPUT"
obj_ChkDesc("type").value = "checkbox"

Q: How to get the no. of description defined in a collection

obj_ChkDesc.Count 'Will return 2 in our case

Q: How to remove a description from the collection

obj_ChkDesc.remove "html tag" 'would delete the html tag property from the collection

Q: How do I check if property exists or not in the collection?
A: The answer is that it’s not possible. Because whenever we try to access a property which is not defined its automatically added to the collection. The only way to determine is to check its value that is use a if statement “if obj_ChkDesc(”html tag”).value = empty then”.

Q: How to browse through all the properties of a properties collection?

For i=0 to obj_ChkDesc.count - 1
    Name= obj_ChkDesc(i).Name
    Value= obj_ChkDesc(i).Value
    RE = obj_ChkDesc(i).regularexpression
Next

By giving the description in form of the string arguments

You can describe an object directly in a statement by specifying property:=value pairs describing the object instead of specifying an object’s
name. The general syntax is:

TestObject("PropertyName1:=PropertyValue1", "..." , "PropertyNameX:=PropertyValueX")

TestObject-the test object class could be WebEdit, WebRadioGroup etc….

PropertyName:=PropertyValue-the test object property and its value. Each property:=value pair should be separated by commas and quotation
marks. Note that you can enter a variable name as the property value if you want to find an object based on property values you retrieve during a run session.

Consider the HTML Code given below:

<input name="txt_Name" type="textbox" />
<input name="txt_Name" type="radio" />

Now to refer to the textbox the statement would be as given below

Browser("Browser").Page("Page").WebEdit("Name:=txt_Name","html tag:=INPUT").set "Test"

And to refer to the radio button the statement would be as given below

Browser("Browser").Page("Page").WebRadioGroup("Name:=txt_Name","html tag:=INPUT").set "Test"

If we refer to them as a web element then we will have to distinguish between the 2 using the index property

'Refers to the textbox
Browser("Browser").Page("Page").WebElement("Name:=txt_Name","html tag:=INPUT","Index:=0").set "Test" 
 
'Refers to the radio button
Browser("Browser").Page("Page").WebElement("Name:=txt_Name","html tag:=INPUT","Index:=1").set "Test"
Rating: 6.0/10 (15 votes cast)