Localizadores relativos em Selenium 4

Saudação, Khabrovsk. Antes do início do curso Java QA Engineer, preparamos para você uma tradução de material interessante.





Localizadores relativos


O Selenium 4 nos trouxe localizadores relativos - Localizadores Relativos (originalmente chamados Localizadores Amigáveis). Essa funcionalidade foi adicionada para ajudá-lo a encontrar itens próximos a outros itens.

Opções disponíveis:

  • above () : o item de pesquisa está acima do item especificado
  • below () : o item pesquisado está abaixo do item especificado
  • toLeftOf () : o item de pesquisa está localizado à esquerda do item especificado
  • toRightOf () : o item de pesquisa está localizado à direita do item especificado
  • near () : o item que você está procurando não está localizado a mais de 50 pixels do item especificado. Há também um método sobrecarregado para especificar a distância.

Todos esses métodos estão sobrecarregados para aceitar Por ou WebElement.

Usando localizadores relativos


Usando este aplicativo de livraria como exemplo , queremos verificar se o livro à esquerda do Advanced Selenium em Java é Java For Testers. Localizadores relativos nos permitem fazer isso.


Aqui está o fragmento DOM dos livros


"Advanced Selenium in Java" representado no DOM pelo identificador pid6 e "Java For Testers" por pid5.

Um método WebDriver::findElementpode usar um método withTagName()que retorna um objeto RelativeLocator.RelativeBy(um descendente de By).

driver.findElement(withTagName("li")


Aqui já posso especificar localizadores relativos. Eu sei que “Java For Testers” está à esquerda de “Advanced Selenium in Java” (pid6) e está abaixo de “Test Automation in the Real World” (pid1). Então, posso apontar de ambos:

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

E recebo o 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 usar above()e métodos toRightOf()para encontrar Experiências de automação de teste (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");
}

Como funciona?


Não consegui encontrar o "Java For Testers" apenas chamando toLeftOf (By.id ("pid6")) . Sozinho, ele retornará a Automação de Testes no Mundo Real (pid1). Isso ocorre porque ele driver.findElement()pesquisa na raiz do DOM e o primeiro item à <li>esquerda do Advanced Selenium em Java é a Automação de Testes no Mundo Real.

O Selenium usa a função JavaScript getBoundingClientRect()para procurar elementos relativos. Essa função retorna propriedades do elemento, como direita, esquerda, inferior e superior.

Observando as propriedades desses três livros, vemos que a Automação de Testes no Mundo Real (pid1) e o Java For Testers (pid5) têm a mesma posição do eixo x.



Portanto, ambos estão à esquerda do Java For Testers, com a Automação de Testes no Mundo Real (pid1) sendo a primeira encontrada.

Outro ponto a ser lembrado são as alterações nas viewports do aplicativo. Se eu fizesse os testes mencionados acima no meu aplicativo na visualização para dispositivos móveis, naturalmente eles teriam falhado porque os livros não estão mais à esquerda / direita de outros livros:



também encontrei um problema com localizadores amigáveis ​​ao tentar usar eles neste aplicativo ToDo .



Tentei usar o método toLeftOf()para encontrar a chave de entrada ao lado do elemento "adeus mundo". Visualmente, essa chave de entrada está localizada à esquerda do rótulo "adeus mundo". Aqui está esta div no 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>

Aqui está o código que eu usei para encontrar o elemento de entrada à esquerda do rótulo:

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

No entanto, deparei-me com uma exceção: parece que, embora esta esteja à esquerda da visual, na realidade não está. Chamei uma função para esses dois elementos, e eles realmente se sobrepõem. Observe que os dois têm a posição x 838, portanto tecnicamente não à esquerda de . E quando seleciono o elemento , agora vejo que ele realmente se sobrepõe ao 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 é uma versão alfa do Selenium WebDriver. Falei com o gerente de projeto do Selenium, Simon Stewart, e descobri que a implementação pode mudar dependendo do feedback.

Isso é tudo. Vejo você no curso !

All Articles