Back-End

16 nov, 2017

Vida longa ao PhantomJS, vamos usar o Chrome Headless

Publicidade

Se você fizer Feature Specs, o ato de carregar um servidor de aplicativos real e, em seguida, um navegador headless real para fazer testes reais de recursos do usuário, então você conhece Capybara e um dos seus drivers mais conhecidos, o Poltergeist. Poltergeist envolve/acaba com o PhantomJS, que é um conhecido navegador headless baseado em WebKit.

Mas o WebKit é conhecido por ser muito complicado de lidar. Então, eu só posso imaginar o pesadelo para manter o PhantomJS, que é semelhante a um navegador web completo como o Chrome ou o Safari.

Portanto, não é de se admirar que, quando a equipe do Chrome anunciou a disponibilidade do Chrome Driver, o mantenedor do PhantomJS decidiu renunciar.

Se você conhece os colaboradores do PhantomJS, agradeça, pois ajudaram a criar recursos de usuário mais sólidos.

Dito isto, não tenha medo. Você pode substituir facilmente Poltergeist/PhantomJS por Selenium WebDriver/Chrome Driver na sua configuração do RSpec/Capybara.

Meu amigo Lucas Caton escreveu sobre isso em junho deste ano. Siga o blog dele também.

Se você estiver usando o Linux com o navegador Chromium, não precisa instalar nada, pois o Chrome Driver vem com o Chromium. Caso contrário, você precisa instalar os pacotes adequados para o seu sistema operacional. Por exemplo, brew install chromedriver para OS X ou pacaur -S chromedriver no Arch se você não gosta de ter Chromium ao redor. Talvez você precise ajustar seu PATH no Ubuntu.

Regra geral: instale o Chromium.

No meu caso, isso é o que tive que mudar:

# Gemfile
- gem "poltergeist"
+ gem "selenium-webdriver"
+ gem "rspec-retry"

Então, na configuração do Capybara:

Capybara.server = :puma # Until your setup is working
Capybara.server = :puma, { Silent: true } # To clean up your test output

- Capybara.register_driver :poltergeist do |app|
-   options = {
-     timeout: 3.minutes,
-     phantomjs_options: [
-       '--proxy-type=none',
-       '--load-images=no',
-       '--ignore-ssl-errors=yes',
-       '--ssl-protocol=any',
-       '--web-security=false'
-     ]
-   }
-   Capybara::Poltergeist::Driver.new(app, options)
- end
- Capybara.javascript_driver = :poltergeist

+ Capybara.register_driver :chrome do |app|
+   capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
+     chromeOptions: {
+       args: %w[ no-sandbox headless disable-popup-blocking disable-gpu window-size=1280,1024]
+     }
+   )
+ 
+   Capybara::Selenium::Driver.new(app, browser: :chrome, desired_capabilities: capabilities)
+ end
+ 
+ Capybara::Screenshot.register_driver :chrome do |driver, path|
+   driver.save_screenshot(path)
+ end
+ 
+ Capybara.javascript_driver = :chrome

Capybara.default_max_wait_time = 5 # you may want to increase this timeout if your app is heavy to load

Nas especificações de recursos, às vezes o próprio Rails leva muito tempo para carregar, compilar ativos/recursos, etc. E as primeiras especificações dos recursos podem demorar. Para evitar uma falha na execução do teste, recomenda-se adicionar a gema rspec-retry, como fiz acima, e adicionar o seguinte ao seu spec/rails_helper.rb:

require 'rspec/retry'

RSpec.configure do |config|
  ...
  # show retry status in spec process
  config.verbose_retry = true
  # Try twice (retry once)
  config.default_retry_count = 2
  # Only retry when Selenium raises Net::ReadTimeout
  config.exceptions_to_retry = [Net::ReadTimeout]
  ...
end

E isso deveria ser assim. Eu não tive que tocar em nenhuma das minhas especificações de recurso e todas executaram lindamente. Então, parabéns para as respectivas equipes que mantêm Capybara, Selenium-WebDriver por suportar isso.

Se você é um desenvolvedor Node.js, provavelmente usou algo como o Casper, que também diz apoiar o Chrome Headless. Mas enquanto estivermos nisso, você também deveria conferir o Puppeteer, da própria equipe do Google. É uma biblioteca baseada em garantia/promessa onde você pode codificar assim:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({path: 'example.png'});

  await browser.close();
})();

Então, sim, o Chrome Headless parece ser uma opção muito boa, pois a maioria dos usuários realmente usa o navegador Chrome, por isso significa que devemos ter especificações de recursos e também ferramentas de rastreamento web mais confiáveis.

***

Artigo traduzido com autorização do autor. Publicado originalmente em: http://www.akitaonrails.com/2017/10/31/beginner-long-live-phantomjs-let-s-use-chrome-headless-now