Sun WorkShop Visual Replay Command Syntax
This appendix describes the keywords used in Sun WorkShop Visual Replay scripts.
The Sun WorkShop Visual Replay script keywords have been divided into the following subsections according to their functions:
|Record and Replay Commands:|
|-||Specifying the context of actions|
|-||Button actions (Simple controls)|
|-||Pulldown Menu operations|
|-||Option Menu operations|
|-||Button actions (Position dependent controls)|
|-||Widget Hierarchy Analysis|
|-||Widget State Expressions|
|-||Importing User-Defined Commands|
in - specify the context of subsequent actions in a script
ApplicationShell - the top level shell of the application
Sun WorkShop Visual Replay scripts consist of actions on widgets. These actions have to take place within the context of the shell (i.e. dialog) which contains that widget. If the shell is not realized, the script will fail at that point. The in command cannot be nested. Once you have come out of a shell (to go into another shell), you must go back in to that shell before attempting any further actions within that context.
push that_buttonpush help_dialog_button
in help_dialog_popuppush cancel_button
in ApplicationShellpush another_button
|widget||the name of a widget|
|modifier||a keyboard modifier|
the number of the mouse button
(default is button 1 with no modifiers).
push simulates a single click (a mouse button press/release sequence) using a mouse button on the named widget. The with keyword allows you to specify a particular mouse button. If this is not used, button1 (the left mouse button) is used. A keyboard modifier (such as the Shift key) can be used to extend the permutations of mouse button events. The permitted modifiers are alt, ctrl and shift.
doubleclick simulates a doubleclick with the left mouse button. This can be used in any widget but is especially useful for selecting from a text widget (see Text Entry).
In some widgets, where the user clicks with the mouse is unimportant. For example, clicking on a button widget in any part of it will activate that button. However, for other widgets, the position is significant; for example pushing on a scale widget will have different effects depending upon the where the push was made.
The following table lists those widgets which are position and non-position dependent:
TABLE A-1 Position independent widgets
1 Recording and replaying user interaction with text widgets is covered in
Refer to Button Actions (Position Dependent Controls) for details on recording and replaying the other widgets in the position-dependent list.
in ApplicationShellpush this_button
in ApplicationShellpush that_button with shift-button2
cascade cascadebuttonselect widget
cascade cascadebuttonpullright cascadebutton
|cascadebutton||the name of a cascadebutton|
|widget||the name of a widget within the cascade button's pulldown menu|
cascade is a shorthand way of describing menu operations. You can also post a menu by pushing on the associated cascade button or using a keyboard accelerator. Similarly, menu options can be selected using accelerators or keyboard mnemonics.
cascade posts a pulldown menu to allow a selection to be made from it. The selection may be a widget (i.e. an option in that menu) or a cascadebutton which displays a pullright menu.
cascade file_mselect open_file
cascade format_menupullright character_menu
Sun WorkShop Visual Replay only supports one level of pullright menu to conform to the Motif style guide. You can however use the push command in your scripts to select pullright menus in succeeding levels.
option selects an option from an option menu.
The next example only selects an option if the option menu itself is sensitive to user input:
if IsSensitive(myoptionmenu->OptionButton)option myoptionmenu::thisoptionendifIf you want to check the current setting of the optionmenu (i.e. what was last selected), you simply examine the option menu menuHistory resource, for example:
if myoptionMenu->menuHistory: select_yesmessage he said yesendif
An alternative method of selecting a member of an option menu is to push the option button and then push the appropriate member widget. However, we recommend use of the option syntax as it more closely mimics user actions.
|alt||-||select current word|
|ctrl||-||select current line|
|key||-||enter a keysym from the keyboard|
Keyboard input is directed at the widget that has the focus. Sun WorkShop Visual Replay does not require any extra programming to enter input from the keyboard.
Users and test scripts alike have to work with the window manager when entering text. Where explicit focus is in place (i.e. you have to click in a window to get the focus), you will have to program this into the test script.
type hallo world
A push or a doubleclick in a text field has the side effect of taking the focus. This is the only place in Sun WorkShop Visual Replay that focus is handled directly.
Data entry into text fields often overrides what is already there and will be preceded by a doubleclick or a multiclick.
|type||-||enter text from the keyboard|
|key||-||enter a keysym from the keyboard|
|doubleclick||-||select current word|
|multiclick||-||select current line|
|keysym||any X keysym (see X11/keysymdef.h for list) without the XK_ prefix|
|textwidget||the name of a text widget|
|text||a text string|
Most text widgets in an application are used for single line data entry (for example the selection fields in a File Selection Box). Sun WorkShop Visual Replay allows testers to replace the default content of the field with a known value and then check the consequences.
type enters text into a text widget. doubleclick and multiclick program word and line selection respectively. multiclick is most commonly used in test scripts, when you want to replace the contents of the text field, regardless of how many words there are on the line.
doubleclick formHorizSpacingFieldtype 100
type My Dialog Title
There is a limit of 512 characters to the length of a line which can be handled by Sun WorkShop Visual Replay. In you want to enter a text string whose length exceeds this limit, split the text and type in each section.
Sun WorkShop Visual Replay works around a problem in some versions of Motif where triple-click is not properly handled in XmTextField widgets. In these circumstances, if your script contains multiclick, it will be converted to doubleclick.
|push||-||press and release a mouse button|
|drag||-||combine a press and release within the same widget|
In some widgets (e.g. drawing areas) where you click is important. In the case of drawing areas, a position within the drawing area is needed. For lists, you need an indication of which item has been selected. The version of push listed above is intended for such position-dependent widgets.
In these widgets, you will often need to do more than just click. You may need to press down at one point and release at another. An example is the setting up of attachments between widgets in the Sun WorkShop Visual form layout editor. This may involve a server grab, so it is described as a single drag operation where the first part describes where you pressed and the second where you released the button.
This mechanism can be used for single user-defined widget instances, such as the drawing areas within your application and also for entire widget classes (as we have done for XmList, XmScale and XmScrollBar and various 3rd party widget sets).
The first example shows how the Motif DrawingArea widget has been implemented for Sun WorkShop Visual testing:
in ApplicationShellpush tree_da(mybutton,centre)
In the next example we show how attachments are made between the frame1 and button_box widgets in the Sun WorkShop Visual form layout editor:
in form_layoutdrag layout(frame1,right)-layout(button_box,left)You can try out these effects in Sun WorkShop Visual.
Information on how to handle your own position-dependent widgets, or those from a 3rd party supplier, are given in Extending the Sun WorkShop Visual Replay Widget Set.
printres - print the value of a widget resource
printres prints the current value of a specified resource within a selected widget. This is especially useful in test scripts where a known resource value is expected. The name of the resource must be specified without any "XmN" prefix, e.g. "labelString".
Your scripts are more likely to include resource evaluation within conditional expressions.
message FAIL: bad setting for my_option_menu
message Setting should be:
|tree||-||produce recursive listing of current widget hierarchy|
|dump||-||show resources assigned to widget|
|snapshot||-||produce recursive listing of current widget hierarchy and the resources assigned to each widget|
The tree, dump and snapshot commands allow you to analyze the structure of the widgets within an application interface and the values of resources assigned to those widgets. The results from the analysis are displayed on standard error.
tree gives a recursive listing of widget names in the widget hierarchy from the nominated widget.
dump displays the resource settings of the nominated widget.
snapshot displays the resource settings of the nominated widget and all other widgets in the widget hierarchy from the nominated widget.
The following command displays the resources allocated to the button1 widget:
in ApplicationShelldump button1Part of the example output is shown below:
button1():Boolean ancestorSensitive:trueHorizontalDimension width:58VerticalDimension height:22Pixel background:color('black')Pixel foreground:color('#72729F9FFFFF')HorizontalDimension highlightThickness:1Pixel highlightColor:color('black')XmString labelString:'Button A'Pixel armColor:color('red')
The next command displays the widget hierarchy from the form1 widget:
in ApplicationShelltree form1Part of the example output is shown below:
Sun WorkShop Visual Replay assigns a unique name to widgets which share a common widget name within a shell (e.g., HorScrollBar#1, HorScrollBar#2, Apply#3, Apply#5, etc.). Where the replay name is different from the actual widget name, it is given within the brackets.
|delay||-||pause replay of user actions|
|sequence||-||label part of a script|
|shell||-||execute shell command|
setenv env-var env-value
delay allows you to insert a pause in a script. This is useful when you wish to visually inspect the application at particular points in its execution. The next action in the script will continue after the pause.
message displays a message on standard error. This allows you to label different parts of the script and communicate expected results and errors to testers. The message text does not have to be enclosed in quotes.
sequence is used to label different sections of a script. Then if an error occurs, you can skip to the next labelled sequence and continue from that point.
To use sequence, you must invoke visu_replay with the -skip-on-error flag. By default, visu_replay is run with the -user-on-error flag which will stop the test and stay in the application when an error occurs. The remaining error flag, -exit-on-error causes will terminate the application when an error occurs.
shell executes a shell command from a script. The script continues when the shell command has terminated. This facility allows you to enrich your scripts to do far more than simply re-running user actions.
setenv is used in conjunction with the shell command to pass information to the shell through environment variables. setenv has two arguments. The first is the name of the variable; the second is an expression that can combine widget resource values and one of the following convenience functions:
breakpoint is used, in conjunction with a debugger, to set a breakpoint in a script when a nominated widget is activated. You can then examine the internals of individual widgets.
A script which contains the breakpoint keyword should be invoked as follows:
visu_replay -f script debugger appwhere script is the name of the script, debugger is the name of your debugger and app is the name of the application to be exercised by the script. The debugger is run by Sun WorkShop Visual Replay. At the breakpoint keyword, the application will stop as if you set the breakpoint directly. This will allow you to inspect widget internals even if your application has been optimized.
exit terminates the script with the specified exit status.
To delay for 5 seconds after pushing a widget:
in ApplicationShellpush mywidgetdelay 5push yourwidgetTo take a screen dump of a shell without window manager decorations:
in ApplicationShellsetenv ID WindowId(ApplicationShell)shell xwd -id $ID -out /tmp/shell.xwdTo take a screen dump with window manager decorations:
in ApplicationShellsetenv ID WindowFrame(ApplicationShell)shell xwd -id $ID -out /tmp/shell.xwdTo take a screen dump of a pulldown menu, when you only know the name of its cascade button:
in ApplicationShellpush cascade_buttonsetenv ID WindowId(cascade_button->subMenuId)shell xwd -id $ID -out /tmp/shell.xwd
Note - If you don't push the button first, the menu will not have been posted and xwd will not be able to snapshot it.
To do the same with an OptionMenu:
in ApplicationShellpush option_menu.OptionButtonsetenv ID WindowId(option_menu->subMenuId)shell xwd -id $ID -out /tmp/shell.xwdTo note the background color of the cascade button's parent:
in ApplicationShellsetenv ID Parent(cascade_button)->backgroundshell echo The Color $ID
The if statement allows the control flow through a script to be sensitive to conditions inside the application as it is being run. For each if there must be a matching endif. If necessary the statement can include optional alternatives (elif) and a default catch-all else condition.
message FAIL: bad setting for my_option_menu
message Setting should be:
message setting ok for my_option_menu
You cannot guarantee that a script recorded on one display will necessarily work on another of a different type. Certain applications make heavy use of color and may display a color restriction message to a user if he is running the application on a display with a limited color map. Your scripts must accommodate such situations.
message Non PseudoColor display
Where parts of a dialog are selectively displayed, you can check which parts are managed and realized using the IsManaged and IsRealized expressions.
IsVisible is intended for small (VGA) displays where the whole of a dialog may not be visible on the screen. This is important as Motif TAB navigation traversal model ignores controls which are off screen.
IsHere simply checks whether the widget exists in the current shell.
message Save Dialog cannot be seen
user command text
|module||the name of the module|
|command||the name of the command|
|text||parameters passed to the command|
The command set of Sun WorkShop Visual Replay is intended for replaying user actions and for checking the state of an application with respect to its widget hierarchy and its resource settings. There is nothing to stop you adding your own commands to meet your own needs. For example:
|To produce screen dumps at various points in a replay session.|
|To do other sorts of consistency checking on the widget hierarchy - one example would be to interface with Doug Young's widgetlint library.|
|To insert a probe or a patch for a particular debugging problem. This will be of most use in a stripped optimized binary, where you do not have access to the full power of the debugger.|
import allows you to load a module of your own commands into a script. Once the module has been loaded the commands in it can be invoked using the user command. You can import as many modules as you wish.
user myscreendumper print_dialog
The shell and setenv interface is the preferred route if the actions you need to perform do not involve extensive access to the widget hierarchy, or inspection of the internals of your program. In the latter case, see Adding your own Sun WorkShop Visual Replay commands to see how to add your own commands to Sun WorkShop Visual Replay.
In Sun WorkShop Visual Replay, the widget name is what you use to reference a widget. One of the main tasks for any widget-based testing tool is identifying the right widget. The naming convention must be unambiguous, without being over-complicated.
Here are the rules used by Sun WorkShop Visual Replay:
|1.||If the control is a widget (i.e. not a gadget), and it is the only widget with that name in the current dialog, use the widget name, e.g.|
|2.||If the control is a gadget, use parentname.gadgetname|
|3.||Where a widget name is null (i.e. ""), use unnamed, e.g.|
|4.||Where there are multiple instances of this widget name (or gadget name) in the current shell, then reference the instance by number, e.g.|
|5.||If you are writing your script by hand, the tree command can be used to examine the widget hierarchy:|
|6.||If the shell name is ambiguous, then use instances, e.g.|
Note - the instance numbers are automatically calculated when you record a script. Instance #3 simply means the third occurrence of that name in a depth-first left to right search of the widget hierarchy for that shell.