Can I modify Capybara page bodies before the browser receives it? - ruby-on-rails

I have a Rails application with Capybara for feature specs. I have some code that results in a url like this /Users/brandoncc/dev/app/public/uploads/.... This is a special circumstance in the test environment. I need to modify the response body before the browser gets it. Is that possible? I need to cut off the /Users/brandoncc/dev/app/public from image urls.

You have a number of options here - the top 3 are probably
A programmable proxy like puffing-billy
Write a rack middleware class and specify to use it in your config/environments/test.rb via config.middleware.use=
Write a rack app to wrap the app under test which modifies the responses before returning them and assign that to Capybara.app
Any of those approaches should do what you want, but you may be better off just figuring out why the code is putting full paths in the URLs and fix it to use something like the rails asset helpers instead.

Related

How to read or get the request payload headers in the browser using ruby

I managed to write a ruby script which uses capybara (Capybara.current_session.driver.browser.manage.all_cookies) to read the cookie from a browser. I could not find methods to read the complete request headers of a API. Like Method, Content-Type, Accept-language, CSRF etc.
Can someone shed some lights please!
tl;dr; You shouldn't be using Capybara to write API tests
You're using the wrong tool for the job. Capybara is designed to test an application from the users perspective. Since a user doesn't really care about things like headers (just the affect they have in the browser) Capybara doesn't provide them. It's also why you had to go so far down in driver specific methods to get cookies - you really shouldn't be directly accessing those in Capybara driven tests either, just testing the behaviors the cookies control happen.

How do I track the os and browser for each event when using the mixpanel gem?

I am leveraging the mixpanel gem to fire off some events via Rack middleware as opposed the browser-based js constructed events. I know I can do all of this via their js API, but I have cases where it is much easier to fire the event from the controller.
BUT, for some reason none of these events include the user's browser and OS.
The gem documentation (https://github.com/zevarito/mixpanel#usage) seems to indicate that I would need to manually include these:
Additional information contained in your environment (e.g., http_referer) can simply be sent in as attributes where appropriate for your use case.
Is this really the case? If so, what's the best way to do this? Use something like the browser gem (https://github.com/fnando/browser) and then populate the browser and os properties in my events?
The reason the standard HTTP info was not being sent to Mixpanel was because I was not correctly using the Rack Middleware setup. To get it working, I had to
Set the persist: true option on both the Middleware config and when initializing the Mixpanel class. This allows messages to be be sent via js even if there is a redirect (pretty typical on a form submit)
Use the mixpanel.append_track method instead of just mixpanel.track
All of this is present in the gem documentation, it's just not very clear.

What is middleware in Slim Framework?

It says
The Slim Framework implements a version of the Rack protocol. As a
result, a Slim application can have middleware that may inspect,
analyze, or modify the application environment, request, and response
before and/or after the Slim application is invoked.
which means "something" to me. Like, it makes something to some things. Like middle in nowhere. Also it states that it is implementation of Rack protocol, something I have never heard in PHP.
Is there any practical use other than onions? What is the proper name of "middleware" in PHP?
Middlewares, in the Slim philosophy, is simply a sort of reusable and stacked hooks designed to alter the Slim environment progressively.
This is very useful - for example - when you need to authenticate an HTTP request, check if it is an AJAX request and log some data when a response is sent - this can be 3 separate middlewares.
The Rack protocol simply refers to the technology that inspired the author to build the Slim middlewares.

Is there a way to catch all URLs ending in something? maybe regex match a request url, and choose to ignore it?

Reason why I ask, is because there are some crawlers that plague my rails server with invalid requests.
So, I was wondering if it's possible to ignore any URL matching a regex matcher.
Like, wp-admin.php or {{.+}} or something like that?
I'm using rails 2.3.14
You probably don't want such requests reaching rails stack, so I'd suggest offloading work to your web server. However, leveraging rack middleware maybe another viable option. You can either use 3rd party code or write your own custom handler.

How can I test Rack middleware?

I'm writing a middleware that does something like this
Given I am logged in
When I visit home page
Then the request and all of my user information should get logged into CouchDB
This is basically it, the middleware itself isn't that complicated, but I'm having trouble with the workflow.
First thing is, that I have no idea how to test something like this. The feature itself is pretty clear, but how would I go about implementing it? Probably the highest level test that I can do is send a request via curl and then check if it got saved into CouchDB.
The problem is, I'm not really sure at what level should I test this and what types of tests will be most helpful. At the moment I basically hit F5 and take a look in the db if there is a new record.
The app is running on Rails 3.2.2 and I'm using couchrest gem to do the logging.
This seems like the place for integration tests. If the stock rails integration tests bypass your middleware treat it like a rack app and use [ https://github.com/brynary/rack-test ]
This Sinatra tutorial ought to help:
http://www.sinatrarb.com/testing.html
You probably also want to redirect logging for your middleware to the Rails logger in an initializer so you can see what's going on while your tests are running:
My::Awesome::Middleware.logger = Rails.logger

Resources