2012-05-09 15 views
34

Estoy usando selenio para probar mi aplicación web y puedo encontrar etiquetas exitosamente usando By.xpath. Sin embargo, de vez en cuando necesito encontrar nodos secundarios dentro de ese nodo.Localizando nodos secundarios de WebElements en selenio

Ejemplo:

<div id="a"> 
    <div> 
     <span /> 
     <input /> 
    </div> 
</div> 

que puedo hacer:

WebElement divA = driver.findElement(By.xpath("//div[@id='a']")) 

Pero ahora tengo que encontrar la entrada, por lo que podía hacer:

driver.findElement(By.xpath("//div[@id='a']//input")) 

Sin embargo en ese momento de código I solo tengo divA, no es su xpath más ... Me gustaría hacer algo como esto:

WebElement input = driver.findElement(divA, By.xpath("//input")); 

Pero tal función no existe. ¿Puedo hacer esto de todos modos?

BTW: A veces necesito encontrar un DIV que tenga un cierto nodo descendente. ¿Cómo puedo preguntar en xpath por "la etiqueta div que contiene un lapso con el texto 'hola mundo'"?

Respuesta

64

Según JavaDocs, usted puede hacer esto:

WebElement input = divA.findElement(By.xpath(".//input")); 

Como puedo pedir en XPath para "la etiqueta div que contiene un lapso con el texto 'hola mundo'" ?

WebElement elem = driver.findElement(By.xpath("//div[span[text()='hello world']]")); 

The XPath spec es una sorprendentemente buena lectura de este.

+0

Muchas gracias. No sabía aún, que podría usar xpaths dentro de '[]' dentro de xpaths ... –

+2

la última versión de la especificación XPath se puede encontrar [aquí] (https://www.w3.org/TR/xpath- 3/# abreviación) –

+0

¡simplemente hermoso! – angryip

0

También me encontré en una posición similar hace un par de semanas. También puede hacer esto creando una ElementLocatorFactory personalizada (o simplemente transfiriendo divA a DefaultElementLocatorFactory) para ver si es un elemento secundario del primer div - entonces debería llamar al método initElements de PageFactory apropiado.

En este caso, si se hizo lo siguiente:

PageFactory.initElements(new DefaultElementLocatorFactory(divA), pageObjectInstance)); 
// The Page Object instance would then need a WebElement 
// annotated with something like the xpath above or @FindBy(tagName = "input") 
-1

El método toString() de Al-Clase de selenio produce algo así como "By.xpath: // XpathFoo"

por lo que podría tomar una subcadena que empieza en el colon con algo como esto:

String selector = divA.toString().substring(s.indexOf(":") + 2); 

con esto, se podía encontrar su elemento dentro de su otro elemento con esto:

WebElement input = driver.findElement(By.xpath(selector + "//input")); 

Ventaja: Solo tiene que buscar una vez en el SUT real, por lo que podría darle una bonificación en el rendimiento.

Desventaja: feo ... si quiere buscar el elemento padre con la selectory css y usar xpath para sus hijos, debe verificar los tipos antes de concatenar ... En este caso, la solución de Slanec (utilizando findElement en un WebElement) es mucho mejor.

-2

Para encontrar todos los ChildNodes puede utilizar el siguiente fragmento

List<WebElement> childs = MyCurrentWebElement.findElements(By.xpath("./child::*")); 

     for (WebElement e : childs) 
     { 
      System.out.println(e.getTagName()); 
     } 

Tenga en cuenta que esto le dará a todos los nodos de los niños en mismo nivel -> Al igual que si usted tiene estructura como esta:

<Html> 
<body> 
<div> ---suppose this is current WebElement 
    <a> 
    <a> 
     <img> 
      <a> 
     <img> 
    <a> 

Me dará nombres de etiquetas de 3 etiquetas de anclaje solo aquí. Si desea todos los elementos secundarios recursivamente, puede reemplazar el código anterior por MyCurrentWebElement.findElements (By.xpath (".//*"));

Espero que ayude !!

1

Si tiene que esperar, existe un método presenceOfNestedElementLocatedBy que toma el elemento "principal" y un localizador, p. a By.xpath:

WebElement subNode = new WebDriverWait(driver,10).until(
    ExpectedConditions.presenceOfNestedElementLocatedBy(
     divA, By.xpath(".//div/span") 
    ) 
); 
Cuestiones relacionadas