A P P E N D I X  A

XD/Replay Command Syntax


Introduction

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:


Specifying the Context of Actions

Keywords

in - specify the context of subsequent actions in a script

ApplicationShell - the top level shell of the application

Synopsis

in shell_widget
	commands
in ApplicationShell
	commands

Inputs

shell_widget - the name of a shell widget other than the main application shell

Description

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.

Examples

in ApplicationShell
	push this_button
	push that_button
	push help_dialog_button
in help_dialog_popup
	push cancel_button
in ApplicationShell
	push another_button


Button Actions (Simple Controls)

Keywords

push - press and release a mouse button

doubleclick - doubleclick mouse button

Synopsis

push widget [with [modifier-]button[1-5]]
doubleclick widget

Inputs

widget - the name of a widget

modifier - a keyboard modifier

button[1-5] - the number of the mouse button (default is button 1 with no modifiers).

Description

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).

Usage

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:

Position Independent Widgets

Position Dependent Widgets

Buttons

Sliders

Toggles

Scales

Lists

Drawing Areas

Text Widgets[1]

Non-Motif widgets


Refer to Button Actions (Position Dependent Controls) for details on recording and replaying the other widgets in the position-dependent list.

Examples

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


Menu Operations

Keywords

cascade - post a pulldown menu

pullright - post a pullright menu from a pulldown menu

Synopsis

cascade cascadebutton
		select widget
cascade cascadebutton
		pullright cascadebutton

Inputs

cascadebutton - the name of a cascadebutton

widget - the name of a widget within the cascade button's pulldown menu

Description

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.

Examples

in ApplicationShell
	 cascade file_m
 		select open_file
in ApplicationShell
	 cascade format_menu
 		pullright character_menu

Notes

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 Menu Operations

Keywords

Synopsis

option opmenu-widget::member_widget

Inputs

Description

option selects an option from an option menu.

Examples

in ApplicationShell
	 cascade format_menu
 		pullright character_menu
		option character_menu::bold

The next example only selects an option if the option menu itself is sensitive to user input:

if IsSensitive(myoptionmenu->OptionButton)
	option myoptionmenu::thisoption
endif

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:

if myoptionMenu->menuHistory: select_yes
		message he said yes
endif

Notes

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.


Keyboard Operations

Keywords

alt - select current word

ctrl - select current line

key - enter a keysym from the keyboard

Synopsis

alt char
ctrl char
key keysym

Inputs

char - a single character

keysym - any X keysym (see X11/keysymdef.h for list)

Description

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.

Example

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

Notes

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.


Text Entry

Keywords

type - enter text from the keyboard

key - enter a keysym from the keyboard

doubleclick - select current word

multiclick - select current line

Synopsis

type text
key keysym
doubleclick textwidget
multiclick textwidget

Inputs

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

Description

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.

Examples

in form_attr_dialog_popup
		doubleclick formHorizSpacingField
		type 100
in coreDialog
		multiclick title_t
		type My Dialog Title

Notes

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.


Button Actions (Position Dependent Controls)

Keywords

push - press and release a mouse button

drag - combine a press and release within the same widget

Synopsis

push widget(mame,qual) 
drag widget(name1,qual1)-widget(name2,qual2)

Inputs

widget - a widget name

name, name1, name2 - application/widget dependent description

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).

Example

The first example shows how the Motif DrawingArea widget has been implemented for X-Designer testing:

in ApplicationShell
	push tree_da(mybutton,centre)

In the next example we show how attachments are made between the frame1 and button_box widgets in the X-Designer form layout editor:

in form_layout
	drag layout(frame1,right)-layout(button_box,left)

You can try out these effects in X-Designer.

Notes

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.


Resource Evaluation

Keywords

printres - print the value of a widget resource

Synopsis

printres widget->resource

Inputs

widget - the name of a widget

resource - the name of the widget resource

Description

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.

Example

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


Widget Hierarchy Analysis

Keywords

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

Synopsis

tree widget
dump widget
snapshot widget

Inputs

widget - the name of a widget

Description

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.

Example

The following command displays the resources allocated to the button1 widget:

in ApplicationShell
	dump button1

Part of the example output is shown below:

button1():
	Boolean ancestorSensitive:true
	HorizontalDimension width:58
	VerticalDimension height:22
	Pixel background:color('black')
	Pixel foreground:color('#72729F9FFFFF')
	HorizontalDimension highlightThickness:1
	Pixel highlightColor:color('black')
	XmString labelString:'Button A'
	Pixel armColor:color('red')

The next command displays the widget hierarchy from the form1 widget:

in ApplicationShell
	tree form1

Part of the example output is shown below:

	rowcol1():
		buttonA():
		button2():
	address_area():
		label1():
		text1():

Notes

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.


Non-application Operations

Keywords

delay - pause replay of user actions

message - print message

sequence - label part of a script

shell - execute shell command

Synopsis

delay duration
message text
sequence text
shell command
setenv env-var env-value
breakpoint widget
exit status

Inputs

duration - time in seconds

text - a text string

widget - the name of a widget

status - either 1 or 0

Description

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.

Examples

To delay for 5 seconds after pushing a widget:

in ApplicationShell
		push mywidget
		delay 5
		push yourwidget
 

To take a screen dump of a shell without window manager decorations:

in ApplicationShell
		setenv ID WindowId(ApplicationShell)
		shell xwd -id $ID -out /tmp/shell.xwd

To take a screen dump with window manager decorations:

in ApplicationShell
		setenv ID WindowFrame(ApplicationShell)
		shell xwd -id $ID -out /tmp/shell.xwd

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:

in ApplicationShell
		setenv ID Parent(cascade_button)->background
		shell echo The Color $ID


Condition Clauses

Keywords

if

else

elif

endif

Synopsis

if expression
	actions
[elif expression
	actions]
[else
	actions]
endif

Inputs

expression - an expression which evaluates to true or false

actions - one or more user actions

Description

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.

Example

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                      
	else
			message setting ok for my_option_menu   
endif


Display Expressions

Keywords

IsPseudoColor

IsDirectColor

IsTrueColor

IsStaticColor

IsStaticGrey

IsGreyScale

Synopsis

if expression
	actions
endif

Inputs

expression - one of the keywords listed above

Description

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.

Example

if !IsPseudoColor
	message Non PseudoColor display
	in warning_popup
			push warning.OK
endif


Widget State Expressions

Keywords

IsVisible

IsManaged

IsRealized

IsHere

Synopsis

if expression
	actions
endif

Inputs

expression - one of the keywords listed above

Description

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.

Example

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


Importing User-Defined Commands

Keywords

import - load a module of additional commands

user - invoke a command from a loaded module

Synopsis

import module
user command text

Inputs

module - the name of the module

command - the name of the command

text - parameters passed to the command

Description

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.

Example

import mymodule
in ApplicationShell
	cascade file_menu
			select fm_print
			in print_dialog
				user myscreendumper print_dialog

Notes

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.


XD/Replay Widget Naming Conventions

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.



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.




1 (TableFootnote) Recording and replaying user interaction with text widgets is covered in Text Entry.