Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test javascript hide/show behaviors on authenticated pages?

Context: When a user is logged and consulting his own profile, he can click on his avatar, this click displays a Dropdown menu with an option 'Upload avatar'. When the user clicks on this option, it opens a modal with a form for uploading a new image for the avatar. I am using twitter bootstrap to handle the dropdown (and the modal).

Of course, I want to test this. But I don't know how.

Let's concentrate on the dropdown feature, as the modal tests will probably almost identical :

At first I was thinking of using capybara, but there is no way to check if an element is visible through its CSS property display: none or display: block. I read that some people advices to check for a class like hidden through capybara. But in this case, as I am using Twitter Bootstrap, there is only a dropdown for instance.

And I don't want to modify bootstrap behavior just to be able to test it, it would be a smell.

Here is a sample of my rspec suite :

describe 'should display a dropdown menu' do
   let(:user) { FactoryGirl.create :user }
   before do
     sign_in_as user
     # I have routes just like that: /1/firstname-lastname
     visit(profile_path(id: user.id, first: user.first_name.downcase, last: user.last_name.downcase))

     click_link 'avatar-dropdown'
   end
   it { should have_css('.dropdown-menu', visible: true) }
   describe 'with an upload link' do [...] end
end

The HTML looks like :

<div class="dropdown" id="avatar-menu">
  <a class="dropdown-toggle" id="avatar-dropdown" data-toggle="dropdown" href="#avatar-menu">
    <%= @user.avatar %>
  </a>
  <ul class="dropdown-menu">
    <li><a class="upload-avatar" href="#">Upload an image</a></li>
  </ul>
</div> <!-- #upload-menu -->

Of course, it is not working with visible: true, as the display: none is set by twitter bootstrap's CSS.

Then, I thought about testing this behavior with Jasmine (A good occasion to dive in), but if I do so, how should I register a user ? I don't know if it shares the test database, but I don't think I can use factory girl to generate new users in Jasmine, can I ? I don't even know if visiting the register page in Jasmine (if it is even possible ?) and submitting the form would do the trick. Same with the authentication.

How can I test those behaviors ? Should I use capybara (Is there a trick ?) or Jasmine (What is the way to go, then ?)

Thanks !

like image 858
Gabriel Dehan Avatar asked Mar 06 '26 00:03

Gabriel Dehan


1 Answers

Well, I have managed to get things work with capybara. I am not sure it would work for each and every other case, but in my case it worked :

We need to activate Selenium for Capybara by passing js: true to either describe or it

describe 'should display a dropdown menu', js: true do
   let(:user) { FactoryGirl.create :user }
   before do
     sign_in_as user
     # I have routes just like that: /1/firstname-lastname
     visit(profile_path(id: user.id, first: user.first_name.downcase, last: user.last_name.downcase))

     click_link 'avatar-dropdown'
   end
   it { should have_css('.dropdown-menu', visible: true) }
   describe 'with an upload link' do [...] end
end

This way, capybara seem to really check if the attribute is visible or not. It also launch Firefox every time I run the tests, which can be pretty painful.

like image 143
Gabriel Dehan Avatar answered Mar 07 '26 12:03

Gabriel Dehan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!