Chapter 10. Frequently Asked Questions

10.1.1. How can I change the default timeout used by the waitForObject function (and for similar functions, like waitForObjectItem)?
10.1.2. How good is Squish's support for custom Qt classes?
10.1.3. Why does text entered with the type function end up garbled in a Qt application? And why does a clickButton call have no effect?
10.1.4. How do I Build Squish and Qt on IRIX with gcc?
10.1.5. How do I Build Squish with Python Support on MinGW?
10.1.6. I have problems building Squish with a single-threaded Qt 3 library on Windows.
10.1.7. Why doesn't Squish record mouse move events?
10.1.8. Why do my widgets always get names like MyWidget34 rather than more descriptive names?
10.1.9. Why does Squish fail to hook into my AUT on AIX?
10.1.10. Why does squishrunner fail to start with the error cannot restore segment prot after reloc: Permission denied?
10.1.11. Why doesn't Squish replay paintings properly in my painting application?
10.1.12. Why doesn't Squish work correctly on Ubuntu 11.

10.1.1.

How can I change the default timeout used by the waitForObject function (and for similar functions, like waitForObjectItem)?

The easiest solution is to create a custom function with the same name, but with the timeout you want. Here's how to create a version with a timeout of 5 seconds; it should go at the top of the test (before the main function), and before any calls to the function are made.

Python

import sys # Add this line

def wrapSquishFunction(functionName, wrappedFunctionGetter): # Add this function
    module = sys.modules["squish"]
    if functionName in dir(module):
        wrappedFunction = wrappedFunctionGetter(getattr(module, functionName))
        setattr(module, functionName, wrappedFunction)
    else:
        raise RuntimeError("function %s not part of squish module" % functionName)

    if functionName in globals():
        globals()[functionName] = wrappedFunction

def myWaitForObject(waitForObjectFunction): # Add this function
    def wrappedFunction(objectOrName, timeout=5000):
        return waitForObjectFunction(objectOrName, timeout)
    return wrappedFunction

def main():
    startApplication("addressbook")
    wrapSquishFunction("waitForObject", myWaitForObject) # Add this line
    # ...
JavaScript
originalWaitForObject = waitForObject

waitForObject = function(obj) {
    return originalWaitForObject(obj, 5000)
}
Tcl
rename waitForObject originalWaitForObject

proc waitForObject {obj} {
    return [originalWaitForObject $obj 5000]
}

The above approach works when AUTs are run automatically. For those started using the startApplication function, all this must be done after that function is called (since only then does all of the Squish API become available). See also, How to Modify Squish Functions (Section 5.20).

(We don't currently have a solution for Perl.)

10.1.2.

How good is Squish's support for custom Qt classes?

Quite often, the subclassing of Qt classes is done to change the look and behavior of standard widgets. Or to store some extra internal information. Squish will recognize those classes at least up to the level it would support the underlying standard classes. So if an application's developers subclass e.g. QPushButton to create a round button or to make the button change shape if pressed, this will no pose a problem as Squish's emulation is purely concerned with user input in terms of keyboard and mouse input independent of the behavior of the underlying C++ functions that are called.

In many test scenarios test engineers are only concerned with standard visible properties, like text or color, and these work out of the box for custom QObject subclasses that inherit such properties. In addition, as of Squish 4, custom QObject subclasses' properties and slots (marked via the Q_PROPERTY and slots macros) are automatically detected. This means that their properties will show up in the Spy and their custom slots (provided the signatures use standard Qt types) are callable.

So in almost all cases Squish's automatic detection is sufficient.

Squish 3 used a less dynamic approach using the squishidl (Section 7.4.5) tool. The tool scans C and C++ header files and provides script bindings for the functions and classes it parses. When building Squish we also use this tool to create script bindings to the Qt libraries themselves. While the tool is powerful, it can be a bit involved to set up as you must perform some build steps with the right include search paths and pre-processor macros set up as when building your application. If there is a specific object that is causing problems in a planned test case contact froglogic technical support so that we can help solve the problem.

10.1.3.

Why does text entered with the type function end up garbled in a Qt application? And why does a clickButton call have no effect?

The Qt 4.3 series has a bug that mixes up the order of posted events in the internal queue. In some rare cases this breaks text input or mouse click sequences. This problem was scheduled to be solved in Qt 4.4 and possibly also in Qt 4.3.4. A source code patch is available on request.

10.1.4.

How do I Build Squish and Qt on IRIX with gcc?

To build Squish, Qt must be linked as a shared library. When compiling Qt with gcc in IRIX, it is built as a static library by default. To build Qt as a shared library, specify the -shared option when running Qt's configure script.

The reason, why static is the default build is because Qt doesn't link as a shared library on IRIX when being built with gcc. To fix this problem, edit the file src/Makefile after you have run configure. Add the switch -Wl,-LD_LAYOUT:lgot_buffer=100 to the Makefile's LFLAGS variable. The line should then look similar to this one:

LFLAGS = -Wl,-LD_LAYOUT:lgot_buffer=100 -shared -Wl,-soname,libqt-mt.so.3 -Wl,-rpath,/usr/people/reggie/qt32-gcc/lib

After doing this just compile Qt as usual (i.e., by running make). Then compile Squish as documented elsewhere in this manual (Installing Squish for Qt from Desktop Source Packages (Section 3.1.2)).

[Note]Note

This fix was been submitted to Trolltech support and was incorporated into Qt in version 3.3.0.

10.1.5.

How do I Build Squish with Python Support on MinGW?

Some Python binary distributions already contain an import library for Python that can be used with MinGW. In such cases you don't have to do anything.

On the other hand, if you don't have the import library you must generate it yourself. For this you need MinGW's pexports and dlltool tools.

In the following example we assume that Python is installed in C:\Python25 and that the Python DLL is C:\WINNT\system32\python25.dll. To generate the import library, do the following:

cd C:\Python25\libs
pexports C:\WINNT\system32\python25.dll > python25.def
dlltool --dllname python25.dll --def python25.def --output-lib libpython25.a

For more information see the MinGW Wiki on Python extensions (just the Basic Setup section).

10.1.6.

I have problems building Squish with a single-threaded Qt 3 library on Windows.

As mentioned in Installation for testing with a single-threaded Qt library (Section 3.1.2.5), most parts of Squish can be built with a single-threaded Qt library. On Windows there is one problem with this: The single-threaded Qt library is linked against the static LIBC.LIB instead of the shared MSVCRT.LIB. This leads to problems with memory management because of different heaps when using multiple DLLs linked against Qt, and this problem affects Squish.

To work around the problem, open the file %QTDIR%\mkspecs\win32-msvc\qmake.conf (or %QTDIR%\mkspecs\win32-icc\qmake.conf, if you use Intel C++) and change the following lines:

QMAKE_CFLAGS_RELEASE	= -O1
QMAKE_CFLAGS_DEBUG	= -Z7

to:

QMAKE_CFLAGS_RELEASE	= -O1 -MD
QMAKE_CFLAGS_DEBUG	= -Z7 -MDd

After doing this you must regenerate Qt's Makefile and then recompile the Qt:

cd %QTDIR%\src
qmake qt.pro
nmake clean
nmake

10.1.7.

Why doesn't Squish record mouse move events?

Squish only records mouse move events when a mouse button is pressed—even if Qt's mouse tracking is enabled. This is because in most cases mouse move events that take place when no mouse button is pressed can be ignored since they don't need to be replayed for the widgets to function properly. Furthermore, recording these events would produce a lot of script code which would not affect the application, but would make the script harder to read and maintain.

For those rare cases where it is necessary to record all the mouse move events because they are essential for the widget to work correctly, you can change Squish's behavior. For example, let's assume that we have a custom widget of type CanvasView for which we want to record all mouse move events. We can tell Squish to switch on mouse tracking for widgets of this type by creating and registering a suitable init file. For example, we could create a file called myinit.tcl that contained this line:

setMouseTracking CanvasView true

Then we can tell Squish to execute this file at startup:

squishrunner --config addInitScript Qt <absolute_path>/myinit.tcl

After this, when recording a test case, mouse move events on CanvasView widgets will be recorded even if no mouse button is pressed. (See also, Configuring squishrunner (Section 7.4.3.7).)

10.1.8.

Why do my widgets always get names like MyWidget34 rather than more descriptive names?

Squish tries to create the most descriptive names for GUI objects. By default is uses the QObject name. If this property isn't unique (or is empty), other possibly unique properties are examined (window caption, button text, etc.) before falling back to <ObjectType><num>.

One solution (and probably the best!) to get better names in generated scripts is to give all the widgets descriptive, short and unique QObject names in the AUT's source code.

If the custom widgets have other possibly unique properties, like a label, etc., Squish can be told to try using these properties. For example, suppose that we have a custom widget called CanvasView which has a unique label property. To tell Squish about this, create a file called, for example, myinit.tcl that contains the following line:

setUniqueProperty CanvasView label

Then tell Squish to interpret this file at startup:

squishrunner --config addInitScript Qt <absolute_path>/myinit.tcl

After doing this, Squish will attempt to use the CanvasView's label property for identification, if its value is unique. (See also, Configuring squishrunner (Section 7.4.3.7).)

10.1.9.

Why does Squish fail to hook into my AUT on AIX?

Usually, Squish hooks into the AUT without requiring any special preparations. However, in some cases—such as on AIX—this is not possible due to technical limitations of the operating system. See the chapter Using the Built-in Hook (Section 7.13.2) in the Tools Reference Manual (Chapter 7) for a solution.

10.1.10.

Why does squishrunner fail to start with the error cannot restore segment prot after reloc: Permission denied?

Due to the usage of third-party code and imperfect compilers, Squish contains libraries with so called "text relocations". By themselves these are harmless but a "hardened" Linux distribution with SELinux (Security Enhanced Linux) installed may nevertheless disallow such a property.

We are still investigating this problem, but meanwhile one workaround is to change the SELinux policy from enforcing to permissive—on most modern systems this can be done via a GUI configuration tool, or it can be done by manually editing the /etc/selinux/config file, and changing the SELINUX=enforcing entry to SELINUX=permissive. Whichever way the change is made, the system must be rebooted for the change to take effect.

A more fine-grained solution is also possible using the chcon tool. This allows for the setting of the security context for individuals files. Here is a command that a customer gave us that should make things work:

find /path/to/squish -type f -name "*.so" | xargs chcon -t textrel_shlib_t

10.1.11.

Why doesn't Squish replay paintings properly in my painting application?

When a mouse press event is followed by mouse move events (while the button is still pressed), Squish compresses all these events into a single mouseDrag.

Using a mouseDrag is much more robust in the face of changes in the AUT then recording the individual mouse events. However, during the replay of the mouseDrag, there is only one mouse move event synthesized, starting from the point where the mouse button was pressed to the point where the mouse button was released.

To enable recording to work properly for applications that depend on all of the individual mouse move events being recorded individually, there's a way to disable the creation of the mouseDrag calls for a specific widget type. See setRecordMouseDrag for further details.

10.1.12.

Why doesn't Squish work correctly on Ubuntu 11.

Ubuntu 11 ships with the Unity desktop by default. This desktop system takes a Mac OS X-like approach with a single menubar at the top of the screen rather than associated with each application. One of the things the Ubuntu developers have done to achieve this is to patch all the GUI libraries shipped with Ubuntu. Unfortunately, many many applications—including the Squish IDE—are broken by these patches, with the result that no menubar is shown at all. See for example, Ubuntu bug 618587 and Eclipse bug 330563.

A workaround is to set the following environment variable: UBUNTU_MENUPROXY=0. (This workaround is used by the SQUISHDIR/squishide script which runs the SQUISHDIR/bin/ide/squishide application, but obviously if you run the application directly you must set the environment variable yourself.)