A P P E N D I X A |
XD/Replay Command Syntax |
This appendix describes the keywords used in XD/Replay scripts.
The XD/Replay script keywords have been divided into the following subsections according to their functions:
in - specify the context of subsequent actions in a script
ApplicationShell - the top level shell of the application
shell_widget - the name of a shell widget other than the main application shell
XD/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.
in ApplicationShell push this_button push that_button push help_dialog_button in help_dialog_popup push cancel_button in ApplicationShell push another_button |
push - press and release a mouse button
doubleclick - doubleclick mouse button
modifier - a keyboard modifier
button[1-5] - 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:
Text Widgets[1] |
|
Refer to Button Actions (Position Dependent Controls) for details on recording and replaying the other widgets in the position-dependent list.
in ApplicationShell push this_button in ApplicationShell push that_button with shift-button2 in my_dialog_popup if color_toggle->set:true push color_toggle endif |
cascade - post a pulldown menu
pullright - post a pullright menu from a pulldown menu
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.
in ApplicationShell cascade file_m select open_file in ApplicationShell cascade format_menu pullright character_menu |
XD/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 opmenu-widget::member_widget
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 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:
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.
key - enter a keysym from the keyboard
keysym - any X keysym (see X11/keysymdef.h for list)
Keyboard input is directed at the widget that has the focus. XD/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.
in ApplicationShell alt f type o in open_file_popup multiclick selection_field type foo.xd push ok_button doubleclick my_text_field type hallo world key Return |
A push or a doubleclick in a text field has the side effect of taking the focus. This is the only place in XD/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
Most text widgets in an application are used for single line data entry (for example the selection fields in a File Selection Box). XD/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.
in form_attr_dialog_popup doubleclick formHorizSpacingField type 100 in coreDialog multiclick title_t type My Dialog Title |
There is a limit of 512 characters to the length of a line which can be handled by XD/Replay. In you want to enter a text string whose length exceeds this limit, split the text and type in each section.
XD/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
name, name1, name2 - application/widget dependent description
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 X-Designer 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 X-Designer testing:
In the next example we show how attachments are made between the frame1 and button_box widgets in the X-Designer form layout editor:
You can try out these effects in X-Designer.
Information on how to handle your own position-dependent widgets, or those from a 3rd party supplier, are given in Extending the XD/Replay Widget Set.
printres - print the value of a widget resource
resource - the name of the 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.
in my_shell if !my_option_menu->menuHistory:default_option message FAIL: bad setting for my_option_menu message Setting should be: printres my_option_menu->menuHistory:default_option endif |
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:
Part of the example output is shown below:
The next command displays the widget hierarchy from the form1 widget:
Part of the example output is shown below:
XD/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
delay duration message text sequence text shell command setenv env-var env-value breakpoint widget exit status |
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 xdreplay with the -skip-on-error flag. By default, xdreplay 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:
xdreplay -f script debugger app
where 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 XD/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:
To take a screen dump of a shell without window manager decorations:
To take a screen dump with window manager decorations:
To take a screen dump of a pulldown menu, when you only know the name of its cascade button:
in ApplicationShell push cascade_button setenv 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 ApplicationShell push option_menu.OptionButton setenv ID WindowId(option_menu->subMenuId) shell xwd -id $ID -out /tmp/shell.xwd |
To note the background color of the cascade button's parent:
expression - an expression which evaluates to true or false
actions - one or more user actions
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.
expression - one of the keywords listed above
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.
expression - one of the keywords listed above
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.
in ApplicationShell cascade file_menu select fm_menu.fm_exit if IsVisible(save_dialog) in save_dialog push save.ok else message Save Dialog cannot be seen endif |
import - load a module of additional commands
user - invoke a command from a loaded module
module - the name of the module
command - the name of the command
text - parameters passed to the command
The command set of XD/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:
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.
import mymodule in ApplicationShell cascade file_menu select fm_print in print_dialog 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 XD/Replay Commands to see how to add your own commands to XD/Replay.
In XD/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 XD/Replay:
This outputs a recursive listing of the widget hierarchy. The listing contains the actual widget name, and in parenthesis, the name you should use for XD/Replay, if it is different from the actual name.
Copyright © 2003, Sun Microsystems, Inc. All rights reserved.