When recording a script in Squish, the event recorder must ensure that
the AUT and the test script are synchronized. One way of achieving this
is for the recorder to automatically insert snooze
statements into the script. These
statements force the script to wait for a specified number of seconds
(which might be a fractional amount such as 2.5). This is necessary to
ensure that a script is replayed at the same speed as it was recorded.
For example, if the user waited for a window to pop up, the script will
wait for the same amount of time. This is important to prevent Squish
from running the AUT too fast for the AUT's toolkit to keep up.
Using snooze
statements is the simplest way
to synchronize the AUT and a test script. But in many cases, simply
waiting for a certain amount of time isn't sufficient. For example, if a
script is recorded on a fast machine and later replayed on a slow
machine the time waited by snooze
might
not be long enough.
Another way of synchronizing is to use waitForObject
statements instead of snooze
statements. If the waitForObject
function is used, before every
action that is recorded, a waitForObject
statement will be recorded so that the object can be accessed. So on
replay, instead of waiting for a specific amount of time, Squish will
wait for the given object to exist and be accessible (i.e., visible).
Since using the waitForObject
function has
proved much more reliable than using the snooze
, it is the default method used when
recording test cases.
A third alternative is to use the waitFor
function. This function waits until a given condition becomes true, or
optionally, until a specified time out expires. The condition can be
anything from a property to a complex script statement. Here is an
example that waits for a particular dialog to pop up, and logs a fatal
error if the dialog doesn't appear within 5 seconds:
ok = waitFor("object.exists(':Address Book - Save As_QFileDialog')", 5000) if not ok: test.fatal("AddressBook Save As dialog didn't appear")
var ok = waitFor("object.exists(':Address Book - Save As_QFileDialog')", 5000); if (!ok) test.fatal("AddressBook Save As dialog didn't appear");
my $ok = waitFor("object::exists(':Address Book - Save As_QFileDialog')", 5000); if (!$ok) { test::fatal("AddressBook Save As dialog didn't appear"); }
ok = waitFor("Squish::Object.exists(':Address Book - Save As_QFileDialog')", 5000) if !ok Test.fatal("AddressBook Save As dialog didn't appear") end
set ok [waitFor {object exists ":Address Book - Save As_QFileDialog"} \ 5000] if {!$ok} { test fatal "AddressBook Save As dialog didn't appear" }
Here is another example, this time one that will wait “forever” since no timeout is specified. So if the expected file doesn't exist and isn't created, the test script will be stuck:
waitFor("QFile.exists('addresses.tsv')")
waitFor("QFile.exists('addresses.tsv')");
waitFor("QFile::exists('addresses.tsv')");
waitFor("QFile.exists('addresses.tsv')")
waitFor {invoke QFile exists "addresses.tsv"}
This next example waits up to 2 seconds for an waitFor
function repeatedly evaluates the code it has been given as its first
argument and returns true
as soon as the code evaluates to
true
; or returns false
if the code doesn't
evaluate to true
within the number of
milliseconds specified by its second argument.
button = findObject(":Address Book - Add.OK_QPushButton") enabled = waitFor("button.enabled", 2000) if not enabled: test.fatal("OK button has not been enabled")
var button = findObject(":Address Book - Add.OK_QPushButton"); var enabled = waitFor("button.enabled", 2000); if (!enabled) test.fatal("OK button has not been enabled");
my $button = findObject(":Address Book - Add.OK_QPushButton"); my $enabled = waitFor("$button->enabled", 2000); if (!$enabled) { test::fatal("OK button has not been enabled"); }
button = findObject(":Address Book - Add.OK_QPushButton") enabled = waitFor("button.enabled", 2000) if !enabled Test.fatal("OK button has not been enabled") end
set button [findObject ":Address Book - Add.OK_QPushButton"] set enabled [waitFor {property get $button enabled} 2000] if {!$enabled} { test fatal "OK button has not been enabled" }
These examples show different variations of synchronization points. As
the condition which is passed to the waitFor
function can be any script code which can
be evaluated, including function calls, there are no limits to
creating synchronization points.
More on synchronization for Web applications and advanced AJAX synchronization can be found at How to Synchronize Web Page Loading for Testing (Section 5.3.8).