2

Gibt es eine einfache Möglichkeit, ein untergeordnetes Element aus einem anderen Element zu finden (beide Elemente wurden mithilfe einer PageFactory gefunden)? Wir haben eine Reihe von Containern, die viele Module enthalten, und ich möchte sicherstellen, dass sie an ihren richtigen Stellen angezeigt werden.Selenelement Position

Die API scheint nur die folgende Methode zu haben:

webElement.findElement(s).(By by); 

Gibt es einen einfachen Weg, um die folgenden Funktionen ausführen:

webElement.findElement(s)(WebElement webElement); 

oder noch besser:

webElement.contains(WebElement webElement); 
+0

Ich kann nicht wirklich herausfinden, was du versuchst zu tun. Könnten Sie bitte ein Beispiel geben? Von dem, was ich verstanden habe, sollte das 'element.findElement (by by)' auch für Ihre Bedürfnisse gut genug sein. Was mache ich falsch? –

+0

Ich würde es vorziehen, die Reflexion nicht erneut zu verwenden, um die FindBy-Annotation von den Feldern abzuziehen. Ich habe zwei Elemente, die bereits mit einer benutzerdefinierten PageFactory initialisiert wurden. Wir haben viele verschiedene Module, die auf verschiedenen Seiten erstellt und hinzugefügt werden können. Ich möchte nicht jeden dieser Tests ändern, wenn die Seiten im CMS geändert werden. Ich suche diese Module selbst und möchte nun überprüfen, ob sie an den richtigen Stellen auf dem Bildschirm vorhanden sind (dh ich möchte um sicherzustellen, dass Modul A in Container A oder B, aber nicht C) ist. – Scott

Antwort

2

I endlich, was du brauchst. Meine beste Lösung wäre etwas in der Art von:

public static void assertContains(WebElement outerElem, WebElement innerElem) { 
    // get borders of outer element 
    Point outerLoc = outerElem.getLocation(); 
    Dimension outerDim = outerElem.getSize(); 
    int outerLeftX = outerLoc.getX(); 
    int outerRightX = outerLeftX + outerDim.getWidth(); 
    int outerTopY = outerLoc.getY(); 
    int outerBottomY = outerTopY + outerDim.getHeight(); 

    // get borders of inner element 
    Point innerLoc = innerElem.getLocation(); 
    Dimension innerDim = innerElem.getSize(); 
    int innerLeftX = innerLoc.getX(); 
    int innerRightX = innerLeftX + innerDim.getWidth(); 
    int innerTopY = innerLoc.getY(); 
    int innerBottomY = innerTopY + innerDim.getHeight(); 

    // assures the inner borders don't cross the outer borders 
    final String errorMsg = "ughh, some error message"; 
    final boolean contains = (outerLeftX <= innerLeftX) 
      && (innerRightX <= outerRightX) 
      && (outerTopY <= innerTopY) 
      && (innerBottomY <= outerBottomY); 
    assertTrue(errorMsg, contains); 
} 

... funktioniert nur, wenn keiner dieser Container überlappt. Wenn sie das tun, würde ich etwas dunkle und wilde Magie mit innerElem.getTag() und getText() versuchen und testen, ob der äußere Text das innere Element enthält. Ein Weg, es zu tun:

public static void assertContains(WebElement outer, WebElement inner) { 
    // e.g. //div[text()='some text in inner element'] 
    final String findInner = ".//" + inner.getTagName() + "[text()='" + inner.getText() + "']"; 
    try { 
     outerElem.findElement(By.xpath(findInner)); 
    } catch (NoSuchElementException ignored) { 
     fail("Some horrible message! We are all doomed!"); 
    } 
    // passed 
} 

... oder etwas Ähnliches. Es ist möglich, dass normalize-space() oder contains() (oder beide) aufgrund von Tags in Tags in Tags benötigt werden.

Und natürlich ist dies immer noch raten. Die erste Methode kann falsche positive und negative Ergebnisse haben (aber ich mag sie eher für meine Bedürfnisse), die zweite sollte nur falsch positive Ergebnisse haben. Sie können sie kombinieren oder selbst etwas erfinden (z. B. mit Reflection, wie Sie bereits erwähnt haben).

Oder file a bug.

+0

Obwohl ich nicht unbedingt in diese Methode verliebt bin, bietet sie den Vorteil, dass wir in der Lage sein zu bestimmen, ob Browser HTML in ähnlicher Weise rendern, aber das ist auch ein zweischneidiges Schwert, Da der HTML-Code tatsächlich ein Kind des Elements sein kann, aber nicht innerhalb seiner Grenzen, wenn wir aufgrund von Renderproblemen vom Treiber ein abgesprengtes Ergebnis erhalten. – Scott

+0

Ja, ich weiß, dass es nicht das ist, was wir eigentlich haben möchten = /. Außerdem habe ich die Antwort so bearbeitet, dass sie für zukünftige Leser nützlicher ist (übrigens, da Sie selbst ziemlich fähig schienen). –

+0

Sieht gut aus, ich werde mehr als wahrscheinlich nur auf einem benutzerdefinierten Locator arbeiten, da ich denke, es wird ein bisschen sauberer sein. Ich werde dies auch im Selen-Google-Code-Repository als Feature-Anfrage veröffentlichen. – Scott