5.27. How to Create Cross-Platform Tests

Table of Contents

5.27.1. How to Create Cross-Platform Java AWT/Swing 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.

5.27.1. 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:

Python

    startApplication("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))
JavaScript

    startApplication("AddressBookSwing.jar");
    activateItem(waitForObjectItem(names.addressBookJMenuBar, "File"));
    activateItem(waitForObjectItem(names.fileJMenu, "Open..."));
        type(waitForObject(names.openFileNameJTextField), "MyAddresses.adr");
    clickButton(waitForObject(names.openOpenJButton));
Perl

    startApplication("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));
Ruby

    startApplication("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))
Tcl

    startApplication "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 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:

Python

    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")
JavaScript

    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");
    }
Perl

    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");
    }
Ruby

    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
Tcl

    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"
    }

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