froglogic / Blog / Tip of the Week / Verifying the Visual Order of GUI Elements

Verifying the Visual Order of GUI Elements

This tip demonstrates how to verify that GUI elements are properly arranged from left to right and top to bottom.

Verifications in Squish

The Squish GUI Tester has several ways to do functional tests of Graphical User Interfaces. One recurring scenario is verifying the layout of GUI elements. A proper layout is usually defined by the following two requirements:

  • UI elements do not overlap and thus are fully visible to the user
  • UI elements are aside or under each other, meaning that they appear in a certain order that does not change accidentally

Squish supports verifications of objects in three major ways. However, out of the box, neither of them are a perfect fit for verifying the layout and order of GUI elements.

Property Verification does not catch relations between multiple GUI elements. Verifying a property captures a single aspect of a GUI element only, and it compares an expected with an actual property value instead of expressing a relation.

Screenshot Verification of whole dialogs to a certain degree does verify geometry and how the geometry of GUI elements relate to each other because the geometry and layout are part of the visual representation. However, screenshots are often not very portable between computers or operating systems. Fonts, colors and object sizes often differ from one setup to the next and ensuring they don’t is a whole topic on its own. In addition, any change to a GUI element can potentially change the visual representation even if the layout and the relation to other GUI elements is not affected. So to sum it up, screenshots are usually too strict.

Visual Verification combines screenshot, object hierarchy, geometry as well as a selected set of properties. Again, that may be too strict for the task at hand. Some toolkits have different element hierarchies between operating systems or toolkit versions. On the other hand a Visual Verification does not necessarily guarantee that GUI elements are laid out on screen in a certain way. The relation of GUI element geometries may not be expressed by either hierarchy or the set of verified properties.

Verifying Order and Layout

The proposed solution to verify the order as well as the layout of GUI elements is to look up a list of objects by name and fetch their global screen coordinates. Fetching screen coordinates is possible in Squish via the object.globalBounds() function:

o = waitForObjectExists("{type='Button' text='Open'}")
bounds = object.globalBounds(o)

The list of objects to fetch should be predetermined inside the test script to ensure a certain order of objects. Element names for the list of objects can be fetched via the Squish IDE by interactively picking the objects and copying their object name. Verifying the layout of a bunch of objects can be as simple as a single function call that receives the list of objects to verify:

validateLayout("Validating toolbar layout",

Screen coordinates are compared between adjacent GUI elements. For each pair of GUI elements we can verify whether they are aside or beneath each other and also ensure that they do not overlap. The following function implements a simple coordinate and overlap check and expects a left-to-right layout:

def fitsLeftToRightLayout(newBounds, oldBounds):
    # new object must start below the top border of the old one
    if newBounds.y >= oldBounds.y:
        oldBottom = oldBounds.y + oldBounds.height
        # new object must start below the bottom border of the old one
        if newBounds.y >= oldBottom:
            return True
        oldRight = oldBounds.x + oldBounds.width
        # new object must start somewhere to the right of the old one
        if newBounds.x >= oldRight:
            return True
    return False

In case a layout problem is detected, the logic can simply log the object name that had a mismatch. For interactive use, the highlightObject() function of Squish can be used to visually highlight mismatches. The complete implementation that does this and calls the above layout check can be seen here:

def validateLayout(title, objectNames):
        lastObject = waitForObjectExists(objectNames[0])
        lastBounds = object.globalBounds(lastObject)
        for name in objectNames[1:]:
            newObject = waitForObjectExists(name)
            newBounds = object.globalBounds(newObject)
            fits = fitsLeftToRightLayout(newBounds, lastBounds)
            if not test.verify(fits,
                               "Object fits into layout: {0}".format(name)):
            lastObject = newObject
            lastBounds = newBounds

Outlook and Improvements

The above script code is kept simple to make it easier to understand as part of this blog entry. There are several ways how it could be improved further.

Logging in case of mismatches could be done in other ways, including logging of application specific properties, taking desktop screenshots or by saving an object snapshot of the surrounding dialog or window via saveObjectSnapshot(). Especially the latter two would allow for a more thorough post-analysis.

Other layout directions could be tested in a similar way. The code currently expects a left-to-right layout. Furthermore layout mechanisms that align objects on their center may cause mismatches. The logic would have to be extended to take such center/middle alignments into account also.

The current code compares single geometry properties only. For more advanced checks, using a more capable geometry type can help keep the logic readable and make it more expressive. Comparisons like rectangle.isLeftOf(otherRectangle) or == can help keep complex checks readable.

A fully working example that verifies two layout aspects on the addressbook example application of Squish for Qt can be downloaded as

Leave a Reply


Copy link
Powered by Social Snap