Sunday, July 6, 2008

strongwind study info

here is my study information about using strongwind test against winforms. also i hope someone can give me idea to handle the problems below here.

How to def an action that strongwind never support?

For example give “press “ action to one button:

def press(self,button):
procedurelogger.action('Press the %s.' % button)

How to check the status when send one action?

For example check the “armed” status when send press action:

def assertResult(self, button, result):
procedurelogger.expectedResult('%s is %s.' % (button, result))
def resultMatches():
if result == "armed":
return button.armed
elif result == "unarmed":
return not button.armed
raise InvalidState, "%s has no such state: %s" %\
(button, result)
assert retryUntilTrue(resultMatches)

How to close an extra windows?

For example to close a Dialog:

def clickResult(self):
self =,"Message Dialog")
#if the dialog have 'ok' 'cancel' etc. Button in here can set like:

For example to close an Alert if there isn't close button on it. Strongwind does not support altF4 to Alert so we should set the action and expected by ourselves:

def clickResult(self):
self =,"Message Dialog")
procedurelogger.action('Press altF4 to close %s' % self)

procedurelogger.expectedResult('%s has been closed' % self)
def resultMatches():
return not self
assert retryUntilTrue(resultMatches)

#if there is close button on Alert windows can set like:
def clickResult(self):
self =,"Message Dialog") .ok()

How to close appliction's windows?

strongwind support altF4() can send action and return expected, so we use it like:

def quit(self):

if the application include 'quit' button we can do like:

def quit(self):

How to insert some text into a Text Filed?

Strongwind support 'typeText(text)' in class Accessible or 'enterText(text)' in class Text so we can use it to input text'aaaa':“aaaa”)
#we also can set like:“aaaa”)

How to insert password text into a Text Filed?

Stringwind support 'class PasswordText' that function is the same as 'class Text', so we also can use 'typeText(text)' or 'enterText(text)'.

How to check if the item list( or menuitem list) appear?

For example to check the combobox menuitem list:

#first set 'self.combobox = self.findComboBox(None)' in __init__
def press(self,button):
procedurelogger.action('Press the \"%s\".' % button)

procedurelogger.expectedResult('list combobox menu item list appear')
def resultMatches():
return self.combobox.findMenuItem(None)
assert retryUntilTrue(resultMatches)

(if menuitem list not appear the test will return fail when do press action.)

How to select item if the item in list is changed instability?

For example the menuitem list in StarDict is changed instability so first we should use '__getattr__' get one item's name then send an action to it:

def selectitem(self,result=None):
#just can get the first item's logname
#self.combobox = self.findComboBox(None)
result = self.combobox.findMenuItem(None).__getattr__('logName')
#strongwind support 'select(self, name, logName=None, log=True)'

#check if the text in text filed is same as the select text
procedurelogger.expectedResult('the text change to %s' % result)
def resultMatches():
return self.combobox.findText(None).text == result
assert retryUntilTrue(resultMatches)

How to test MenuBar and MenuItem?

Strongwind supports '_open, select, open' function default. 'select' can send click action to what you want menuitem. '_open, open' just send click action to menu to list the item but not click menuitem.

For example there are 'New' 'Open' MenuItem in 'File' MenuBar in Gedit application:

#check if the menuitem in menubar can be clicked
#first set 'self.menubar = self.findMenuBar('')' in __init__
def menuSelect(self, menuname, itemname):[menuname]) and self.findMenuItem(itemname).click()
#is the same action as below, but not log for the click action[menuname, itemname])

if itemname == 'New':
def resultMatches():
procedurelogger.expectedResult('Unsaved Document 1 appears')
return self.findPageTab('Unsaved Document 1')
assert retryUntilTrue(resultMatches)

if itemname == 'Open...':,logName='Open Files').cancel()


# check if the menu can be clicked and if the menuitem list can be showed
def menuResult(self, menuname, itemname):
procedurelogger.action('click %s menu' % menuname)

procedurelogger.expectedResult('%s menu status is selected and found %s item in %s' % (menuname, itemname, menuname))
def resultMatches():
return self.findMenuItem(itemname) and self.findMenu(menuname).selected

assert retryUntilTrue(resultMatches)

How to test StatusBar?

For example in StatusBar there is a Label to show the numbers of line&character when we enter text in TextBox(see gedit). What we need to do is first find the TextBox to enter some character by enterText(text), then check if we can find the StatusBar with the Label's Text(cont the numbers of line&character):

def statusbarResult(self):
self.findPageTab('Unsaved Document 1').findText(None).enterText('enter some character')

procedurelogger.expectedResult('Label text in statusbar is \" Ln 1, Col 21\"')
def resultMatches():
return self.findStatusBar(' Ln 1, Col 21').text
assert retryUntilTrue(resultMatches)

How to test ToolBar?

For example in gedit ToolBar there is a 'New' pushbutton, we can click New button then to check if rise a new textbox pagetab:

def toolbarResult(self, buttonName):

procedurelogger.expectedResult('Unsaved Document 3 appears')
def resultMatches():
return self.findPageTab('Unsaved Document 3')

assert retryUntilTrue(resultMatches)

How to test PageTab(or TabPage)?

Strongwind support 'findPageTab(Name)' to PageTabList, and 'select()' to do PageTab action, and 'assertSelected()' to check the select result.

For example in gedit when we click 'New' button it will rise some new PageTab:

#use 'select()' to change the tabpage, use 'assertSelected()' to check the selected or by checking the Label's change in statusbar
def pagetabResult(self, pagetabName):
pagetab = self.findPageTab(pagetabName)
if pagetabName == '*Unsaved Document 1':
procedurelogger.expectedResult('change TabPage to \"*Unsaved Document 1\"')
def resultMatches():
return self.findStatusBar(' Ln 1, Col 21').text
assert retryUntilTrue(resultMatches)

How to test ScrollBar?

For example in gedit there is a scrollbar the Value is 0-169, we can set newValue as '0' '30' '169' '-10' '200' to test if it can be set.

def scrollbarResult(self,newValue=None):
#if we didn't know maximumValue previously, we can get it like:
maximumValue = self.findScrollBar(None)._accessible.queryValue().maximumValue

procedurelogger.action('set scrollbar value to \"%s\"' % newValue)

def resultMatches():
if 0 <= newValue <= maximumValue:
procedurelogger.expectedResult('the current value of scrollbar is \"%s\"' % newValue)
return self.findScrollBar(None).__getattr__('value') == newValue
procedurelogger.expectedResult('value \"%s\" out of run ' % newValue)
return not self.findScrollBar(None).__getattr__('value') == newValue
assert retryUntilTrue(resultMatches)

How to click buttons those without name?

For example there are three radiobutton without name(see stardict application), we can use 'findAllRadioButtons(None)' to show all radiobutton, then send click action to one of them:

def radiobuttonResult(self,buttonnum):
rblist = self.findAllRadioButtons("")
#it will rise action log default

procedurelogger.expectedResult('you have clicked radiobutton \"%s\"' % buttonnum)

def resultMatches():
if buttonnum == 1:
return self.findTableCell("Links")
elif buttonnum == 2:
return self.findPushButton("Translate")
assert retryUntilTrue(resultMatches)

thanks bgmerrell ^ ^

How to test suspend menu list?

For example when click one button it rise a suspend menu and have one menuitem name 'About' in menu (sometimes it has CheckMenuItem in menu list):

def suspendResult(self):


procedurelogger.action('click \"About\" in menuitem list')"About").click()"About stardict").close()

How to move the mouse and How to test ToolTips?

For example there are some button have tooltip, now we should use 'generateMouseEvent' move the mouse to the button and halt one second, than search for tooltip's label:

def mousePoint(self,buttonnum, tooltipLabel, xOffset=0, yOffset=0):

procedurelogger.action('move mouse to radiobutton \"%s\"' % buttonnum)

bbox = self.findAllRadioButtons(None)[buttonnum].extents

x = bbox.x + (bbox.width / 2) + xOffset

y = bbox.y + (bbox.height / 2) + xOffset

pyatspi.Registry.generateMouseEvent(x, y, 'abs')


procedurelogger.expectedResult('found tooltip, the label is \"%s\"' % tooltipLabel)

def resultMatches():

return"%s" % tooltipLabel)

assert retryUntilTrue(resultMatches)

How to sort the TableCells?

For example to check if all of the TableCell items have been sorted after click TableColumnHeader in TreeView test:

#define the tuple of table cell names
ASCENDING = ('parent 0', 'parent 1', 'child 0 of parent 0')
DESCENDING = ('parent 1', 'parent 0', 'child 0 of parent 1')

#click TableColumnHeader
def tchClick(self, accessible):
procedurelogger.action('click %s.' % accessible)

#assert that the sorting of the TreeView is ascending
def assertAscending(self):
procedurelogger.expectedResult('TreeView sorting is ascending')
self.table_cells = self.findAllTableCells(None)
tcs = [ for table_cell in self.table_cells]
def resultMatches():
return tuple(tcs) == self.ASCENDING
assert retryUntilTrue(resultMatches)

#assert that the soring of the TreeView is descending
def assertDescending(self):
procedurelogger.expectedResult('TreeView sorting is decending')
self.table_cells = self.findAllTableCells(None)
tcs = [ for table_cell in self.table_cells]
def resultMatches():
return tuple(tcs) == self.DESCENDING
assert retryUntilTrue(resultMatches)


1.Accerciser in openSUSE 11.0 can't show tooltip detail, but in openSUSE 10.3 works well. 'gail' cause the problem.

1 comment:

bgmerrell said...

For Problem #1 you can use the findAll* methods for finding widgets without names. For example, to find all radio buttons without names you can use findAllRadioButtons(None). If you wanted to find radio buttons with blank names, you'd just use findAllRadioButtons(""). The method returns a list of all the accessibles found.

For problem #3 you can use the generateMouseEvent. It will look something like the mouseClick method (on line 435) in The third argument of generateMouseEvent uses one of the MOUSE_* constants in pyatspi.constants (they are described at ). Use the "abs" to move the mouse to the location of the widget with the tooltip, wait for a second (the default wait in gtk is well under 1 second), and then check to make sure that the tooltip window opens. The tooltip window is a window with no name, but it will contain a single label with the text of the tooltip. Also, you can find the x,y coordinates (for generateMouseEvent) under "Component" on the "Interface Viewer" tab in Accerciser. In practice, though, you'll want to get the coordinates programmatically in your test script.

I didn't get a chance to look at #2 yet, but there should be a good way to handle it.

I hope that helps!