Table of Contents
In Squish test scripts it is possible to react to events that occur inside the AUT. This can be useful, for example, to provide a test script response for when a dialog appears unexpectedly, such as an error message box. This can be done by registering an event handler function for a particular event and that should be called when that event occurs on a specified object, or on an object of a specified type, or for any object.
Event handler functions are registered by calling an installEventHandler
function. For a handler that
should apply to all the AUT's objects—that is, a global event
handler—just the event type and the handler function are passed as
arguments. For a handler that should apply to a particular object or to
all objects of a particular type, the object or type is passed as the
first argument, followed by the event type and the handler function. In
addition to standard toolkit events (such as Qt's
QKeyEvent
), some Squish- and toolkit-specific generic
events are supported such as MessageBoxOpened
and
Crash
.
![]() | Squish for Web-specific |
---|---|
For Squish for Web, event handler functions are always called with
no argument, rather than passed an object
(typically the object the event happened to). It is still possible to
access objects inside Squish for Web event handlers, but we must obtain
references to the objects ourselves, for example, using the |
In the following subsections we will look at example event handlers for all three cases.
When a message box pops up the MessageBoxOpened
event
occurs. (In fact, the MessageBoxOpened
event only applies
to the Squish for Java™, Squish for Qt, and Squish for Windows
editions; however, there are similar events for the other toolkits.)
Like all such events the test script will ignore the event, but we can
register an event handler function to be called whenever such events
occur. It doesn't really make sense to associate a global event like
this with a particular object or type, so it is usually handled by a
global event handler.
Here we will look at an example of creating and installing a handler for message boxes.
def handleMessageBox(messageBox): test.log("MessageBox opened: '%s' - '%s'" % ( messageBox.windowText, messageBox.text)) messageBox.close() def main(): startApplication("myapp") installEventHandler("MessageBoxOpened", "handleMessageBox") ...
function handleMessageBox(messageBox) { test.log("MessageBox opened: '" + messageBox.windowText + "' - '" + messageBox.text + "'"); messageBox.close(); } function main() { startApplication("myapp"); installEventHandler("MessageBoxOpened", "handleMessageBox"); // ... }
sub handleMessageBox { my $messageBox = shift @_; test::log("MessageBox opened: '" . $messageBox->windowText . "' - '" . $messageBox->text + "'"); $messageBox->close(); } sub main { startApplication("myapp"); installEventHandler("MessageBoxOpened", "handleMessageBox"); # ... }
# encoding: UTF-8 require 'squish' include Squish def HandleMessageBox(messageBox) Test.log("MessageBox opened: '%s' - '%s'" % [ messageBox.windowText, messageBox.text]) messageBox.close end def main startApplication("myapp") installEventHandler("MessageBoxOpened", "HandleMessageBox") ... end
proc handleMessageBox {messageBox} { test log [concat "MessageBox opened: '" \ [property get $messageBox windowText] "' - '" \ [property get $messageBox text] "'"] invoke $messageBox close } proc main {} { invoke startApplication "myapp" installEventHandler "MessageBoxOpened" "handleMessageBox" # ... }
Note that if we were using a similar Squish for Web event (e.g.,
ModalDialogOpened
), the dialog would
not be passed as an argument, because Squish for Web
event handlers receive no arguments.
Another special event is Crash
. This is useful when we want
to install an event handler to be called when the AUT crashes—for
example, to do cleanups or to restart the AUT. (The Crash
event is supported by all Squish versions, except for Squish for Web.)
Here's an example:
def crashHandler(): test.log("Deleting lock files after AUT crash") deleteLockFiles() def main(): startApplication("myapp") installEventHandler("Crash", "crashHandler") ...
function crashHandler() { test.log("Deleting lock files after AUT crash"); deleteLockFiles(); } function main() { startApplication("myapp"); installEventHandler("Crash", "crashHandler"); // ... }
sub crashHandler { test::log("Deleting lock files after AUT crash"); deleteLockFiles(); } sub main { startApplication("myapp"); installEventHandler("Crash", "crashHandler"); # ... }
# encoding: UTF-8 require 'squish' include Squish def crashHandler Test.log("Deleting lock files after AUT crash") deleteLockFiles end def main startApplication("myapp") installEventHandler("Crash", "crashHandler") ... end
proc crashHandler {} { test log "Deleting lock files after AUT crash" deleteLockFiles } proc main {} { invoke startApplication "myapp" installEventHandler "Crash" "crashHandler" # ... }
A third kind of special event is the Timeout
event. These
events are triggered whenever the AUT fails to respond to some Squish
command within five minutes. This can happen if the application got
stuck in an endless loop, or if there is some other reason that keeps
it from being able to respond. You can install an event handler for this
event so that your tests can handle such situations gracefully.
The timeout time can be changed by using the squishrunner's or
squishserver's
setResponseTimeout
option (see Configuring squishrunner (Section 7.4.3.27) or Configuring squishserver (Section 7.4.4.3)), or using the Squish IDE (see Squish Preferences Child Panes (Section 8.3.17.7.1).)
It is possible to set up an event handler that will respond to
particular types of events for all objects of a specified type.
Only the Qt version installEventHandler
supports this kind of
usage currently. For example, we can install an event handler which is
always called when a QMouseEvent
occurs on a
QCheckBox
. This means that every time the event occurs,
that is, whenever any of the AUT's checkboxes is clicked, the event
handler is called. Here's an example:
def handleCheckBox(obj): test.log("QCheckBox '%s' clicked" % objectName(obj)) def main(): startApplication("myapp") installEventHandler("QCheckBox", "QMouseEvent", "handleCheckBox") ...
function handleCheckBox(obj) { test.log("QCheckBox '" + objectName(obj) + "' clicked"); } function main() { startApplication("myapp"); installEventHandler("QCheckBox", "QMouseEvent", "handleCheckBox"); // ... }
sub handleCheckBox { my $obj = shift @_; test::log("QCheckBox '" . objectName($obj) . "' clicked"); } sub main { startApplication("myapp"); installEventHandler("QCheckBox", "QMouseEvent", "handleCheckBox"); # ... }
# encoding: UTF-8 require 'squish' include Squish def handleCheckBox(obj) Test.log("QCheckBox '%s' clicked" % [objectName(obj)]) end def main startApplication("myapp") installEventHandler("QCheckBox", "QMouseEvent", "handleCheckBox") ... end
proc handleCheckBox {obj} { test log [concat "QCheckBox '" [objectName $obj] "' clicked"] } proc main {} { invoke startApplication "myapp" installEventHandler "QCheckBox" "QMouseEvent" "handleCheckBox" # ... }
The third kind of event handling that Squish supports is for events
that occur to particular objects. The only toolkit that supports this
currently is the Qt toolkit. We can install an event handler that is called
every time a line editor receives a QKeyEvent
, so the event handler
would be called every time some text is typed into the line editor. Here's an
example:
def handleDescriptionLineEdit(obj): lineEdit = cast(obj, QLineEdit) test.log("QLineEdit '%s' text changed: %s" % ( objectName(obj), lineEdit.text)) def main(): startApplication("myapp") lineEdit = waitForObject(":Description:_QLineEdit") installEventHandler(lineEdit, "QKeyEvent", "handleDescriptionLineEdit") ...
function handleDescriptionLineEdit(obj) { var lineEdit = cast(obj, QLineEdit); test.log("QLineEdit '" + objectName(obj) + "' text changed: " + lineEdit.text) } function main() { startApplication("myapp"); var lineEdit = waitForObject(":Description:_QLineEdit"); installEventHandler(lineEdit, "QKeyEvent", "handleDescriptionLineEdit"); // ... }
sub handleDescriptionLineEdit { my $obj = shift @_; my $lineEdit = cast($obj, QLineEdit); test::log("QLineEdit '" . objectName($obj) . "' text changed: " . $lineEdit->text); } sub main { startApplication("myapp"); my $lineEdit = waitForObject(":Description:_QLineEdit"); installEventHandler($lineEdit, "QKeyEvent", "handleDescriptionLineEdit"); # ... }
# encoding: UTF-8 require 'squish' include Squish def handleDescriptionLineEdit(obj) lineEdit = cast(obj, QLineEdit) Test.log("QLineEdit '%s' text changed: %s" % [ objectName(obj), lineEdit.text]) end def main startApplication("myapp") lineEdit = waitForObject(":Description:_QLineEdit") installEventHandler(lineEdit, "QKeyEvent", "handleDescriptionLineEdit") ... end
proc handleDescriptionLineEdit {obj} { set lineEdit [cast $obj QLineEdit] test log [concat "QLineEdit '" [objectName $obj] \ "' text changed: " [toString [property get $lineEdit text]]] } proc main {} { invoke startApplication "myapp" set lineEdit [waitForObject ":Description:_QLineEdit"] installEventHandler $lineEdit "QKeyEvent" "handleDescriptionLineEdit" # ... }
The object passed as obj
is just a generic Squish object;
we must cast it to an object of the correct type using the cast
function, to be able to access the object's
methods and properties.