5.26. How to Create Cross-Platform Tests

5.26.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, Mac OS X, and Windows. However, in certain situations cross-platform playback may not work—at least not out of the box.

5.26.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 Mac OS X 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 Mac OS X due to Java AWT/Swing differences between the platforms.

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

Python

    startApplication("AddressBookSwing.jar")
    activateItem(waitForObjectItem(":Address Book_javax.swing.JMenuBar", "File"))
    activateItem(waitForObjectItem(":File_javax.swing.JMenu", "Open..."))
        type(waitForObject(":Open.File Name:_JTextField"), "MyAddresses.adr")
    clickButton(waitForObject(":Open.Open_javax.swing.JButton"))
JavaScript

    startApplication("AddressBookSwing.jar");
    activateItem(waitForObjectItem(":Address Book_javax.swing.JMenuBar", "File"));
    activateItem(waitForObjectItem(":File_javax.swing.JMenu", "Open..."));
        type(waitForObject(":Open.File Name:_JTextField"), "MyAddresses.adr");
    clickButton(waitForObject(":Open.Open_javax.swing.JButton"));
Perl

    startApplication("AddressBookSwing.jar");
    activateItem(waitForObjectItem(":Address Book_javax.swing.JMenuBar", "File"));
    activateItem(waitForObjectItem(":File_javax.swing.JMenu", "Open..."));
        type(waitForObject(":Open.File Name:_JTextField"), "MyAddresses.adr");
    clickButton(waitForObject(":Open.Open_javax.swing.JButton"));
Ruby

  startApplication("AddressBookSwing.jar")
  activateItem(waitForObjectItem(":Address Book_JMenuBar", "File"))
  activateItem(waitForObjectItem(":File_JMenu", "Open..."))
    type(waitForObject(":Open.File Name:_JTextField"), "MyAddresses.adr")
  clickButton(waitForObject(":Open.Open_JButton"))
Tcl

    startApplication "AddressBookSwing.jar"
    invoke activateItem [waitForObjectItem ":Address Book_javax.swing.JMenuBar" "File"]
    invoke activateItem [waitForObjectItem ":File_javax.swing.JMenu" "Open..."]
        invoke type [waitForObject ":Open.File Name:_JTextField"] "MyAddresses.adr"
    invoke clickButton [waitForObject ":Open.Open_javax.swing.JButton"]

To make this work cross-platform (i.e., on Windows, Linux, and Mac OS X), 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 Mac OS X, 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(":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(":Open.File Name:_JTextField"), "MyAddresses.adr")
JavaScript

    if (java_lang_System.getProperty( "os.name" ).indexOf( "Mac OS") == 0) {
        var ftable = waitForObject(":Open_JTable");
        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(":Open.File Name:_JTextField"), "MyAddresses.adr");
    }
Perl

    if (java_lang_System::getProperty( "os.name" ) =~ /Mac OS/) {
        my $ftable = waitForObject(":Open_JTable");
        my @rows = object::children($ftable);
        foreach $row (@rows) {
            my @cells = object::children($row);
            if ($cells[0]->toString() =~ /MyAddresses\.adr$/) {
                mouseClick($cells[0]);
                last;
            }
        }
    } else {
        type(waitForObject(":Open.File Name:_JTextField"), "MyAddresses.adr");
    }
Ruby

  if LC::Java_lang_System.getProperty("os.name").start_with?("Mac OS")
    table = waitForObject(":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(":Open.File Name:_JTextField"), "MyAddresses.adr")
  end
Tcl

    if {[string match "Mac OS*" [invoke java_lang_System getProperty "os.name"]]} {
        set ftable [waitForObject ":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 ":Open.File Name:_JTextField"] "MyAddresses.adr"
    }

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