Seleccione el elemento principal del elemento conocido en Selenium


116

Tengo un determinado elemento que puedo seleccionar con Selenium 1.

Desafortunadamente, necesito hacer clic en el elemento principal para obtener el comportamiento deseado. El elemento que puedo localizar fácilmente tiene un atributo no seleccionable, lo que lo hace inactivo para hacer clic. ¿Cómo navego hacia arriba con XPath ?

Respuestas:


169

Hay un par de opciones ahí. El código de muestra está en Java, pero la adaptación a otros lenguajes debería ser sencilla.

JavaScript:

WebElement myElement = driver.findElement(By.id("myDiv"));
WebElement parent = (WebElement) ((JavascriptExecutor) driver).executeScript(
                                   "return arguments[0].parentNode;", myElement);

XPath:

WebElement myElement = driver.findElement(By.id("myDiv"));
WebElement parent = myElement.findElement(By.xpath("./.."));

Obtener el controlador del WebElement

Nota: Como puede ver, para la versión de JavaScript necesitará driver. Si no tiene acceso directo a él, puede recuperarlo WebElementusando:

WebDriver driver = ((WrapsDriver) myElement).getWrappedDriver();

41
Y si desea navegar hasta el abuelo, use By.Xpath ("../ ..").
Monseñor

@Monsignor funciona como rutas de archivo ... o rutas de URL: stackoverflow.com/questions/8577636/../../questions/8577636/…
jpaugh

Ninguno de estos XPaths es correcto para su uso con Selenium. Se necesita usar By.xpath(“./..”)para subir correctamente el árbol DOM cuando se usa element.findElement. El "./" inicial es necesario para establecer el nodo de contexto.
JimEvans

35

Poco más sobre XPath axes

Digamos que tenemos la siguiente HTMLestructura:

<div class="third_level_ancestor">
    <nav class="second_level_ancestor">
        <div class="parent">
            <span>Child</span>
        </div>
    </nav>
</div>
  1. //span/parent::*- devuelve cualquier elemento que sea padre directo.

En este caso la salida es <div class="parent">

  1. //span/parent::div[@class="parent"]- devuelve el elemento padre solo del tipo de nodo exacto y solo si el predicado especificado es Verdadero.

Salida: <div class="parent">

  1. //span/ancestor::*- devuelve todos los antepasados ​​(incluido el padre).

Salida: <div class="parent">, <nav class="second_level_ancestor">, <div class="third_level_ancestor">...

  1. //span/ancestor-or-self::*- devuelve todos los antepasados y el elemento actual en sí.

Salida: <span>Child</span>, <div class="parent">, <nav class="second_level_ancestor">, <div class="third_level_ancestor">...

  1. //span/ancestor::div[2]- devuelve el segundo ancestro (comenzando por el padre) de tipo div.

Salida: <div class="third_level_ancestor">


Hola @Anderson Necesito ayuda con mi pregunta ¿Tienes tiempo para echar un vistazo? Gracias de antemano. stackoverflow.com/questions/54647055/…

18

Consideremos su DOM como

<a>
    <!-- some other icons and texts -->
    <span>Close</span>
</a>

Ahora que necesita seleccionar la etiqueta principal 'a' según el <span>texto, utilice

driver.findElement(By.xpath("//a[.//span[text()='Close']]"));

Explicación: seleccione el nodo según el valor de su nodo secundario


Si estamos buscando divque está anidado de nuevo con varias Div entonces en vez de .//spanen By.xpath("//div[.//span[text()='Close']]")que podemos utilizar *//span, que se verá durante la mayor parte de los padres elemento div del rango dado. Ahora se verá asídriver.findElement(By.xpath("//div[*//span[text()='Close']]"));
Jai Prak

14

Eche un vistazo a los posibles ejes XPath que probablemente esté buscando parent. Dependiendo de cómo encuentre el primer elemento, puede ajustar el xpath para eso.

Alternativamente, puede probar la sintaxis de doble punto , ..que selecciona el padre del nodo actual.


5

Esto podría ser útil para otra persona: Usar este HTML de muestra

<div class="ParentDiv">
    <label for="label">labelName</label>
    <input type="button" value="elementToSelect">
</div>
<div class="DontSelect">
    <label for="animal">pig</label>
    <input type="button" value="elementToSelect">
</div>

Si, por ejemplo, quiero seleccionar un elemento en la misma sección (por ejemplo, div) como etiqueta, puede usar esto

//label[contains(., 'labelName')]/parent::*//input[@value='elementToSelect'] 

Esto sólo significa, busque una etiqueta (Podría algo así a, h2) llamado labelName. Navegue hasta el padre de esa etiqueta (es decir div class="ParentDiv"). Busque dentro de los descendientes de ese padre para encontrar cualquier elemento hijo con el valor de elementToSelect. Con esto, no seleccionará el segundo elementToSelectcon DontSelectdiv como padre.

El truco es que puede reducir las áreas de búsqueda de un elemento navegando primero al padre y luego buscando el elemento que necesita en el descendiente de ese padre. following-sibling::h2En algunos casos también se pueden utilizar otras sintaxis similares . Esto significa el elemento siguiente del hermano h2. Esto funcionará para elementos del mismo nivel, que tengan el mismo padre.


0

Puede hacer esto usando / parent :: node () en el xpath. Simplemente agregue / parent :: node () a los elementos secundarios xpath.

Por ejemplo: Sea xpath del elemento hijo childElementXpath .

Entonces xpath de su antepasado inmediato sería childElementXpath / parent :: node () .

XPath de su próximo antepasado sería childElementXpath / parent :: node () / parent :: node ()

y así..

Además, puede navegar a un ancestro de un elemento usando 'childElementXpath/ancestor::*[@attr="attr_value"]'. Esto sería útil cuando tiene un elemento hijo conocido que es único pero tiene un elemento padre que no se puede identificar de forma única.


0

Podemos seleccionar la etiqueta principal con la ayuda de Selenium de la siguiente manera:

driver.findElement(By.xpath("//table[@id='abc']//div/nobr[.='abc']/../.."));

esto te ayudará a encontrar al abuelo del Elemento conocido. Simplemente elimine uno (/ ..) para encontrar el elemento principal inmediato.

Me gusta:

driver.findElement(By.xpath("//table[@id='abc']//div/nobr[.='abc']/..));

Hay otras formas de implementar esto, pero funcionó bien para mí.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.