#capybara_helper.rb
require 'rails_helper'
require 'capybara/rspec'
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
RSpec.configure do |config|
config.extend FeatureMacros, :type => :feature
Capybara.javascript_driver = :webkit
Capybara.default_wait_time = 10
config.infer_spec_type_from_file_location!
end
J'ai rajouté un fichier spec/capybara_helper.rb à require dans tous les fichiers de test de views.
De cette façon capybara est chargé uniquement là où c'est nécessaire.
Ce capybara_helper est configuré avec le driver :webkit
, ainsi que 10
sec de timeout pour laisser le temps au javascript et partial de s'exécuter / se charger.
#feature_macros.rb
module FeatureMacros
def login_user
user.nil? rescue let(:user) {FactoryGirl.create(:user)}
before(:each) do
visit admin_dashboard_path
button = find("#navigation > ul > li.loginlink > a")
expect(button).to have_content("LOG IN")
button.click
expect(page).to have_content 'Login to Pandasuite'
fill_in('user[email]', with: user.email)
fill_in('user[password]', with: user.password)
click_button('LOGIN')
end
end
end
J'ai aussi rajouté un spec/support/feature_macros.rb.
Toute les methodes de ce fichier seront disponible dans les specs qui héritent de capybara_helper.rb
et qui implementent :type => :feature
.
#dashboard_spec.rb
require 'capybara_helper'
RSpec.describe 'Views::Admin::Dashboard', :type => :feature do
context 'when logged out' do
it 'does redirect to home page', driver: :rack_test do
visit admin_dashboard_path
expect(page).to have_content 'Log in'
end
end
context 'when logged in', :js => true, driver: :webkit do
let(:new_publication) {FactoryGirl.build(:publication)}
login_user # let(:user)...
it 'does connect to the dashboard' do
expect(page).to have_content user.email.upcase
end
it 'does create a first project' do
expect(page).to have_content 'No project yet?'
button_clone = find('body > div > div > div.dashboard-content > div.no-project > div > div.choices > a.scratch')
button_clone.click
expect(page).to have_content 'Create a new project'
fill_in('name', with: new_publication.name)
fill_in('description', with: new_publication.description)
click_button('Create')
expect(page).to have_content new_publication.name.upcase
end
end
end
##Drivers
it 'does redirect to home page', driver: :rack_test do
Je spécifie le driver :rack_test
qui est plus léger est plus rapide que webkit
pour effectuer ce test.
context 'when logged in', :js => true, driver: :webkit do
Je spécifie le driver :webkit
pour tous les test se trouvant dans le context.
:js => true
permet de spécifié à capybara qu'il va y avoir du js à prendre en compte. Dans capybara_helper.rb
je set Capybara.javascript_driver = :webkit
, qui signifie qu'à chaque fois que :js => true
est spécifié :webkit
doit être utilisé.
driver: :webkit
n'est donc pas obligatoire (c'est juste pour montrer que c'est possible).
:rack_test
est le driver par default de capybara. Il est plus léger et plus rapide que :webkit
mais ne supporte pas le javascript.
Les sessions ne sont pas partagé entre drivers. Donc si d'un test à un autre le driver change les sessions sont détruites.
##Code
let(:new_publication) {FactoryGirl.build(:publication)}
Il vaut mieux utiliser let
pour initialiser des variables partagés plutôt que des @
.
Les variables créé avec let
sont lazy-loadé, utiliser let!
pour les loader direct.
def login_user
user.nil? rescue let(:user) {FactoryGirl.create(:user)}
before(:each) do
Si user n'existe pas on en créé un avec let
.
À l'intérieur du before(:each)
se trouve le process pour connecter un user à l'interface admin.
À chaque nouveau it 'does something'
, before(:each)
sera executé et donc le user sera reconnecté à chaque nouveau test.