Introdução ao Selenium 2

Entenda mais sobre Selenium e entenda como ele pode ajudar em aplicações web.

por Igor Ribeiro Lima 18/12/2013 Comentários

Selenium é uma ferramenta de apoio às necessidades de testes em aplicações web. Altamente flexível, permite muitas opções para a localização de elementos de interface no navegador e simular comportamentos reais de um usuário. A versão 2.0 tem como funcionalidade primária a integração da API WebDriver. Projetado para fornecer uma interface ainda mais simples, concisa e orientada a objeto, o que melhora de forma significativa o suporte aos problemas complexos que são enfrentados ao testar uma aplicação web.

Essa API pode ser chamada através de diversas linguagem de programação, porém, em nosso exemplo, iremos utilizar o NodeJS (JavaScript), que pode ser baixado no site oficial e que possui um gerenciador de pacotes (Node Package Manager – NPM), o qual permite a interação com um repositório online via linha de comando, facilitando a instalação de várias outras ferramentas.

Nesse exemplo, será utilizado uma ferramenta chamada Vows, gerenciada e instalada pelo NPM, que ajuda no desenvolvimento orientado a comportamento assíncrono. Usar testes assíncronos no NodeJS tem dois motivos. Primeiro (e talvez óbvio), é que o NodeJS é assíncrono e por isso os testes também deveriam ser. Segundo, é fazer com que os testes, os quais lidam com entrada e saída de dados, rodem mais rápido.

Breve resumo dos conceitos do Vows. Suite: um objeto que contêm um ou mais batches, e pode ser executado ou exportado. Batch: uma estrutura de contextos. Context: um objeto que pode conter um topic(opcional), nenhum ou mais vows, nenhum ou mais sub-contextsTopic: pode ser tanto um valor ou uma função de código assíncrono. Vow: é uma função que recebe o _topic_ como um argumento e roda assertivas no topic.

O teste que será feito possui quatro passos: _(i) abrir o navegador, (ii) acessar uma página de teste(iii) verificar o título da página e (iv)_ fechar o navegador. Algo bem simples. Suficiente para experimentar a versão 2.0 do Selenium.

As dependências necessárias podem ser instaladas usando o NPM, digitando o seguinte _script_ no terminal:

npm install -g phantomjs vows 
 npm install chai wd vows 

Há duas maneiras de instalar dependências no NodeJS: globalmente ou localmente. Quando uma dependência é global, os arquivos são executáveis, tornando possível a utilização de uma dependência através da linha de comando. Quanto às dependências locais, estas são instaladas no diretório corrente, dentro de um diretório chamado _nodemodules.

O primeiro script, utilizando o parâmetro -g, instala duas dependências globais: phantomjs e vows.PhantomsJS é um headless WebKit, feito totalmente em javascript e possui suporte rápido e nativo para vários padrões web como manipulação de DOM, seletores CSS, JSON, Canvas e SVG.

Já o segundo script, instala três dependências locais: chai, wd e vows. Chai é uma biblioteca de assertivas BDD/TDD para NodeJS e navegadores, a qual pode ser ‘graciosamente’ utilizada com qualquer framework de teste JS. WD é um cliente em NodeJS para facilitar o acesso à API do Selenium 2, a qual suporta métodos como: fazer requisições GET e POST, clicar no botão VOLTAR do navegador, fazer refresh no navegador, pegar um printscreen da tela corrente, redimensionar e mover a janela do navegador, submeter formulário, digitar texto, usar cookies, selecionar um elemento DOM, clicar e mover um elemento DOM selecionado, etc.

Após a instalação de todas as dependências necessárias, vamos criar dois arquivos: _configuracao-webdriver-usando-phantom.js com as informações de configurações do webdriver e apenas-um-exemplo.js_ com os passos-a-passos simulando o comportamento real de um usuário.

configuracao-webdriver-usando-phantom.js

var exports   = module.exports = {},
    webdriver = require('wd'),
    browser   = exports.browser = webdriver.remote({
      hostname: "localhost",
      port: 8910
    });
 
/**
Vows Errored » callback not fired
http://birkett.no/blog/2013/05/01/vows-errored-callback-not-fired/
*/
process.on( 'uncaughtException', function(err) {
  console.error('Caught exception: ' + err.stack );
});

apenas-um-exemplo.js

var vows    = require('vows'),
    expect  = require('chai').expect,
    browser = require('./configuracao-webdriver-usando-phantom.js').browser;
 
vows.describe('Apenas um exemplo')
.addBatch({
  'Criando uma nova sessão no WebDriver': {
    topic: function() {
      var callback = this.callback;
      browser.init( {}, function(err, sessionID, capabilities) {
        callback( err );
      });
    },
    'Sessão criada': function() { /**...*/ }
  }
})
.addBatch({
  'Acessando a página de teste do SauceLabs': {
    topic: function() {
      var callback = this.callback;
      browser.get( 'http://saucelabs.com/test/guinea-pig', function(err) {
        callback( err );
      });
    },
    'Página de teste aberta': function() { /**...*/ }
  }
})
.addBatch({
  'Verificando o título da página': {
    topic: function() {
      var callback = this.callback;
      browser.title( function(err, title) {
        callback( err, title );
      });
    },
    "O título da página deve conter 'Sauce Labs'": function(title) {
      expect(title).to.contain('Sauce Labs');
    },
    "O título da página deve conter 'page title'": function(title) {
      expect(title).to.contain('page title');
    },
    "O título da página deve conter 'I am a'": function(title) {
      expect(title).to.contain('I am a');
    }
  }
})
.addBatch({
  'Fechando o navegador': {
    topic: function() {
      var callback = this.callback;
      browser.quit( function(err){
        callback( err );
      });
    },
    'Fim': function() { /**...*/ }
  }
}).export(module);

Criado esses dois arquivos, é preciso, em um outro terminal, rodar o PhantomJS em modo WebDriver, digitando o seguinte comando:

phantomjs --webdriver=localhost:8910 

Uma vez o PhantomJS rodando em segundo plano, basta rodar o vows, o parâmetro –spec serve apenas para ter um diferente tipo de ‘reporter’, segue o comando e uma ilustração do resultado obtido:

vows apenas-um-exemplo.js --spec 

Resultado obtido

Esse exemplo contempla de forma bem simples a utilização da API do WebDriver/Selenium 2. Essa abordagem também pode ser feita em diferentes tipos de navegadores. Como é sempre melhor começarmos aos poucos, aplicando pequenos passos de cada vez, isso ficará para uma próxima discussão. Para quem se interessar, todo código está disponível em um gist. Muito obrigado.