In a nutshell¶
For object level automation of file dialogs Squish for Qt requires that file dialogs are based on Qt itself.
Qt 4.x allows enforcing Qt based dialogs in many cases.
Qt 5.3 to Qt 5.6 does not allow forcing Qt based dialogs in most cases.
Qt 5.7 allows it again, and Squish 6.2 takes advantage of it.
Qt application developers can explicitly request Qt based file dialogs through changes in the source code of the applications.
When recording on Windows native file dialogs Squish records interactions with the native Windows GUI controls, but when trying to access these GUI objects upon replay results such messages:
Dialogs in Qt applications¶
Qt applications running on Windows use the native Windows file dialogs by default. The native Windows file dialogs looks like this:
However, when a Qt application is run as an AUT in Squish (on Windows), the application may use Qt's own dialogs (implemented using Qt GUI controls). The Qt 4/5 based file dialogs look like this:
As you can see the Qt based dialogs may look different from the native dialogs. (This also applies to the directory chooser dialogs.)
This means that Squish tries to force Qt to use Qt dialogs rather than native dialogs. This is done because:
Squish's Qt support works with GUI objects of Qt's own dialogs, which is more reliable than automating native dialogs via nativeType() and similar functions as a "black box".
Using Qt's dialogs means that recorded tests may work cross-platform (e.g., on Mac OS X and Linux), something that is more difficult with native dialogs since they are platform-dependent.
Even though the dialogs look different, this should have no affect on your program. This is true for Qt dialogs on other platforms as well.
Qt 4.x to 5.2 (incl.) & Qt 5.7 and higher¶
It is possible for Squish to try to force the use Qt dialogs over native ones, and Squish does so by default.
If for some reason, you wish to see native dialogs instead, you can edit the SQUISHDIR/etc/qtwrapper.ini
entry for UseNativeDialogs
and set it to 1.
Qt 5.3 to Qt 5.6¶
Qt 5.3 to Qt 5.6 do not allow Squish to disable native dialogs, which has a number of drawbacks:
Test scripts are not cross-platform anymore because automated objects inside the file dialog are different depending on the platform (Windows).
Users may need additional licenses for the native toolkit (Mac, Windows).
In case of Linux/X11 with a Gtk+/Gnome file dialog Squish does not record anything at all.
Solutions¶
General solution #1 - Automate the dialogs via nativeType()
¶
This solution does not allow for precise synchronization based on object existence, therefore the snooze()
command must be used in addition to ensure that the dialog really is already on the screen and has input focus when starting to send key presses via nativeType()
.
For more details please see Automating file dialogs with type() and nativeType() .
General solution #2 - Request Qt based dialogs via parameter "-platformtheme none"¶
Adding the command line arguments -platformtheme none
when starting the AUT may enable Qt based file dialogs. For example:
The above will make Qt try to load a plug-in with the name "none" and since no such plug-in exists, it will fall back to its internal defaults.
This solution has been successfully tested on Linux/X11 and Windows using Qt 5.3.0 and it applies to the traditional QFileDialog as well as the new QML/QtQuick2 FileDialog.
Known issues with the solution:
The application may not use color and font settings from the desktop environment anymore since that is also provided by "platformtheme" plug-ins.
Pure QtQuick 2 applications may need to use/link to the QtWidgets module to fall back to the built-in Qt file dialog, that may be a problem for some users.
On macOS: Does not work for Qt 5.2.0 on macOS (yet).
On macOS: Lack of menus - only the application menu is shown.
General solution #3 - Request Qt based dialogs in application's source code itself¶
A Qt application can itself request Qt based dialogs through the QFileDialog.DontUseNativeDialog
option
which is passed as options
to many of the QFileDialog
static public
functions, as well as through its own getter/setter.
This could be done optionally, based on the existence of the environment variable SQUISH_PREFIX
, to limit this behavior to cases where the application is being started by Squish.