Testeando javascript con Steak y Akephalos +
Por Boris Barroso
Saludos de tiempo, quiero decirles que me declaro un fanatico de Steak, es una gema que hace que testear sea mas simple y poderlo combinar con akephalos es algo increible, busque la forma de como hacer funcionar Steak y Akephalos juntos pero lo no lo logre por algún tiempo, ya ahora se como hacerlo, primero les recomiendo de que instalen java para los que usan LINUX ubuntu, debian o mint deben ejecutar
sudo apt-get install curl g++ openjdk-6-jre-headless sudo apt-get install ant openjdk-6-jdk
La segunda linea es opcional ya que funciona con solo instalar la primera linea, ahora debemos instalar akephalos
gem install akephalos
Esta gema tarda un poco en ser instalada pero veran lo interesante que es y como utilizarla para poder correr tests, no voy a dar indicaciones para instalar Steak pero les muestro como debe lucir el Gemfile
source 'http://rubygems.org' gem 'rails', '3.0.5' # Bundle edge Rails instead: # gem 'rails', :git => 'git://github.com/rails/rails.git' gem 'sqlite3-ruby' gem 'steak', :group => :development group :test do gem 'akephalos' gem 'rspec-rails' gem 'steak' gem 'capybara' gem 'database_cleaner' gem 'spork' end
Corremos
bundle install
Corremos los instaladores para rspec y steak
rails g rspec:install rails g steak:install
Y ahora a generar un scaffold y nuestro test
rails g scaffold post title:string body:text publish:boolean rails g rspec:steak javascript
El rspec:steak nos genera un archivo spec/acceptance/javascript_feature_spec.rb y ahora corremos las migraciones
rake db:migrate rake db:migrate RAILS_ENV=test
Y ahora tenemos que hacer las pruebas y modificar el código para que funcione, entonces añadimos lo siguiente para que pueda funcionar el AJAX de forma sincrona en app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>Javascript</title>
<%= stylesheet_link_tag :all %>
<%= javascript_include_tag 'jquery-1.5.1.min' %>
<%= csrf_meta_tag %>
<% if Rails.env == 'test' %>
<script type="text/javascript">
$.ajaxSetup({ async: false });
</script>
<% end %>
<%= yield %>
</body>
</html>
Con esto nos aseguramos que el AJAX de jQuery sea sincrono (No olvides descargar jquery y hubicarlo en public/javascripts).
Ahora a escribir los tests, para esto editamos el archivo app/views/posts/index.html.erb de la siguiente forma:
<h1>Posts</h1>
<%= link_to 'Nuevo Post', new_post_path %>
<table>
<tr>
<th>Título</th>
<th>Contenido</th>
<th>Publcado</th>
<th></th>
</tr>
<% @posts.each do |post| %>
<tr>
<td><%= post.title %></td>
<td><%= post.body %></td>
<td><%= post.published %></td>
<td>
<%= link_to 'Show', post %>
<%= link_to 'Edit', edit_post_path(post) %>
<%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %>
</td>
</tr>
<% end %>
</table>
<hr/>
<br />
<%= link_to "more", "#", :id => 'more_link' %>
<%= link_to "ajax", new_post_path, :id => 'ajax' %>
<div id="more"></div>
<script type="text/javascript">
$('#more_link').live('click', function() {
$('#more').html('this is the content for more');
});
$('#ajax').live('click', function() {
$('#more').load($(this).attr("href"));
return false;
});
</script>
Con esto tenemos el código con dos vínculos, el primero #more_link que añade contenido directamente y despues el vínculo #ajax que hara una llamada AJAX y presentara el contenido de posts/new, ahora debemos realizar los tests pero antes una ultima configuración, añadimos el archivo spec/acceptance/support/javascript.rb con el siguiente contenido
require 'akephalos'
Rspec.configure do |config|
config.before(:each) do
Capybara.current_driver = :akephalos if example.metadata[:js]
#Capybara.current_driver = :selenium #if example.metadata[:js] # Por defecto capybara usa selenium
end
config.after(:each) do
Capybara.use_default_driver if example.metadata[:js]
end
end
Aqui estamos indicando cuando debe usar Capybara javascript indicando que el driver a usar es akephalos, escribamos nuestros test en el al archivo spec/acceptance/javascript_feature_spec.rb
require File.expand_path(File.dirname(__FILE__) + '/acceptance_helper')
feature "First Feature", %q{In order to test ajax I must use akephalos} do
scenario "Scenario name", :js => true do
visit "/posts"
page.should have_css("#more", :text => '')
click_link "more"
page.should have_css("#more", :text => 'this is the content for more')
click_link "ajax"
page.should have_css("#more form")
end
end
Y para correr el test ejecutamos en consola
rspec spec/acceptance/javascript_feature_spec.rb
El código de este post se encuentra en https://github.com/boriscy/akephalos_steak
Muchas gracias. Llevaba unos dias peleandome para hacer que funcionase. Me olvidé de:
$.ajaxSetup({ async: false });