How to Design & Implement Infrastructure
This page provides an overview of the process of designing and implementing
the infrastructure for a PRODUCT subsystem.
The Design Phase
Select a 2 or 3 character prefix that you'll use for all global symbols
associated with the subsystem. There may already be one reserved for you.
Explore the Window
Carefully and thoroughly explore the window's UI.
Try to find a way to make all of the window's UI gadgets visible simultaneously.
Then take a screen shot. On the Mac, I use "ScreenShot".
If the window has more than one significant state, then take one screen shot
of each state. You shouldn't need more than 2 or 3.
Convert the screen shots to GIF files (on the Mac I use Graphic Converter),
and increaase the brightness by 50%.
This will give the screen shot a slightly washed-out look, which makes it
more obvious that it's a picture of a window, and not an actual window.
Use the screen shots in the documentation.
Declare the UI Gadgets
Use QAP's "Record Declarations" to figure out which UI gadgets it can see.
Typically, this won't be very many. It might even be none.
All of the UI gadgets that QAP can't see will be some subclass of
(If they're not, you've got a problem that's outside the scope of this document.)
You need to determine the pane ID and class of each gadget.
Go to the Debug Window and select UI Shell from its menu.
Where it says "Keycode for dump key", enter "6F" (without the quotes).
Now, when you hit the F12 key, the console or debug window will display
information about the
APane directly beneath the cursor.
The information will include the pane ID (in quotes), and the class.
If the class is one of our
4Test UI Shell classes,
then you'll use that class to declare the gadget in your window declaration.
APane's class isn't one of our known classes,
you'll have to go into the application's source code to determine
which of our known classes the unknown class derives from, and
then use that parent class in your window declaration.
With these tools at your disposal, create a window declaration that contains
all of the window's gadgets.
Take care to select "nice" names for the gadgets, being both self-consistent
and consistent with the rest of the PRODUCT infrastructure.
The name of the window itself will be
where "XXX" is the subsystem prefix.
All of the tags for UI Shell gadgets must be empty strings.
Class or No Class?
One question you'll have to decide is whether to declare a class for
the window, or just use a window declaration. You'll need to declare
a window regardless; the question is whether to put all the contents
of the window directly in its declaration, or in a class.
If there can ever be more than one instance of the window (e.g. Bins
and Popup Monitors), then you must declare a class.
If you need to define extension functions for the window,
then you must declare a class.
Once you have all the UI gadgets declared, it's time to think about
The idea here is to provide the script writer with a set of routines
that shield her from details of the UI that are either subject to
change, or just plain not interesting.
Here are some rules of thumb:
Beyond that, use your experience, judgement, and good taste to come up
with additional methods that represent common operations that script
writers will want to perform.
You don't need to be exhaustive; you can always add more methods later.
- For every text field, provide a Get and a Set method.
- For every checkbox, provide a Get and a Set method.
If the value of the checkbox translates unambiguously into a boolean value,
the Get and Set methods should operate on booleans.
Otherwise, define an enum type with two values,
and use that instead of a boolean.
- For every set of radio buttons, define an enum type that contains
one value for each radio button.
Provide a Get and a Set method for each group of radio buttons
(not for each individual radio button).
- For every popup menu that always has exactly one item selected,
define an enum type that contains one value for each menu item.
Provide a Get and a Set method for each popup menu.
If your subsystem has any important dialogs associated with it,
you must create window declarations for them, also.
It's not necessary to track down every one, but be sure to take
care of the ones that will be encountered most often.
If you're not very familiar with the subsystem,
find someone who is, and ask them about dialog boxes.
Most dialog boxes will not contain UI Shell gadgets,
and will be completely readable by QA Partner.
However, some newer dialog boxes do use the UI Shell.
Produce a Design Spec
If you don't already have an HTML document describing everything you've
done so far, then produce one now.
Your design spec will be the documentation when you're done.
If you're not sure what to put in your spec, look at any of the existing
documentation for a subsystem API.
Notify The Team
and anyone else that might be interested that the spec exists.
Hold a review meeting. This is really important. No one person can think of
everything, and your design will be much stronger as a result.
Revise the spec accordingly, and if the changes were substantial,
have another review meeting.
The Implementation Phase
Take another look at the pane IDs for the UI Shell gadgets in your window.
If one of them looks like "<<Pane #9>>", then you won't be able to use it,
and you'll have to go into the application source code and assign a pane ID.
If you've never done this before, find someone who has.
The Parent Window
Every window of class
ChildWin (or one of its subclasses)
must contain a "parent" statement.
The parent statement always references the application's main window.
For the PRODUCT, this is always:
The Init Method
If you have any UI Shell gadgets at all, then you'll need to define a
Init, that takes no arguments and returns
This method will call the
Init method for each UI Shell gadget
in your window, passing it the pane ID of the gadget.
You should also include some code to make sure that
only does anything useful the first time it's called.
Invoking the Window
If your window can be invoked by selecting a menu pick from the main menu bar,
then include a line near the top of your window declaration as follows:
window wInvoke = gwMCmainWin.Tools.MyWindowToolThing;
This tells QAP's built-in
Invoke method how to invoke your window.
If your window is invoked in some other way, then you'll have to implement
Invoke method, performing whatever operations are
necessary to invoke your window.
Invoke method should also call
This page is maintained by
It was last updated 5 June 1997.