Localización de nodos secundarios de WebElements en selenium

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

Ejemplo:

 

Puedo hacer:

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

Pero ahora necesito encontrar la entrada, así que podría hacer:

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

Sin embargo, en ese punto en el código I solo tengo divA , no 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?

Por cierto, a veces necesito encontrar un DIV que tenga un cierto nodo decente. ¿Cómo puedo preguntar en xpath por “la etiqueta div que contiene un lapso con el texto ‘hola mundo'”?

Según JavaDocs , puedes hacer esto:

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

¿Cómo puedo preguntar en xpath por “la etiqueta div que contiene un lapso con el texto ‘hola mundo'”?

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

La especificación XPath es sorprendentemente buena lectura sobre esto.

Si tiene que esperar, hay un método presenceOfNestedElementLocatedBy que toma el elemento “principal” y un localizador, por ejemplo, un By.xpath :

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

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 hiciste 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") 

El método toString () de Selenium By-Class produce algo así como “By.xpath: // XpathFoo”

Entonces podrías tomar una subcadena que comience en el colon con algo como esto:

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

Con esto, puedes encontrar tu elemento dentro de tu 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 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 (usando findElement en un WebElement) es mucho mejor.

Para encontrar todos los ChildNodes, puede usar el siguiente fragmento

 List childs = MyCurrentWebElement.findElements(By.xpath("./child::*")); for (WebElement e : childs) { System.out.println(e.getTagName()); } 

Tenga en cuenta que esto dará todos los Nodos secundarios al mismo nivel -> Me gusta si tiene una estructura como esta:

   
---suppose this is current WebElement

Solo me dará nombres de tags de 3 tags de anclaje. Si desea todos los elementos secundarios recursivamente, puede reemplazar el código anterior por MyCurrentWebElement.findElements (By.xpath (“.//*”));

Espero que ayude !!