How to Create Cross-Platform Tests

In general, a Squish test recorded on one platform will not only playback on the platform it was recorded on, but also on any other platform that Squish supports. For example, a test recorded for a Qt application on Linux will normally playback on Linux, macOS, and Windows. However, in certain situations cross-platform playback may not work—at least not out of the box.

How to Create Cross-Platform Java AWT/Swing Tests

Tests recorded with Java AWT/Swing AUTs should playback on any Java platform. Thus, a test recorded on Windows should playback on macOS or Linux, and so on. Unfortunately, this does not work when the recording involves a file selection dialog. If a test that involves a file selection dialog is recorded on Windows or Linux it will playback correctly on either platform. But it will not work on macOS due to Java AWT/Swing differences between the platforms.

For example, if we record the opening of a file—but not on macOS—Squish will record code like this:

    startApplication('"' + os.environ["SQUISH_PREFIX"] + '/examples/java/addressbook/AddressBookSwing.jar"')

    activateItem(waitForObjectItem(names.address_Book_JMenuBar, "File"))
    activateItem(waitForObjectItem(names.file_JMenu, "Open..."))

        type(waitForObject(names.open_File_Name_JTextField), "MyAddresses.adr")

    clickButton(waitForObject(names.open_Open_JButton))
    startApplication('"' + OS.getenv("SQUISH_PREFIX") +
        '/examples/java/addressbook/AddressBookSwing.jar"');
    activateItem(waitForObjectItem(names.addressBookJMenuBar, "File"));
    activateItem(waitForObjectItem(names.fileJMenu, "Open..."));
        type(waitForObject(names.openFileNameJTextField), "MyAddresses.adr");
    clickButton(waitForObject(names.openOpenJButton));
        startApplication("\"$ENV{'SQUISH_PREFIX'}/examples/java/addressbook/AddressBookSwing.jar\"");
    activateItem(waitForObjectItem($Names::address_book_jmenubar, "File"));
    activateItem(waitForObjectItem($Names::file_jmenu, "Open..."));

        type(waitForObject($Names::open_file_name_jtextfield), "MyAddresses.adr");
    clickButton(waitForObject($Names::open_open_jbutton));
    startApplication("\"#{ENV['SQUISH_PREFIX']}/examples/java/addressbook/AddressBookSwing.jar\"")
    activateItem(waitForObjectItem(Names::Address_Book_JMenuBar, "File"))
    activateItem(waitForObjectItem(Names::File_JMenu, "Open..."))

        type(waitForObject(Names::Open_File_Name_JTextField), "MyAddresses.adr")
    clickButton(waitForObject(Names::Open_Open_JButton))
    startApplication "\"$::env(SQUISH_PREFIX)/examples/java/addressbook/AddressBookSwing.jar\""
    invoke activateItem [waitForObjectItem $names::Address_Book_JMenuBar "File"]
    invoke activateItem [waitForObjectItem $names::File_JMenu "Open..."]

        invoke type [waitForObject $names::Open_File_Name_JTextField] "MyAddresses.adr"
    invoke clickButton [waitForObject $names::Open_Open_JButton]

To make this work cross-platform (i.e., on Windows, Linux, and macOS), we must replace the line with the type(objectOrName, text) function (which is shown indented—which it wouldn't really be for Python of course), with some custom code that will work on macOS, and fall back to the original code on other platforms. Here is the code necessary to replace the type line:

    if java_lang_System.getProperty("os.name").startswith("Mac OS"):
        table = waitForObject(names.open_JTable)
        rows = object.children(table)
        for row in rows:
            cells = object.children(row)
            if cells[0].toString().endswith("MyAddresses.adr"):
                mouseClick(cells[0])
                break
    else:
        type(waitForObject(names.open_File_Name_JTextField), "MyAddresses.adr")
    if (java_lang_System.getProperty( "os.name" ).indexOf( "Mac OS") == 0) {
        var ftable = waitForObject(names.openJTable);
        var rows = object.children(ftable);
        for (var i = 0; i < rows.length; ++i) {
            var cells = object.children(rows[i]);
            if (cells[0].toString().indexOf("MyAddresses.adr") > -1) {
                mouseClick(cells[0]);
                break;
            }
        }
    } else {
        type(waitForObject(names.openFileNameJTextField), "MyAddresses.adr");
    }
    if (java_lang_System::getProperty( "os.name" ) =~ /Mac OS/) {
        my $ftable = waitForObject($Names::open_jtable);
        my @rows = object::children($ftable);
        foreach my $row (@rows) {
            my @cells = object::children($row);
            if ($cells[0]->toString() =~ /MyAddresses\.adr$/) {
                mouseClick($cells[0]);
                last;
            }
        }
    } else {
        type(waitForObject($Names::open_file_name_jtextfield), "MyAddresses.adr");
    }
    if LC::Java_lang_System.getProperty("os.name").start_with?("Mac OS")
        table = waitForObject(Names::Open_JTable)
        rows = Squish::Object.children(table)
        for row in rows
            cells = Squish::Object.children(row)
            cell = String(cells[0])
            if cell.match("MyAddresses.adr$")
                mouseClick(cells[0])
                break
            end
        end
    else
        type(waitForObject(Names::Open_File_Name_JTextField), "MyAddresses.adr")
    end
    if {[string match "Mac OS*" [invoke java_lang_System getProperty "os.name"]]} {
        set ftable [waitForObject $names::Open_JTable]
        set rows [object children $ftable]
        foreach row $rows {
            set cells [object children $row]
            if { [string last "MyAddresses.adr" [toString [lindex $cells 0]]] > -1 } {
                invoke mouseClick [lindex $cells 0]
                break
            }
        }
    } else {
        invoke type [waitForObject $names::Open_File_Name_JTextField] "MyAddresses.adr"
    }

    invoke clickButton [waitForObject $names::Open_Open_JButton]

With this code in place, the test script should replay correctly on Linux, macOS, and Windows.

© 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.