Featured

QTP 10 not Recognizing Oracle Forms Obje

Bidun Meduza shared on our Facebook page a problem and solution that I thought might be useful to you too. Problem He had a situation where QTP 10 was unable to recognize objects of Oracle Forms. Th

Read More
QTP 10 not Recognizing Oracle Forms Objects

New Navigation Menus

In order to ease orientation through our vast knowledge archive, we have added the following navigation menus: First Steps Scripting QTP VBScript Tutorial Knowledge Articles (by levels of expertise) B

Read More
New Navigation Menus

Permalinks

We’ve changed the permalinks format, so if you have been experiencing some trouble with finding materials with the old links, then remove the YYYY/MM/ from the URL and you’d be fine. In ca

Read More
Permalinks

Advanced QTP on Android

A first version of AdvancedQTP for Android can be found here. Now you can take this perfect companion with you to keep updated on what’s new in our site.

Read More
Advanced QTP on Android

New Advanced QTP Features: Layout and FB

As you have most surely noticed, we’ve recently changed the site’s theme in order to enhance the overall user experience. As from today, you can also register and login seamlessly with you

Read More
New Advanced QTP Features: Layout and FB Integration

A Free, External, .Net Object Spy

0
by on June 7, 2008 at 01:17

Max Sch had recently brought to our attention the existence of a free, external .Net object spy, which is far superior to QTP’s internal object spy, and .Net object spy.

This new object spy is called Runtime Object Editor, and is downloadable from here (Courtesy of The Code Project).

Update: there’s a more advanced version of the project, located here.

So, what makes this object spy so special compared to QTP’s pretty impressive .Net object spy? It doesn’t hold back. While the native .Net spy will give you an object’s public properties and events, this object spy will present properties, events, methods, and “Fields”, which includes some behind-the-scenes backdoor properties, such as the underlying data layer behind public collections, etc.

So, let’s see it in action. Once you’ve downloaded and extracted the project’s archive, you start the object spy by activating RuntimeObjectEditorLoader.exe, which will present you with this basic screen. In order to spy on a .Net object, you simply have to drag the target icon from the top left corner onto the relevant object.

image image

Beside the usual icons for arranging the data by categories image or by alphabetical order image , the window presents several view options. You can choose to see properties image, all properties image, all fields (kind of extended properties) image, events image, methods image and process info image.

Here’s from the project’s documentation:

The Properties tab simply emulates the Properties tab we normally see in Visual Studio. This Properties tab will show the properties of the object based on the attributes they have set. Some properties that are normally visible at design time only, might not be visible here. Also, properties that are marked with DesignerSerializationVisibily(Hidden) or Browsable(false) will not be visible in this tab.

The AllFields tab will show you all the fields defined in each class from the selected object’s hierarchy. The fields can be modified (unless marked as read-only).

The AllProperties tab will display all the properties defined on the objects, disregarding the attributes or visibility of the properties. The AllProperites tab also allows hierarchical navigation inside the collections by allowing you to expand them and select items you want to modify.

The Events tab will display all the events defined on an object and give you the option to view all the event listeners attached to each event, including the objects that own the event handler and the function name that will handle the event.

The Methods tab displays the object methods and allows you to invoke them.

As the number of the view options indicates, this external spy far surpasses the native .Net spy of QTP on every account. The ability to view semi-private properties via the AllProperties tab is extremely useful for understanding the flow of information within the AUT’s objects.

Its only main drawback is the inability to use it on hidden / layered controls (as you cannot visually point at them); while the native QTP spy always offers the .spy command in these cases (something like SWFWindow(“X”).SWFObject(“Y”).Spy, which opens the spy window for the relevant object once the test is run).

In short, it’s a valuable tool, which can come in handy whenever you’re exploring custom controls, or just trying to figure out what makes the AUT tick.

, ,

Reusing Web Objects after the Page Reloads

0
by on May 27, 2008 at 23:18

Will Roden from the Software Inquisition writes about a major undocumented feature in QTP, which could potentially allow you to write far more elegant test than though possible to date.

One of the more frustrating limitations of QTP web test objects was that they went out of sync whenever the webpage reloaded. This means that if you held a reference to a web-object, you couldn’t could on it to work throughout your script.

For example, this script would break at the last line, since the reference was no longer valid after the webpage reloads:

<span style="color: #0000ff;">Set</span> oBrowser = Browser(<span style="color: #006080;">"version:=inter.*"</span>)
oBrowser.navigate <span style="color: #006080;">"http://www.google.com"</span> <span style="color: #008000;">\'Just navigate to a demo page</span>
<span style="color: #0000ff;">Set</span> oWebEdit = oBrowser.WebEdit(<span style="color: #006080;">"name:=q"</span>, <span style="color: #006080;">"index:=0"</span>) <span style="color: #008000;">\'Get a reference to a web object</span>
oWebEdit.<span style="color: #0000ff;">Set</span> <span style="color: #006080;">"software inquisition"</span>
oWebEdit.submit <span style="color: #008000;">\'This causes the page to reload</span>
oBrowser.sync

<span style="color: #008000;">\'The next line would break</span>
oWebEdit.<span style="color: #0000ff;">Set</span> <span style="color: #006080;">"wally llama"</span>

This means that you cannot count on your variables and references, thus making your script far less elegant than they could have been.

Well, luckily, Will found out an undocumented method which apparently solves the problem. By using a .Init command after the page loads, the web-object “resyncs”, and the script will not break:

<span style="color: #0000ff;">Set</span> oBrowser = Browser(<span style="color: #006080;">"version:=inter.*"</span>)
oBrowser.navigate <span style="color: #006080;">"http://www.google.com"</span>
<span style="color: #0000ff;">Set</span> oWebEdit = oBrowser.WebEdit(<span style="color: #006080;">"name:=q"</span>, <span style="color: #006080;">"index:=0"</span>)
oWebEdit.<span style="color: #0000ff;">Set</span> <span style="color: #006080;">"software inquisition"</span>
oWebEdit.submit <span style="color: #008000;">\'Page reloads</span>
oBrowser.sync

<span style="color: #008000;">\'This "resyncs" oWebEdit:</span>
oWebEdit.init

<span style="color: #008000;">\'Now the next line will work</span>
oWebEdit.<span style="color: #0000ff;">Set</span> <span style="color: #006080;">"wally llama"</span>

 

This means that we can use references, variables, function, and everything we’d ever wanted – we just have to remember to use the .Init command, and all will be well.

 

This post, code examples and knowledge were all taken from this article at Will Roden’s excellent QTP and QA blog – the Software Inquisition.

, , ,

Creating a ZIP Archive

0
by on May 15, 2008 at 06:14

Windows XP has a built-in ZIP mechanism integrated into its file-system. We can easily use this to create standard ZIP archives with only a few commands:

<span style="color: #606060;"> 1:</span> <span style="color: #008000;">\'Variable Declaration</span>
<span style="color: #606060;"> 2:</span> <span style="color: #0000ff;">Dim</span> sSourceFolder
<span style="color: #606060;"> 3:</span> <span style="color: #0000ff;">Dim</span> sArchiveFile
<span style="color: #606060;"> 4:</span>
<span style="color: #606060;"> 5:</span> <span style="color: #0000ff;">Dim</span> oShell
<span style="color: #606060;"> 6:</span> <span style="color: #0000ff;">Dim</span> oZIP
<span style="color: #606060;"> 7:</span> <span style="color: #0000ff;">Dim</span> oSourceFolder
<span style="color: #606060;"> 8:</span>
<span style="color: #606060;"> 9:</span> <span style="color: #008000;">\'Variable Initalization</span>
<span style="color: #606060;"> 10:</span> sSourceFolder = <span style="color: #006080;">"C:\SomeFolder"</span>
<span style="color: #606060;"> 11:</span> sArchiveFile = <span style="color: #006080;">"C:\some.zip"</span>
<span style="color: #606060;"> 12:</span> <span style="color: #0000ff;">set</span> oShell = CreateObject(<span style="color: #006080;">"Shell.Application"</span>)
<span style="color: #606060;"> 13:</span>
<span style="color: #606060;"> 14:</span> <span style="color: #008000;">\'Create ZIP</span>
<span style="color: #606060;"> 15:</span> <span style="color: #0000ff;">Set</span> oZIP= oShell.<span style="color: #0000ff;">NameSpace</span>(sArchiveFile)
<span style="color: #606060;"> 16:</span>
<span style="color: #606060;"> 17:</span> <span style="color: #008000;">\'Get Source Folder</span>
<span style="color: #606060;"> 18:</span> <span style="color: #0000ff;">Set</span> oSourceFolder=oShell.<span style="color: #0000ff;">NameSpace</span>(sSourceFolder)
<span style="color: #606060;"> 19:</span>
<span style="color: #606060;"> 20:</span> <span style="color: #008000;">\'Add source items to ZIP</span>
<span style="color: #606060;"> 21:</span> oZIP.CopyHere(oSourceFolder.Items)

 

Update: As some of you have remarked, the above code only works if there’s already an empty ZIP file in place. Well, no problem – just add this code after line 11:

<span style="color: #606060;"> 1:</span> <span style="color: #008000;">\'Create an empty ZIP file</span>
<span style="color: #606060;"> 2:</span> <span style="color: #008000;">\'Insert after line 11 (when sArchiveFile is defined</span>
<span style="color: #606060;"> 3:</span>
<span style="color: #606060;"> 4:</span> <span style="color: #0000ff;">Dim</span> oFSO
<span style="color: #606060;"> 5:</span> <span style="color: #0000ff;">dim</span> oFile
<span style="color: #606060;"> 6:</span>
<span style="color: #606060;"> 7:</span> <span style="color: #0000ff;">Set</span> oFSO = CreateObject( <span style="color: #006080;">"Scripting.FileSystemObject"</span> )
<span style="color: #606060;"> 8:</span> <span style="color: #0000ff;">Set</span> oFile = oFSO.OpenTextFile( sArchiveFile , ForWriting, <span style="color: #0000ff;">True</span> )
<span style="color: #606060;"> 9:</span> oFile.Write <span style="color: #006080;">"PK"</span> & Chr(5) & Chr(6) & <span style="color: #0000ff;">String</span>( 18, Chr(0) )
<span style="color: #606060;"> 10:</span> oFile.Close
<span style="color: #606060;"> 11:</span> <span style="color: #0000ff;">Set</span> oFile = <span style="color: #0000ff;">Nothing</span>
<span style="color: #606060;"> 12:</span> <span style="color: #0000ff;">Set</span> oFSO = Nothing

, ,

Extracting a ZIP File

0
by on May 15, 2008 at 06:10

Windows XP has a built-in ZIP mechanism integrated into its file-system. We can easily use this to extract standard ZIP files with only a few commands:

<span style="color: #606060;"> 1:</span> <span style="color: #008000;">\'Variable Definition</span>
<span style="color: #606060;"> 2:</span> <span style="color: #0000ff;">Dim</span> sZIPFile
<span style="color: #606060;"> 3:</span> <span style="color: #0000ff;">Dim</span> sExtractToPath
<span style="color: #606060;"> 4:</span>
<span style="color: #606060;"> 5:</span> <span style="color: #0000ff;">Dim</span> oShell
<span style="color: #606060;"> 6:</span> <span style="color: #0000ff;">Dim</span> oZippedFiles
<span style="color: #606060;"> 7:</span>
<span style="color: #606060;"> 8:</span> <span style="color: #008000;">\'Variable Initialization</span>
<span style="color: #606060;"> 9:</span> sZIPFile=<span style="color: #006080;">"C:\Source.zip"</span>
<span style="color: #606060;"> 10:</span> sExtractToPath=<span style="color: #006080;">"C:\Dest\InnerDir\"</span>
<span style="color: #606060;"> 11:</span> <span style="color: #0000ff;">Set</span> oShell = CreateObject(<span style="color: #006080;">"Shell.Application"</span>)
<span style="color: #606060;"> 12:</span>
<span style="color: #606060;"> 13:</span> <span style="color: #008000;">\'Get the contents of the ZIP archive</span>
<span style="color: #606060;"> 14:</span> <span style="color: #0000ff;">Set</span> oZippedFiles=oShell.<span style="color: #0000ff;">NameSpace</span>(sZIPFile).items
<span style="color: #606060;"> 15:</span>
<span style="color: #606060;"> 16:</span> <span style="color: #008000;">\'Copy the contents into the destination folder</span>
<span style="color: #606060;"> 17:</span> oShell.<span style="color: #0000ff;">NameSpace</span>(sExtractToPath).CopyHere(oZippedFiles)
<span style="color: #606060;"> 18:</span>
<span style="color: #606060;"> 19:</span> <span style="color: #008000;">\'Free Objects</span>
<span style="color: #606060;"> 20:</span> <span style="color: #0000ff;">Set</span> oZippedFiles = <span style="color: #0000ff;">Nothing</span>
<span style="color: #606060;"> 21:</span> <span style="color: #0000ff;">Set</span> oShell = <span style="color: #0000ff;">Nothing</span>
<span style="color: #606060;"> 22:</span>

, ,

A Pitfall for Beginners when Working with a Dictionary

0
by on April 23, 2008 at 11:00

Introduction

First and foremost I wish to thank two of my team members, Yasmin Helled and Eyas Kopty, who actually brought this issue to my attention. This post actually replaces an earlier post in which I prematurely and erroneously declared the issue as being a bug. My apologies to you, my loyal readers, for falling with such pitfall. I hope this short article will enable you avoid another one, even more substantial – one that can impact the way your code behaves.

 

Discussion

Yasmin had showed me a piece of code similar to the following (I simplified it a bit for illustration purposes):

<span style="color: #0000ff">If</span> <span style="color: #0000ff">Not</span> (objDic.Exists(<span style="color: #006080">"MyKey"</span>) <span style="color: #0000ff">Or</span> IsNumeric(objDic(<span style="color: #006080">"MyKey"</span>))) <span style="color: #0000ff">Then</span>
    MsgBox <span style="color: #006080">"Key Not Found"</span>
<span style="color: #0000ff">Else</span>
    MsgBox <span style="color: #006080">"Key Found: "</span> & objDic(<span style="color: #006080">"MyKey"</span>)
<span style="color: #0000ff">End</span> If

The key, needless to say, was not previously added, but the condition consistently entered the Else clause, printing an Empty value in the MsgBox. This sounded weird to Yasmin, who had forgotten that VBScript always checks ALL conditional clauses, so that even though the first part of the condition already returned true, the second part is also checked. This resulted in runtime problems, since the key thus added contained an empty value!

To overcome this problem, the above code was replaced with the following:

<span style="color: #008000">\'Declare variables</span>
<span style="color: #0000ff">Dim</span> objDic, strKey

<span style="color: #008000">\'Create instance of Dictionary</span>
<span style="color: #0000ff">Set</span> objDic = CreateObject(<span style="color: #006080">"Scripting.Dictionary"</span>)

<span style="color: #008000">\'Assign value to required key</span>
strKey = <span style="color: #006080">"MyKey"</span>

<span style="color: #0000ff">If</span> <span style="color: #0000ff">Not</span> (objDic.Exists(strKey)) <span style="color: #0000ff">Then</span>                 <span style="color: #008000">\'Check if the key exists</span>
    MsgBox <span style="color: #006080">"Key "</span> & strKey & <span style="color: #006080">" was not found."</span>
<span style="color: #0000ff">ElseIf</span> <span style="color: #0000ff">Not</span> IsNumeric(objDic(strKey)) <span style="color: #0000ff">Then</span>           <span style="color: #008000">\'The key exists so check if it\'s numeric</span>
    MsgBox <span style="color: #006080">"Value is not numeric: "</span>  & objDic(strKey)
<span style="color: #0000ff">Else</span>                                                <span style="color: #008000">\'Report that the validation succeeded</span>
    MsgBox <span style="color: #006080">"Key "</span> & strKey & <span style="color: #006080">" was found and the value is "</span> & objDic(strKey)
<span style="color: #0000ff">End</span> <span style="color: #0000ff">If</span>

So that functional independence between key existence and value type validation is achieved.

 

Conclusion

 

When addressing a non-existing key in a Dictionary object, the add method is invoked by default. The problem is that the Windows Script Host does not inform during runtime that there is a missing key. Moreover, the automatically assigned Empty value may cause trouble to our subsequent code execution. I hope that bringing up this issue will benefit programmers and enable them to avoid such a pitfall.

 

*Note: This revised post replaces a previous post titled "Amazing Bug in the Dictionary Object!"

, ,

Display Records

0
by on April 12, 2008 at 05:26

The following example demonstrates how to display all records from a table. and loop thorough a record-set.

<span style="color: #0000ff;">Dim</span> oConn, oRst, oField
<span style="color: #0000ff;">Dim</span> sql

<span style="color: #0000ff;">set</span> oConn = CreateObject(<span style="color: #006080;">"ADODB.Connection"</span>)
oConn.Open <span style="color: #006080;">"QT_Flight32"</span>
<span style="color: #0000ff;">set</span> oRst = CreateObject(<span style="color: #006080;">"ADODB.recordset"</span>)
oRst.Open <span style="color: #006080;">"Select * from Orders"</span>, oConn
<span style="color: #0000ff;">Do</span> <span style="color: #0000ff;">Until</span> oRst.EOF
    <span style="color: #0000ff;">For</span> <span style="color: #0000ff;">each</span> oField <span style="color: #0000ff;">in</span> oRst.Fields
        Print oField.Name & <span style="color: #006080;">" = "</span> & oField.Value
    <span style="color: #0000ff;">Next</span>
    Print <span style="color: #0000ff;">String</span>( 20, <span style="color: #006080;">"-"</span> )
    oRst.MoveNext
<span style="color: #0000ff;">loop</span>

oRst.close
oConn.close

 

, ,

Return ASCII Character Code of a Letter

0
by on April 1, 2008 at 23:55

The Asc function returns the ASCII code of the first character in the string.

Print Asc( <span style="color: #006080;">"ABCD"</span> )     \' prints 65

, ,

Convert ASCII Value to Character

0
by on April 1, 2008 at 23:54

The Asc function takes an ASCII character code and returns the character.

Print Chr( 65 )   <span style="color: #008000;">\' prints "A"</span>
Print Chr( 34 )   <span style="color: #008000;">\' prints " ( quote )</span>

, ,

Convert String to a Number

0
by on April 1, 2008 at 23:52

Use the CInt function to convert a string to Integer data subtype representation.

Use the CDbl function to convert a string to Double data subtype representation.

Use the CSng function to convert a string to Single data subtype representation.

Use the CLng function to convert a string to Long data subtype representation.

Use the CByte function to convert a string to Byte data subtype representation.

pi = <span style="color: #006080;">"3.14"</span>

Print <span style="color: #0000ff;">CInt</span>( pi )  <span style="color: #008000;">\' Prints 3</span>
Print <span style="color: #0000ff;">Clng</span>( pi )  <span style="color: #008000;">\' Prints 3</span>
Print <span style="color: #0000ff;">CDbl</span>( pi )  <span style="color: #008000;">\' Prints 3.14</span>
Print <span style="color: #0000ff;">CSng</span>( pi )  <span style="color: #008000;">\' Prints 3.14</span>
Print <span style="color: #0000ff;">CByte</span>( pi ) <span style="color: #008000;">\' Prints 3</span>

, , ,

Convert Number to a String

0
by on April 1, 2008 at 23:51

Use the CStr to convert a number into it’s string representation

pi = 3.14
Print <span style="color: #0000ff;">CStr</span>( pi )  <span style="color: #008000;">\' Prints "3.14"</span>

, ,