Dumping all objects

Last edited on

Introduction

To have a better understanding of the GUI objects in an application it can be useful to create a dump of the objects.

An object dump can be created by using the script functions offered by Squish.

Dumping the desired object and children (recursively)

To dump objects, you will need to put the dump_objects.* (dump_objects.pl for Perl, dump_objects.py for Python) script on your computer. (An example object dump for the Qt addressbook example is available qt_addressbook_objectdump.xml.)

This script should then be loaded and executed at the point where the object that should get dumped is visible in the AUT.

In Python Test Scripts

The following code snippet provides an outline of how the dump_objects.py script can be loaded and its dump_objects_to_file() function used (the code below assumes that the file dump_objects.pl is in the test case folder, the test suite shared resource folder or the global shared scripts folder):

Dumping a specific object’s tree to a file

import os.path

source(findFile("scripts", "dump_objects.py"))

def main():
    # ...

    obj_name = "{type='MainWindow' visible='1'}"
    dump_file = os.path.join(os.path.expanduser("~"), "objectdump.xml")

    widget = waitForObject(obj_name)

    # Dump object to file:
    dump_objects_to_file(obj=widget, xml_out_file_name=dump_file)
test.py

Dumping the complete object tree to a file

import os.path

def main():
    # ...

    dump_objects_py_file = os.path.join(squishinfo.testCase, "..", "dump_objects.py")
    dump_file = os.path.join(os.path.expanduser("~"), "objectdump.xml")

    # Load object dump functionality:
    source(dump_objects_py_file)

    # Dump all objects to file:
    dump_objects_to_file(obj=None, xml_out_file_name=dump_file)
test.py

Dumping a specific object’s tree to the Test Results/Log

import os.path

def main():
    # ...

    dump_objects_py_file = os.path.join(squishinfo.testCase, "..", "dump_objects.py")

    widget = waitForObject(obj_name)

    # Load object dump functionality:
    source(dump_objects_py_file)

    # Dump object to Test Results/Log:
    dump_objects(obj=widget)
test.py

Dumping the complete object tree to the Test Results/Log

import os.path

def main():
    # ...

    dump_objects_py_file = os.path.join(squishinfo.testCase, "..", "dump_objects.py")

    # Load object dump functionality:
    source(dump_objects_py_file)

    # Dump all objects to Test Results/Log:
    dump_objects()
test.py

For all of the above to work correctly you must, of course, set obj_name to the name of the actual AUT object you want to dump. You may also need to correct or change the path/filenames of dump_objects_py_file and dump_file.

After the execution of the test script the resulting dump_file contains the GUI object and its children (recursively) and shows their hierarchical relationship to each other.

In Perl Test Scripts

The following code snippet provides an outline of how the dump_objects.pl script can be loaded and its dump_objects_to_file() function be used (the code below assumes that the file dump_objects.pl is in the test case folder, the test suite shared resource folder or the global shared scripts folder):

source(findFile("scripts", "dump_objects.pl"));

sub main {
    startApplication("SwingFrame.class");
    mouseClick( waitForObjectItem( ":Lists_JList", "three" ),
        23, 6, 0, Button::Button1 );
    dump_objects_to_file(obj=>":Lists_JList", xml_out_file_name=>"/tmp/dump.txt", take_screenshots=>1);
    #dump_objects(obj=>":Lists_JList");
    snooze(1.4);
    closeWindow(":foo{bar_SwingFrame");
}
test.pl

Alternative JavaScript Variant

After (adjusting) and executing this script successfully there is a new file called “_objectsdump.txt” in the Test Case Resources section of the Test Suites View which can be opened via double click to view it.

function main() {
    startApplication(...);

    //...

    var o = waitForObject(object_name_here);

    var dumpFile = File.open("_objectsdump.txt","w");
    forEachChildRecursive(o, logChild, dumpFile);
    dumpFile.close();
}

function forEachChildRecursive(obj, doWithChildObjectFunction, fileToLogTo, nestingLevel)
{
    if (nestingLevel == undefined) {
        nestingLevel = 0;
    }
    var children = object.children(obj);
    for (var i = 0; i < children.length; i++) {
        var child = children[i];
        doWithChildObjectFunction(child, fileToLogTo, nestingLevel);
        forEachChildRecursive(child, doWithChildObjectFunction, fileToLogTo, nestingLevel+1);
    }
}

function logChild(childObj, fileToLogTo, nestingLevel) {
    var properties = object.properties(childObj);
    var indent = getIndent(nestingLevel);
    var indent2 = getIndent(1);
    var s = "";
    for (var name in properties) {
        s += indent + indent2 + name + "=";
        var value = properties[name];
        try {
            s += value;
        } catch(e) {
            s += "<error getting value>";
        }
        s += "\n";
    }

    // Special handling for QActions, for which
    // objectMap.realName() might hang:
    var objTitle;
    if (typeName(childObj) == "QAction") {
        objTitle = "QAction: " + childObj.text;
    } else {
        objTitle = objectMap.realName(childObj);
    }

    if (fileToLogTo == undefined) {
        test.log(indent + objTitle, s);
    } else {
        try {
            fileToLogTo.write(indent);
            fileToLogTo.write(objTitle);
            fileToLogTo.write("\n");
            fileToLogTo.write(s);
            fileToLogTo.write("\n");
        } catch(e) {
            test.warning("Writing to log file failed: " + e.toString());
        }
    }
}

function getIndent(indentLevel) {
    var s = "";
    for (var i = indentLevel; i > 0; i--) {
        s += "    ";
    }
    return s;
}
test.js

Resources