Localizadores relativos en Selenium 4

Saludo, Khabrovsk. En previsión del inicio del curso de Java QA Engineer, hemos preparado una traducción de material interesante para usted.





Localizadores relativos


Selenium 4 nos trajo localizadores relativos - Localizadores relativos (originalmente llamados Localizadores amigables). Esta funcionalidad se ha agregado para ayudarlo a encontrar elementos que están al lado de otros elementos.

Opciones Disponibles:

  • above () : el elemento de búsqueda está por encima del elemento especificado
  • debajo de () : el elemento buscado está debajo del elemento especificado
  • toLeftOf () : el elemento de búsqueda se encuentra a la izquierda del elemento especificado
  • toRightOf () : el elemento de búsqueda se encuentra a la derecha del elemento especificado
  • near () : el elemento que está buscando no se encuentra a más de 50 píxeles del elemento especificado. También hay un método sobrecargado para especificar la distancia.

Todos estos métodos están sobrecargados para aceptar By o WebElement.

Usar localizadores relativos


Usando esta aplicación de librería como ejemplo , queremos verificar que el libro a la izquierda de Advanced Selenium en Java sea Java For Testers. Los localizadores relativos nos permiten hacer esto.


Aquí está el fragmento DOM para los libros


"Selenium avanzado en Java" representado en el DOM por el identificador pid6, y "Java For Testers" por pid5.

Un método WebDriver::findElementpuede tomar un método withTagName()que devuelve un objeto RelativeLocator.RelativeBy(un descendiente de By).

driver.findElement(withTagName("li")


Aquí ya puedo especificar localizadores relativos. Sé que "Java For Testers" está a la izquierda de "Advanced Selenium in Java" (pid6) y está debajo de "Test Automation in the Real World" (pid1). Entonces, puedo señalar de ambos:

driver.findElement(withTagName("li")
                .toLeftOf(By.id("pid6"))
                .below(By.id("pid1")));

Y obtengo Java For Testers (pid5).

@Test
public void test_book5_is_left_of_book6_and_below_book1(){
    String id = driver.findElement(withTagName("li")
            .toLeftOf(By.id("pid6"))
            .below(By.id("pid1")))
            .getAttribute("id");
 
    assertEquals(id, "pid5");
}

Podemos utilizar above()y métodos toRightOf()para encontrar Experiencias de Automatización de Pruebas (PID2):

@Test
public void test_book2_is_above_book6_and_right_of_book1(){
    String id = driver.findElement(withTagName("li")
                    .above(By.id("pid6"))
                    .toRightOf(By.id("pid1")))
            .getAttribute("id");
 
    assertEquals(id, "pid2");
}

¿Cómo funciona?


No pude encontrar "Java For Testers" solo llamando a Izquierda (By.id ("pid6")) . Solo, devolverá Test Automation en el mundo real (pid1). Esto se debe a que driver.findElement()busca desde la raíz del DOM, y el primer elemento a la <li>izquierda de Advanced Selenium en Java es Test Automation in the Real World.

Selenium utiliza la función de JavaScript getBoundingClientRect()para buscar elementos relativos. Esta función devuelve propiedades del elemento, como derecha, izquierda, abajo y arriba.

Al observar las propiedades de estos tres libros, vemos que tanto la Automatización de pruebas en el mundo real (pid1) como Java For Testers (pid5) tienen la misma posición en el eje x.



Por lo tanto, ambos están a la izquierda de Java For Testers, y Test Automation in the Real World (pid1) es el primero que se encuentra.

Otro punto a tener en cuenta son los cambios en las ventanas gráficas de la aplicación. Si ejecuté las pruebas mencionadas anteriormente en mi aplicación en la vista móvil, entonces, naturalmente, habrían fallado porque los libros ya no están a la izquierda / derecha de otros libros:



también tuve un problema con los localizadores amigables cuando intenté usar ellos en esta aplicación ToDo .



Intenté usar el método toLeftOf()para encontrar el interruptor de entrada al lado del elemento "adiós mundo". Visualmente, este interruptor de entrada se encuentra a la izquierda de la etiqueta "adiós mundo". Aquí está este div en el DOM:

<div class="view" data-reactid=".0.1.2.$645c3b67-884e-4e4f-aecd-8f9367e670f8.0">
    <input class="toggle" type="checkbox" data-reactid=".0.1.2.$645c3b67-884e-4e4f-aecd-8f9367e670f8.0.0">
    <label data-reactid=".0.1.2.$645c3b67-884e-4e4f-aecd-8f9367e670f8.0.1">goodbye world</label>
    <button class="destroy" data-reactid=".0.1.2.$645c3b67-884e-4e4f-aecd-8f9367e670f8.0.2"></button>
</div>

Aquí está el código que usé para encontrar el elemento de entrada a la izquierda de la etiqueta:

driver.findElement(withTagName("input")
      .toLeftOf(By.xpath("//label[text()='goodbye world']")))
      .click();

Sin embargo, me encontré con una excepción: parece que aunque esta está a la izquierda de la visual, en realidad no lo está. Llamé a una función para ambos elementos, y en realidad se superponen. Tenga en cuenta que ambos tienen posición x 838, por lo que técnicamente no está a la izquierda de . Y cuando selecciono el elemento , ahora veo que realmente se superpone al elemento . <img src = " habrastorage.org/webt/hj/aa/46/hjaa46ps-of5_hhlplqaldclc7s.png " /

org.openqa.selenium.NoSuchElementException: Cannot locate an element using [unknown locator]

<input><label>getBoundingClientRect()<input><label>



<label><input>


Nota : Esta es una versión alfa de Selenium WebDriver. Hablé con el gerente de proyectos de Selenium, Simon Stewart, y descubrí que la implementación puede cambiar dependiendo de los comentarios.

Eso es todo. ¡Nos vemos en el curso !

All Articles