Squish API

This section introduces the APIs that Squish provides in addition to the standard features of the scripting languages it supports. The Squish APIs provide the facilities that test engineers need to test GUI applications, and offer a wide range of functionality, from interacting with AUT objects, to recording information in test logs, performing verifications, controlling the AUT, and more.

Squish API Objects/Classes

ApplicationContext Class

Represents a connection to a running AUT.

Image Object

Provides functions for reading and writing image files.

RemoteSystem Object

Functions for accessing the OS/file system of the squishserver host.

Screen Object

Provides information about screens.

TopLevelWindow Object

Information about and access to Top Level Windows.

UiTypes Namespace

User Interface Types: DateTime, ScreenRectangle, ScreenPoint

objectMap Functions

Functions to support the Text-Based Object Map.

squishinfo Object

Provides information about Squish version, Test Suite name, Test Case name, result directory.

testData Functions

Functions for dealing with tables of test data.

testInteraction Functions

Functions for user interaction during test replay.

testSettings Object

Properties for configuring Test Suite Settings.

Squish API Functions

Here are some quick links to the Squish API functions (not including the Squish objects or the toolkit-specific convenience functions):

Squish API Function Parameters

For all of the Squish API functions that take an objectOrName argument, it can be a reference to an object or the name of an object.

Some of the Squish API functions can take a modifierState argument that indicates which special keys are pressed at the time of a mouse click. Further, some of the functions take a mouseButton argument that indicates which mouse button was clicked.

The modifierState can be 0 (Modifier.NoModifier, the default), or the following: Modifier.Alt, Modifier.Control, Modifier.Shift. If more than one modifier is used, they must be OR-d together. For example, Modifier.Alt|Modifier.Shift. The form shown here works for Python and JavaScript. For Perl and Ruby, replace the period with two colons: Modifier::Control. For Tcl, use the enum function: enum Modifier Control.

The mouseButton can be any one of: MouseButton.LeftButton, MouseButton.MiddleButton,MouseButton.RightButton, or MouseButton.NoButton.

For Perl use: MouseButton::LeftButton, etc.

For Ruby use: MouseButton::LEFT_BUTTON, etc.

For Tcl use: enum MouseButton LeftButton, etc.

Note: Windows test suites also support two more possible mouse button specifiers, MouseButton.PrimaryButton and MouseButton.SecondaryButton. These values respect the global Windows setting used to swap the mouse buttons. If the buttons are not swapped (the default), the left button is the primary button. Otherwise, the right button is the primary button.

Identifying Objects

Many of the APIs' functions apply to particular objects, so being able to identify the object of interest is particularly important.

Squish provides several naming schemes, but the ones normally used are symbolic names and real names. Symbolic names are the most robust in the face of AUT changes, but real names can sometimes be more convenient to use. See How to Identify and Access Objects for more about names.

For Qt programs, the easiest and most reliable way of identifying an object in code is to set an object name in C++ for all the objects of interest (using the QObject::setObjectName method), and then in test scripts use a real (multi-property) name specifying the object's objectName and its type. For example:

textEdit = findObject("{objectName='ConfigEditor' type='QTextEdit'}")
var textEdit = findObject("{objectName='ConfigEditor' type='QTextEdit'}");
my $textEdit = findObject("{objectName='ConfigEditor' type='QTextEdit'}");
textEdit = findObject("{objectName='ConfigEditor' type='QTextEdit'}")
set textEdit [findObject "{objectName='ConfigEditor' type='QTextEdit'}"]

It is rare that an AUT has a unique name for every single widget. Sometimes we must identify unnamed objects. This can be done using symbolic names or by matching an object's unique set of property values. The necessary information can be obtained using the Spy tool (How to Use the Spy). This tool can provide an object's symbolic name and its property-based (real) name. Another approach is to create a dummy test, interact with the objects of interest and then look in Squish's object map to see the names that Squish uses, and copy any that are needed.

Here's an example that shows both approaches for finding an unnamed object of type QTextEdit. The object is in a QMainWindow whose title is "My App":

# symbolic name
textEdit = waitForObject(":MyApp_QTextEdit")
# real (multi-property) name
textEdit = waitForObject("{type='QTextEdit' unnamed='1' " +
        "visible='1' window=':MyApp_MainWindow'}")
// symbolic name
var textEdit = waitForObject(":MyApp_QTextEdit");
// real (multi-property) name
var textEdit = waitForObject("{type='QTextEdit' unnamed='1' " +
        "visible='1' window=':MyApp_MainWindow'}");
# symbolic name
my $textEdit = waitForObject(":MyApp_QTextEdit");
# real (multi-property) name
my $textEdit = waitForObject("{type='QTextEdit' unnamed='1' " .
        "visible='1' window=':MyApp_MainWindow'}");
# symbolic name
textEdit = waitForObject(":MyApp_QTextEdit")
# real (multi-property) name
textEdit = waitForObject("{type='QTextEdit' unnamed='1' " +
        "visible='1' window=':MyApp_MainWindow'}")
# symbolic name
set textEdit [waitForObject ":MyApp_QTextEdit"]
# real (multi-property) name
set textEdit [waitForObject "{type='QTextEdit' unnamed='1' \
        visible='1' window=':MyApp_MainWindow'}"]

The Object waitForObject(objectOrName) function waits for the identified object to be ready (visible and enabled) and then returns a reference to it.

On the whole it is best to use symbolic names since they are more robust in the face of AUT changes, since they only require us to update the Object Map rather than our test script code if an object's properties change. (Note that for most GUI toolkits the type property is mandatory when using real names.)

Constructors, Functions and Properties

Squish objects blend in seamlessly with the scripting language's native objects. This means that you can use standard language features to construct objects of the wrapped types, invoke member functions, and get, set, and iterate over properties on these objects.

Here are some simple examples:

# create an object of type QPoint
point = QPoint(10, 20)

# read a widget's width property
width = widget.width

# set widget's y-coordinate property
widget.y = 240

# call a member function
widget.setWindowTitle("My Widget")

# call a static function
QApplication.setOverrideCursor(Qt.WaitCursor)
// create an object of type QPoint
var point = new QPoint(10, 20);

// read a widget's width property
var width = widget.width;

// set widget's y-coordinate property
widget.y = 240;

// call a member function
widget.setWindowTitle("My Widget");

// call a static function
QApplication.setOverrideCursor(Qt.WaitCursor);
# create an object of type QPoint
my $point = new QPoint(10, 20);

# read a widget's width property
my $width = widget->width;

# set widget's y-coordinate property
$widget->y(240);

# call a member function
$widget->setWindowTitle("My Widget");

# call a static function
QApplication::setOverrideCursor(Qt::WaitCursor);
# create an object of type QPoint
point = QPoint.new(10, 20)

# read a widget's width property
width = widget.width

# set widget's y-coordinate property
widget.y = 240

# call a member function
widget.setWindowTitle("My Widget")

# call a static function
QApplication.setOverrideCursor(Qt::WAIT_CURSOR)
# create an object of type QPoint
set point [construct QPoint 10 20]

# read a widget's width property
set width [property get $widget width]

# set widget's y-coordinate property
property set $widget y 240

# call a member function
invoke $widget setWindowTitle "My Widget"

# call a static function
invoke QApplication setOverrideCursor [enum Qt WaitCursor]

For Tcl we must use the enum function to get enum values. (See Tcl Notes.)

Functions and Properties (macOS)

The function names in the scripting language API use the following convention: each colon (:) in the selector name is replaced by an underscore (_). So, for example, the +stringWithCString:encoding: selector becomes the script function stringWithCString_encoding_ (note the underscore at the end of the function).

Here are some examples to illustrate the usage.

# create an object of type NSString and initialize it with a value
s = NSString.stringWithUTF8String_("Ambient")

# read an object's intValue property
n = acontrol.intValue

# set an object's intValue property
acontrol.intValue = 33

# call an instance method
s.characterAtIndex_(1)

# call a class method
s = NSString.stringWithCString_encoding_("Zenith", 4)
// create an object of type NSString and initialize it with a value
var s = NSString.stringWithUTF8String_("Ambient");

// read an object's intValue property
var n = acontrol.intValue;

// set an object's intValue property
acontrol.intValue = 33;

// call an instance method
s.characterAtIndex_(1);

// call a class method
s = NSString.stringWithCString_encoding_("Zenith", 4);
# create an object of type NSString and initialize it with a value
my $s = NSString::stringWithUTF8String_("Ambient");

# read an object's intValue property
my $n = $acontrol->intValue;

# set an object's intValue property
$acontrol->intValue(33);

# call an instance method
$s->characterAtIndex_(1);

# call a class method
$s = NSString::stringWithCString_encoding_("Zenith", 4);
# create an object of type NSString and initialize it with a value
s = NSString.stringWithUTF8String_("Ambient");

# read an object's intValue property
n = acontrol.intValue

# set an object's intValue property
acontrol.intValue = 33

# call an instance method
s.characterAtIndex_(1)

# call a class method
s = NSString.stringWithCString_encoding_("Zenith", 4)
# create an object of type NSString and initialize it with a value
set s [invoke NSString stringWithUTF8String_ "Ambient"]

# read an object's intValue property
set n [property get $acontrol intValue]

# set an object's intValue property
property set $acontrol intValue 33

# call an instance method
invoke $s characterAtIndex_ 1

# call a class method
set s [invoke NSString stringWithCString_encoding_ "Zenith" 4]

Conversion Functions

In Squish, we have different ways to convert and cast, depending on what kind of value we are working with. In short,

  1. cast() can be used for converting values or pointers.
  2. object.convertTo() is for converting basic types, and value types related to QVariant.
  3. castToQObject() is specifically for downcasting QObject-pointers/references in Squish for Qt using run-time type identification.

Ensuring that functions are always called pairwise

Some functions need to be called in pairs to work correctly. For instance, fixateResultContext & restoreResultContext should go together, just like startsection & endSection. In order to ensure that this is the case even when script exceptions are raised (or the control flow could bypass one of the statements by other means, e.g., a return; statement), it is advisable to wrap the calls to the function pairs into helper functions which ensure that they always go together.

Here are some examples for how to ensure that fixateResultContext and restoreResultContext always go together. The same approach is applicable to startSection & endSection:

def resultsReportedAtCallsite(ancestorLevel = 1):
    class Ctx:
        def __enter__(self):
            test.fixateResultContext(ancestorLevel + 1)
        def __exit__(self, exc_type, exc_value, traceback):
            test.restoreResultContext()
    return Ctx()

def libraryFunction():
    with resultsReportedAtCallsite():
        test.compare("Apples", "Oranges")
function withResultsReportedAtCallsite(f)
{
    test.fixateResultContext(2);
    try {
        return f();
    } finally {
        test.restoreResultContext();
    }
}

function libraryFunction()
{
    withResultsReportedAtCallsite(function() {
        test.compare("Apples", "Oranges");
    });
}
sub withResultsReportedAtCallsite {
    my $code = shift;
    test::fixateResultContext(2);
    $code->();
    test::restoreResultContext();
}

sub libraryFunction
{
    withResultsReportedAtCallsite sub {
        test::compare("Apples", "Oranges");
    };
}
require 'squish'

include Squish

def withResultsReportedAtCallsite
  Test.fixateResultContext( 2 )
  begin
    yield
  ensure
    Test.restoreResultContext()
  end
end

def libraryFunction
  withResultsReportedAtCallsite do
    Test.compare("Apples", "Oranges")
  end
end
proc withResultsReportedAtCallsite {body} {
    test fixateResultContext 2
    uplevel 1 $body
    test restoreResultContext
}

proc libraryFunction {} {
    withResultsReportedAtCallsite {
        test compare "Apples" "Oranges"
    }
}

Grouping test results into sections

test.startSection(title)

test.startSection(title, description)

test.endSection()

These functions can be used to group test results into logical units. A set of comparison or log/warning statements can be enclosed in startSection/endSection to have it logged as a distinct result section. The squishide will display result sections as a nested set of test results. Executing tests on the commandline will, except when the XML3 report generator is used, get log messages added to the test report whenever a section starts or ends.

Note: Omitting a call to test.endSection after calling test.startSection can result in very misleading or malformed test reports. For possible solutions, see Ensuring that functions are always called pairwise.

Script-based Creation of Visual Verification Points

createVisualVP(objectNameOrReference, vpFile)

This function creates a Visual Verification Point named vpFile to be used with Boolean test.vp(name) and Boolean test.xvp(name) in a later test run. Whereas this action is typically performed via point & click in the squishide.

The expected visual state is determined through an internal call to saveObjectSnapshot(objectNameOrReference, snapshotImageFile.xml) for the object denoted by objectNameOrReference.

The newly created verification point will have all of content, geometry and screenshot checks enabled. The Visual Verification Point Editor can later be used to modify these checks.

In case vpFile already exists the function will throw a catchable script exception.

Miscellaneous Functions

String findFile(where, filename)

This function returns the path of the given filename or raises a LookupError exception if the file cannot be found.

If the where parameter is "scripts", findFile looks for the filename in the test case scripts directory. If that doesn't contain the file the function next tries the test suite's shared/scripts directory. If that doesn't contain the file, the function tries the paths in the paths.ini initialization file. If it still isn't found, the function tries all of the directories listed in the SQUISH_SCRIPT_DIR environment variable (if it is defined). As soon as the file is found, the filename path is returned; otherwise a catchable LookupError exception is raised.

If the where parameter is "testdata", findFile looks for the filename in the test case's testdata directory. If that doesn't contain the file the function next tries the test suite's shared/testdata directory, and failing that the function tries the test case directory. As soon as the file is found, the filename path is returned; otherwise a catchable LookupError exception is raised.

(See also, the source(filename) function and the Test Data Functions.)

source(filename)

Reads and evaluates the contents of filename, line-by-line. Unlike the scripting language's normal "import" mechanism, (such as Python's import or Perl's use), this is more like the C++ #include directive in that the statements are inserted into your script at that location. This is one way to parse your own shared script files rather than using the scripting language's import mechanism, which may require customization to your environment for it to locate your own modules.

A common use case is to write something like source(findFile("scripts", "common.js")). This uses the String findFile(where, filename) function to produce a filename including a path and then evaluates that file's contents as a script. This typically results in additional functions (and even new classes and variables) becoming available to the test script that performs this call.

For Ruby, use the built-in require method instead—inside a function or method. For example, require findFile("scripts", "common.rb")).

See also, How to Create and Use Shared Data and Shared Scripts, Import Squish Resource dialog, and New Squish Test Script dialog.

Object Access Functions

cast

Casts an object to a given type, returning a reference to it.

findAllObjects

Finds a list of objects filtered by symbolic or real name.

findAllOcrText

Returns a sequence of ScreenRectangle, 1 for each occurrence of text found by OCR.

findImage

Returns the ScreenRectangle of an Image, if it is found on the AUT's display.

findObject

Finds an object by symbolic or real name.

findOcrText

Returns a ScreenRectangle of the AUT's display if certain text is found by OCR.

getOcrText

Returns text found by OCR search on the AUT's display.

grabDesktopScreenshot

Returns an Image of the desktop.

object.children

Returns a list of the object's child objects.

object.convertTo

Converts value types, and extracts values from QVariant.

object.createNull

Creates a null pointer or value for a given type.

object.exists

Returns true if an object exists, using symbolic or real name lookup.

object.globalBounds

Returns the bounding rectangle of an object in screen coordinates.

object.grabScreenshot

Returns an Image (screenshot) of an object.

object.parent

Returns the object's parent or null if parentless.

object.properties

Returns a dictionary of the object's properties.

object.topLevelObjects

Returns a list of the AUT's top level widgets/windows.

saveDesktopScreenshot

Saves an Image of the desktop to a location on the squishrunner host.

—deprecated— grabWidget

Returns a QImage (screenshot) of an object.

Synchronization Functions

snooze

Tells Squish to sleep for a number of seconds.

waitFor

Waits for a boolean condition to be true.

waitForApplicationLaunch

Returns a new ApplicationContext if a new AUT is successfully started/hooked.

waitForImage

Returns a ScreenRectangle of an Image, if it is found in the screen/region.

waitForObject

Returns a reference to an object if it is visible and enabled.

waitForObjectExists

Returns a reference to an object, if it exists.

waitForObjectItem

Waits for an item inside a List/Tree/Table/Menu.

waitForOcrText

Returns a ScreenRectangle of text, if it is found by OCR search on the screen/region.

Interaction Functions

doubleClick

Performs a mouse double-click at the specified position.

keyPress

Performs a single-key press without release.

keyRelease

Releases a key after a keyPress.

mouseClick

Performs a mouse click at a given position.

mouseMove

Moves the mouse to a specified position.

mousePress

Performs a mouse press (without release).

mouseRelease

Performs a mouse release.

nativeMouseClick

Simulates a native mouse click on currently active window.

nativeType

Simulates a native mouse click on currently active window.

sendNativeEvent

Sends a sequence of low-level native events to a given Window.

tapObject

Performs a touch tap at the given position.

Low-Level Functions

nativeMouseClick

Simulates a native mouse click on currently active window.

nativeType

Simulates a native mouse click on currently active window.

sendNativeEvent

Sends a sequence of low-level native events to a given Window.

Debugging Functions

className (Python only)

Returns the object's class name as a string.

highlightObject

Highlights with a red rectangle around the specified object for a configurable time.

isNull

Returns true if value of argument is null.

saveObjectSnapshot

Saves to XML a representation of the object tree.

test.attachDesktopScreenshot

Attaches a desktop screenshot to the test report.

test.attachFile

Attaches a file to a Squish test report.

test.attachImage

Attaches an Image to the Squish test report.

test.breakpoint

Causes the Squish Debugger to stop at this position.

test.fixateResultContext

Temporarily alters/restores call stack frame for log messages.

test.stackTrace

Returns a list of stack frames representing the active function calls.

test.startVideoCapture

Starts video capture of the desktop.

test.stopVideoCapture

Stops desktop video capture of the desktop.

typeName (non-Python only)

Returns the object's class name as a string.

Verification Functions

The compare, verify, and exception functions are used to record the results of tests applied to a running AUT in Squish's test log as passes or fails. The other functions can be used to programmatically record any kind of test results in the test log. See also, the Verification Point Creator view and How to Create and Use Verification Points.

test.compare

Compares two values for equality.

test.compareJSONFiles

PASS if 2 JSON files are the same, FAIL otherwise.

test.compareTextFiles

PASS if 2 text files are "the same", FAIL otherwise.

test.compareXMLFiles

PASS if 2 XML files are "the same", FAIL otherwise.

test.exception

Executes code and expects an exception to be thrown.

test.fail

Adds a FAIL entry to the Squish test log.

test.fatal

Adds a FATAL entry to the Squish test log.

test.imagePresent

PASS if an Image Search is successful, FAIL if not.

test.log

Adds a LOG entry to the Squish test log with a given message.

test.ocrTextPresent-function

PASS if an OCR search is successful. FAIL if not.

test.pass

Adds a PASS entry to the SQUISH test log.

test.resultCount

Returns the number of results of the given category.

test.skip

Skips further execution of the current test case/scenario.

test.verify

PASS if boolean condition is true. FAIL otherwise.

test.vp

Executes a named verification point.

test.vpWithImage

Execute a named Screenshot VP against a specified Image.

test.vpWithObject

Execute a named VP against a specified object.

test.warning

Adds a WARNING entry to the Squish test log.

test.xcompare

Logs XFAIL if the two values compared are not equal.

test.xfail

Adds an XFAIL to the Squish test log.

test.xpass

Adds an XPASS to the Squish test log.

test.xverify

If boolean condition is false, XPASS. If true, XFAIL.

test.xvp

Executes a named VP and logs XPASS or XFAIL depending.

Comparing Files

test.compareJSONFiles

PASS if 2 JSON files are the same, FAIL otherwise.

test.compareTextFiles

PASS if 2 text files are "the same", FAIL otherwise.

test.compareXMLFiles

PASS if 2 XML files are "the same", FAIL otherwise.

© 2024 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners.
The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation.
Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.