Squish tip of the week: Handling implementation differences between platforms

Squish tip of the week: Handling implementation differences between platforms

A great question from our Webinar Q&A session this week: What is the best way to solve implementation differences between platforms (e.g. Windows Vs Unix)?

When dealing with cross-platform applications, for example Java or Qt, the majority of your Squish tests are not impacted by the platform, as your application, and it’s controls/widgets are identical across platforms. Occasionally however differences may exist.

Using Squish there’s an easy way to handle platform differences: Identify and branch for differences

Example working with Java Applications

You can try it using our sample Addressbook application, located in:
<squishDir>\examples\java\addressbook

In the following script (javascript), lines 12 and 13 are valid for Linux and Windows, but not valid for Mac:

function main() {
    startApplication("AddressBookSwing.jar");
    activateItem(waitForObjectItem(":Address Book_javax.swing.JMenuBar", "File"));
    activateItem(waitForObjectItem(":File_javax.swing.JMenu", "New..."));
    activateItem(waitForObjectItem(":Address Book - Unnamed_javax.swing.JMenuBar", "Edit"));
    activateItem(waitForObjectItem(":Edit_javax.swing.JMenu", "Add..."));
    type(waitForObject(":Address Book - Add.Forename:_javax.swing.JTextField"), "jane");
    type(waitForObject(":Address Book - Add.Surname:_javax.swing.JTextField"), "smith");
    type(waitForObject(":Address Book - Add.Email:_javax.swing.JTextField"), "jane@smith.com");
    type(waitForObject(":Address Book - Add.Phone:_javax.swing.JTextField"), "123.123.1234");
    clickButton(waitForObject(":Address Book - Add.OK_javax.swing.JButton"));
    activateItem(waitForObjectItem(":Address Book - Unnamed_javax.swing.JMenuBar", "File"));
    activateItem(waitForObjectItem(":File_javax.swing.JMenu", "Quit"));
    clickButton(waitForObject(":Address Book.No_JButton"));
}

To accommodate the platform difference we’ll:

  1. Check the platform prior to the impacted steps
  2. Branch the script to take one path when the platform is Mac, and another path it isn’t

Which results in the following:

function main() {
    startApplication("AddressBookSwing.jar");
    activateItem(waitForObjectItem(":Address Book_javax.swing.JMenuBar", "File"));
    activateItem(waitForObjectItem(":File_javax.swing.JMenu", "New..."));
    activateItem(waitForObjectItem(":Address Book - Unnamed_javax.swing.JMenuBar", "Edit"));
    activateItem(waitForObjectItem(":Edit_javax.swing.JMenu", "Add..."));
    type(waitForObject(":Address Book - Add.Forename:_javax.swing.JTextField"), "jane");
    type(waitForObject(":Address Book - Add.Surname:_javax.swing.JTextField"), "smith");
    type(waitForObject(":Address Book - Add.Email:_javax.swing.JTextField"), "jane@smith.com");
    type(waitForObject(":Address Book - Add.Phone:_javax.swing.JTextField"), "123.123.1234");
    clickButton(waitForObject(":Address Book - Add.OK_javax.swing.JButton"));
    if (java_lang_System.getProperty("os.name").indexOf("Mac OS") == 0) {
        nativeType("<Command+q>");
    } else {
        activateItem(waitForObjectItem(":Address Book - Unnamed_javax.swing.JMenuBar", "File"));
        activateItem(waitForObjectItem(":File_javax.swing.JMenu", "Quit"));
    }
    clickButton(waitForObject(":Address Book.No_JButton"));
}

Notice, line 12 in the modified script retrieves the platform where the application is *currently* executing. This is important, as the test may be triggered by a remote system using another platform.

Example working with Qt Applications

You can try it using our sample Addressbook application, located in:
<squishDir>\examples\java\addressbook

In the following script (javascript), lines 10 and 11 are valid for Linux and Windows, but not valid for Mac:

function main() {
    startApplication("addressbook");
    clickButton(waitForObject(":Address Book.New_QToolButton"));
    clickButton(waitForObject(":Address Book - Unnamed.Add_QToolButton"));
    type(waitForObject(":Forename:_LineEdit"), "jane");
    type(waitForObject(":Surname:_LineEdit"), "smith");
    type(waitForObject(":Email:_LineEdit"), "jane@smith.com");
    type(waitForObject(":Phone:_LineEdit"), "123.123.1234");
    clickButton(waitForObject(":Address Book - Add.OK_QPushButton"));
    activateItem(waitForObjectItem(":Address Book - Unnamed_QMenuBar", "File"));
    activateItem(waitForObjectItem(":Address Book - Unnamed.File_QMenu", "Quit"));
    clickButton(waitForObject(":Address Book - Delete.No_QPushButton"));
}

To accommodate the platform difference we’ll:

  1. Check the platform prior to the impacted steps
  2. Branch the script to take one path when the platform is Mac, and another path it isn’t

Unlike in Java, where the host platform is available with the java_lang_System.getProperty(“os.name”) statement, for Qt the platform should be passed to the squishrunner service when started.

For example, you may start your squishserver using the following commands:
export SQUISH_HOST_OS=`uname`
./squishserver

For Windows, use ver instead of uname:

for /f "delims=" %a in ('ver') do @set SQUISH_HOST_OS=%a
squishserver.exe

Then modify the script as follows:

function getHostOS(){
    myAUT = currentApplicationContext();
    hostOS = myAUT.environmentVariable("SQUISH_HOST_OS");
    return hostOS
}

function main() {
    startApplication("addressbook");
    clickButton(waitForObject(":Address Book.New_QToolButton"));
    clickButton(waitForObject(":Address Book - Unnamed.Add_QToolButton"));
    type(waitForObject(":Forename:_LineEdit"), "jane");
    type(waitForObject(":Surname:_LineEdit"), "smith");
    type(waitForObject(":Email:_LineEdit"), "jane@smith.com");
    type(waitForObject(":Phone:_LineEdit"), "123.123.1234");
    clickButton(waitForObject(":Address Book - Add.OK_QPushButton"));

    if (getHostOS() == "Darwin"){
        nativeType("<Command+q>")
    } else{
        activateItem(waitForObjectItem(":Address Book - Unnamed_QMenuBar", "File"));
        activateItem(waitForObjectItem(":Address Book - Unnamed.File_QMenu", "Quit"));
    }

    clickButton(waitForObject(":Address Book - Delete.No_QPushButton"));
}

Notice, line 3 in the modified script retrieves the platform where the application is *currently* executing using the value set in the environment variable before starting the squish server. This is important, as the test may be triggered by a remote system using another platform.