Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get my jasmine tests fixtures to load before the javascript considers the document to be "ready"?

I am fairly certain that the issue is that the jquery bindings set to run on $(document).ready do not have the fixture html available to them. So when my events occur that are intended to make a change to the DOM via a jquery function, nothing happens, and my tests fail. I saw a "solution" to this problem here, but that solution which did work for me, required changing my working jquery function to bind with the .live method instead of the .click method. I have two issue with this. First I do not want to have to change my working code so that the tests will pass properly. The testing framework ought to test whether the code will work in the app, where the DOM load and the javascript bindings occur in the correct order. The second issue I have with the solution is that .on and .delegate both did not work for some reason and the only thing that ended up working was to use the .live method which is currently in the process of being deprecated. In conclusion, I would like to figure out how to change either my tests or the testing framework itself, such that the fixtures are loaded before the functions that run in $(document).ready.

I am working with rails 3.2.8 and I have two different branches set up to experiment with jasmine testing. One of the branches uses the jasminerice gem and the other uses the jasmine-rails gem. The Javascript and jQuery(when using the .live method) tests all pass properly in both of these set-ups.

Here is a description of the branch using jasminerice:

Here are the lines from my Gemfile.lock file describing the jasmine and jQuery set-up:

jasminerice (0.0.9)
  coffee-rails
  haml
jquery-rails (2.1.3)
  railties (>= 3.1.0, < 5.0)
  thor (~> 0.14)

Jasminerice includes the jasmine-jquery extension by default. The jasmine-jQuery extension provides the toHaveText method I am using in the tests.

The test file jasmine_jquery_test.js which is located directly within the spec/javascripts directory contains this content:

#= require application

describe ("my basic jasmine jquery test", function(){

    beforeEach(function(){
        $('<a id="test_link" href="somewhere.html">My test link</a>').appendTo('body');
    });

    afterEach(function(){
        $('a#test_link').remove();
    });

    it ("does some basic jQuery thing", function () {
        $('a#test_link').click();
        expect($("a#test_link")).toHaveText('My test link is now longer');
    });

    it ("does some the same basic jQuery thing with a different trigger type", function () {
        $('a#test_link').trigger('click');
        expect($("a#test_link")).toHaveText('My test link is now longer');
    });

});
describe ('subtraction', function(){

    var a = 1;
    var b = 2;

    it("returns the correct answer", function(){
        expect(subtraction(a,b)).toBe(-1);
    });

});

My javascript file tests.js which is located in the app/assets/javascripts dir has this content:

function subtraction(a,b){
    return a - b;
}

jQuery (function($) {
/* 
    The function I would rather use - 
    $("a#test_link").click(changeTheTextOfTheLink)
    function changeTheTextOfTheLink(e) {
        e.preventDefault()
        $("a#test_link").append(' is now longer');
    }
*/

    $("a#test_link").live('click', function(e) {
        e.preventDefault();
        $("a#test_link").append(' is now longer');
    });

});

My application.js file located in the same app/assets/javascripts dir has this content:

//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require vendor
//= require_tree . 

And the description of the jasmine-rails branch can be found in the content of my first jasmine test related stackoverflow question.

So if anyone has an idea how to manipulate the tests such that the $(document).ready functions are run after the fixtures are loaded I would very much like to hear your thoughts?

like image 899
Rebekah Waterbury Avatar asked Oct 03 '12 19:10

Rebekah Waterbury


2 Answers

Adding the jQuery directly to the html fixture worked for me to get the desired behavior. It is not exactly an answer to this question, but I am starting to believe it's the best solution currently available. My changes where made in the jasmine-rails gem set-up and I haven't yet tried it in the jasminerice branch.

Here is my test file:

describe ("my basic jasmine jquery test", function(){

    beforeEach(function(){
        loadFixtures('myfixture.html');
    });

    it ("does some basic jQuery thing", function () {
        $('a#test_link').click();
        expect($("a#test_link")).toHaveText('My test link is now longer');
    });

    it ("does the same basic jQuery thing with a different event initiation method", function () {
        $('a#test_link').trigger('click');
        expect($("a#test_link")).toHaveText('My test link is now longer');
    });

});
describe ('substraction', function(){

    var a = 1;
    var b = 2;

    it("returns the correct answer", function(){
        expect(substraction(a,b)).toBe(-1);
    });

});

And here is my fixture file:

<a id="test_link" href="somewhere.html">My test link</a>

<script>
    $("a#test_link").click(changeTheTextOfTheLink)
    function changeTheTextOfTheLink(e) {
        e.preventDefault()
        $("a#test_link").append(' is now longer');
    }
</script>
like image 166
Rebekah Waterbury Avatar answered Oct 16 '22 23:10

Rebekah Waterbury


Personally, I consider this to be a bug jasmine-jquery. I "solved" this by making my fixtures part of the SpecRunner.html. Not ideal but it works in simple cases.

like image 27
Guy Royse Avatar answered Oct 17 '22 00:10

Guy Royse