Testing Qt Quick Text Truncation

The Qt framework is well-known among those who develop user interfaces for cross-platform applications. Qt Quick, a module for writing fluid and dynamic user interfaces using the QML language, is a part of this framework. One important functional consideration for QA engineers is to check elements containing a text for truncation. When can truncation happen? For example, if the content of a text element exceeds its width and the text element has the elide property set. This article will introduce two approaches to testing text truncation in Qt Quick applications with Squish: one approach for plain text and one approach for Rich Text Format (RTF). 

Testing Plain Text Truncation

Let's create a QML text element that has a width property set to a number which is less than the width of the actual text. It is plain text, so it may contain the elide property. Let's use Text.ElideRight. In our case, this truncates the text and adds an ellipsis at the end:

QML code for a text element showing the current date.
QML code for text element showing the date.

We observe our truncated text element in the top left corner:

Qt Quick Window showing truncated text.
Qt Quick application window showing truncated text.

It is easy to check text truncation using the following Squish script:

obj = waitForObjectExists(names.date)
text = str(obj.text)
name = objectMap.symbolicName(obj)
msg = "Verify 'truncated' property: '%s' of %s" % (text, name)
if obj.truncated:
test.fail(msg)
else:
test.passes(msg)

The date in left upper part of the application window is truncated, so our test fails:

Test result, showing failure of the truncation check.

Testing RTF Truncation

The above approach works for text that is not of Rich Text Format. RTF does not have a truncated property, so to test truncation of RTF, we should use another approach. Have a look at the following code:

def checkTruncation(obj, stripHTML=True):
text = obj.text
if stripHTML:
text.remove(QRegExp("<[^>]*>"))
text = str(text)
name = objectMap.symbolicName(obj)
msg = "Verify truncation: '%s' of %s" % (text, name)
if len(text) != 0:
width = builtins.int(obj.width)
# If it has decimal places, round up:
if builtins.float(width) != builtins.float(obj.width):
width += 1
width_required = requiredWidth(obj, text)
if width < width_required:
detail = "Obj. width: %s, but requires: %s" % (width, width_required)
return test.fail(msg, detail)
return test.passes(msg)

def requiredWidth(obj, text):
fm = QFontMetrics(obj.font)
return fm.boundingRect(QString(text)).width

In requiredWidth() we are obtaining the width that a text element should have in order to show the whole text without truncating it. Then, in checkTruncation(), we are comparing the width of text shown on the screen to the required width. The purpose of stripHTML is to remove HTML tags from the text before comparing the width. These tags are not visible on the screen.

In this case, Squish gives the following output:

Wrap Up

To provide the best UX/UI, it is important to check text items for truncation in Qt Quick. It can be done with Squish using two approaches. The first one is to access the truncated property which works for plain text, and the second one is to compare the required width of a text element with the actual displayed text width which works also for RTF.

Comments

    The Qt Company acquired froglogic GmbH in order to bring the functionality of their market-leading automated testing suite of tools to our comprehensive quality assurance offering.