Capybara not rendering .js.erb - ruby-on-rails

Hi: I've been stuck on this test using Capybara for some days now and can't work out a solution.
Have some DOM modification to be performed using AJAX, long story short:
1) My ajax event triggers the request successfully:
$.ajax({ url: 'nice_url', data: data, complete: function() {debugger}
});
2) The controller receives the request just fine:
def update_dom
<other stuff>
respond_to do |format|
format.js
end
end
3) IMPORTANT: the file update_dom.js.erb is correctly rendered in DEV environment but NOT in the test using Capybara + RSpec.
update_dom.js.erb:
debugger; //first line, breakopint no stopp in Test
<% unless %W(boolean datetime).include?(#operators[:type])%>
$.each($('.values'), function(i, valueField){
<other stuff, etc...>
This is actually the whole issue and will appreciate any thoughts on it

I had an error on my *.js.erb file which was not being reflected on the developers' console stack trace. I was able to debug it using following guide (used plain firefox instead of firebug but still worked): solution

Related

File download feature in grails application

I am looking to create a file on the fly and offer a download link to the user in a GRAILS application.
I followed the approach from here. I have no errors however it doesn't seem to work. Here's my controller code.
`render (file: pptFile, fileName:'someppt.pptx', contentType: 'application/octet-stream')
Client side code makes an AJAX call to retrieve the file from server. It does not cause the server to force downloading of the file on the client (browser). Here's the client side code.
$.ajax({
type : 'POST',
url : '<<URL>>',
success: function(result) {
var uri = 'data:application/octet-stream;charset=UTF-8,' +
encodeURIComponent(result);
window.open(uri, 'somePPT.pptx');
},
failure: function(){
alert ('failure')
}
});
Perhaps something akin to this (paraphrased, but used for downloading a json file):
def someControllerMethod() {
def dlContent = someService.marshalJson()
def contentType = "application/octet-stream"
def filename = "someFilename.json"
response.setHeader("Content-Disposition", "attachment;filename=${filename}")
render(contentType: contentType, text: dlContent as JSON)
}
okay. So I finally got this to work. As proposed by #railsdog and many others (This problem has been discussed on other threads in stackoverflow but the specific case I had was slightly different from those) I ended up writing to response directly from server and took out the AJAX call. The only reason I was doing an AJAX call was because I did not want to submit the current page that had the "generate file" functionality (There are many data elements on the page and I did not want to re-do the entire page just for downloading the file). So I ended up using an anchor tag with target as "_blank". Here's the code snippet
<a href="myControllerMethodToGenerateFileAndWriteToHTTPResponseDirectlyAsSuggestedByOthersInThisPost"
target="_blank"/>
This actually opened a new page and did the submission to initiate the download. Problem solved. It's working fine in CHROME. :) Thanks guys!
I like the solution using the render method from #railsdog !
A slightly other approach which I used so far was:
def controllerMethod() {
...
File file = sepaXmlService.createTransfersFile(...)
response.setContentType("application/xml")
response.setHeader("Content-disposition", "attachment;filename=${file.getName()}")
OutputStream out = response.getOutputStream()
out.write(file.bytes)
out.close()
file.delete()
return
...
}
In the view I use the following statement in the form:
<g:actionSubmit action="controllerMethod" class="btn" value="Get XML!" /></td>
I think it should also be possible to use a
<g:link controller="foobar" action="controllerMethod" class="btn">GetXML</g:link>

Rails controller renders JSON in browser

I have a simple controller that I have responding to both html and json. I'm using the json response for a Backbone app. Everything works as expected, except that when I click a link that uses the show method, and then click the back button, the index method just prints a big string of JSON into the browser. If I refresh, it displays HTML as expected. Here's the controller.
class RecipesController < ApplicationController
def index
#user = User.find(params[:user_id])
#recipes = Recipe.all
respond_to do |format|
format.html
format.json { render json: Recipe.where(user_id: params[:user_id]).featured }
end
end
...
end
I tried adding a check for response.xhr?, and only rendering JSON if it was an AJAX request, but that didn't work.
Edit
This is a Rails 3 app not utilizing turbolinks.
Edit 2
Here is the relevant Backbone code.
# app/assets/javascripts/collections/recipe_list_.js.cofee
#App.Collections.RecipeList = Backbone.Collection.extend
url: ->
"/users/#{#userId}/recipes"
model: window.App.Models.Recipe
initialize: (opts) ->
#userId = opts.userId
# app/assets/javascripts/app.js.coffee
$ ->
urlAry = window.location.href.split('/')
userId = urlAry[urlAry.length - 2]
App = window.App
App.recipeList = new App.Collections.RecipeList(userId: userId)
App.recipeListView = new App.Views.RecipeListView
If you're referring to a chrome and turbolinks issue, then an easy fix is to disable caching on ajax requests:
$.ajaxSetup({cache: false})
you could try using /recipes.html
and /recipes.json
and /recipes/1.html and /recipes/1.json
instead of relying on backbone and history to always send the correct headers
I bet it's due to turbolink, or ajax based page rendering (backbone, remote=true, ...)
I always disable turbolink and keep control over which links are remote=true, and for all ajax response I insert this javascript line at the end
history.pushState(null, '', '/the/requested/url' );
If you don't want to manually implement this line for each of your link responses, you can wrap it in an ajax:complete event (more info), and I assume turbolink has an event you can use as well.
Second part of the trick is to bind popstate so when your users click on the "back" button the page will be refreshed from the server (through the url that was pushState-ed earlier) and the ajax/js/json/whatever response won't be displayed anymore.
setTimeout( function () {
$(window).bind('popstate', function () {
window.location = location.href;
});
}, 500);
As you see I wrap the popstate event binding in a setTimeout, because if you don't do that you may have trouble with some browser that would infinitely refresh the page.
Are you using Chrome? if so this is a known issue. When you hit the back button chromes serves the page from cache since what was returned was json that is what it dumps on the screen. This post has some suggested workarounds
https://code.google.com/p/chromium/issues/detail?id=108766

Allowing POST method to an HTML page in ASP.NET MVC

Allowing POST method to an HTML page in ASP.NET MVC
I am using ASP.NET with MVC 5.2 and I am integrating RoxyFileManager to my CKEditor.
The integration was fine, the problem is when I try to upload some file to my web server, I got this error:
NetworkError: 405 Method Not Allowed - http://localhost:35418/FileManager/index.html?...
The RoxyFileManager uses the POST method to upload the file and my webserver does not accept it. I can't figure out how can I fix it.
If I put manually an image to my directory I can see it in the file manager, also I can create and exclude folders there.
To clarify my question: I want to know how can I make my webserver accept the POST method to a HTML page, just it. All the relevant information are above. I have a HTML page and want to make it accept POST.
#UPDATE:
I've figured out the problem is a browser issue.
In Google Chrome everything works fine;
In Firefox I get the error above;
In IE things seens to work fine, but it have cache problems (I can upload and edit previously sent files, but I can't see the changes neither the recent file uploads until cache expires);
I'll work on these problems and post the answer here, if successful.
To solve the IE bug it's simple but it's hard-work: You need to add in every ajax call of RoxyFileMan the line cache: false. You need to do it in every .js file on the RoxyFileMan folder.
Example:
$.ajax({
url: d, dataType: "json", async: true, success: function (h) {
for (i = 0; i < h.length; i++) { e.push(new File(h[i].p, h[i].s, h[i].t, h[i].w, h[i].h)) }
g.FilesLoaded(e)
},
error: function (h) { alert(t("E_LoadingAjax") + " " + d) },
cache: false
})
With this, all the ajax made by Roxy will have no cache, solving the IE issue.
To solve the Firefox bug I've changed this in the main.min.js:
BEFORE:
document.forms.addfile.action = RoxyFilemanConf.UPLOAD
AFTER:
$('form[name="addfile"]').attr('action', RoxyFilemanConf.UPLOAD);
I've found this solution here.
And now my file manager is working on all modern browsers.

Testing AngularJS controllers using expectPOST

I've got a AngularJS/Rails app and I want to test my AngularJS controller is posting to the backend server when creating a new record. (I'm using jasmine for my tests)
Here is my attempted test
describe "create", ->
beforeEach(inject ( ($controller, $rootScope, $location, $state, $httpBackend) ->
#redirect = spyOn($location, 'path')
#httpBackend.whenGET('/assets/layouts/default.html.erb').respond(200)
#httpBackend.whenGET('/assets/letters/index.html.erb').respond(200)
#httpBackend.whenPOST('/api/letters').respond(200)
$controller("LettersController", { $scope: #scope, $location: #location })
))
it "sends a post to the backend", ->
#httpBackend.expectPOST('/api/letters', {"letter":{},"_utf8":"☃"}).respond(200)
#scope.create()
Here s the code which I'm testing:
$scope.create = ->
Letter.save(
{}
,
letter:
subject: $scope.letter.subject
body: $scope.letter.body
# success
, (response) ->
$location.path "/letters"
# failure
, (response) ->
)
The code in question works correctly and the test passes. The problem is if I comment my Letter.save code out (which makes the post through AngularJS resources) then my test still passes.
How can I get my test to work properly?
My full test application is here: https://github.com/map7/angularjs_rails_example2
You need to verify that there are no outstanding requests at the end of your tests:
$httpBackend.verifyNoOutstandingRequest();
You also need to verify that there are no outstanding expectations with $httpBackend.verifyNoOutstandingExpectation
This should prevent you from getting false positives I believe.
Also, I'm not sure that your expectPOST should return true because you don't seem to be sending "_utf8":"☃", however I haven't looked at the full source code so I could be missing something.
I would try to trim down the example so that your create method calls a route and you expect that route to be called and work from there. You might try removing the whenPOST and replace the expectPOST with #httpBackend.expectPOST('/api/letters').respond(200)

ajax request in rails 2 not working

function ajaxRequest(){
$.ajax({
type: 'GET',
url: 'client/orders/send_mail_to_notaries',
data: { subject: "hi" }
});
return false;
}
It doesn't pass any params in controller.Can any one trigger this out?
Following the question that you have asked today morning page.replace_html method in rails 2 i guess you are using prototype.
Can you check if jQuery is included? Unless jQuery is included this ajax request will not work.
I just tried the method you're using and it worked for me. Perhaps there's a problem with the router/controller?
When debugging ajax it's very handy to use the Chrome developer toolbar. Bring it up, run the javascript and see what happens.
To see the response from the server you can then flip to the Network tab to see what the response is.

Resources