01. April 2019
Auf Unterelemente von GUI-Komponenten zugreifen
In den meisten Fällen haben wir mit mehr oder weniger einfachen GUI-Komponenten zu tun wie z.B. Buttons oder Textfelder. Nichtsdestotrotz müssen wir uns auch oft mit komplexeren GUI-Komponenten wie Bäumen, Tabellen und Listen befassen. Diese GUI-Komponenten haben Unterelemente. Zum Beispiel besteht die GUI-Komponente „Tabelle“ aus Tabellenfelder (=Unterelemente einer Tabelle):
QF-Test bietet viele Möglichkeiten auf Unterelemente von GUI-Komponenten zuzugreifen:
Mit der „QF-Test Komponenten ID“ das Unterelement spezifizieren
Im „QF-Test ID der Komponente“ Attribut kann man spezifizieren, dass eine Aktion auf einem Unterelement einer GUI-Komponente wiederholt wird. Dazu wird ein Identifikator zur Komponenten ID hinzugefügt. Dieser Identifikator kann numerisch (repräsentiert durch das & Zeichen), textuell (repräsentiert durch das @ Zeichen) oder als regulärer Ausdruck (repräsentiert durch das % Zeichen) dargestellt werden.
Beispiele
Listen oder Comboboxen
Sie brauchen nur einen Identifikator, um das Unterelement einer Liste oder einer Comobox zu beschreiben:
Wie Sie sehen, hat die Combobox vier verschiedene Unterelemente. Das Unterelement „-no special model-„ (mit dem numerischen Index 1), „Jazz“ (mit dem numerischen Index 2) und das Unterelement „Luxus“ (mit dem numerischen Index 3). Somit kann man entweder "qftestIdOfComboBox@Jazz" oder "qftestIdOfComboBox&2" auf das Unterelement “Jazz” in dieser Combobox zugreifen.Als Alternative können wir auch mit "qftestIdOfComboBox%J.*" mit „J.*“ als regulären Ausdruck benutzen, der mit dem Unterelement „Jazz“ übereinstimmt.
Und um auf das Unterelement „Gomera“ zuzugreifen, können wir folgendes benutzen:
Tabellen
Bei Tabellen braucht man zwei Identifikatoren. Der erste Identifikator legt die Spalte und der zweite die Zeile der gewünschten Zelle fest. Wenn Sie also folgende Tabelle haben:
Eine Aktion auf die GUI-Komponente ID „qftestIdOfTable@Price%.*12.*“ wird auf die Zelle zugreifen, die den Text "$12,300.00" enthält. Dieselbe Zelle kann man mit der QF-Test Komponenten ID "qftestIdOfTable@Price&0" anspringen.
Bäume
Um Unterelemente in einem Baum zu erreichen, brauchen wir einen Identifikator, der den hierarchischen Aufbau dieser GUI-Komponente mit in Betracht zieht. Wenn wir also den folgenden Baum haben:
Kann das Unterelement “Mats” damit angesprungen werden
- qftestIdOfTree@/Information/Accessories/Mats
- qftestIdOfTree&/0/0/2
- qftestIdOfTree%/Inf.*/Acc.*/M.*
- qftestIdOfTree%/.*/.*/Mats
(und über andere reguläre Ausdrücke). Trotzdem wird es nicht funktionieren auf das Unterelement „Mats“ über die QF-Test Komponenten ID "qftestIdOfTree%/.*/Mats" zuzugreifen. Das liegt daran, dass wir QF-Test mit "%/.*/Mats" ein Unterelement suchen, das zu dem regulären Ausdruck “.*“ in der ersten Ebene des Baums passt. In diesem Beispiel ist dort nur ein Unterelement auf der ersten Ebene („Information“). Der reguläre Ausdruck, der QF-Test geliefert wird (".*") passt zu diesem Unterelement. QF-Test wird dann weiter gehen und den nächsten regulären Ausdruck („Mats“) hernehmen, um innerhalb der Kindknoten nach einem passenden Knoten ("Accessories", "Description") zu suchen. Wie man sehen kann passen beide Strings nicht zum gewünschten regulären Ausdruck, somit funktioniert "%/.*/Mats" nicht.
Elementknoten zum Spezifizieren des gewünschten Unterlements
Elementknoten haben dieselbe Funktionalität, nämlich um das gewünschte Unterelement durch einen Index, Namen oder einen regulären Ausdruck festzulegen. Dennoch werden diese Elementknoten nicht so häufig benutzt.
Sie können diese Knoten über die Menüleiste (Einfügen → Komponentenknoten → Element) als Kindknoten von jeglichem Listen-, Tabellen- oder Komponentenknoten (oder allgemeiner gesagt jedem Knoten, der eine Komponente repräsentiert, das Unterelemente haben kann):
Der im “QF-Test ID” Attribut festgelegte Text dieses Knotens (GomeraItemInComboBox ist das Beispiel, aber sie können auch wirklich fast jeden beliebigen anderen Text nehmen) kann dann in im „QF-Test Komponenten ID“ Attribut eines Mausevent-Knotens (oder irgendeinem anderen Eventwiedergabe Knoten) genutzt werden. Wenn solch ein Eventknoten ausgeführt wird, wird QF-Test als erstes die gewünschte GUI-Komponente mit Hilfe der Komponentenerkennungsinformation festlegen, die vom Elternknoden des eingefügten Elementknotens geliefert wird. Dann wird QF-Test das gewünschte Unterelement durch die Information im eingefügten Elementknoten festlegen. Wenn das durchgeführt ist, kann die gewünschte Aktion auf dem Unterelement abgespielt.
QPath
Manchmal müssen wir Unterkomponenten anspringen, die innerhalb von Unterelementen eines anderen GUI-Elements enthalten sind. Das kann z.B. ein Button oder eine Checkbox sein, die innerhalb einer Tabellenzelle liegt. Um solche Unterkomponenten zu erreichen, können wir die "@:ClassName"-Syntax (die sog. QPath Syntax) anwenden. Wenn wir beispielsweise einen Button innserhalb eines Tabellenzelle haben, können wir ihn hierüber erreichen:
"qfcomponentIdOfTheTable@columnname@rowname@:Button<0>".
XPath und CSS Selektoren
Wenn Sie eine Web-Anwendung testen, können Sie auch XPath oder CSS-Selektoren verwenden um die gewünschten GUI-Komponenten und/oder Unterelemente zu erreichen. Nachdem XPath und CSS Selektoren bekanntermaßen ziemlich schwierig zu schreiben sind, sind sie normalerweise nicht meine erste Wahl. Aber diese Funktionalität ist trotzdem nützlich, wenn es darum geht existierende Selenium Webtests in QF-Test umzuschreiben.
Die generelle Syntax, um XPath/CSS-Selektoren innerhalb eines „QF-Test Komponenten ID“-Attributs eines Eventknotens zu nutzen, ist:
- genericHtml@:xpath=${quoteitem:yourXPathGoesHere}
- genericHtml@:css=${quoteitem:yourCSSSelectorGoesHere}
Alternativ dazu ist es möglich, dass man einen XPath und/oder CSS-Selektoren in einem Extrafeature eines Komponentenknotens (oder in einem SUT Skript) spezifiert. Das kann man über das “Must match” Extrafeature mit dem Namen "qfs:item" und dem Wert "@:xpath=${quoteitem:yourXPathGoesHere}". (Vielleicht wollen Sie ja einen CSS-Selektoren mit "@:css=${quoteitem:yourCSSSelectorGoesHere}" als Wert benutzen.)
Hinweise
Aus offensichtlichen Gründen lässt die @:xpath/@:css-Syntax vermuten, dass die genutzte XPath/CSS-Syntax einen einzelnen Komponenten zurückgibt. Die Nutzung einer XPath-Syntax gibt nicht eine einzelne Komponente zurück, aber z.B. ein Integer (Beispiel: "count(.//input[@id!='Google'])") oder ein Boolean (Beispiel: "nilled($in-xml//child[1])") kann zu unerwartetem Verhalten führen.
Wenn Sie wissen, was Sie tun, können Sie mehrere XPath/CSS-Selektoren Statements verschachteln, z.B.: genericHtml@:xpath=${quoteitem:firstXPath}@:xpath=${quoteitem:secondXPath}
Für diejenigen unter Ihnen, die sich fragen, was der "genericHtml" Teil im String genericHtml@:xpath=${quoteitem:yourXPathGoesHere} bedeutet. Dieser Unterstring bezieht sich auf den "genericHtml" Komponentenknoten, welcher in der qfs.qft beschrieben ist. Der XPath sucht nach der gewünschten Komponente ab dieser GUI Komponente an.
Beispiele
Nehmen wir an, Sie haben ein einzelnes Textfeld auf Ihrer Webseite, das mit
<input type="text" ... additional attributes ... />
implementiert ist.
XPath innerhalb einer QF-Test Komponenten-ID
Im Event Knoten kann man das Text Inputfeld (in der obigen Beispiel-Webseite) über die QF-Test Komponenten ID "genericHtml@:xpath=${quoteitem:.//input}" adressiert.
CSS-Selektoren innerhalb einer QF-Test Komponenten-ID
Im Event Knoten kann man das Text Inputfeld (in der obigen Beispiel-Webseite) über die QF-Test Komponenten ID "genericHtml@:css=${quoteitem:input}" adressiert.
XPath innerhalb eines QF-Test Komponenten-Knotens
Das folgende Bild zeigt ein Beispiel für einen Komponenten-Knoten, der einen XPath spezifiziert in seinen Extrafeatures:
Wenn dieser Komponentenknoten einmal als Kindelement des „Fenster und Komponenten“-Knotens eingefügt wurde, ist es möglich, dass der String "myXPathEle" (oder was sonst in der „QF-Test ID“ festgelegt wurde dieses Komponenten-Knotens) im „QF-Test ID der Komponente“ Attribut eines Eventknotens.
XPath und/oder CSS-Selektoren innerhalb eines SUT Skripts
Um XPath in einem SUT Skript zu verwenden, kann man folgende Statements benutzen:
com = rc.getComponent("genericHtml") # or rc.getComponent("genericDocument")
res = com.getByXPath(rc.lookup("xpath")) # find subcomponent via xpath
res = com.getByCSS(rc.lookup("css")) # find subcomponent via css
res = com.getAllByXPath(rc.lookup("xpath")) # find all subcomponent via xpath
res = com.getAllByCSS(rc.lookup("css")) # find all subcomponent via css