I need to test a GET request in sendRequest.js:
$.get( '/test/test2', {name: 'Larry', time: '2pm'} );
This sends the request fine and everything works on the JavaScript end, but obviously returns a 404 (route not found) so I added in app.rb:
get '/test/test2' do
logger.info "this is a test log"
end
I sent the request again, and I got the same 404.
This scenario originates from none of my changes in app.rb going into effect. I've deleted entire routes, commented stuff out, etc., nothing I do in app.rb seems to have any effect on the server.
Any ideas?
Have you tried stopping and restarting the server?
By default Sinatra won't know its code has changed, and Ruby will have loaded all the script into memory and won't look at the file.
Stopping the server, by using Cntrl+C then restarting the server will refresh Ruby's idea of what should be done.
Related
We use Capybara along with Chrome Headless for integration testing. I'd like to write a linter, that checks some metrics on the HTML structure everytime chrome navigates to another page. Then I'd raise an error when something is against our linter.
We have some tests without javascript, and monkey patching rack-test works so far:
Capybara::RackTest::Browser.class_eval do
alias_method :process_orig, :process
def process *args
response = process_orig *args
# do some linting
response
end
end
But I haven't found a way inside Capybara and/or Chrome Headless where I could intercept a response, and check the body of the page.
Is it possible to trigger a hook, when a page changes? Or is there some kind of API Chrome provides where I could get the body of every request? Or would a proxy be a feasible solution?
This isn't possible directly with Capybara, since it doesn't actually know about page transitions/requests that happen in the browser unless they are specifically user initiated with visit.
A potential way to do what you want would be using a programmable proxy like puffing-billy to handle every request to the app under test. If you use puffing-billy you'll want to look at the pass_request feature - https://github.com/oesmith/puffing-billy#in-your-tests-capybarawatir - to forward on the initial request and then do whatever you want with the response.
I'd not tangle capybara tests with HTML linting. It may seem smart at this moment, as you get a list of URL's to check for free with each test, but:
You'd probably lint each URL few times because some tests go through it
You might get failures because HTML is not perfect, even though the feature you're testing is actually ok.
You probably have something like sitemap.xml or other sources of all available URLs. I'd use it to make a separate check, which will be simple: request the URL, lint the response. Rinse and repeat.
If still not convinced, try using page.html and do sth like
expect(page.html).to pass_linter
https://github.com/teamcapybara/capybara#debugging
You can then add it as an around hook for every type: :feature spec if you want.
EDIT: here's another workaround to have every visited path. Just parse the server log file (like this cat log/devlopment.log | grep path) to get a full list if visited paths:
method=POST path=/users/login format=html controller=SessionsController action=create
status=302 duration=256.82 view=0.00 db=52.29 location=http://0.0.0.0:3000/platform/admin/dashboard params={"utf8"=>"✓", "authenticity_token"=>"ubGnWKOq8gbUE5C/aK375QQn5DpjHarUYxHtBLglGe6Lr9Ie3O5XPq90k5gr/SZbIPoDiiasvY0mGlwhzD/MsQ==", "user"=>{"email"=>"alex-3d51048235c9d1a8#toptal.io", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Log in"} uid=983 remote_ip=127.0.0.1 x_forwarded_for= x_request_id=
method=GET path=/admin/dashboard format=html controller=XXX action=show status=200 duration=3285.54 view=1051.32 db=2016.87 params={} uid=983 remote_ip=127.0.0.1 x_forwarded_for= x_request_id=
and use it for linting.
I implemented a longpoll mechanism for my website, which keeps the connection to the client open for upto 30 seconds and only sends an answer if the resource requested changes within these 30 seconds, otherwise it sends status 400.
This is the code I used for the mechanism: (it is part of a Sinatra server)
get '/longpoll' do
state = Array.new( $callbacks )
0.upto 60 do |i|
if $callbacks != state
return json $callbacks
end
sleep 0.5
end
400
end
$callbacks is a global array, which gets changed when new callbacks are posted, or finished callbacks are deleted. My client just needs to dynamically update when new callbacks arrive or old callbacks disappear. On client-side a $.ajax()-Call requests the ressource and updates the website if an answer is received. Otherwise it just continues polling.
When I execute the Sinatra server on its own, everything works fine. The client gets the answers if anything changes, or error '400' after 30 seconds.
But when I start the whole thing using Passenger and Apache2 it always responds with '400' after 30 seconds, regardless if $callbacks changed or not. The rest of my Sinatra code is working fine within Apache2 and Passenger, and when I check the $callbacks object manually it shows the changes. It just does not recognize the change within the if-statement.
I have a modular Sinatra app which runs fine when executed with rackup. The config.ru file is defined as follows:
map '/' do
run My::Controllers::Default
end
map '/api' do
run My::Controllers::Api
end
When I run the app under nginx/passenger I get nothing but 404's, even for the '/' route. Suspecting that something was wrong with routing, I modified config.ru as follows:
run My::Controllers::Default
After restarting nginx, I was served the default page of the app. However, the default page of the app reaches into the api route to get some documentation to display, and that part returns a 404. Given that config.ru is able to run the Default controller, I'm sure that the issue has nothing to do with being able to load all of the relevant ruby files--which seems to be the problem in other related questions I've found on SO.
With that in mind I modified config.ru as follows:
map '/api' do
run My::Controllers::Api
end
run My::Controllers::Default
At this point I'm back to getting nothing but 404's, even for the '/' route. It seems that the map statement is confusing the webserver and making it unable to find the correct routes.
If I just run the app using rackup everything behaves as expected, so I'm really at a loss to explain what I'm seeing.
I remember this being the answer. Let me know if it works for you. If it does I'll "Accept" the answer so that others will find it.
Middleware
A bug in passenger prevents it from understanding the map statement in config.ru https://groups.google.com/forum/#!msg/phusion-passenger/PoEEp9YcWbY/1y0QL_i3tHYJ
class PassengerFix
def initialize(app)
#app = app
end
def call(env)
env["SERVER_NAME"] = env["HTTP_HOST"]
return #app.call(env)
end
end
config.ru
configure do
use PassengerFix
end
I implemented a small jruby sinatra app and if i run it directly on
WEBrick locally all the routings work perfectly. However when I deploy
the war file (i use warbler) to a server instance (like
"example.com/myapp" or "localhost:8080/myapp") I have routing
issues within the post requests.
For example:
get '/login' do
slim :login
end
post '/login' do
session.clear
login_correct? = check_password (params[:user], params[:pass])
if(login_correct?)
session[:user] = params[:user]
redirect to('/')
else
redirect to('/login')
end
end
get '/redirect' do
redirect to('/login')
end
Here the 3rd route handler (get '/redirect' do ..) redirects to
localhost:8080/myapp/login properly with status code 303, however 2nd route handler redirects
to localhost:8080/login with status code 404.
What should i do so that redirections in post route handler works
properly when i deploy the app?
Thanks a lot!
UPDATE on Solution: After checking the code again and again I realized that the problem was me using form action = '/login' in slim:login instead of form action= "#{url('/login')}". So it wasn't even handled by the post route handler since the post request was sent to localhost:8080/login but I thought it was route handler who is redirecting it to there..
try setting set :prefixed_redirects, true with Sinatra
(it should than use rack.env['SCRIPT_NAME'] with redirects)
UPDATE: even without the set :prefixed_redirects, true (default is false) works perfectly fine under Trinidad (which should behave the same as Warbler since bot use JRuby-Rack) ... request.env['SCRIPT_NAME'] is set to the /context_path correctly.
I would try updating (if they're not the latest) JRuby-Rack/Warbler as well as Sinatra as a last resort, otherwise this probably needs a detailed look at what's going on (esp. if SCRIPT_NAME is set correctly).
I'm using Modernizr in one of my projects. I want to test for the existence of placeholder before downloading a polyfill for it. Here's the code I'm using to accomplish this:
yepnope({
test : Modernizr.input.placeholder,
nope : '/js/jquery.placeholder.js',
complete: function(){
$('input, textarea').placeholder();
}
});
I'm experiencing an odd issue with this. It works perfectly when I hit the page without loading any resources from cache, but if I refresh the page, I'm getting an undefined method error for the call to .placeholder().
Looking in the dev tools, an empty jquery.placeholder.js (from the cache) seems to be the culprit. I can verify in Fiddler that the second response is returning a 304, and sending an empty body, which means IE should have the right version in cache, but it is empty somehow. What could cause this behavior?
EDIT: If I add placeholder.js to the head, everything works fine all the time. Just thought I'd point that out.