Esse será um “quick-post” (pretendo fazer mais desses durante o tempo). Basicamente, esses dias eu percebi que meus testes de integração, quando eu usava Capybara com Selenium, falhavam (ou passavam quando não deveriam) e eu não sabia direito o por quê. Para tentar identificar melhor, pensei em identificar aonde o browser estava clicando, quais elementos estavam sendo usados para fazer o “match” da página. Basicamente, eu adicionei um código que, no spec_helper, modifica um pouco o comportamento do Capybara:
module Capybara module Node module Matchers def find(*args) Capybara.page.driver.browser.execute_script %{ try { var element = jQuery('.seleniumHighlighted'); element.css('border', '').css("background", "").css("color", "").removeClass("seleniumHighlighted"); } catch(e) {} } if Capybara.page.driver.browser.respond_to? :execute_script element = super path = '' if element[:id].blank? path = element.tag_name path += ":contains(#{element.text})" unless element.text.blank? path += "[name='#{element[:name]}']" unless element[:name].blank? path += "[value='#{element.value}']" unless element.value.blank? else path = "##{element[:id]}" end Capybara.page.driver.browser.execute_script %{ try { var element = jQuery(#{path.inspect}); element.css('border', '4px double black').css("background", "lightyellow").css("color", "black"). addClass("seleniumHighlighted"); } catch(e) {} } if Capybara.page.driver.browser.respond_to? :execute_script return element end end end end
Explicando-o: reimplemento o método “find”, do Capybara, e antes de fazer qualquer coisa, procuro pelos elementos que eu fiz “highlight” antes (que, nesse caso, eu achei interessante adicionar a classe “seleniumHighlighted”) e removo TODOS os estilos que eu adicionei. Isso, circundado num “try…catch” caso o driver não suporte esse tipo de configuração (lembre-se, estamos re-escrevendo métodos do Capybara, não do Selenium especificamente).
Logo depois, eu chamo “super”, que vai trazer o elemento que o Capybara encontrou. Nas linhas de baixo, eu procuro por todos os parâmetros e crio um “matcher” do jQuery, para depois finalmente adicionar a classe “seleniumHighlighted” e adicionar um estilo específico. Com isso, antes de clicar em qualquer elemento, o browser o exibe com um estilo diferente (no meu caso aqui, com a fonte em preto, o fundo creme, e uma borda dupla ao redor do elemento). Isso é interessante também para testes de aceitação, para o cliente ver aonde está sendo clicado na tela. Serviria, até, como um tutorial, se for feito da forma correta.