domingo, 26 de dezembro de 2010

Rodando testes offline com Selenium e Firefox

O Firefox tem um curioso "recurso" que consiste em colocar o browser em modo "offline" quando o computador se desconecta da rede. Isto se torna um pequeno estorvo quando, por exemplo, se está fora da rede e acessando uma aplicação web local e acaba sendo necessário desmarcar a opção "Work offline". Enfim, todo mundo que usa Firefox e desenvolve para a web já deve ter passado por isto. Até aí, nada demais. O "pequeno estorvo", porém, torna-se um problema real quando se utiliza Selenium com Firefox com o computador desconectado. Aparentemente, isto aqui resolve o problema, que também é possível de ser resolvido manualmente a partir da versão 3.6 do Firefox setando uma variável oculta no Firefox, mas acabaria caindo no antipadrão "works-on-my-machine", pois apenas o meu Firefox funcionaria offline, quando o correto seria que qualquer máquina que rodasse as specs do projeto pudesse fazê-lo sem atropelos.

Tive este problema inicialmente com o Capybara (Ruby) e uma boa alma já havia postado a solução, reproduzida abaixo, que utiliza a API do Capybara para definir a variável network.manage-offline-status, a tal "variável oculta" que citei no parágrafo anterior.

class Capybara::Driver::Selenium
def self.driver
unless @driver
profile = Selenium::WebDriver::Firefox::Profile.new
profile['network.manage-offline-status'] = false
@driver = Selenium::WebDriver.for :firefox, :profile => profile
at_exit do
@driver.quit
end
end
@driver
end
end

Para aplicações Python, há até pouco tempo não tínhamos algo como o Capybara, até que outro grupo de boas almas, o Cobrateam, formado pelos ex-colegas de NSI Hugo Lopes e Gustavo Rezende e mais alguns membros da Globo.com, decidiram fazer algo semelhamnte para Python, o Splinter. Apesar de ser um projeto bastante recente, o Splinter já é um ótimo substituto para boa parte das tarefas do dia-a-dia de quem escreve testes de aceitação. Porém, o Splinter não possui uma API para acessar detalhes e/ou configurar o browser utilizado. Assim, consegui resolver o problema fazendo um hack no Selenium.

from selenium.firefox.firefox_profile import FirefoxProfile
prefs = FirefoxProfile._get_webdriver_prefs()
prefs['network.manage-offline-status'] = 'false'
@staticmethod
def prefs_func():
return prefs
FirefoxProfile._get_webdriver_prefs = prefs_func

Por sinal, o Splinter é um projeto muito legal, vale a pena dar uma olhada e ajudar, nem que seja só falando bem dele no seu blog, como eu fiz aqui :P Give back to open-source!

Update (05/01/2011, 13h50m): Francisco Souza abriu um issue no Splinter para uma API que possibilite customizar o perfil do Firefox no Webdriver, evitando - do ponto de vista do cliente do Splinter - o tipo de acesso de baixo nível mostrado aqui.