tags:

views:

55

answers:

1

We have a function which accesses two types of controls like button and list box in standard windows app. The function uses only the control name as arguments, so there is no way qtp could understand what type of control it is. how to resolve this? Write 2 separate functions- 1 for button & another for list box?

+2  A: 

It depends what you want to do with the object, if you want to do something that is common to all WinObjects (e.g. Click or GetROProperty) you can do that, if it's specific to different test objects you'll have to have different methods (or at least treat it differently internally)

Example for Calc.exe in scientific mode:

Public Function Click(ByVal Name)
   Window("text:=Calculator").WinObject("text:=" & Name).Click
End Function

Click "8" ''# This is a button
Click "Oct" ''# This is a radio button

After running the result is 10 (8 in octal)


Another way to do this would be to use ChildObjects in order to get all the objects that match this property (in this case one), check what type of object it is (GetROProperty("micclass")) and switch on that to perform your specific actions.

Motti
Beware, however, that the references that the collection returned by ChildObjects contains get invalid in the moment the controls change their state. This can be nasty if you try to cover controls that asynchronously move, disappear, change their icon etc. -- you will then get random results, or runtime errors.
TheBlastOne
@TheBlastOne this will only be problematic if the controls themselves change (not just their appearance) e.g. if a browser navigates, otherwise it should be OK.
Motti
That's what I'd expect, too. However, if you change a parent container's visibility, any child element reference in ChildObjects collection becomes invalid. That's exactly the (unexpected) issue I targeted. My guess is that QTP addresses via WNHD handles, and those get invalid if the child object is re-created due to a state change (as is often done in UI frameworks like the one in JBoss' ServerFaces, or in Delphi's component framework).
TheBlastOne
HP even tried to "fix" this by letting .Exists return always TRUE when called for a ChildObjects reference in one of the newer patches. What a mess...they really should fix it by reorganizing how they reference the GUI objects.
TheBlastOne
@TheBlastOne I think this is a *leaky abstraction* problem. When you call `ChildObjects` you get a set of controls from the application, QTP does not create a persistent description for these objects and when you call `Exists` what you're saying is *does this object's description map to a live control in the tested app?*, therefore from QTP's perspective it doesn't make sense to ask `Exists` on the result of `ChildObjects`. The problem is that the validity of objects returned by `ChildObjects` is implicitly until the application changes.
Motti
"HP even tried to "fix" this" - not quite so. When Exist method is invoked on an object from ChildObjects collection, that object becomes invalid because its connection to real object is cleared - that's how Exist works. By making Exist to always return True for such objects (without mentioned side-effect) HP tried to minimize the outcome of misunderstanding described above by Motti.
Andrey
@TheBlastOne this [blog post](http://h30501.www3.hp.com/t5/The-Future-of-Testing-Blog/Technical-How-QTP-identifies-Objects/ba-p/10332) may interest you it addresses exactly this issue.
Motti
Post was useful and clarified what happens, thanks. It still is disturbing that you can call ChildObjects, and the GUI object references returned can be invalidated *any*time, at least for GUIs that change their state asynchroneously to the test robot execution. Makes ChildObjects unusable for such GUI apps (except for the .Count of the returned collection the whole collection returned is useless).
TheBlastOne
@TheBlastOne, it is my (unproven) belief that most applications don't change their state that often, you're right that if you do have such an application then you can't depend of `ChildObjects`.
Motti