Expecco GUI Tests Extension Reference/en: Unterschied zwischen den Versionen

Aus expecco Wiki (Version 2.x)
Zur Navigation springen Zur Suche springen
(Link to German version)
 
(133 dazwischenliegende Versionen von 4 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
[[Expecco GUI Tests_Extension Reference|Deutsche Version]] | '''English Version'''
<!-- Notes
<!-- Notes
- integrated expecco extension
- integrated expecco extension
- common tool for different ui technologys
- common tool for different UI technologies
- information about the ui structure and control properties
- information about the UI structure and control properties
- creating testsequences
- creating testsequences
- recording
- recording


Features
Features
- fully integrated in expecco ui
- fully integrated in expecco UI
- one tool for multiple technologys
- one tool for multiple technologies
- examine ui structure
- examine ui structure
- examine control properties and details
- examine control properties and details
Zeile 29: Zeile 30:
-->
-->


The "expecco GUI Tests Extension" provides a common base for the development of test sequences for graphical user interfaces (GUIs) in expecco. The tool integrates seamless into the common expecco UI philosophy. It is used as a common interface for various diferent GUI technologies (Qt, Java/Swing, Android, iOS, MFC, etc). In addition to plain recording & replay and UI-structure inspection (widget tree and attributes), it is possible to try and experiment with individual actions, partial and complex sequences, which can be developed interactivly and added to the suite, when completed ("explorative Test Development").
The "''expecco GUI Tests Extension''" ("''GUI Browser''" for short) provides a common base for the development of test sequences for graphical user interfaces (GUIs) in expecco. The tool integrates seamless into the expecco UI philosophy. It is used as a common interface for various different GUI technologies (Web, Qt, Java and Windows Apps, Android, iOS, MFC, VNC, etc).

In addition to plain recording & replay and UI-structure inspection (widget tree and attributes), it is possible to try and experiment with individual actions, partial and complex sequences, which can be developed interactively and added to the suite, when completed ("explorative Test Development").


=Main Features=
=Main Features=
* Seamless integration into the expecco user interface
* Seamless integration into the expecco user interface
* One common tool for various differen UI technologies
* One common tool for various different UI technologies
* Hierarchical visualisation of the user interfaces structure (componen structure)
* Hierarchical visualization of the user interfaces structure (component structure)
* Informationen on state and attributes
* Information on state and attributes
* Locator (xpath) generation, compression and verification
* Feedback and convenient localization of interface components through highlighting, screen shots and mouse-over feedback
* Feedback and convenient localization of interface components through highlighting, screen shots and mouse-over feedback
* Filtering and presentation of function blocks matching the corresponding UI technology
* Filtering and presentation of function blocks which match the corresponding UI technology
* Creation f test sequences via "Drag &Drop" and/or automatic capture, or import of formal and nn-formal descriptions from external documents (XMI, UML, XML, Word, Excel, CSV)
* Creation of test sequences via "''Drag &Drop''" and/or automatic capture, or import of formal and non-formal descriptions from external documents (XMI, UML, XML, Word, Excel, CSV)
* Experimental try and compose of actions, partial sequences and access pathes
* Experimental try and compose of actions, partial sequences and access paths
* Incremental creation of complex tests from shorter sequences in the test project
* Incremental creation of complex tests from shorter sequences in the test project

=General Architecture=

In order to communicate with the controlled GUI application,
expecco needs to setup a communication channel to it and exchange commands and queries with it.
The details of how this is done depends on the particular UI technology, and also on the way the app was built/deployed:
* Windows<br>Uses the standard Windows UIAutomation mechanism
* Java<br>Communicates with an agent which was either injected dynamically (if possible), or is already running inside the app.
* Qt<br>Communicates with an agent which is either injected dynamically, or relinked with the application
* VisualWorks<br>Communicates with an agent which must be loaded (as a parcel) and already running in the application.

Further details are found in the individual technology's decumentation.

=General Design Philosophy=
Like any other action in expecco, GUI-interaction and verification is performed through the execution of actions within activity diagrams.

Thus, for test execution, actions are placed into a test sequence, which control and verify the GUI to be tested or to be manipulated as part of the test.

It should be emphasized, that such GUI interaction is not limited to testing:
it is also a valuable tool to automate common tasks such as initialization, configuration or deployment procedures, in situations where manual user interface interaction is required.
Such automation may otherwise be difficult even for very simple tasks. For example if the operating system opens dialog boxes for warnings or user confirmations (as often happens in e.g. the Windows operating system).

Although similar in many ways, different UI technologies (e.g. Java Swing vs. Android vs. Qt) may provide different operations when automated. Depending on the set of widget elements, the way the UI technology is interfaced and possibly even the way it is configured, some operations depend on the concrete technology.
Therefore, each technology is supported by its own GUI interface library, which provides action blocks for the particular technology.

Inside a test suite, multiple such libraries can be imported, and interaction blocks be placed in any order - it is therefore possible and often useful, to interact with different devices using different technologies even within a single test sequence. For example, it is quite common to trigger some operation on e.g. a mobile device (using actions from the appium interface library) followed by actions to verify some field in a Java GUI (using actions from the Java Swing interface library). Of course, it is even possible, to add totally different actions to the same sequence, which might perform database- or protocol requests.

==Locating UI Elements==
When UI interaction blocks are executed, they typically need a way to specify which element is to be manipulated. For example, a "''Send Button Press''" action will need to know, which UI element the event should be sent to.
This information is typically named "''locator''", and different technologies may use different locator styles.

===Challenges===
Most locators are based on the XPath syntax, which specifies UI elements using a path from the top element (typically the application window or the screen) down to the destination element.
<br>For example, an XPath to locate a button inside a panel, inside the main window may look like:
/Window/Panel/Button

Intermediate components can be left empty or specified as wildcards. For example:
/Window//Button
addresses any button arbitrarily deep below the top window,
or:
/Window/*/Button
addresses buttons inside one arbitrary component below the top window.

It is obvious, that a compromise is needed in that we want both deterministic, exact and unique addressing of the UI element, and at the same time the most possible flexibility in case of structural or visual changes of the user interface.

As a concrete example, let us assume that a button element is located inside a hierarchy of 3 other panels, which care for the subelement's geometries.
The testsuite should be as much as possible independent from both the layout (i.e. the actual position of the button), and also be independent from any change in the hierarchy: i.e. if the next version of the app has the same button embedded in a different number of panels or in another panel.

Whether such independence is possible or not in a particular technology and for a particular application, often depends on how the application was built, and whether enough information is available to the test tool.

For example, if the button contains a unique identifier (widgetID) in its attributes, it can be uniquely identified and addressed by this, and the best XPath locator for it would be
//button[@id="XYZ"]
This XPath is completely independent of the hierarchy.

This being the optimal situation - in practice, app developers often fail to be nice to testers and fall into one of the following error-traps:
* use of dynamically generated ids
* changing ids between versions/releases
* changing ids between national language variants
* not providing ids at all and not providing any unique alternative

If all of the above are given (and in real world testing, they often are), the XPath must depend on the hierarchy; for example, we could specify it to be the 3rd button in the second subpanel as:
//panel/panel[2]/button[3]
Such an XPath would work as long as no other button gets placed before the target button, and as long as the button is somewhere inside the second panel of another top-level panel.

==Solutions==
Expecco offers a number of solutions to this problem. However, if you can talk to your developers, the first thing to do is to ask them for constant identifiers, which will not change between versions, and which will be independent of national languages or sessions. Most GUI frameworks allow for such identifiers to be added.

=== Scenario 1: Developers can provide information ===
It is often possible, that the app-developer can provide widget ID information. Especially, if the UI is generated via a WindowBuilder tool, it is often possible to export an XML or CSV containing such information. The test could then import this file, and generate a mapping table (into an expecco variable, or into a number of variables) at test startup. Then, instead of using hard-wired XPath strings, those variable values will be used as locators. Use one of the XML- or CSV reader actions to parse the data, and place the element-IDs into either a dictionary or into the environment and use those values in the test.

=== Scenario 2: Dynamic session-ids ===
If all sub-element ids can be constructed from a session id, a similar strategy is possible, by remembering this sessionID during startup (in an expecco variable), compute the sub-ids into a table or individual variables, and use those a locators.

=== Scenario 3: None of the above ===
This is the worst case fallback. If no information is available at all, you have to use possibly sensitive XPaths.
With VNC- and local screen connections, you can also fall back to either geometric locator information (i.e. specify that the button is in a particular bounding rectangle) or image locator (e.g. specifying the bitmap image of the button, and having expecco search for the image in the UI).
VNC and local screen connections are supported with expecco 18.1 (= 2.12).

Most other UI libraries also allow for a relative geometric offset to be provided to mouse and keyboard actions.
As a fallback (but really: only if all else fails), you can use events on the parent widget, giving an x/y offset.

Finally, some other UI libraries also support image-search within an element.
You can use this to get the x/y coordinate.

Be aware that image-searching may make your test depending on the icons used (scaling?, color compensations) and also
on the graphic card (edge antialiasing, leading to different color values).
For this, the image search operation can be adjusted with various error parameters (color tolerance, pixel percentage, smoothing).

=GUIBrowser's Role in Test Development=
The GUIBrowser helps to deal with the above challenges. You can interactively explore the UI widget hierarchy, find out which attributes are present and what values are found there, try different XPath expressions to locate elements, and collect actions into subsequences interactively. You can switch between the GUIBrowser's view of the application and the test diagram - even in the middle of a stopped or paused test run, change the diagram or parameters on the fly, and possibly proceed or restart test sequences.

The GUIBrowser supports both interactive composition and recording of action sequences. Either way, these can be edited, reorganized and parametrized immediately within the GUIBrowser.


=Description=
=Description=
[[Datei:GuiBrowser openButton marked.jpg|200px|thumb|right|Opening a concrete UI]]
[[Datei:GuiBrowser openButton marked.jpg|200px|thumb|right|Opening the GUIBrowser]]
The "expecco GUI Tests Extension" provides a common base for the interaction with graphical user interface applications. Various different UI technologies are supported, in that the concrete interface is realized by technology specific plugin extensions. Currently available are interfaces for Qt, Java/Swing, MFC, DevExpress, Android, iOS, Windows Mobile.
The "''expecco GUI Tests Extension''" (or "''GuiBrowser''" for short) provides a common base for the interaction with graphical user interface applications. Various different UI technologies are supported, in that the concrete interface is realized by technology specific plugin extensions and action block libraries. Currently available are interfaces for Qt, Java Swing, MFC, DevExpress, Android, iOS, Windows Mobile and VNC.


Therefore, in order to use the "expecco GUI Tests Extension", at least one concrete UI-technology plugin is required.
Therefore, in order to use the "''expecco GUI Tests Extension''", at least one concrete UI-technology plugin is required.


One the other hand, it is possible to handle complex test scenarios in which multiple technologoes are involved (for example, Qt plus Android plus Java-Swing). Any combination of interfaces can be controlled simultaneously, within a single test scenario and even execute in parallel.
One the other hand, it is possible to handle complex test scenarios in which multiple technologies are involved (for example, Qt plus Android plus Java-Swing). Any combination of interfaces can be controlled simultaneously, within a single test scenario and even execute in parallel.


Thus, complex integration test scenarios, End-to-End tests and other multi-technology tests are easily created, in which both mobile and web-based and classical user interfaces are to be controlled and verified.
Thus, complex integration test scenarios, End-to-End tests and other multi-technology tests are easily created, in which both mobile and web-based and classical user interfaces are to be controlled and verified.


To open the "expecco GUI Tests Extension" within expecco, click on the "GUI Browser" icon in the toolbar.
To open the "''expecco GUI Tests Extension''" within expecco, click on the "''GUI Browser''" icon in the toolbar.


==User Interface==
==User Interface==


[[Datei:GuiBrowser mainView labled ger.jpg|400px|thumb|right|Abb1: Gliederung der Hauptansicht]]
[[Datei:GuiBrowser mainView labled ger.jpg|400px|thumb|right|Fig.1: Main View (pre 2.10 version)]]
[[Datei:GuiBrowser mainView usageFlow ger.jpg|400px|thumb|right|Abb2: Bedienfluss]]
[[Datei:GuiBrowser mainView usageFlow ger.jpg|400px|thumb|right|Fig.2: Usage (pre 2.10 version)]]
Overview on the layout, usage and the functions of the UI. Fig. 1 Shows the main view. Fig. 2 shows the control flow.
Overview on the layout, usage and the functions of the UI. Fig.1 Shows the main view. Fig.2 shows the control flow. In the 2.10 version, the look has changed slightly changed, and an additional preview has been added.


;Connection Setup
;Connection Setup
: Provides a selection list with available UI technologies.<p>After a click, a connection setup dialog opens, which lets you choose among connected devices (i.e. if multiple mobile devices are connected) or applications (if multiple applications are present inside the device or running on a machine). Once connected to a concrete technology/device and application, the components of the user interface are presented in the hierarchical tree on the left.
: Eine Auflistung der verfügbaren Benutzer-Oberflächen Technologien. Per Klick auf eine der Schaltflächen wird der Verbindungsaufbau der jeweiligen UI-Technologie gestartet. Nach dem Verbindungsaufba erscheint die Anwendung in der Benutzeroberflächenstruktur (Hierarchie der Komponenten).


;UI Component Hierarchy
;UI Component Hierarchy (left view)
: This view displays both connected and disconnected applications. Underneath each connection, the component (widget-) hierarchy of the application is shown. Disconnected applications can be reconnected via the context menu.
: Zeigt alle verbundenen und nicht verbunden Anwendungen. Unter jeder Anwendung wird der Aufbau der Benutzeroberfläche mit allen verfügbaren Bedienelementen dargestellt. Beim Aufklappen einer nicht verbundenen Anwendung wird versucht die Verbindung wieder herzustellen, falls diese verloren ging oder noch nicht bestand. Die Selektion eines Bedienelements oder einer Anwendungen aktualisiert die Menge der dazu passenden Aktionen sowie die Ansicht der Block-Bibliothek, Eigenschaftenübersicht, Bedienelementübersicht und den Bedienelementpfad.
When an element is selected, matching operations (i.e. actions which are applicable to that element) are shown in the "''actions / properties''" list (in the middle top view), and the component's attributes are shown in the parameter view (in the middle bottom view).

The XPath to the component (the locator to address the component) is shown at the bottom, and a list of alternatives provided in its pull down list.
The automatically generated XPath may be too specific (as described in "''challenges''" section above). You can shorten the XPath and replace intermediate components in it by wildcards ("*" or "**"), and re-verify that the optimized XPath is still valid (i.e.refers to exactly the one selected component).

It takes a little experience and gut-feeling to get to the optimum - and often also some interaction with app developers, so they know, on what hierarchical details your test suite depends upon. The dropdown list beside the xpath field offers various variations, among them a shortened (compressed) xPath and the full path. Depending on the technology, other locator strategies may also be offered there; for example, for web-GUIs, alternative css locators are offered.


;Tools
;Tools
: A number of functions are available as toolbar buttons or on the selection menu (widget-tree's right-button menu). Most of them are context menu functions and provide operations specific to the selected element.
: Eine Auflistung verschiedener Werkzeuge. Ein Klick auf eine der Schaltflächen löst die Aktionen aus. Einige Aktionen sind von der Selektion in der Benutzeroberflächenstruktur abhängig.
: '''Alle Verbindungen Trennen'''
: '''Disconnect All'''
:: Closes all connections of all technologies.
:: Trennt alle Verbindungen aller Technologien.
: '''Ausgewählte Verbindung trennen'''
: '''Disconnect Selected'''
:: Closes the selected connection (or the connection used by the selected widget element).
:: Trennt die Verbindung bezüglich des in der Benutzeroberflächenstruktur ausgewählten Bedienelementes.
: '''Aktuallisieren'''
: '''Refresh'''
:: Reloads the widget hierarchy from the device/application. Some technologies can do this automatically; however, on many, this would take too long and slow down or even interfere with the application's operation. For example, a refresh of an Android app can take a few seconds, depending on the number of UI items, and the speed of the USB connection, and is therefore not done automatically. Also, a refresh may close currently open popup menus or change the keyboard focus in some technologies, and would change the state of the application, which is another reason for not doing this automatically.<p>Use this when the UI changed without user interaction (normally, the tree is refreshed when you click or enter keyboard input. But sometimes, changes come late or without any user action.)</p>
:: Aktuallisiert die obersten Bedienelemente aller verbundenen Anwendungen.
: '''Kinderelemente erneut Laden'''
: '''Reload Child Elements'''
:: Only reloads the child elements of the selected element. Notice that not all UI technologies support a partial reload, and these will do a (slow) full reload.
:: Aktuallisiert die Kinderelemente bezüglich des in der Benutzeroberflächenstruktur ausgewählten Bedienelementes.
: '''Hervorheben'''
: '''Highlight'''
:: Emphasizes the widget's display area (usually by drawing a rectangle around it).
:: Hebt das in der Benutzeroberflächenstruktur ausgewählte Bedienelement in der Benutzeroberfläche hervor.
: '''Zeiger Folgen'''
: '''Follow Pointer'''
:: When active, the element under the mouse pointer is automatically selected whenever moved over an item in the UI. Not all UI technologies support this function.
:: Wenn diese Funktion aktiviert wurde, folgt die Selektion der Benutzeroberflächenstruktur automatisch dem unter dem Mauszeiger befindlichen Bedienelement (Quick-Scan).
: '''Start Recording (on all)'''
: '''Aufzeichnung für alle Anwendungen beginnen'''
:: Starts recording your interaction with all connected devices. I.e. you can interact with any application or mobile device and have all those recorded in one recording sequence. If there is already a partial recording in the sequence view, the new interactions are appended to the end of the sequence.<p>For some technologies (eg. Android and iOS), a separate recorder window is opened, which presents the screen, and records user input. Thus, you do not need to have the physical device on your desktop (which is especially useful, if the device is located in the server room...)</p>
:: Beginnt die automatische Aufzeichnung einer Testsequenz für alle verbundenen Anwendungen. Während der Interaktion mit der/den Benutzeroberfläche(n) wird die Testsequenz im Sequenzeditor generiert. Befindet sich bereits eine Sequenz im Sequenz-Editor, so wird diese fortgesetzt.
: '''Stop Recording (for all)'''
: '''Aufzeichnung für alle Anwendungen beenden'''
:: Stops the recording.
:: Beendet die Aufzeichnung für alle verbundenen Anwendungen.


;Attribute View
;Attributes
: Shows the attributes of the selected element. The list of attributes depends on the underlying technology (i.e. a Java Swing element may show more attributes than e.g. an Android UI element) and the type of element (i.e. a Button will have different attributes than e.g. a Combolist). When an attribute is selected, corresponding action blocks are shown in the upper action/attribute list, so that only blocks are presented, which are applicable to the selected element and selected attribute.
: Listet verfügbare Eigenschaften des ausgewählten Elements auf. Selektion einer der Eigenschaften ändert die Ansicht der Block-Bibliothek, so dass nur Blöcke die sich auf diese Eigenschaft beziehen, angezeigt werden.


;Action-Library
;Action-Library
: Shows action blocks which are applicable to the selected element. These blocks are user-interaction blocks, which generate click, press, release, keyboard or other user events. The list will only show the set of action for a particular kind of element. For example, if an input-field element is selected, actions for text entry will be shown, whereas these are not seen when a panel or label is selected.
: Zeigt die verfügbaren Blöcke aus der Technologiebibliothek, für das in der Benutzeroberflächenstruktur ausgewählte Element an. Unter "Aktionen" werden die Blöcke aufgeführt, die passend zum Element sind, beispielsweise das Setzen des Textes einer Label-Komponente. Unter "Eigenschaften" werden die Blöcke aufgeführt, die für eine unter "Eigenschaftenübersicht" ausgewählte Eigenschaft relevant sind, wie zum Beispiel das Abfragen der Sichtbarkeit.
: Whenever an action block is selected, it is copied to the the test-pane and any locator/path input pin is set to refer to the selected UI element. I.e. it will be presented as it would be used within a test sequence. You can now either execute the action in isolation, or copy it to the end of the sequence (by pressing the "''Add to Sequence''" button in the top-right. Of course, you can also edit the network in this test view and add any other action block (drag & drop from the suite or via the context menu) or modify the pin parameters.
: Wird ein Block selektiert, so ändert sich die Ansicht der Editoransicht auf "Test" und der Block wird angezeigt.
: If you double click on the action block, it is immediately added to the recorded sequence.
: Zieht man den Block mit der Maus über die Editoransicht, so wechselt die Ansicht auf "Sequenz". Lässt man den Block in der Sequenz fallen, so wird er als Schritt an die Sequenz angefügt.


;Test Network and Sequence Views
;Editor View
: As already mentioned above, the "''Test''" pane shows the selected block from the action/attribute list. You can edit and change the pin setup. Also, the block can be executed and the results are shown in the lower right execution log window. Finally, the block is added to the end of the recorded sequence via the "''Add to Sequence''" button.
: Unter "Test" wird der in der Blockbibliothek ausgewählte Block dargestellt. Die Pins können editiert werden. Anschließend kann der Block gegen die Anwendung ausgeführt werden. Die Editoransicht wechselt dabei auf "Lauf". Die Ausführung des Blocks kann hier überprüft werden. Aus der Test-Ansicht heraus kann der Block direkt mittels der Schaltfläche "In Sequenz Übernehmen" in die Testsequenz übernommen werden. Der Block wird als Schritt an die Testsequenz angefügt.
: The "Sequence"-View presents the test sequence as recorded so far. This is a regular diagram editor as described elsewhere. So any of the well known editing features can also be used here. Especially, it is possible to insert other blocks from the library, to change the execution order of recorded steps, or to replace them by other steps (without a need to re-record the sequence). The sequence view also allows for the whole sequence to be replayed in whole or in part, to be single stepped, breakpointed etc. Finally, when complete, you can create a new action block in your project, which contains the recorded sequence (by pressing on the "''Define Action Block''" button at the top right).
: Die "Sequenz"-Ansicht stellt die aktuelle Testsequenz dar. Diese kann manuell oder durch Aufzeichnung erweitert werden. Die Testsequenz lässt sich ausführen, die Ansicht wechselt dann auf "Lauf". Hier kann die Ausführung der gesamten Testsequenz überprüft werden. In der "Sequenz"-Ansicht lässt sich die gesamte Sequenz in das aktuelle Projekt übertragen. Dazu wird die Schaltfläche "In Projekt Übernehmen" ausgewählt.


;Path Display
;Path Display
: Shows the XPath (locator) of the selected UI element. By default, a full explicit path is automatically generated and added as freeze value to the locator pins (in the recorded sequence). However, it is often desirable to shorten this path via placeholders. This will make your test less affected by changes in the widget hierarchy. Therefore, it is useful to reduce the path as long as it uniquely identifies the desired element. The details depend on the way the UI was programmed; for example, if each element has a unique ID, no path is needed at all, and the locator can be something like "/*[ID=xxx]". In contrast, if no ID or other unique attribute is present, a full path which enumerates the parent hierarchy might be required. The "Check Path" button will apply the entered path to the element hierarchy and give an OK-response if the element is still uniquely identified by it.
: Zeigt den Pfad des in der Benutzeroberflächenstruktur ausgewählten Bedienelements. Der Pfad kann verändert werden; insbesondere sollten längere verschachtelte Containerpfade durch "*" ersetzt werden, damit die Addressierung der Komponente möglichst unabhängig von späteren Änderungen der UI-Hierarchie werden. Mit der Schaltfläche "Pfad-Prüfen" wird sichergestellt, daß der geänderte Pfad immer noch das in der Benutzeroberflächenstruktur ausgewählte Bedienelement referenziert.


;Component Preview
;Component Preview
: Display a preview (snapshot image) of the selected UI element or the application's main window/screen, with the element's bounds emphasized.
: Zeigt Informationen des in der Benutzeroberflächenstruktur ausgewählten Bedienelementes an und stellt, falls möglich, eine Vorschau dar. Ein Klick auf die Vorschau öffnet das Bild in Originalgrösse.


<br style="clear: both" />
<br style="clear: both">


=Locator Path (xPath)=
=Bedienelementpfad=
The locator addresses elements within a user interface. It is based on the XPath notation as known in the XML world. Locator paths are specified during test development, and used later, at test execution time, to refer to UI elements. The path of a selected UI element is shown in the lower right "''Path''" field, and is updated when another element is selected. Vice versa can the path be changed in that input field, in order to check which element(s) would be addressed by a given path. The path does not need to and should not be specified in full detail. It can contain wildcards and dynamic parts, which makes it more flexible and more robust against possible future changes in the test application; especially against changes in the hierarchy, when new container elements are inserted (which is one of the most common reasons for test cases to fail on new releases).
Der "Bedienelementpfad" dient als Referenz auf Bedienelemente innerhalb der Benutzeroberfläche. Er ist vergleichbar mit der XPath-Notation im XML Umfeld. Komponentenpfade werden bei der Testentwicklung festgelegt und später, bei der Testausführung, verwendet um UI-Komponenten zu referenzieren. Der Pfad eines ausgewählten Bedienelements wird unten im "Bedienelement-Pfad" Feld angezeigt, und bei Auswahl eines Elements automatisch aktualisiert. Umgekehrt kann er an dieser Stelle auch geändert und überprüft werden, welche(s) Element(e) durch einen gegebenen Pfad referenziert werden. Der Pfad muss nicht vollständig sein - er kann dynamische Teile enthalten. Dies erhöht die Flexibilität und macht die Testsequenz robuster gegenüber einer möglichen späteren Änderung der getesteten Benutzeroberfläche. Insbesondere gegenüber Änderungen der Hierarchie, z.B. wenn weitere Containerelemente eingefügt werden.


'''Hinweis: '''
'''Notice: '''
Many user interfaces change their structure dynamically during the execution. Often container and interaction elements are added or removed during the run. Especially in these situations, the flexibility in the XPath notation is very useful.
Viele Benutzeroberflächen ändern während der Ausführung die Struktur dynamisch. Oft werden Container- und Bedienelemente während dem Lauf hinzugefügt oder entfernt. In solchen Fällen sind dynamische Teile im Pfad sehr hilfreich.


==Pfade Definieren==
==Defining Paths==
A typical path may look like:
Ein typischer Pfad kann wie folgt aussehen:
/frame[@name='Notepad']/root pane/layered pane/panel/panel/panel/tool bar/push button[2]
/frame[@name='Notepad']/root pane/layered pane/panel/panel/panel/tool bar/push button[2]
This path describes the full explicit path to the second button inside a toolbar, which itself is contained in a nested hierarchy of containers (panels).
Dieser Pfad beschreibt die vollständige Adressierung des zweiten Buttons in einer Toolbar, welche ihrerseits in einer verschachtelten Containerhierarchie (panels) liegt.


The path consists of a list of identifiers, beginning and separated by "/". Each individual identifier describes a subcomponent of the element which is already described by the left part.
Der Pfad wird beschrieben durch eine Liste von Identifikatoren, getrennt durch und beginnend mit "/". Jeder einzelne Identifikator beschreibt eine Unterkomponente des bereits durch den linken Teilpfad beschriebenen Elements. "/frame[@name='Notepad']" referenziert das Hauptfenster der Anwendung. "root pane", "layered pane", "panel" etc. referenzieren jeweils das korrespondierende Kindelement. Zur Referenzierung einer einzelnen konkreten Komponente wird der Pfad beginnend mit dem obersten Bedienelement schrittweise verfolgt.


A path component may be a wildcard or a deep wildcard:
Im Beispiel wird zuerst versucht, das Fenster mit Namen "Notepad" zu finden. Das Fenster hat ein oder mehrere Kinder, dessen Identifikator zu "root pane" passt. "root pane" wiederum hat Kinder die zum Identifikator "layered pane" passen und so weiter.
/frame[@name='Notepad']/*/*/*/*/*/tool bar/push button[2]
refers to a button inside a toolbar, which is 5 levels below the toplevel window. Independent of the type of containers in-between,
and:
/frame[@name='Notepad']//tool bar/push button[2]
refers to a button inside a toolbar, which is any number of levels below the toplevel window.


The path:
Die Syntax eines jedes individuellen Identifikators ist:
"/frame[@name='Notepad']"
/<KnotenIdentifikator><[Optionaler Selektor]>
refers to the top-level application window. "root pane", "layered pane", "panel" etc. refer to corresponding child elements. To get to the final destination, each component is found along the path starting with the top level window.


In this concrete example, expecco will first look for a top-level window which has the name "Notepad". This window will have one or more child elements, which match the identifier "root pane". Each such "root pane" will have children, matching the identifier "layered pane", and so on. At the end, there should be exactly one element, which matches all of those "constraints", and this will be the target element. If no element matches, or of multiple elements match, a runtime error will be triggered at test execution time, and the normal exception handling mechanism of expecco applies (i.e. the test will finish with a failure, or an exception handling action is triggered).
===KnotenIdentifikator===
Der KnotenIdentifikator beschreibt den Typ des Bedienelementes das gesucht wird.


The syntax of each individual identifier is:
'''Mögliche Identifikator:'''
/<NodeIdentifier><[Optional Selector]>
;Der Typ des Bedienelements
: Das Ergebnis sind eine oder mehrere Bedienelemente die dem angegebenen Typ entsprechen.
;Der "Jeder" Identifikator ("*")
: Löst den Rest des Pfades unter Verwendung alle Kindelemente, unabhängig vom Typ des aktuell aufzulösenden Identifikators auf.


===Node Identifier===
Beispiel:<br>
The Node Identifier defines the type of UI element, which is to be searched
Vollständiger Pfad:

'''Possible Identifiers:'''
;The type of the UI element
: eg. "<code>button</code>", "<code>panel</code>" etc., or in case of a webtest, the HTML element tag (e.g.. "<code>h1</code>", "<code>div</code>", etc.)
: this matches all elements of that type (can be zero, one or multiple elements).

;The "Any" identifier ("<code>*</code>")
: matches all child elements, independent of their type. Further matching must be done via the selector or via child element matches (e.g. the right rest of the XPath).

;The "Parent" identifier ("<code>..</code>")
: walks up one step after a match. This can be used to find siblings of labels, buttons, etc. Be aware that not all UI technologies support this.

===== Examples =====

Full path:
/frame[@name='Notepad']/root pane/layered pane/panel/panel/panel/tool bar/push button[2]
/frame[@name='Notepad']/root pane/layered pane/panel/panel/panel/tool bar/push button[2]

Der selbe Pfad mit "*" Identifikatoren:
the same path using Any ( " * " ) identifiers:
/*[@name='Notepad']/*/layered pane/*/panel/*/tool bar/push button[2]
/*[@name='Notepad']/*/layered pane/*/panel/*/tool bar/push button[2]


Both paths refer to the same UI element. However, the second version is less sensible to changed types of the intermediate components. For example, the app developer might replace a "<code>panel</code>" component by a "<code>box</code>" component in a new release. The first path would then fail to find the UI component, as no element will then match the "<code>panel</code>" identifier.
Diese zwei Pfade adressieren in obigem Fall das selbe Bedienelement. Jedoch ist die zweite Variante unempfindlicher gegenüber geänderten Komponenten in der Hierarchie. Zum Beispiel könnten die Entwickler der zu testenden Anwendung eine panel-Komponente durch eine box-Komponente ersetzen. Der erste Pfad würde dann im Testlauf zu einem Fehler wegen nicht auflösbarem Pfad führen.
Notice that the "<code>*</code>"-identifier is a wildcard for only one component (i.e. the hierarchy must still be as deep as before). To make the path robust against hierarchy changes, use the "<code>//</code>"-Notation (as described below).
Zu beachten ist, dass der "*"-Identifikator zur als Platzhalter einer einzelnen Komponente dient. Um den Pfad auch robust gegenüber zusätzlich in die Hierarchie eingebrachte Komponenten zu machen, sollte die "//"-Notation (siehe unten) verwendet werden.


===Selektor===
===Selector===
The selector is optional. It is used to select among same-typed elements. For example, if a component contains 3 buttons as child elements (eg. child elements of the same type), the selector can be used to specify which of the 3 buttons is to be matched. The selector is specified in square "<code>[ ]</code>" brackets after the node identifier, and is applied during the match process after matching the node identifier.
Der Selektor ist Optional. Er wird benötigt um Bedienelemente mit gleichem Typ zu unterscheiden. Gibt es beispielsweise 3 Buttons als Kinder eines Bedienelements, so kann mit dem Selektor der zu referenzierende Button festgelegt werden. Der Selektor wird in eckigen "[ ]" Klammern angegeben. Der Selektor wird nach der Auflösung des KnotenIdentifikators auf das Ergebnis angewendet. Gibt es zum Beispiel ein Bedienelement mit zwei Buttons und zwei Checkboxen als Kinder, und der Identifikator liefert als Ergebnis 2 Buttons, so wird der Selektor auf diese 2 Buttons angewendet.


For example, if an elements contains 2 buttons plus 2 checkboxes as child elements, and the node identifier gives 2 buttons as result, the selector will only be applied to the 2 buttons.
'''Mögliche Selektoren:'''
;Der "Index" Selektor
: Wählt das Bedienelement anhand des Index. Der Index ist 1 basiert (i.e. [1] bezieht sich auf die erste Komponente).
;Der "Schlüssel-Wert" Selektor (engl. "Key-Selector")
: Wählt das Bedienelement dessen Schlüssel den angegebenen Wert hat. Die Menge der möglichen Schlüssel ist abhängig von der jeweiligen UI-Technologie, der betroffenen Komponente und deren Attribute. Typische Schlüssel sind "name", "id", "label", "value" etc. Bei einigen Komponenten sind auch dynamische Schlüssel möglich, so dass diese erst während der Laufzeit angelegt werden.


===== Possible Selectors: =====
Beispiel (Index Selector):
;"Index"
/*/tool bar/push button[2]
: chooses an element by its index, which is the position within the list of children (of the matching type). The index is 1-based (i.e. <code>[1]</code> refers to the first child).
Wählt den zweiten Button innerhalb der Toolbar aus.


;"Attribute Key" (or "''Attribute-Value''")
Beispiel (Schlüssel Selector):
: chooses the element, which has a particular value associated to a given attribute. The set of attributes depends on the concrete UI technology, the component type and possibly its current state. Typical attributes are "<code>name</code>", "<code>id</code>", "<code>label</code>", "<code>value</code>" etc. but also "<code>visible</code>", "<code>enabled</code>" or "<code>isActive</code>". Some components have dynamic attributes (and therefore keys which show up dynamically), which are created during the execution time.
/*/tool bar/push button[@name='Save As...']
Wählt den Button aus dessen Attribut "name" (= Schlüssel) den Wert "Save As..." hat.


;Function on "Attribute"
===Platzhalter Schreibweise===
: similar to the above, this allows for a match or check function to be applied to an attribute value. Be aware that not all UI technologies support this kind of locator. Typical functions are "<code>starts-with</code>", "<code>ends-with</code>", "<code>contains</code>" and "<code>matches</code>".
Die Platzhalterschreibweise ("//") kann Pfade stark verkürzen und flexibel gegenüber zusätzlich eingefügten Hierarchieebenenen machen. "//" ersetzt dabei ganze Teile des Pfades. Der Vergleich findet nicht nur auf Kinder eines Bedienelementes statt, sondern auf ganze Teilpfade.
===== Example (Index Selector) =====
To address the second button inside the toolbar:
/*/toolbar/push button[2]


&nbsp;
Beispiel:<br/>

Angenommen der vollständige Pfad eines Buttons wäre folgender:
===== Example (Attribute Selector) =====
To address the button which has the name attribute "Save As...".
/*/toolbar/pushbutton[@name='Save As...']
&nbsp;

===== Example (Function Selector) =====
To address the button whose label matches the [[Regex Pattern Info|regex pattern]] "<CODE>.*Save.*</CODE>" and which is contained in a window whose label starts with <CODE>"MyApp"</CODE>, use an xPath like:
/Window[starts-with(@label,"MyApp")]//Button[matches(@label='.*Save.*')]
&nbsp;

Be careful with attribute values which depend on the national language. If attributes are present, which are language independent, (e.g. "<code>id</code>", "<code>refID</code>", "<code>uuid</code>" etc.) those are to be preferred.
If not, you should keep the language texts separate from the action block (i.e. attachment, external file or expecco variable) and construct the XPath using those values. This makes it much easier to later support multiple languages or changed button labels in your test suite.

Be also careful with dynamic session-id, i.e. id-attributes which are regenerated with every session. If such ids are present in the tested application, ask your programmer/web designer to add additional ids, which remain constant across sessions. Those session-ids are not useful for test developers.

==="Super Wildcard"===
The super wildcard ("<code>//</code>") can dramatically shorten paths, and also makes them robust against additional inserted or removed hierarchy levels. "<code>//</code>" matches arbitrary subpaths: children are not only matched in the immediate sub-child level, but also in any level below.

Example:<br>
Given the full path of a button as:
/frame[@name='Notepad']/root pane/layered pane/panel/panel/panel/tool bar/push button[@name='Save As...']
/frame[@name='Notepad']/root pane/layered pane/panel/panel/panel/tool bar/push button[@name='Save As...']


also assuming, that the application contains only one single button by the name "<code>Save As...</code>". Then, the path can be rewritten (using the super wildcard) as:
Außerdem angenommen, die Anwendung hat nur einen Button mit dem Namen "Save As...", welche sichtbar ist. Dann kann der Pfad mittels Platzhalterschreibweise wie folgt verkürzt werden:
//push button[@name='Save As...']
//push button[@name='Save As...']


even short, if there is only one single element by that name (i.e. no other non-button exists, which has that name attribute). Then, the following path is also possible:
Noch kürzer ginge es, wenn nur ein Bedienelement mit Namen "Save As..." existiert. Dann wäre folgender Pfad möglich:
//*[@name='Save As...']
//*[@name='Save As...']


The following example shows, that you can also use the super wildcard for partial hierarchies:
Auch ist es möglich, wie im folgenden Beispiel, nur Teile des Pfades mit Platzhaltern zu versehen:
/*[@name='Notepad']//panel//tool bar/*[@name='Save As...']
/*[@name='Notepad']//panel//tool bar/*[@name='Save As...']
this matches a component by the name "Save As...", which is inside a toolbar, which is arbitrarily deep inside a panel, which is arbitrarily deep inside the top window named "Notepad".

'''Notice:'''
The short paths as shown above are dramatically more robust against changes in the layout and hierarchy of the user interface. However, at the same time, they may increase a risk to match multiple elements inside the GUI, which would also lead to an error being reported at test execution time ("non specific component path"). In the above example, this might happen if the UI contains another menu item by the same name.
In real world testing, the choice of path will always be a compromise between flexibility (as short as possible) and unambiguousness.

'''Also notice:'''
Some GUI technologies contain very slow implementations of their XPath search engine, and especially addressing via the Super Wildcard leads to slow response times. This may or may not be the responsibility of expecco itself, as most XPath implementations are implemented in the target system's UI or automation framework (eg. Windows Automation, Selenium or Appium).

=css Selector Locator=
Some GUI technologies (in particular the webTest technologies based on Selenium/WebDriver) also support the "css" selector notation as locator. This is semantically similar to xPath, but somewhat more compact.
It is described in detail in [https://www.w3schools.com/cssref/css_selectors.asp "www.w3schools.com css reference"].

If supported by the technology, the corresponding css selector is presented in the pulldown list of the locator entry field (at the bottom of the GUI browser).

=Image Locator=
Image locators are mostly used with GUI technologies where only a bitmap representation (i.e. a screen image) is available. Here, elements are defined as a bitmap image which is searched.
Various parameters control the image detection mechanism (pixel errors, color variance) to allow for images to be detected even in situations where the graphic hardware generates different pixel values (eg. when anti-aliasing or blending alpha values).

Image locators are described in more detail in [[VNC_Plugin_Reference/en#Locators|the VNC plugin reference documentation]]. How to use image locators with other GUI technologies is described in [[Graphical_Elements_in_GUI_Technologies/en|Graphical Elements in GUI Technologies]].

=Mapping Locators=
If the tested UI is prone to change and chances are that locators will change in future versions, it is a good idea to not use XPath locators directly (in an action's freeze value), but instead go through a locator mapping, where logical names (such as "NameField", "LoginButton" etc.) are used as key into a table which provides the actual locator to use.

Expecco provides two such mechanisms:
* via environment variables
* via screenplay attachments

== Using Environment Variables for Locator Mapping ==
By using a string like "$(KEY)" as a locator, the value of "KEY" will be looked up int the environment of the action at execution time and sliced into the freeze value of any input pin.

Be reminded, that there is not only one top-level environment, but there also exist local environments eg. of test plans, test cases and compound actions. Thus, a global variable value can easily be redefined for sub-actions.
The string expansion can be applied to a whole freeze value, substrings and even multiple times; thus very flexible locator mappings are possible.

For example, if a subcomponent of the UI is present multiple times within different containers, both the container's locator and the path relative to that container can be provided by different variables:
$(ui.container)//div//$(ui.NameField)
could be used as XPath, where "ui.container" could even be provided by the containing compound action as a local variable value.
A UI action using this locator can then be called from within different contexts (eg. test cases or compound actions) each providing a different value for the "ui.container" value.

By convention, you should name the logical keys "ui.XXX"; i.e. prefix them with "ui.". This is just a convention which makes it easier to filter locators or to import/export parts of the mapping table.

== Using Screenplay Attachments ==
Screenplay attachments provide a more formal definition of locator mappings and are represented as XML. Their structure is similar to that of existing UI frameworks which are based on scenes and players, and import/export to new formats can be accomplished eg. via XSLT translation, or by parsing XML with the expecco XML library.

=xPath Generation=
By default, the GUI browser generates both a full xPath and a compressed shortened xPath, and offers them in the locator entry field (and its pulldown list). Usually, the short xPath is the preferred locator.
If a logical name has been defined for the element, that is provided in the pull down list as well, and used as default locator.

Be aware that the generated xPath might fail to identify a unique element at execution time if your application adds/removes elements dynamically. However, at the time the path is generated, expecco verifies that it is correctly referring to the one-and-only selected current element.

==Preferred Attribute Selectors==
When multiple elements with the same node-type are present, expecco uses either an attribute (if present) or the index to make sure that only one element matches. For this, a builtin list of preferred attributes is tried sequentially for the first attribute which resolves any ambiguities. You can modify this list and/or the order in which they are tried via a context menu of the attribute list ("''Preferred xPath Attribute''").

==Unwanted Attribute Selectors==
The dialog opened via "''Preferred xPath Attribute''" (in the property/attribute list) can also be used to explicitly exclude attributes from the xPath generator's strategy.
This is useful for applications with dynamic "<code>id</code>"-attributes, which should not be used in the context of such applications.
For this, select the attribute which is to be ignored, open the dialog, and click on the "''Do not Use''" button.

==Separating Locators from the Test Sequence==

Place locators into either the project's environment,
or use attachments which provide mappings between logical names and actual locators.

This will reduce maintenance work later, when the UI, the structure or naming/ids change in later versions of the tested application.

=Technology Specific Features=

== Firefox, Edge, Internet Explorer, Chrome etc. ==
See [[Selenium WebDriver Plugin/en | "Selenium WebDriver Plugin"]]

==Android and iOS==
These are documented in the separate document: [[ Mobile Testing Plugin/en | "Mobile Testing Plugin" ]]

== Java Applications ==
See [[Java GUI Plugins/en | "Java GUI Plugin"]]

== Windows Applications ==
See [[WindowsAutomation Reference 2.0/en|"WindowsAutomation Reference 2.0"]]
<br>(or the previous version, which is now outdated: [[WindowsAutomation Reference 1.0 | "WindowsAutomation Reference 1.0"]])

==VNC and Local Screen==
These are documented in the separate document: [[ VNC Plugin Reference/en | "VNC Testing Plugin"]].
<br>Local screen automation behaves as described there, with slight differences in the connection setup.

==Qt==
Please read: [[ Qt Plugin Reference/en | "Qt Testing Plugin"]]

==VisualWorks==
Find additional information in: [[ VisualWorks Testing Plugin Reference/en | "VisualWorks Testing Plugin"]]

= Frequently Asked Questions =

=== Why does it not update the widget tree automatically? ===

We did this in an early version, but found it to be very inconvenient to interact with transient views (such as dialogs, popups, menus etc.).
If the element vanishes automatically, you often got no chance to inspect the item's attributes and/or create actions for it.

Now, you can either press the update toolbar button, or a hotkey, or schedule a timed update ("update after"). The later is perfect to catch the hierarchy of popup menus and similar views, which vanish with the next user interaction or when the mouse button is released (such as a popup menu).

= See Also =
[[Selenium_WebDriver_Plugin|Web Testing with Selenium WebDriver]]
<br>[[Java GUI Plugins|Java Swing/SWT UI Testing]]
<br>[[WindowsAutomation Reference 2.0/en|Windows App UI Tests (GUI Access Interfacing Library V2)]]
<br>[[Mobile Testing Plugin/en|Mobile Testing for Android and iOS]]
<br>[[VNC Plugin Reference/en|UI Testing with VNC]]
<br>[[VNC Plugin Reference/en|Local Screen Automation]]
<br>[[Qt Plugin Reference/en|UI Testing and Qt-Applications]]
<br>[[OpenETS Plugin Reference/en|UI Testing for Custom-Applications (OpenETS)]]

[[AutoIt Library|AutoIt GUI Interface Library]]


[[WindowsAutomation Reference 1.0/en|(Obsolete) Windows App UI Tests (GUI Access Interfacing Library 1.0)]]
'''Hinweis:'''
Die verkürzten Pfade in den oben gezeigten Beispielen sind wesentlich unanfälliger gegenüber Änderungen im Layout der Benutzeroberfläche. Jedoch erhöht es je nach Anwendung und Benutzeroberfläche auch die Wahrscheinlichkeit, dass mehrere passende Bedienelemente gefunden werden. Dies wird dann ebenfalls zur Laufzeit zu einem Fehler führen ("Nicht eindeutiger Komponentenpfad"). In obigem Beispiel könnte dies passieren, wenn im UI neben dem Button auch ein Menueintrag mit dem selben Text existiert.
In der Praxis wird die Auswahl des geeigneten Pfades immer einen Kompromiss aus Flexibilität (möglichst kurz) und Eindeutigkeit darstellen.

Aktuelle Version vom 1. September 2023, 10:51 Uhr

Deutsche Version | English Version

The "expecco GUI Tests Extension" ("GUI Browser" for short) provides a common base for the development of test sequences for graphical user interfaces (GUIs) in expecco. The tool integrates seamless into the expecco UI philosophy. It is used as a common interface for various different GUI technologies (Web, Qt, Java and Windows Apps, Android, iOS, MFC, VNC, etc).

In addition to plain recording & replay and UI-structure inspection (widget tree and attributes), it is possible to try and experiment with individual actions, partial and complex sequences, which can be developed interactively and added to the suite, when completed ("explorative Test Development").

Main Features[Bearbeiten]

  • Seamless integration into the expecco user interface
  • One common tool for various different UI technologies
  • Hierarchical visualization of the user interfaces structure (component structure)
  • Information on state and attributes
  • Locator (xpath) generation, compression and verification
  • Feedback and convenient localization of interface components through highlighting, screen shots and mouse-over feedback
  • Filtering and presentation of function blocks which match the corresponding UI technology
  • Creation of test sequences via "Drag &Drop" and/or automatic capture, or import of formal and non-formal descriptions from external documents (XMI, UML, XML, Word, Excel, CSV)
  • Experimental try and compose of actions, partial sequences and access paths
  • Incremental creation of complex tests from shorter sequences in the test project

General Architecture[Bearbeiten]

In order to communicate with the controlled GUI application, expecco needs to setup a communication channel to it and exchange commands and queries with it. The details of how this is done depends on the particular UI technology, and also on the way the app was built/deployed:

  • Windows
    Uses the standard Windows UIAutomation mechanism
  • Java
    Communicates with an agent which was either injected dynamically (if possible), or is already running inside the app.
  • Qt
    Communicates with an agent which is either injected dynamically, or relinked with the application
  • VisualWorks
    Communicates with an agent which must be loaded (as a parcel) and already running in the application.

Further details are found in the individual technology's decumentation.

General Design Philosophy[Bearbeiten]

Like any other action in expecco, GUI-interaction and verification is performed through the execution of actions within activity diagrams.

Thus, for test execution, actions are placed into a test sequence, which control and verify the GUI to be tested or to be manipulated as part of the test.

It should be emphasized, that such GUI interaction is not limited to testing: it is also a valuable tool to automate common tasks such as initialization, configuration or deployment procedures, in situations where manual user interface interaction is required. Such automation may otherwise be difficult even for very simple tasks. For example if the operating system opens dialog boxes for warnings or user confirmations (as often happens in e.g. the Windows operating system).

Although similar in many ways, different UI technologies (e.g. Java Swing vs. Android vs. Qt) may provide different operations when automated. Depending on the set of widget elements, the way the UI technology is interfaced and possibly even the way it is configured, some operations depend on the concrete technology. Therefore, each technology is supported by its own GUI interface library, which provides action blocks for the particular technology.

Inside a test suite, multiple such libraries can be imported, and interaction blocks be placed in any order - it is therefore possible and often useful, to interact with different devices using different technologies even within a single test sequence. For example, it is quite common to trigger some operation on e.g. a mobile device (using actions from the appium interface library) followed by actions to verify some field in a Java GUI (using actions from the Java Swing interface library). Of course, it is even possible, to add totally different actions to the same sequence, which might perform database- or protocol requests.

Locating UI Elements[Bearbeiten]

When UI interaction blocks are executed, they typically need a way to specify which element is to be manipulated. For example, a "Send Button Press" action will need to know, which UI element the event should be sent to. This information is typically named "locator", and different technologies may use different locator styles.

Challenges[Bearbeiten]

Most locators are based on the XPath syntax, which specifies UI elements using a path from the top element (typically the application window or the screen) down to the destination element.
For example, an XPath to locate a button inside a panel, inside the main window may look like:

/Window/Panel/Button

Intermediate components can be left empty or specified as wildcards. For example:

/Window//Button

addresses any button arbitrarily deep below the top window, or:

/Window/*/Button

addresses buttons inside one arbitrary component below the top window.

It is obvious, that a compromise is needed in that we want both deterministic, exact and unique addressing of the UI element, and at the same time the most possible flexibility in case of structural or visual changes of the user interface.

As a concrete example, let us assume that a button element is located inside a hierarchy of 3 other panels, which care for the subelement's geometries. The testsuite should be as much as possible independent from both the layout (i.e. the actual position of the button), and also be independent from any change in the hierarchy: i.e. if the next version of the app has the same button embedded in a different number of panels or in another panel.

Whether such independence is possible or not in a particular technology and for a particular application, often depends on how the application was built, and whether enough information is available to the test tool.

For example, if the button contains a unique identifier (widgetID) in its attributes, it can be uniquely identified and addressed by this, and the best XPath locator for it would be

//button[@id="XYZ"]

This XPath is completely independent of the hierarchy.

This being the optimal situation - in practice, app developers often fail to be nice to testers and fall into one of the following error-traps:

  • use of dynamically generated ids
  • changing ids between versions/releases
  • changing ids between national language variants
  • not providing ids at all and not providing any unique alternative

If all of the above are given (and in real world testing, they often are), the XPath must depend on the hierarchy; for example, we could specify it to be the 3rd button in the second subpanel as:

//panel/panel[2]/button[3]

Such an XPath would work as long as no other button gets placed before the target button, and as long as the button is somewhere inside the second panel of another top-level panel.

Solutions[Bearbeiten]

Expecco offers a number of solutions to this problem. However, if you can talk to your developers, the first thing to do is to ask them for constant identifiers, which will not change between versions, and which will be independent of national languages or sessions. Most GUI frameworks allow for such identifiers to be added.

Scenario 1: Developers can provide information[Bearbeiten]

It is often possible, that the app-developer can provide widget ID information. Especially, if the UI is generated via a WindowBuilder tool, it is often possible to export an XML or CSV containing such information. The test could then import this file, and generate a mapping table (into an expecco variable, or into a number of variables) at test startup. Then, instead of using hard-wired XPath strings, those variable values will be used as locators. Use one of the XML- or CSV reader actions to parse the data, and place the element-IDs into either a dictionary or into the environment and use those values in the test.

Scenario 2: Dynamic session-ids[Bearbeiten]

If all sub-element ids can be constructed from a session id, a similar strategy is possible, by remembering this sessionID during startup (in an expecco variable), compute the sub-ids into a table or individual variables, and use those a locators.

Scenario 3: None of the above[Bearbeiten]

This is the worst case fallback. If no information is available at all, you have to use possibly sensitive XPaths. With VNC- and local screen connections, you can also fall back to either geometric locator information (i.e. specify that the button is in a particular bounding rectangle) or image locator (e.g. specifying the bitmap image of the button, and having expecco search for the image in the UI). VNC and local screen connections are supported with expecco 18.1 (= 2.12).

Most other UI libraries also allow for a relative geometric offset to be provided to mouse and keyboard actions. As a fallback (but really: only if all else fails), you can use events on the parent widget, giving an x/y offset.

Finally, some other UI libraries also support image-search within an element. You can use this to get the x/y coordinate.

Be aware that image-searching may make your test depending on the icons used (scaling?, color compensations) and also on the graphic card (edge antialiasing, leading to different color values). For this, the image search operation can be adjusted with various error parameters (color tolerance, pixel percentage, smoothing).

GUIBrowser's Role in Test Development[Bearbeiten]

The GUIBrowser helps to deal with the above challenges. You can interactively explore the UI widget hierarchy, find out which attributes are present and what values are found there, try different XPath expressions to locate elements, and collect actions into subsequences interactively. You can switch between the GUIBrowser's view of the application and the test diagram - even in the middle of a stopped or paused test run, change the diagram or parameters on the fly, and possibly proceed or restart test sequences.

The GUIBrowser supports both interactive composition and recording of action sequences. Either way, these can be edited, reorganized and parametrized immediately within the GUIBrowser.

Description[Bearbeiten]

Opening the GUIBrowser

The "expecco GUI Tests Extension" (or "GuiBrowser" for short) provides a common base for the interaction with graphical user interface applications. Various different UI technologies are supported, in that the concrete interface is realized by technology specific plugin extensions and action block libraries. Currently available are interfaces for Qt, Java Swing, MFC, DevExpress, Android, iOS, Windows Mobile and VNC.

Therefore, in order to use the "expecco GUI Tests Extension", at least one concrete UI-technology plugin is required.

One the other hand, it is possible to handle complex test scenarios in which multiple technologies are involved (for example, Qt plus Android plus Java-Swing). Any combination of interfaces can be controlled simultaneously, within a single test scenario and even execute in parallel.

Thus, complex integration test scenarios, End-to-End tests and other multi-technology tests are easily created, in which both mobile and web-based and classical user interfaces are to be controlled and verified.

To open the "expecco GUI Tests Extension" within expecco, click on the "GUI Browser" icon in the toolbar.

User Interface[Bearbeiten]

Fig.1: Main View (pre 2.10 version)
Fig.2: Usage (pre 2.10 version)

Overview on the layout, usage and the functions of the UI. Fig.1 Shows the main view. Fig.2 shows the control flow. In the 2.10 version, the look has changed slightly changed, and an additional preview has been added.

Connection Setup
Provides a selection list with available UI technologies.

After a click, a connection setup dialog opens, which lets you choose among connected devices (i.e. if multiple mobile devices are connected) or applications (if multiple applications are present inside the device or running on a machine). Once connected to a concrete technology/device and application, the components of the user interface are presented in the hierarchical tree on the left.

UI Component Hierarchy (left view)
This view displays both connected and disconnected applications. Underneath each connection, the component (widget-) hierarchy of the application is shown. Disconnected applications can be reconnected via the context menu.

When an element is selected, matching operations (i.e. actions which are applicable to that element) are shown in the "actions / properties" list (in the middle top view), and the component's attributes are shown in the parameter view (in the middle bottom view).

The XPath to the component (the locator to address the component) is shown at the bottom, and a list of alternatives provided in its pull down list. The automatically generated XPath may be too specific (as described in "challenges" section above). You can shorten the XPath and replace intermediate components in it by wildcards ("*" or "**"), and re-verify that the optimized XPath is still valid (i.e.refers to exactly the one selected component).

It takes a little experience and gut-feeling to get to the optimum - and often also some interaction with app developers, so they know, on what hierarchical details your test suite depends upon. The dropdown list beside the xpath field offers various variations, among them a shortened (compressed) xPath and the full path. Depending on the technology, other locator strategies may also be offered there; for example, for web-GUIs, alternative css locators are offered.

Tools
A number of functions are available as toolbar buttons or on the selection menu (widget-tree's right-button menu). Most of them are context menu functions and provide operations specific to the selected element.
Disconnect All
Closes all connections of all technologies.
Disconnect Selected
Closes the selected connection (or the connection used by the selected widget element).
Refresh
Reloads the widget hierarchy from the device/application. Some technologies can do this automatically; however, on many, this would take too long and slow down or even interfere with the application's operation. For example, a refresh of an Android app can take a few seconds, depending on the number of UI items, and the speed of the USB connection, and is therefore not done automatically. Also, a refresh may close currently open popup menus or change the keyboard focus in some technologies, and would change the state of the application, which is another reason for not doing this automatically.

Use this when the UI changed without user interaction (normally, the tree is refreshed when you click or enter keyboard input. But sometimes, changes come late or without any user action.)

Reload Child Elements
Only reloads the child elements of the selected element. Notice that not all UI technologies support a partial reload, and these will do a (slow) full reload.
Highlight
Emphasizes the widget's display area (usually by drawing a rectangle around it).
Follow Pointer
When active, the element under the mouse pointer is automatically selected whenever moved over an item in the UI. Not all UI technologies support this function.
Start Recording (on all)
Starts recording your interaction with all connected devices. I.e. you can interact with any application or mobile device and have all those recorded in one recording sequence. If there is already a partial recording in the sequence view, the new interactions are appended to the end of the sequence.

For some technologies (eg. Android and iOS), a separate recorder window is opened, which presents the screen, and records user input. Thus, you do not need to have the physical device on your desktop (which is especially useful, if the device is located in the server room...)

Stop Recording (for all)
Stops the recording.
Attribute View
Shows the attributes of the selected element. The list of attributes depends on the underlying technology (i.e. a Java Swing element may show more attributes than e.g. an Android UI element) and the type of element (i.e. a Button will have different attributes than e.g. a Combolist). When an attribute is selected, corresponding action blocks are shown in the upper action/attribute list, so that only blocks are presented, which are applicable to the selected element and selected attribute.
Action-Library
Shows action blocks which are applicable to the selected element. These blocks are user-interaction blocks, which generate click, press, release, keyboard or other user events. The list will only show the set of action for a particular kind of element. For example, if an input-field element is selected, actions for text entry will be shown, whereas these are not seen when a panel or label is selected.
Whenever an action block is selected, it is copied to the the test-pane and any locator/path input pin is set to refer to the selected UI element. I.e. it will be presented as it would be used within a test sequence. You can now either execute the action in isolation, or copy it to the end of the sequence (by pressing the "Add to Sequence" button in the top-right. Of course, you can also edit the network in this test view and add any other action block (drag & drop from the suite or via the context menu) or modify the pin parameters.
If you double click on the action block, it is immediately added to the recorded sequence.
Test Network and Sequence Views
As already mentioned above, the "Test" pane shows the selected block from the action/attribute list. You can edit and change the pin setup. Also, the block can be executed and the results are shown in the lower right execution log window. Finally, the block is added to the end of the recorded sequence via the "Add to Sequence" button.
The "Sequence"-View presents the test sequence as recorded so far. This is a regular diagram editor as described elsewhere. So any of the well known editing features can also be used here. Especially, it is possible to insert other blocks from the library, to change the execution order of recorded steps, or to replace them by other steps (without a need to re-record the sequence). The sequence view also allows for the whole sequence to be replayed in whole or in part, to be single stepped, breakpointed etc. Finally, when complete, you can create a new action block in your project, which contains the recorded sequence (by pressing on the "Define Action Block" button at the top right).
Path Display
Shows the XPath (locator) of the selected UI element. By default, a full explicit path is automatically generated and added as freeze value to the locator pins (in the recorded sequence). However, it is often desirable to shorten this path via placeholders. This will make your test less affected by changes in the widget hierarchy. Therefore, it is useful to reduce the path as long as it uniquely identifies the desired element. The details depend on the way the UI was programmed; for example, if each element has a unique ID, no path is needed at all, and the locator can be something like "/*[ID=xxx]". In contrast, if no ID or other unique attribute is present, a full path which enumerates the parent hierarchy might be required. The "Check Path" button will apply the entered path to the element hierarchy and give an OK-response if the element is still uniquely identified by it.
Component Preview
Display a preview (snapshot image) of the selected UI element or the application's main window/screen, with the element's bounds emphasized.


Locator Path (xPath)[Bearbeiten]

The locator addresses elements within a user interface. It is based on the XPath notation as known in the XML world. Locator paths are specified during test development, and used later, at test execution time, to refer to UI elements. The path of a selected UI element is shown in the lower right "Path" field, and is updated when another element is selected. Vice versa can the path be changed in that input field, in order to check which element(s) would be addressed by a given path. The path does not need to and should not be specified in full detail. It can contain wildcards and dynamic parts, which makes it more flexible and more robust against possible future changes in the test application; especially against changes in the hierarchy, when new container elements are inserted (which is one of the most common reasons for test cases to fail on new releases).

Notice: Many user interfaces change their structure dynamically during the execution. Often container and interaction elements are added or removed during the run. Especially in these situations, the flexibility in the XPath notation is very useful.

Defining Paths[Bearbeiten]

A typical path may look like:

/frame[@name='Notepad']/root pane/layered pane/panel/panel/panel/tool bar/push button[2]

This path describes the full explicit path to the second button inside a toolbar, which itself is contained in a nested hierarchy of containers (panels).

The path consists of a list of identifiers, beginning and separated by "/". Each individual identifier describes a subcomponent of the element which is already described by the left part.

A path component may be a wildcard or a deep wildcard:

/frame[@name='Notepad']/*/*/*/*/*/tool bar/push button[2]

refers to a button inside a toolbar, which is 5 levels below the toplevel window. Independent of the type of containers in-between, and:

/frame[@name='Notepad']//tool bar/push button[2]

refers to a button inside a toolbar, which is any number of levels below the toplevel window.

The path:

"/frame[@name='Notepad']"

refers to the top-level application window. "root pane", "layered pane", "panel" etc. refer to corresponding child elements. To get to the final destination, each component is found along the path starting with the top level window.

In this concrete example, expecco will first look for a top-level window which has the name "Notepad". This window will have one or more child elements, which match the identifier "root pane". Each such "root pane" will have children, matching the identifier "layered pane", and so on. At the end, there should be exactly one element, which matches all of those "constraints", and this will be the target element. If no element matches, or of multiple elements match, a runtime error will be triggered at test execution time, and the normal exception handling mechanism of expecco applies (i.e. the test will finish with a failure, or an exception handling action is triggered).

The syntax of each individual identifier is:

/<NodeIdentifier><[Optional Selector]>

Node Identifier[Bearbeiten]

The Node Identifier defines the type of UI element, which is to be searched

Possible Identifiers:

The type of the UI element
eg. "button", "panel" etc., or in case of a webtest, the HTML element tag (e.g.. "h1", "div", etc.)
this matches all elements of that type (can be zero, one or multiple elements).
The "Any" identifier ("*")
matches all child elements, independent of their type. Further matching must be done via the selector or via child element matches (e.g. the right rest of the XPath).
The "Parent" identifier ("..")
walks up one step after a match. This can be used to find siblings of labels, buttons, etc. Be aware that not all UI technologies support this.
Examples[Bearbeiten]

Full path:

/frame[@name='Notepad']/root pane/layered pane/panel/panel/panel/tool bar/push button[2]

the same path using Any ( " * " ) identifiers:

/*[@name='Notepad']/*/layered pane/*/panel/*/tool bar/push button[2]

Both paths refer to the same UI element. However, the second version is less sensible to changed types of the intermediate components. For example, the app developer might replace a "panel" component by a "box" component in a new release. The first path would then fail to find the UI component, as no element will then match the "panel" identifier. Notice that the "*"-identifier is a wildcard for only one component (i.e. the hierarchy must still be as deep as before). To make the path robust against hierarchy changes, use the "//"-Notation (as described below).

Selector[Bearbeiten]

The selector is optional. It is used to select among same-typed elements. For example, if a component contains 3 buttons as child elements (eg. child elements of the same type), the selector can be used to specify which of the 3 buttons is to be matched. The selector is specified in square "[ ]" brackets after the node identifier, and is applied during the match process after matching the node identifier.

For example, if an elements contains 2 buttons plus 2 checkboxes as child elements, and the node identifier gives 2 buttons as result, the selector will only be applied to the 2 buttons.

Possible Selectors:[Bearbeiten]
"Index"
chooses an element by its index, which is the position within the list of children (of the matching type). The index is 1-based (i.e. [1] refers to the first child).
"Attribute Key" (or "Attribute-Value")
chooses the element, which has a particular value associated to a given attribute. The set of attributes depends on the concrete UI technology, the component type and possibly its current state. Typical attributes are "name", "id", "label", "value" etc. but also "visible", "enabled" or "isActive". Some components have dynamic attributes (and therefore keys which show up dynamically), which are created during the execution time.
Function on "Attribute"
similar to the above, this allows for a match or check function to be applied to an attribute value. Be aware that not all UI technologies support this kind of locator. Typical functions are "starts-with", "ends-with", "contains" and "matches".
Example (Index Selector)[Bearbeiten]

To address the second button inside the toolbar:

    /*/toolbar/push button[2]

 

Example (Attribute Selector)[Bearbeiten]

To address the button which has the name attribute "Save As...".

    /*/toolbar/pushbutton[@name='Save As...']

 

Example (Function Selector)[Bearbeiten]

To address the button whose label matches the regex pattern ".*Save.*" and which is contained in a window whose label starts with "MyApp", use an xPath like:

    /Window[starts-with(@label,"MyApp")]//Button[matches(@label='.*Save.*')]

 

Be careful with attribute values which depend on the national language. If attributes are present, which are language independent, (e.g. "id", "refID", "uuid" etc.) those are to be preferred. If not, you should keep the language texts separate from the action block (i.e. attachment, external file or expecco variable) and construct the XPath using those values. This makes it much easier to later support multiple languages or changed button labels in your test suite.

Be also careful with dynamic session-id, i.e. id-attributes which are regenerated with every session. If such ids are present in the tested application, ask your programmer/web designer to add additional ids, which remain constant across sessions. Those session-ids are not useful for test developers.

"Super Wildcard"[Bearbeiten]

The super wildcard ("//") can dramatically shorten paths, and also makes them robust against additional inserted or removed hierarchy levels. "//" matches arbitrary subpaths: children are not only matched in the immediate sub-child level, but also in any level below.

Example:
Given the full path of a button as:

/frame[@name='Notepad']/root pane/layered pane/panel/panel/panel/tool bar/push button[@name='Save As...']

also assuming, that the application contains only one single button by the name "Save As...". Then, the path can be rewritten (using the super wildcard) as:

//push button[@name='Save As...']

even short, if there is only one single element by that name (i.e. no other non-button exists, which has that name attribute). Then, the following path is also possible:

//*[@name='Save As...']

The following example shows, that you can also use the super wildcard for partial hierarchies:

/*[@name='Notepad']//panel//tool bar/*[@name='Save As...']

this matches a component by the name "Save As...", which is inside a toolbar, which is arbitrarily deep inside a panel, which is arbitrarily deep inside the top window named "Notepad".

Notice: The short paths as shown above are dramatically more robust against changes in the layout and hierarchy of the user interface. However, at the same time, they may increase a risk to match multiple elements inside the GUI, which would also lead to an error being reported at test execution time ("non specific component path"). In the above example, this might happen if the UI contains another menu item by the same name. In real world testing, the choice of path will always be a compromise between flexibility (as short as possible) and unambiguousness.

Also notice: Some GUI technologies contain very slow implementations of their XPath search engine, and especially addressing via the Super Wildcard leads to slow response times. This may or may not be the responsibility of expecco itself, as most XPath implementations are implemented in the target system's UI or automation framework (eg. Windows Automation, Selenium or Appium).

css Selector Locator[Bearbeiten]

Some GUI technologies (in particular the webTest technologies based on Selenium/WebDriver) also support the "css" selector notation as locator. This is semantically similar to xPath, but somewhat more compact. It is described in detail in "www.w3schools.com css reference".

If supported by the technology, the corresponding css selector is presented in the pulldown list of the locator entry field (at the bottom of the GUI browser).

Image Locator[Bearbeiten]

Image locators are mostly used with GUI technologies where only a bitmap representation (i.e. a screen image) is available. Here, elements are defined as a bitmap image which is searched. Various parameters control the image detection mechanism (pixel errors, color variance) to allow for images to be detected even in situations where the graphic hardware generates different pixel values (eg. when anti-aliasing or blending alpha values).

Image locators are described in more detail in the VNC plugin reference documentation. How to use image locators with other GUI technologies is described in Graphical Elements in GUI Technologies.

Mapping Locators[Bearbeiten]

If the tested UI is prone to change and chances are that locators will change in future versions, it is a good idea to not use XPath locators directly (in an action's freeze value), but instead go through a locator mapping, where logical names (such as "NameField", "LoginButton" etc.) are used as key into a table which provides the actual locator to use.

Expecco provides two such mechanisms:

  • via environment variables
  • via screenplay attachments

Using Environment Variables for Locator Mapping[Bearbeiten]

By using a string like "$(KEY)" as a locator, the value of "KEY" will be looked up int the environment of the action at execution time and sliced into the freeze value of any input pin.

Be reminded, that there is not only one top-level environment, but there also exist local environments eg. of test plans, test cases and compound actions. Thus, a global variable value can easily be redefined for sub-actions.

The string expansion can be applied to a whole freeze value, substrings and even multiple times; thus very flexible locator mappings are possible.

For example, if a subcomponent of the UI is present multiple times within different containers, both the container's locator and the path relative to that container can be provided by different variables:

$(ui.container)//div//$(ui.NameField)

could be used as XPath, where "ui.container" could even be provided by the containing compound action as a local variable value. A UI action using this locator can then be called from within different contexts (eg. test cases or compound actions) each providing a different value for the "ui.container" value.

By convention, you should name the logical keys "ui.XXX"; i.e. prefix them with "ui.". This is just a convention which makes it easier to filter locators or to import/export parts of the mapping table.

Using Screenplay Attachments[Bearbeiten]

Screenplay attachments provide a more formal definition of locator mappings and are represented as XML. Their structure is similar to that of existing UI frameworks which are based on scenes and players, and import/export to new formats can be accomplished eg. via XSLT translation, or by parsing XML with the expecco XML library.

xPath Generation[Bearbeiten]

By default, the GUI browser generates both a full xPath and a compressed shortened xPath, and offers them in the locator entry field (and its pulldown list). Usually, the short xPath is the preferred locator. If a logical name has been defined for the element, that is provided in the pull down list as well, and used as default locator.

Be aware that the generated xPath might fail to identify a unique element at execution time if your application adds/removes elements dynamically. However, at the time the path is generated, expecco verifies that it is correctly referring to the one-and-only selected current element.

Preferred Attribute Selectors[Bearbeiten]

When multiple elements with the same node-type are present, expecco uses either an attribute (if present) or the index to make sure that only one element matches. For this, a builtin list of preferred attributes is tried sequentially for the first attribute which resolves any ambiguities. You can modify this list and/or the order in which they are tried via a context menu of the attribute list ("Preferred xPath Attribute").

Unwanted Attribute Selectors[Bearbeiten]

The dialog opened via "Preferred xPath Attribute" (in the property/attribute list) can also be used to explicitly exclude attributes from the xPath generator's strategy. This is useful for applications with dynamic "id"-attributes, which should not be used in the context of such applications. For this, select the attribute which is to be ignored, open the dialog, and click on the "Do not Use" button.

Separating Locators from the Test Sequence[Bearbeiten]

Place locators into either the project's environment, or use attachments which provide mappings between logical names and actual locators.

This will reduce maintenance work later, when the UI, the structure or naming/ids change in later versions of the tested application.

Technology Specific Features[Bearbeiten]

Firefox, Edge, Internet Explorer, Chrome etc.[Bearbeiten]

See "Selenium WebDriver Plugin"

Android and iOS[Bearbeiten]

These are documented in the separate document: "Mobile Testing Plugin"

Java Applications[Bearbeiten]

See "Java GUI Plugin"

Windows Applications[Bearbeiten]

See "WindowsAutomation Reference 2.0"
(or the previous version, which is now outdated: "WindowsAutomation Reference 1.0")

VNC and Local Screen[Bearbeiten]

These are documented in the separate document: "VNC Testing Plugin".
Local screen automation behaves as described there, with slight differences in the connection setup.

Qt[Bearbeiten]

Please read: "Qt Testing Plugin"

VisualWorks[Bearbeiten]

Find additional information in: "VisualWorks Testing Plugin"

Frequently Asked Questions[Bearbeiten]

Why does it not update the widget tree automatically?[Bearbeiten]

We did this in an early version, but found it to be very inconvenient to interact with transient views (such as dialogs, popups, menus etc.). If the element vanishes automatically, you often got no chance to inspect the item's attributes and/or create actions for it.

Now, you can either press the update toolbar button, or a hotkey, or schedule a timed update ("update after"). The later is perfect to catch the hierarchy of popup menus and similar views, which vanish with the next user interaction or when the mouse button is released (such as a popup menu).

See Also[Bearbeiten]

Web Testing with Selenium WebDriver
Java Swing/SWT UI Testing
Windows App UI Tests (GUI Access Interfacing Library V2)
Mobile Testing for Android and iOS
UI Testing with VNC
Local Screen Automation
UI Testing and Qt-Applications
UI Testing for Custom-Applications (OpenETS)

AutoIt GUI Interface Library

(Obsolete) Windows App UI Tests (GUI Access Interfacing Library 1.0)



Copyright © 2014-2024 eXept Software AG