Multitag Statement

Action

In a window declaration, defines one or more tags that the Agent uses internally to uniquely identify the object at runtime. By default, the Agent generates multitag statements for GUI objects when you record window declarations.

Note: Never use the tag in your scripts to refer to an object; always use the object's identifier.

Syntax

[gui-specifier] multitag tag-string 
  [tag-string] …
Variable Description
gui-specifier Optional. Specifies the GUIs that the statement applies to. See window declaration. If omitted, the statement applies to all GUIs.
tag-string A STRING expression that evaluates to the object's tag. You can specify as many tag-strings as you want. The tag can be expressed in several ways, as described below.

Forms for the tag-string Argument

The tag-string argument can express the object's tag in one of several ways. Use the arguments in the order listed.

Tag Type Description
Window ID GUI-specific ID. You must use the $ character to preface a window ID tag. Always unique.
Caption The caption or label as it appears to the user. Note that multiple windows may contain the same caption.
Prior text The nearest previous static text above or to the left of the object. You must use the ^ character to preface a prior text tag.
Index The order (from top left to bottom right) in relation to its sibling objects of the same class. Index tags must begin with the # character. Use for statically-presented Visual Basic and C/C++ applications.
Location The physical location, expressed as a pair of (x, y) coordinates. You must use the @ character to preface a location tag. The location tag is always relative to the parent control. Use only if Prior text and Index fail. Use for static applications; consider using WindowID instead.
Attributes The attribute name(s) of the Html object. If the object is not an Html object, nothing is recorded.

Example

The check box in the Find dialog in the Text Editor has these possible tags (displayed in the Record Window Declarations dialog):

Tag Type Value Comment
Caption Case sensitive The label for the check box.
Prior text ^Find What: The closest static text above the check box.
Index #1 It is the first check box in the dialog.
Window ID $1041 GUI-specific tag.
Location @(57,65) (x, y) location of the check box in the dialog.
Attributes [blank] Attributes are only recorded for Html objects.

What is Recorded by Default

By default, when you generate window declarations, the Agent generates tags based on the object's caption (if it has one) and window ID (if it has one).

Example

The default generated tag for the Case Sensitive check box is:

CheckBox CaseSensitive
multitag "Case sensitive" 
"$1041"

The string "Case sensitive" is its caption. The string "$1041" is its Window ID.

Specifying Additional tag-strings

You can specify as many tag-strings as you want in a multitag statement. You can even specify more than one value for each tag type. For example, if a control's caption can change dynamically, specify each valid caption in its tag, such as:

PushButton Confirm
multitag "Yes" 
"OK"

The Agent would find the pushbutton if it had either caption.

How to Choose a tag-string Form

The caption form for the window tag is the most portable. Along with the windowID, this is the form that the Agent uses by default when it creates tags for recorded declarations.

The Agent automatically generates valid, unique tags. However, in some situations you might want to edit the tags. The following table describes which form of the tag to use in specific situations:

In This Situation Use This Form for the Tag
The GUI object’s label contains dynamic text. For example the third text string in a dialog is labeled with the path c:\myapp.

The index, for example: "#3".

Note: Avoid using the index format for objects of the MoveableWin class. This syntax may result in your choosing a window at random in cases where there are multiple windows.
The GUI object’s parent can vary at runtime. For example, the Open dialog can have more than one application as a parent at runtime.

Specify that the parent is the currently active application, for example:

"~ActiveApp/[DialogBox]Open"

You want to assign the tag dynamically at runtime.

Replace the tag with a function call. For example, where CreateTag is a user-defined function that returns a string:

MenuItem CheckBox
tag CreateTag(this)
…

STRING CreateTag (WINDOW 
wWindowIdentifier)

switch (wWindowIdentifier)
case TestApp.Control.CheckBox
return "Check box|$200"

…
Two dialogs have the same label or caption, but do not have identical contents. For example, one Open dialog has a Name text field and the other Open dialog has a Search pushbutton.

Specify the tag of a unique child in each tag. You may use any unambiguous tag form for the child, but do not use the window identifier of the child. For example,

"[DialogBox]Open/[TextField]First Name/.."

"[DialogBox]Open/[PushButton]New Search/.."

"[DialogBox]Open/[ComboBox] #2/.."

"[BrowserChild]ThePage/[BrowserChild]One
of several frames with the same caption/
[HtmlHeading]Unique heading/..": tag of
the browser frame (BrowserChild with
caption "One of several frames with the
 same caption")

"[BrowserChild]ThePage/[BrowserChild]One
of several frames with the same /
[HtmlHeading]Unique heading/../..": tag of
the browser page (BrowserChild with
caption "ThePage")
Note: Include an "/.." at the end of each tag for each level the child is below the parent. For example, if the child object is one level below the parent, include "/.." at the end of the tag. If the child object is two levels below the parent, include "/../.." at the end of the tag.
The GUI object has no label or caption and the position (and hence the index) can change dynamically at runtime. The window ID.
The GUI object has a label or caption, but you don't want to use it as the tag because it is changeable for this object. The index or prior text.
You need to internationalize your application. The window ID, or replace the tag with a variable.
The GUI object is a graphical control like a tool bar. The location.
You want to invoke a dialog, not the main window, when your application starts. For example, you want to invoke a dialog named Login.

Change the class of the dialog from DialogBox to MainWin, and then specify the real class in the tag, for example:

"[DialogBox]Login"

More than one instance of the window might be displayed at one time

Use the instance syntax, which takes the form tag-string[n], where [n] refers to the instance. [1] refers to the instance of the window that is closest to the top on the desktop, [2] refers to the instance that is next highest to the top, and so on.

For example, you could have one declaration for the window whose tag is "My Window[1]" and another declaration whose tag is "My Window[2]". With these declarations, you can record and play back tests against two instances of the same window. Note that when an instance of the window becomes active, it automatically becomes MyWindow[1].

The Agent automatically accounts for dynamic strings in the caption of a main window (for example, file names) and replaces these dynamic strings with the wildcard character "*".

Tag Syntax

The examples in the table above use these syntactic elements:

This Syntactic Element Is Used in a Tag to
/ Separate a parent from a child object.
[ ] Delimit the class or instance of a GUI object.
.. Specify that the Agent should use the parent of the child object in the tag.
~ActiveApp Specify that the top-level parent of a GUI object is the currently active application at runtime. Do not use ~ActiveApp in any window declaration that will be used with SilkBean.
* Act as a placeholder for 0 or more characters in a string. Can be used for dynamic strings in the caption of a main window (for example, file names).
? Act as a placeholder for one character in a string.
| Delimit segments of a multiple tag. Use this element to create and/or statements.
~ Match everything. It can be described as the equivalent to [AnyWin]* which means "any window with any caption."

How Parent Specifiers Work

You can specify the parent of a GUI object in the tag-string by using a slash ( / ), as in:

multitag "parent/tag1"
"tag2"

A parent specifier on the first tag in a multitag statement is duplicated in all the remaining tags within the statement. It is not necessary, for example, to specify:

multitag "parent/tag1"
"parent/tag2"

Both of these statement produce the tag parent/tag1|tag2. It is up to you whether to include the parent again. However, an error will result if you use a different specifier on a later tag, or if the first tag does not have a parent specifier and a later tag does.

Note: '|' has precedence over '/' in the tag statement. If a window can have different parents where the parents are at different levels in the window hierarchy, then you must use a tag function in order to specify both parents in a single tag.

Alternative Syntax

Instead of using a multitag statement, you can use a tag statement and concatenate all the tag forms with the pipe character ( | ). For example, the following two statements are equivalent:

multitag "Case sensitive"
"$1041" 
tag "Case sensitive|$1041"

Use of the pipe separator will make code much easier to read where you have multiple tags.

How Multiple Tags are Resolved at Runtime

The Agent attempts to resolve each segment of a multiple tag, from left to right, until it finds a match that is unique. If an error occurs when resolving a tag, an exception is raised and the process is immediately halted—unless the error is Window Not Found or Window Not Unique, in which case the Agent continues evaluating other tag segments. Here are some examples:

Tag What Happens at Runtime
"#xyz|MyWin" A syntax error results, because #xyz is an illegal tag. The MyWin tag is never evaluated.
"Yes|OK" Yes is used when both Yes and OK exist and are unique.
"Yes|OK" OK is used when only OK exists.
"Yes|OK" OK is used when both Yes and OK exist, but Yes is not unique.

Fully Qualified Window Tag Syntax

The term fully qualified window tag refers to a tag that uniquely and unambiguously identifies a GUI object. A fully qualified window tag is composed of the class and tag of the object joined with the class and tag of each of the object’s ancestors in the GUI hierarchy. This is how, for example, the Agent can distinguish the OK button in one dialog from the OK buttons in other dialogs.