How to access cookies and session in Capybara 2.4.1 - ruby-on-rails

I'm using rails 4 with the following gems:
guard-rspec (4.3.1)
rspec (3.0.0)
rspec-core (3.0.3)
rspec-expectations (3.0.3)
rspec-mocks (3.0.3)
rspec-rails (3.0.2)
rspec-support (3.0.3)
capybara (2.4.1)
capybara-webkit (1.1.0)
Capybara works as expected in normal scenarios/examples, but when I want access to a cookie or session, I get a NameError:
undefined local variable or method `session'
I have a custom class I'm using that stores cookie data and retrieves it to remember things about the user and then present certain things on the screen.
But I can't seem to get the tests to pass and I can't view the cookie or session.
Does it need to be mocked? How can I do this?

Capybara.current_session.driver.request.session works in 2.17.0. I'm assuming much hasn't changed though since 2.4.

Webkit exposes cookies like this:
page.driver.browser.manage.all_cookies
Reference here: https://github.com/thoughtbot/capybara-webkit/issues/168

Related

Reasons rails is not stopping at debugger

In our application in Ruby on Rails (4.0.2) we've always had this problem. I never understood quite well why the application doesn't stop at the debugger statement sometimes.
In some cases, we discovered some constant behavior such as: in a test, it never stops if the statement's placed at the end of the test block like this:
describe '#some_method' do
it 'should do something as in the requirements etc' do
model_x = FactoryGirl.create(:model_x)
model_x.should be_valid
# ...more code
model_x.should be_valid
debugger
end
end
To make debugger stop at the statement, we have to add a p "foo"
after it.
In some other misterious cases it doesn't stop, but if you add prints before and after, it does.
When debugging a delayed job, you may have to require the debugger and add some prints for it to stop.
I can't find a deterministic reason why the debugger skips the debugger statement sometimes.
Can someone list the reasons for this behavior?
Obs: I'm using byebug right now, but I know that the plain debugger has this behavior too.
Obs2: From my Gemfile.lock:
byebug (2.4.0)
columnize (~> 0.3.6)
debugger-linecache (~> 1.2.0)
...
debugger (1.6.3)
columnize (>= 0.3.1)
debugger-linecache (~> 1.2.0)
debugger-ruby_core_source (~> 1.2.4)
debugger-linecache (1.2.0)
debugger-ruby_core_source (1.2.4)
This is a known issue in the debugger gem, see here (bullet point number three).
It seems that you are interested in why it doesn't work. The following is the explanation:
What debugger does is watching some events provided by ruby that tell the debugger when to stop. In this case, the debugger tracks what we call a line event that is triggered once per line executed, so in the case of the last line of a method, the debugger will stop in the next line event, which actually happens outside the method that is being debugged.
In byebug, however, I also track what we call return events, that are called every time a method finishes. That's why I'm able to stop execution before the method actually finishes.
Hope this helps.

How do I cherry-pick the active_support for 5.seconds?

I want to use the ActiveSupport extensions 3600.seconds syntax in a plain Ruby file but I'm having trouble finding the right ActiveSupport file to require.
As far as I can work out from the guides, I need to require "active_support/core_ext/date/calculations". That doesn't seem to do it though
NoMethodError:
undefined method `seconds' for 3600:Fixnum
In activesupport that goes with Rails 3.1 this extension is in active_support/core_ext/numeric/time. You can see it here.

How to resolve name collision between i18n's Hash#slice and ActiveSupport's Hash#slice

I'm working on a Rails 2.3.14 project, which uses 0.6.0 of the i18n gem and 2.3.14 of the ActiveSupport gem. Both of these define a Hash#slice method (i18n's; ActiveSupport's), but they function differently: the i18n version uses Hash#fetch, and so raises an i18n/core_ext/hash.rb:4:in 'fetch': key not found (IndexError) exception if any requested key is missing, while the ActiveSupport version happily ignores missing keys, and the rest of ActiveSupport depends on that happy ignoring.
In my app, the i18n version is loading first (because, incidentally, faker is loading it as a dependency), so when ActiveSupport tries to depend on the ignore-missing-keys behavior I get the exception.
Is there a way to tell Rails to load ActiveSupport before faker and i18n?
You could also monkey patch the Hash class after the gems are required. You could just paste the contents of ActiveSupport's hash/slice.rb into your app somewhere. The URL can be found here:
https://github.com/lifo/docrails/blob/master/activesupport/lib/active_support/core_ext/hash/slice.rb
That would override the definitions from the gems though, so YMMV.
I used #Eugene's idea of reverting back to ActiveSupport's method (and so he gets the happy green checkmark), but did it in such as way as to avoid duplicating the code. First we test to see if we're using the i18n version, and if we are we use remove_method to wipe it out (it was added by opening the class) and let the ActiveSupport 2.3.14 module fill in (note I didn't use undef, which also wipes out the module's override).
So into an initializer goes the code:
begin
{}.slice(:a) # ActiveSupport's slice is fine with this; i18n's is not
rescue IndexError
class Hash
remove_method :slice #kill i18n's implementation, allow the ActiveSupport module to work
end
end
If you can't control the order of loading, you could try the method in this blog post http://banisterfiend.wordpress.com/2010/11/04/baking-module-methods-into-classes-with-alias_method/
I've used it and it worked for me, but that was with modules I'd written myself.
I've opened an issue on the i18n project to make slice more safe, and created a PR to implement it. You can find the issue / PR at https://github.com/svenfuchs/i18n/pull/292.
To manually patch yourself, you can just add if has_key?(key) after the fetch.

Rails 3.1 RC5 Mountable Engine testing with Spork

I've been able to get RSpec, Cucumber, and Autotest to work against my Rails 3.1 Mountable Engine. Where things fall down is trying to integrate Spork into the mix. Spork runs fine, and my tests use Spork, but the problem I'm having is that Spork doesn't reload models unless I bring down the Spork server which isn't exactly efficient. I'm using factory_girl as well. I tried various things using Spork.trap_method, yet nothing has worked.
Here's the gems I'm using (although I have since abandoned Spork in my project due the grief it was causing me):
rails (3.1.0.rc5)
spork (0.9.0.rc9)
rspec (2.6.0)
rspec-core (2.6.4)
rspec-expectations (2.6.0)
rspec-mocks (2.6.0)
rspec-rails (2.6.1)
factory_girl (2.0.3)
factory_girl_rails (1.1.0)
cucumber (1.0.2)
cucumber-rails (1.0.2)
Thanks,
-Damien
I figured out my problem. It was actually Autotest and not Spork. I've moved from a mountable engine to a standard engine (plugin) since it ended up being a better fit for what I needed.
I'm now using the released version of Rails 3.1.
In this scenario, I figured things would be easier, but I encountered the same issue. Anyway, this ended up being the fix for testing a non-namespaced engine (mountable), although with a few path tweaks, I believe it will work.
Add an .autotest file to the root of the project with the following:
Autotest.add_hook :initialize do |at|
at.add_mapping %r%^app/models/(.*)\.rb$% do |_, m|
"spec/models/#{m[1]}_spec.rb"
end
at.add_mapping %r%^app/controllers/(.*)\.rb$% do |_, m|
["spec/controllers/#{m[1]}_spec.rb",
"spec/functional/#{m[1]}_spec.rb"]
end
at.add_mapping %r%^app/helpers/(.*)_helper.rb% do |_, m|
["spec/views/#{m[1]}_view_spec.rb",
"spec/functional/#{m[1]}_controller_spec.rb"]
end
at.add_mapping %r%^app/views/(.*)/% do |_, m|
["spec/views/#{m[1]}_view_spec.rb",
"spec/functional/#{m[1]}_controller_spec.rb"]
end
end
I came up with the solution when I ran across this answer on another question: how to tell autotest to correctly track changes in app source?, as well as other examples found around the web.
Hope this helps someone else out.
[Edit 2011-09-20]
Fixed the Cucumber/Spork problem with a "hack." Within the Spork.each_run block, I forced a reload of the models and controllers like so:
ENGINE_ROOT=File.join(File.dirname(__FILE__), '../../')
# Couldn't get spork to reload models, hence the reason for this hack
Dir[File.join(ENGINE_ROOT, "app/models/*.rb")].each {|f| load f }
# or controllers...
Dir[File.join(ENGINE_ROOT, "app/controllers/*.rb")].each {|f| load f }
It seems like there should be a better way...

fakefs + paperclip on rails3 + rspec2 will give me an error "cannot generate tempfile"

rails (3.0.1)
fakefs (0.2.1)
paperclip (2.3.4)
rspec (2.0.1)
I am testing my model with rspec.
Since this is a test, I want to prevent any file creations under the public directory as paperclip normally does.
I am thinking this workaround is to use fakefs.
Although I implemented this
http://trevorturk.com/2008/12/11/easy-upload-via-url-with-paperclip/
to be able to save an image from a remote url, if I don't put this line
include FakeFS::SpecHelpers
to activate fakefs in my rspec, it works fine (and DOES create files under public/system..., which I don't want for tests)
if I activate fakefs, for some reasons, I get an error such as
cannot generate tempfile `/tmp/stream20101027-704-adna7o-9.gif'
at the method
def download_remote_image
self.image = do_download_remote_image
^ happening in this method
self.image_remote_url = image_url
end
/tmp permission is drwxrwxrwt, so I think anyone can write on it.
and here are my questions.
Should I not use fakefs to test for paperclip related methods?
Should I not care about the paperclip file creations for such tests? or there are any other ways to solve the problem?

Resources