Capybara prevents attaching onsubmit event to form - capybara

In my rails app I attach onsubmit event to my form using jquery like this:
$("form.my_form").submit(function(){
alert("test")
return true;
});
This is working fine when I manually open the page and submit the form (clicking on the submit button) - I see the alert "test"
BUT I have a Capybara test (over Selenium) that loads the page, fills in some values in the form, and then clicks on submit.
And the function is NOT triggered.
Note 1: when running the test the form is indeed submitted, new values recorded in the DB etc. so there is no problem with clicking on the submit button itself
Note 2: if instead of jquery, in the rails view in the form_for tag I put
html: {onsubmit: "onsubmitfunc();"}
with the alert in the onsubmitfunc() - everything works as expected in the capybara test
Note 3: in order for the jquery way to work the js file is defer loaded e.g.:
<%= javascript_include_tag 'application', defer: true %>
I am very new to JQuery, so am I doing something criminal there?
Or Capybara has some problem? with defer loading of the JS file? Or with JQuery? Any ideas?

Since you're using Selenium - the most common reason would be that you have an error in one of your JS assets. When in the dev environment all your JS assets are served in separate files which means an error in one file doesn't stop others from being processed. In the test environment (and production) the assets are concatenated into one file which means an error in any file can cause assets concatenated after it to not be processed.
Check the browsers console log for any JS errors and fix them.

Related

Javascript code in a Rails partial gets executed every time if placed inside of $(document).ready()

I've got a problem that JS code in my partials (Rails) that is in $(document).ready() gets executed once the partial is displayed and I continue clicking through the page.
I'm using the jquery-turbolinks gem.
If I reload the page, the JS code in partials is not executed anymore (if current view does not contain the partial).
Any ideas? I'd probably have to disable the 'page:load' event that gets added from jquery-turbolinks.
Thanks!
AFAIK to execute JS code on page reload with turbolinks you need to use $(window).bind 'page:change' instead of $(document).ready

CKEditor script does not work on heavy HTML page

I am trying to use the CKEditor gem with Rails 4.0.3. I have setup everything according to the docs, but it does not work.
I have a main project with a page which contains many html elements. In this page CKEditor does not work, and does not give any errors or warnings, neither on server side nor on client side (Javascript).
But when I created a test project, and applied the same settings, it worked!
After a lot of struggling, I finally came to this conclusion:
CKEditor inserts a bit of Javascript after the textarea which is supposed to converted. Here is the code:
//<![CDATA[
if (typeof CKEDITOR != 'undefined') { CKEDITOR.replace('article_body'); }
//]]>
I think the problem is that, on the page with many html elements, the code above is run before the DOM is completey loaded, so it has no effect. But on the other page the DOM loads quickly and the code is run in time.
One thing that validates my assumption is that if I run the Javascript code above in the Chrome Developer tools' console, when the page has been completely loaded, it does work.
I don't know if I am right or not, but supposing I am right, how can I force the code above to run when the DOM is fully loaded?
I found the problem. It is because I moved the
<%= stylesheet_link_tag "application" %>
line to the end of the file, before the closing body tag. This line:
//<![CDATA[
if (typeof CKEDITOR != 'undefined') { CKEDITOR.replace('article_body'); }
//]]>
was executed before any other Javascript files were loaded, so it did nothing.
And the solution:
One way is to move the stylesheet_link_tag line to top of the file (which I don't like).
Another way is to add a CSS class named ckeditor to the textarea which you want to be converted. For example:
= form_for #article do |f|
= f.text_area :body, class: "ckeditor"
This will tell CKEditor to convert that textarea to a WYSIWYG editor.

Using javascript global window variables and integration testing

There's this nifty stackoverflow post on passing variables to Javascript. It echos this railscast episode. The technique works like a charm for configuring a jquery datepicker, but cause all my javascript integration tests to fail.
Here is the code in application.html.erb
<script type="text/javascript">
<%-# commented line -%>
window.sDateFormatLocal = "<%= t 'date.formats.js_date' %>"
</script>
This is a datepicker initialization that uses it
$("input.datepicker").datepicker({
dateFormat: sDateFormatLocal,
onClose: function(value, ui) {
console.log("regular old datepicker");
}
}
It appears to work very well. The only problem, all my integration tests with 'js: true' now fail. Here are the errors I get.
Capybara::Poltergeist::JavascriptError:
One or more errors were raised in the Javascript code on the page:
ReferenceError: Can't find variable: sDateFormatLocal
When I run in browser (Chrome, Firefox) there are no errors or warnings in the console.
For completeness, a typical spec looks like this:
describe "The root" do
it "should load the page and have js working.", :js => true do
visit root_path
page.should have_content "Hello world"
end
end
Is there a setting I am missing to allow variables like this in poltergeist?
If your datepicker function is not in jQuery document ready function or similar methods such as window.onload you'll have trouble.
By default the application.js will be loaded in head, and the JS code in your html.erb later. The html and assets are loaded by browser in parallel, and very likely assets will finish loading at first. If you execute the function right away instead of waiting for document ready, the variable is undefined.
If you missed that, put such code in ready block.
A better practice for exporting server variable is, instead of put it in html body, put it on head before application.js so you won't have any problem on undefined variable.
Just to follow-up on this, in case someone in is debugging a similar problem. It turned out in this case, not every view was using the same template. For instance, the signin screen has a different head. That was causing this not to load in certain circumstances, yet not others, like the ones where my tests were failing. Bottom line, make sure when you replicate your tests, you are doing it exactly as the tests do, like in my case, passing through a signin screen.

How can I get haml to recompile in rails?

I added a div to my haml file:
%section.splunk
.splunk_results Loading splunk data...
that will later be populated by an ajax call. However, it isn't showing up in my html file, even when I restart rails and navigate to that page. My research showed that it should auto-compile when I load the page -- why isn't this so?
EDIT:
The haml file is located at myAppName/client/order_details.haml. The HTML that it should be presumably compiling to is in myAppName/public/templates/order_details.html.
HAML files get interpreted as HTML files using the asset pipeline, which requires that your file be in app/assets.
Additionally, the controller action specifies the file that will be rendered. Take a look at your Rails logs to see what file the action is actually rendering.

Display html file inside iframe

How to display a HTML file from my system in iframe using rails?
I will explain my issue...
I have a view file that has an iframe which calls an action through <iframe src="controller/action?param=somevalue"></iframe> and the action renders a HTML file based on the params.
The HTML file called has reference to stylesheets and javascripts in the format <script type="text/javascript" src="../common/About.js"></script>
When viewed in browser the HTML file displays correctly with the styles and javascript but when viewed in the application the styling and scripts are not working from the external file. On viewing the source code for the external files i get "Unknown action" error.
What is that i am doing wrong in this?
(reacting to yr last comment): you need to specify css and js files in the iframed html page separately. html in an iframe is rendered completely independent from the surrounding page.
This is not a rails-related question imho.
I found the mistake I made. Its because of routes being not defined properly. When I give relative urls in the html file, the rails views assumes the full path to be some thing like src="controller/common/About.js". As there is no action defined by the name common I was getting the Unknown action error. I have redefined my routes and its working fine now.

Resources