Temos usado o selênio com grande sucesso para lidar com testes de sites de alto nível (além de extensos doctests em Python em nível de módulo). No entanto, agora estamos usando extjs para muitas páginas e está sendo difícil incorporar testes Selenium para componentes complexos como grades.
Alguém teve sucesso ao escrever testes automatizados para páginas da web baseadas em extjs? Muitas pesquisas no Google encontram pessoas com problemas semelhantes, mas poucas respostas. Obrigado!
unit-testing
extjs
selenium
web-testing
mm2001
fonte
fonte
Respostas:
O maior obstáculo em testar ExtJS com Selenium é que ExtJS não renderiza elementos HTML padrão e o Selenium IDE irá ingenuamente (e corretamente) gerar comandos direcionados a elementos que atuam apenas como decoração - elementos supérfluos que ajudam ExtJS com toda a área de trabalho- aparência e sensação. Aqui estão algumas dicas e truques que reuni enquanto escrevia um teste Selenium automatizado em um aplicativo ExtJS.
Dicas Gerais
Localizando Elementos
Ao gerar casos de teste Selenium gravando as ações do usuário com Selenium IDE no Firefox, o Selenium baseará as ações registradas nos ids dos elementos HTML. No entanto, para a maioria dos elementos clicáveis, ExtJS usa ids gerados como "ext-gen-345" que provavelmente mudarão em uma visita subsequente à mesma página, mesmo se nenhuma alteração de código tiver sido feita. Depois de registrar as ações do usuário para um teste, é necessário um esforço manual para passar por todas as ações que dependem dos IDs gerados e substituí-los. Existem dois tipos de substituições que podem ser feitas:
Substituindo um Localizador de Id por um Localizador CSS ou XPath
Os localizadores CSS começam com "css =" e os localizadores XPath começam com "//" (o prefixo "xpath =" é opcional). Os localizadores CSS são menos detalhados e mais fáceis de ler e devem ser preferidos aos localizadores XPath. No entanto, pode haver casos em que os localizadores XPath precisam ser usados porque um localizador CSS simplesmente não pode cortá-lo.
Executando JavaScript
Alguns elementos requerem mais do que simples interações mouse / teclado devido à complexa renderização realizada pelo ExtJS. Por exemplo, um Ext.form.CombBox não é realmente um
<select>
elemento, mas uma entrada de texto com uma lista suspensa separada que está em algum lugar na parte inferior da árvore do documento. Para simular adequadamente uma seleção de ComboBox, é possível primeiro simular um clique na seta suspensa e depois clicar na lista que aparece. No entanto, localizar esses elementos por meio de localizadores CSS ou XPath pode ser complicado. Uma alternativa é localizar o próprio componente ComoBox e chamar métodos nele para simular a seleção:No Selenium, o
runScript
comando pode ser usado para realizar a operação acima de uma forma mais concisa:Lidando com AJAX e renderização lenta
Selenium tem sabores "* AndWait" para todos os comandos para aguardar o carregamento da página quando uma ação do usuário resulta em transições de página ou recarregamentos. No entanto, como as buscas AJAX não envolvem carregamentos de página reais, esses comandos não podem ser usados para sincronização. A solução é fazer uso de dicas visuais como a presença / ausência de um indicador de progresso AJAX ou a aparência de linhas em uma grade, componentes adicionais, links etc. Por exemplo:
Às vezes, um elemento aparecerá somente após um determinado período de tempo, dependendo da rapidez com que ExtJS renderiza os componentes após uma ação do usuário resultar em uma mudança de visualização. Em vez de usar atrasos arbitrários com o
pause
comando, o método ideal é esperar até que o elemento de interesse esteja ao nosso alcance. Por exemplo, para clicar em um item depois de esperar que ele apareça:Depender de pausas arbitrárias não é uma boa ideia, pois as diferenças de tempo que resultam da execução dos testes em navegadores diferentes ou em máquinas diferentes tornarão os casos de teste instáveis.
Itens não clicáveis
Alguns elementos não podem ser acionados pelo
click
comando. É porque o ouvinte de evento está realmente no contêiner, observando os eventos do mouse em seus elementos filho, que eventualmente borbulham para o pai. O controle da guia é um exemplo. Para clicar em uma guia, você deve simular ummouseDown
evento no rótulo da guia:Validação de Campo
Os campos do formulário (componentes Ext.form. *) Que possuem expressões regulares ou vtypes associados para validação irão acionar a validação com um certo atraso (veja a
validationDelay
propriedade que é definida como 250ms por padrão), após o usuário inserir o texto ou imediatamente quando o campo perder foco - ou desfoca (veja avalidateOnDelay
propriedade). Para acionar a validação de campo após emitir o comando type Selenium para inserir algum texto dentro de um campo, você deve fazer o seguinte:Validação com atraso de disparo
ExtJS dispara o cronômetro de atraso de validação quando o campo recebe eventos de ativação. Para acionar esse temporizador, simplesmente emita um evento de keyup fictício (não importa qual tecla você usa, pois ExtJS o ignora), seguido por uma pequena pausa que é mais longa do que o validationDelay:
Validação Imediata de Gatilho
Você pode injetar um evento de desfoque no campo para acionar a validação imediata:
Verificando os resultados da validação
Após a validação, você pode verificar a presença ou ausência de um campo de erro:
Observe que a verificação "display: none" é necessária porque uma vez que um campo de erro é mostrado e precisa ser escondido, ExtJS irá simplesmente ocultar o campo de erro em vez de removê-lo totalmente da árvore DOM.
Dicas para elementos específicos
Clicar em um Ext.form.Button
Opção 1
Comando: clique em Destino: css = botão: contém ('Salvar')
Seleciona o botão pela legenda
opção 2
Comando: clique em Destino: css = # botão salvar-opções
Seleciona o botão por seu id
Selecionando um valor de um Ext.form.ComboBox
Primeiro define o valor e, em seguida, dispara explicitamente o evento select caso haja observadores.
fonte
Esse blog me ajudou muito. Ele escreveu muito sobre o assunto e parece que ainda está ativo. O cara também parece apreciar um bom design.
Ele basicamente fala sobre como enviar javascript para fazer consultas e usar o método Ext.ComponentQuery.query para recuperar coisas da mesma maneira que você faz em seu aplicativo ext internamente. Dessa forma, você pode usar xtypes e itemIds e não precisa se preocupar em tentar analisar qualquer uma das coisas malucas geradas automaticamente.
Achei este artigo em particular muito útil.
Posso postar algo um pouco mais detalhado aqui em breve - ainda estou tentando entender como fazer isso corretamente
fonte
Tenho testado meu aplicativo da web ExtJs com selênio. Um dos maiores problemas era selecionar um item na grade para fazer algo com ele.
Para isso, escrevi o método auxiliar (na classe SeleniumExtJsUtils, que é uma coleção de métodos úteis para facilitar a interação com ExtJs):
e quando eu precisasse selecionar uma linha, eu apenas chamaria:
Para que isso funcione, preciso definir meu id na grade e não deixar ExtJs gerar o seu próprio.
fonte
Para detectar que o elemento está visível, você usa a cláusula:
not(contains(@style, "display: none")
É melhor usar isto:
fonte
Você pode fornecer mais informações sobre os tipos de problemas que está tendo com o teste extjs?
Uma extensão do Selenium que considero útil é waitForCondition . Se o seu problema parece ser com os eventos Ajax, você pode usar waitForCondition para esperar que os eventos aconteçam.
fonte
As páginas da web Ext JS podem ser complicadas de testar, por causa do HTML complicado que acabam gerando como nas grades Ext JS.
O robô HTML5 lida com isso usando uma série de práticas recomendadas para pesquisar e interagir com segurança com componentes com base em atributos e condições que não são dinâmicos. Em seguida, ele fornece atalhos para fazer isso com todos os componentes HTML, Ext JS e Sencha Touch com os quais você precisaria interagir. Ele vem em 2 sabores:
Por exemplo, se você deseja encontrar a linha da grade Ext JS contendo o texto "Foo", pode fazer o seguinte em Java:
... e você poderia fazer o seguinte em Gwen:
Há muita documentação para Java e Gwen sobre como trabalhar com componentes específicos do Ext JS. A documentação também detalha o HTML resultante para todos esses componentes Ext JS, que também podem ser úteis.
fonte
Dicas úteis para buscar grade via Id de grade na página: Acho que você pode estender a função mais útil desta API.
fonte
Teste mais fácil por meio de atributos de dados HTML personalizados
Da documentação do Sencha :
Substituindo o
Ext.AbstractComponent
'sonBoxReady
método, eu definir um atributo de dados personalizado (cujo nome vem do meu costumetestIdAttr
propriedade de cada componente) para o componenteitemId
de valor, se ele existir. Adicione aTesting.overrides.AbstractComponent
classe ao arrayapplication.js
do seu arquivorequires
.Este método fornece aos desenvolvedores uma maneira de reutilizar um identificador descritivo em seu código e ter esses identificadores disponíveis cada vez que a página é renderizada. Chega de pesquisar ids não descritivos e gerados dinamicamente.
fonte
Estamos desenvolvendo uma estrutura de teste que usa selênio e encontramos problemas com extjs (já que é a renderização do lado do cliente). Acho útil procurar um elemento assim que o DOM estiver pronto.
fonte
Para UI complexa que não é HTML formal, xPath é sempre algo com que você pode contar, mas um pouco complexo quando se trata de implementação de UI diferente usando ExtJs.
Você pode usar Firebug e Firexpath como extensões do firefox para testar o xpath de um determinado elemento e simplesmente passar o xpath completo como parâmetro para o selênio.
Por exemplo em código java:
fonte
Quando eu estava testando o aplicativo ExtJS usando o WebDriver, usei a próxima abordagem: procurei o texto do campo por rótulo e obtive o
@for
atributo do rótulo. Por exemplo, temos um rótuloE precisamos apontar algumas informações para o WebDriver:
//input[@id=(//label[contains(text(),'Name Of Needed Label')]/@for)]
.Então, ele pegará o id do
@for
atributo e o usará posteriormente. Este é provavelmente o caso mais simples, mas fornece a maneira de localizar o elemento. É muito mais difícil quando você não tem rótulo, mas então você precisa encontrar algum elemento e escrever seu xpath procurando por irmãos, elementos descendentes / ascendentes.fonte