velesin / jasmine-jquery Goto Github PK
View Code? Open in Web Editor NEWjQuery matchers and fixture loader for Jasmine framework
License: MIT License
jQuery matchers and fixture loader for Jasmine framework
License: MIT License
It would be useful to be able to check for some css properties in some jQuery objects.
something like:
expect($('.highlighted')).toHaveCss('background-color': 'yellow', 'font-weight': 'bold')
What do you think about this?
Be advised: this is day 1 with jasmine and jasmine-jquery for me. It's entirely likely that I am making some basic n00b mistake.
My environment:
Rails 3.0.3 app with
jasmine (1.0.1.1)
jasmine-jquery-1.1.3
I started with just the example tests that come with jasmine and those were passing. Now simply saving the jasmine-jquery-1.1.3.js file in the public/javascripts directory causes all those tests to fail with:
Error: TypeError: Cannot call method 'remove' of null
at new <anonymous> (http://localhost:8888/__JASMINE_ROOT__/lib/jasmine.js:94:36)
at [object Object].fail (http://localhost:8888/__JASMINE_ROOT__/lib/jasmine.js:1963:27)
at [object Object].execute (http://localhost:8888/__JASMINE_ROOT__/lib/jasmine.js:970:15)
at [object Object].next_ (http://localhost:8888/__JASMINE_ROOT__/lib/jasmine.js:1739:31)
at http://localhost:8888/__JASMINE_ROOT__/lib/jasmine.js:1729:18
I suspect this has to do with the jasmine fixture DIV autocleanup. Again, I haven't even started coding to the jasmine-jquery API, this failure comes from just installing the .js library. (Which is referenced via a glob in my spec/javascripts/support/jasmine.yml file).
Not sure if this is an incompatibility with this release of jasmine or what.
appendTo($("body")) will append to actual body but not
jQuery return the color of an element in rgb values, while usually i use Hex notation to set that. For example if i set a color like this
$( '#foo' ).css( 'border-left-color' : '#FF0000' );
And then i use the toHaveCss() matcher
expect( $( '#foo' ) ).toHaveCss( { 'border-left-color' : '#FF0000' } );
i got a test that fails because this.actual.css( 'border-left-color' ) returns rgb(255, 0, 0). So i made my custom toHaveCss() matcher with the following code.
jasmine.JQuery.matchersClass.toHaveCss = function( css ) {
var colorToHex = function( color ) {
if ( color.substr(0, 1) === '#' ) {
return color;
}
var digits = /(.*?)rgb\((\d+), (\d+), (\d+)\)/.exec(color);
var red = parseInt(digits[2]);
var green = parseInt(digits[3]);
var blue = parseInt(digits[4]);
var rgb = blue | (green << 8) | (red << 16);
return digits[1] + '#' + rgb.toString(16);
};
var convertToHexIfRgb = function( value_to_check ) {
if( value_to_check.substr(0, 4) === 'rgb(' ) {
return colorToHex( value_to_check );
}
return value_to_check;
};
for( var prop in css ) {
var actual_prop = convertToHexIfRgb( this.actual.css( prop ) ).toUpperCase();
var expected_prop = convertToHexIfRgb( css[prop] ).toUpperCase();
if( actual_prop !== expected_prop ) {
return false;
}
}
return true;
}
i've been using it for a while with no problems, but maybe there is a better approach, like holding a list of known CSS properties that need to passed to the converter function and pass to the converter only those requests
After spending a few hours on it, we've found that due to jQuery 1.5's changed ajax functionality (http://api.jquery.com/jQuery.ajax/) fixtures can't be loaded.
The solution is to revert to jQuery 1.4.x.
Hope this helps anyone else stuck!
Hi,
I'm having some issue with loading fixture. Below is my code
$(function() {
beforeEach(function(){
loadFixtures("categories.html");
keywordsListView = new KeywordsListView({
el: $("#keywords_list")
})
})
it("should ...", function() {
expect(keywordsListView.el.attr("id")).toEqual("keywords_list");
})
})
For some reason keywordsListView.el is undefined even though the fixture file exists and #keywords_list exist in the file. However, if I have loadFixtures before "beforeEach" then everything works fine. In other words, this will work
$(function() {
loadFixtures(...) //having this makes everything works
beforeEach(function() {
loadFixtures(...)
})
})
Hi,
It'd be useful to have a toBeEnabled() to balance the toBeDisabled().
toBeEnabled: function(selector){
return this.actual.is(':enabled');
},
Easy enough to hack in, but worth adding in a future release, IMNSHO.
. Topher
The toExist
matcher simply checks whether or not the jQuery element has a size greater than 0.
toExist: function() {
return this.actual.size() > 0;
}
This is fine for most cases, but if you already have a reference to a jQuery object and you want to test that some function properly removed that object from the DOM, toExist
won't work.
Here's an example:
var el = $('#some-element');
el.remove()
expect(el).not.toExist() // incorrectly fails
Perhaps my expectation isn't the intended purpose of toExist
, but it seems to me toExist should test whether or not an element exists in the DOM. (Or, I suppose, a new matcher could be created to test existence in the DOM.)
It could look something like this:
toExistInDOM: function() {
return $(document).find(this.actual).size() > 0;
}
I've been trying to configure jasmine-jquery, but loading fixtures didn't work.
After some debugging, I've seen the reason is that I'm using jasmine-ajax from pivotal to mock jQuery AJAX requests. Since jasmine-jquery uses $.ajax to retrieve the fixtures, they don't get properly loaded.
So far the solution I've found is to apply the patch at https://gist.github.com/813872 (note that the code is taken from the jasmine-dom project).
Is there a simpler way to solve the conflict I haven't found?
Thanks.
The docs:
var spyEvent = spyOnEvent('#some_element', 'click'); //sm_com: selector
$('#some_element').click();
expect('click').toHaveBeenTriggeredOn('#some_element'); //sm_com: selector
expect(spyEvent).toHaveBeenTriggered();
But the tests do not reflect this usage.
Please note the spyOnEvent usage here:
https://github.com/velesin/jasmine-jquery/blob/master/spec/suites/jasmine-jquery-spec.js#L886
and toHaveBeenTriggeredOn usage here:
https://github.com/velesin/jasmine-jquery/blob/master/spec/suites/jasmine-jquery-spec.js#L892
I have also run into issues in my own project with this, i.e. the problem is not just hypothetical. My question (and why I haven't sent a PR): are the docs wrong, or is the source/tests not functioning as expected?
When I execute the following spec:
$('#p30').trigger('click');
expect('click').toHaveBeenTriggeredOn($('#p30'));
the toHaveBeenTriggeredOn succeeds even if the click event was never attached to element #p30. It even succeeds if I replace 'click' with a random other string. I've tried this with both JQuery 1.4.4 and 1.5.2 in Firefox 4.0.1 and Safari 5.0.5.
I've got a mixed Prototype/jQuery setup that lets Prototype use the $ variable. Please wrap the jasmine-jquery code in a
function($) {
//...
}(jQuery)
block, or use jQuery
in stead of $
.
I have posted a git repo illustrating this problem. If I have a hidden element and call .show() on it and .hide() it again multiple times all my specs pass. However if I add animation such as .show('fast'), the first time is called I get the expected result but not the second time.
The repo is: https://github.com/structuralartistry/jasmine_jquery_animation_issue
The actual test code is (note that I run this code both with and without using sinon.js fake timer):
(function() {
describe('jasmine jquery with jquery animation', function() {
describe('without sinon fake timer', function() {
// note the only difference between the two specs below is that the first uses .show() and second uses .show('fast')
it('jquery show without animation passes on second try of same call', function() {
var fixture_html;
fixture_html = "<div id='selector' style='display: none'><table><tr><td id='select_option_1'>B</td></tr></table></div><table><tr><td id='button' onmousedown=\"$('#selector').show();\">Click Me</td></tr></table>";
setFixtures(fixture_html);
expect($('#selector')).toBeHidden();
$('#button').mousedown();
expect($('#selector')).toBeVisible();
$('#selector').hide();
expect($('#selector')).toBeHidden();
$('#button').mousedown();
return expect($('#selector')).toBeVisible();
});
it('jquery show with animation fails on second try of same call', function() {
var fixture_html;
fixture_html = "<div id='selector' style='display: none'><table><tr><td id='select_option_1'>B</td></tr></table></div><table><tr><td id='button' onmousedown=\"$('#selector').show('slow');\">Click Me</td></tr></table>";
setFixtures(fixture_html);
expect($('#selector')).toBeHidden();
$('#button').mousedown();
expect($('#selector')).toBeVisible();
$('#selector').hide();
expect($('#selector')).toBeHidden();
$('#button').mousedown();
// to make spec pass uncomment the below
return expect($('#selector')).toBeVisible();
});
});
describe('with sinon fake timer', function() {
// note the only difference between the two specs below is that the first uses .show() and second uses .show('fast')
it('jquery show without animation passes on second try of same call', function() {
clock = sinon.useFakeTimers()
var fixture_html;
fixture_html = "<div id='selector' style='display: none'><table><tr><td id='select_option_1'>B</td></tr></table></div><table><tr><td id='button' onmousedown=\"$('#selector').show();\">Click Me</td></tr></table>";
setFixtures(fixture_html);
expect($('#selector')).toBeHidden();
$('#button').mousedown();
expect($('#selector')).toBeVisible();
$('#selector').hide();
expect($('#selector')).toBeHidden();
$('#button').mousedown();
clock.tick(5000)
expect($('#selector')).toBeVisible();
return clock.restore()
});
it('jquery show with animation fails on second try of same call', function() {
clock = sinon.useFakeTimers()
var fixture_html;
fixture_html = "<div id='selector' style='display: none'><table><tr><td id='select_option_1'>B</td></tr></table></div><table><tr><td id='button' onmousedown=\"$('#selector').show('slow');\">Click Me</td></tr></table>";
setFixtures(fixture_html);
expect($('#selector')).toBeHidden();
$('#button').mousedown();
expect($('#selector')).toBeVisible();
$('#selector').hide();
expect($('#selector')).toBeHidden();
$('#button').mousedown();
clock.tick(5000)
// to make spec pass uncomment the below
expect($('#selector')).toBeVisible();
return clock.restore()
});
});
});
}).call(this);
I have the same issue as #27, but here's a concrete example of where it can make testing difficult. In jQuery 1.6 and up, 'is' should still work with a jquery object or an element (http://api.jquery.com/is/) but for some reason its only working when I test with a selector string.
Code I want to test:
$this.data("warning", warn);
Where 'warn' is a jQuery object of an element I have extracted from the DOM, because I'm progressively enhancing things.
What I want to test is that the right thing gets passed into the data function. Data function can then do what it likes, I'm testing my code and not jQuery.
In beforeEach:
spyOn(jQuery.fn, "data").andCallThrough(); //spying on all instances of data function because my reference to the element does not yet exist
inst.init(); //running my module
A little later in my spec:
expect(jqLoggedout.data.mostRecentCall.args[0]).toBe("warning"); //happy green assertion
expect(jqLoggedout.data.mostRecentCall.args[1]).toBe(jQuery(logoutP)); //fails with message Expected '<p>Some message</p>' to be { 0 : HTMLNode, context : .... etc. etc.
expect(jqLoggedout.data.mostRecentCall.args[1]).toBe('<p>Some message</p>');
//fails with Error: Syntax error, unrecognized expression: > in http://localhost:8888/assets/jquery.js?body=1 (line 4268)
testing the element passed in
expect(jqLoggedout.data.mostRecentCall.args[1]).toBe(logoutP);
//fails with Expected '<p style="display: inline-block;">Please login or register to bookmark</p>' to be HTMLNode.
I'm trying to make a test for this event handler:
// Disable all AJAX buttons.
$( '#facebook a.btn' ).click( function( e ) {
e.preventDefault();
e.stopImmediatePropagation();
} );
The test i wrote is this one
// Call the function
utility_functions.block_all_submit_and_ajax( $button.get(0) );
// check that all submit are disabled
spyOnEvent( $('.ai1ec-facebook-refresh-multiselect:first'), 'click' );
$( '.ai1ec-facebook-refresh-multiselect:first' )[0].click();
expect( 'click' ).toHaveBeenTriggeredOn( $('.ai1ec-facebook-refresh-multiselect:first') );
expect( 'click' ).toHaveBeenPreventedOn( $('.ai1ec-facebook-refresh-multiselect:first') );
Which fails. The test doesn't fail if i dont call the .stopImmediatePropagation() and that makes sense because the "spy handler" is set after that handler. Any solution?Maybe it would be a good idea to rewrite the spyOnEvent function so that it always attach the spy event handler as the first event.
Jasmine 1.1.2
Head of jasmine-jquery on Github: 7fcfa63
TypeError: Cannot call method 'cleanUp' of undefined
at [object Object]. (http://localhost:8888/**spec**/helpers/jasmine-jquery.js:288:27)
at [object Object].execute (http://localhost:8888/**JASMINE_ROOT**/jasmine.js:1001:15)
at [object Object].next_ (http://localhost:8888/**JASMINE_ROOT**/jasmine.js:1790:31)
at http://localhost:8888/**JASMINE_ROOT**/jasmine.js:1780:18
Shim in place:
84c84
< jasmine.Fixtures.prototype.getFixtureHtml_ = function(url) {
---
> jasmine.Fixtures.prototype.getFixtureHtml_ = function(url) {
226c226
<
---
>
287,289c287
< if(jasmine.JQuery.events !== undefined){
< jasmine.JQuery.events.cleanUp();
< }
---
> jasmine.JQuery.events.cleanUp();
I am new to jasmine. For some reason this chunk of code does not seem to work. This might be something very simple -
expect($('<div class="wall_C wallPlan" style="width: 544.875px; height: 727.1667px;"><div class="validDoorArea ui-droppable" style="width: 544.875px; height: 595.9167px; top: 131.25px; left: 0px;"></div></div>')).toHaveCss({width: "544.875px"});
Where did Jasmine's native toBe
object identity matcher go? I use it all the time (obviously). Testing based on jQuery.fn.is
is useful too, but a totally different thing!
if you do
loadFixtures("this-file-does-not-exist.html");
it silently fails, which makes my test fail but I don't realise it's because the fixture file doesn't exist. which is bad.
I work around it with my own (probably ugly) function for the moment.
function myLoadFixture(filename){
loadFixtures(filename);
if($("#jasmine-fixtures").html().trim() === ""){
throw "fixture " + FIXTURES_PATH + filename + " doesn't exist";
}
}
but otherwise, love this project - keep up the good work!
Hi,
I am having issues when loading in html fixture. I checked the request and response in firebug, and it said you can't locate my URL.
As I was puzzled since it was a valid URL, I looked at the plugin code.
I noticed that in the function:
jasmine.Fixtures.prototype.loadFixtureIntoCache_ = function (relativeUrl) {
var url = this.fixturesPath.match('/$') ? this.fixturesPath + relativeUrl : this.fixturesPath + '/' + relativeUrl;
...
};
that is prepends a "/" before the URL no matter what. This is not correct when making a jQuery.ajax call, and is not required.
Also, the "type" property for ajax is not set.
It has to be set to: type: 'GET'
when I changed the above. It began working for me and my tests passed.
this.fixturesPath is also correct for me.
Being that this has been around for around, and has to be working for other people, I think I may be missing something.
When I get updates, I don't want to have to keep modifying the source code to get it to work for me.
So am I missing something. Here's my code.
describe("An_Area_Div", function () {
beforeEach(function () {
loadFixtures('MyFixture.htm');
});
it("should have html", function () {
expect($('#Area0')).toExist();
});
});
I noticed that I was getting 404 errors when trying to load the fixtures from the typical /spec/javascripts/fixtures folder. I moved the fixture folder to /public/spec/javascripts/fixtures and manually set the path in my tests and it worked fine.
Having test-related code in a publicly-accessible folder seems like a security risk (although minor) to me. Do you have any recommendations for best practices regarding the fixture file location?
Thanks,
-Peter
Assuming I have some element <a id="element" style="display: none" />
,
function foo() {
$('#element').show(); // sets display inline
}
it("should be visible", function() {
expect($('#element')).not.toBeVisible(); // returns true
foo();
expect($('#element')).toBeVisible(); // returns false
expect($('#element').css('display')).toEqual('inline'); // returns true
});
Based off of this explanation of toBeVisible
toBeVisible()
Elements are considered visible if they consume space in the document. Visible elements have a width or height that is greater than zero.
It seems that the third expectation should return true instead of false.
Hi, when i run this test
// check that all submit are disabled
var first_multi = $( 'a.ai1ec-facebook-refresh-multiselect:first' );
var my = spyOnEvent( first_multi, 'click' );
first_multi.click();
expect( 'click' ).toHaveBeenPreventedOn( $( '.ai1ec-facebook-refresh-multiselect:first' ) );
I always get the message "TypeError: Cannot call method 'isDefaultPrevented' of undefined". What am i doing wrong? This is the code i'm trying to test:
$( 'a' ).click( function( e ) {
e.preventDefault();
e.stopImmediatePropagation();
} );
I also tried
// Get a button
var $button = $( '#ai1ec_subscribe_users' );
// Call the function
utility_functions.block_all_submit_and_ajax( $button.get(0) );
// check that all submit are disabled
var first_multi = $( '.ai1ec-facebook-refresh-multiselect:first' );
spyOnEvent( '.ai1ec-facebook-refresh-multiselect:first', 'click' );
first_multi.click();
expect( 'click' ).toHaveBeenTriggeredOn( '.ai1ec-facebook-refresh-multiselect:first' );
This gives me back
Expected event click to have been triggered on .ai1ec-facebook-refresh-multiselect:first
Hi,
I found that if the event is not present in the element, "toHandle" throws the following error
$('.test').change(function() { });
expect($('.test')).toHandle('click');
TypeError: Cannot read property 'length' of undefined
I'd like to suggest you to add checking for events[eventName]
from
toHandle: function(eventName) {
var events = this.actual.data("events");
return events && events[eventName].length > 0;
},
toHandle: function(eventName) {
var events = this.actual.data("events");
return events && events[eventName] && events[eventName].length > 0;
},
I am doing something simple to test out fixtures for the first time: loadFixtures('test.html');
I think I put it in the proper relative path by changing my fixturesPath.
The thing is I can run my test 10x and about 75% of the time it will error out:
"During Page reloaded unexpectedly during or after null triggered by unload"
I'm really lost since it's so unpredictable. If it happened every time I would just think my fixture is in the wrong place, but it's not doing that.
In the test suit, toHaveCss
test set css properties by jquery:
$("#sandbox").css("margin", "10px")
and then expect by:
expect($("#sandbox")).toHaveCss({margin: "10px"})
but this fails in Firefox and IE8, the reason is that jQuery does not support shorthand css properties.
Shorthand CSS properties (e.g. margin, background, border) are not supported. For example, if you want to retrieve the rendered margin, use:
$(elem).css('marginTop') and $ (elem).css('marginRight'), and so on.
I think expect like this can solve this problem
expect($("#sandbox")).toHaveCss({"margin-left": "10px"})
see this jsbin test code http://jsbin.com/avohoz/1/edit
When running the SpecRunner.html for Jasmine1.1.0.rc2 revision 1308965645 the load fixture file that does not exist test case fails. This is for Chrome 13.0.782.220 and Safari Version 5.1 (6534.50) on Mac OSX Snow Leopard 10.6.8
Line 278:
describe("when fixture file does not exist", function() {
var fixtureUrl = "not_existing_fixture";
it("should throw an exception", function() {
expect(function() {
jasmine.getFixtures().read(fixtureUrl);
}).toThrow();
});
});
Error: Expected function to throw an exception.
at new (http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:102:32)
at [object Object].toThrow (http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:1171:29)
at [object Object]. (http://tools/jasmine-jquery/spec/suites/jasmine-jquery-spec.js:284:10)
at [object Object].execute (http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:1001:15)
at [object Object].next_ (http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:1790:31)
at [object Object].start (http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:1743:8)
at [object Object].execute (http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:2070:14)
at [object Object].next_ (http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:1790:31)
at [object Object].start (http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:1743:8)
at [object Object].execute (http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:2215:14)
Firefox 6.0.2 throws the above error & the additional
jasmine.Fixtures - load - when fixture contains an inline <script> tag - should execute the inline javascript after the fixture has been inserted into the body
Expected '' to have class 'foo'.
([object Object])@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:102 ()@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:1176 ()@http://tools/jasmine-jquery/spec/suites/jasmine-jquery-spec.js:282 ((function () {if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {completedSynchronously = true;return;}if (self.blocks[self.index].abort) {self.abort = true;}self.offset = 0;self.index++;var now = (new Date).getTime();if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {self.env.lastUpdate = now;self.env.setTimeout(function () {self.next_();}, 0);} else {if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {goAgain = true;} else {self.next_();}}}))@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:1001 ()@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:1790 ((function () {spec.finish(onComplete);}))@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:1743 ((function () {if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {completedSynchronously = true;return;}if (self.blocks[self.index].abort) {self.abort = true;}self.offset = 0;self.index++;var now = (new Date).getTime();if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {self.env.lastUpdate = now;self.env.setTimeout(function () {self.next_();}, 0);} else {if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {goAgain = true;} else {self.next_();}}}))@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:2070 ()@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:1790 ((function () {self.finish(onComplete);}))@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:1743 ((function () {if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {completedSynchronously = true;return;}if (self.blocks[self.index].abort) {self.abort = true;}self.offset = 0;self.index++;var now = (new Date).getTime();if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {self.env.lastUpdate = now;self.env.setTimeout(function () {self.next_();}, 0);} else {if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {goAgain = true;} else {self.next_();}}}))@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:2215 ()@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:1790 ((function () {self.finish(onComplete);}))@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:1743 ((function () {if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {completedSynchronously = true;return;}if (self.blocks[self.index].abort) {self.abort = true;}self.offset = 0;self.index++;var now = (new Date).getTime();if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {self.env.lastUpdate = now;self.env.setTimeout(function () {self.next_();}, 0);} else {if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {goAgain = true;} else {self.next_();}}}))@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:2215 ()@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:1790 ()@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:1786 ((function () {if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {completedSynchronously = true;return;}if (self.blocks[self.index].abort) {self.abort = true;}self.offset = 0;self.index++;var now = (new Date).getTime();if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {self.env.lastUpdate = now;self.env.setTimeout(function () {self.next_();}, 0);} else {if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {goAgain = true;} else {self.next_();}}}))@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:2172 ()@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:2216 ()@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:1800 ()@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:1786 ((function () {if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {completedSynchronously = true;return;}if (self.blocks[self.index].abort) {self.abort = true;}self.offset = 0;self.index++;var now = (new Date).getTime();if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {self.env.lastUpdate = now;self.env.setTimeout(function () {self.next_();}, 0);} else {if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {goAgain = true;} else {self.next_();}}}))@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:2172 ()@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:2216 ()@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:1800 ()@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:1786 ((function () {if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {completedSynchronously = true;return;}if (self.blocks[self.index].abort) {self.abort = true;}self.offset = 0;self.index++;var now = (new Date).getTime();if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {self.env.lastUpdate = now;self.env.setTimeout(function () {self.next_();}, 0);} else {if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {goAgain = true;} else {self.next_();}}}))@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:2044 ()@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:2071 ()@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:1800 (17)@http://tools/jasmine-jquery/vendor/jasmine/jasmine.js:1780 @:0
Hello,
I am just checking Jasmine and this JQuery add-on. The only way I have seen to locate fixtures is to place the fixture files in the root folder of the project. You can specify a path each time you include a fixture but I would prefer to have some convention (for example, all the fixtures should be located under the spec/javascripts/fixtures path)
Perhaps I am missing something and this is already possible. If not, I can submit a patch for achieving this behaviour, if you consider it interesting.
Thanks
I think you forget to catch and handle interrupts, or perhaps its an issue with webrick. When I send a ctrl-c to the web server, it logs:
[2010-08-24 09:48:07] ERROR Interrupt:
/home/michael/.rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/webrick/server.rb:91:in `select'
but it doesn't actually kill it. Normal kill commands have the same effect. At that point I have to resort to kill -9
the implementation of toHaveHtml
is far too literal, using ==
and not allowing a regex check.
so I made toContainHtml
which uses a simple indexOf
string check:
toContainHtml: function(html) {
var actualHtml = this.actual.html();
var expectedHtml = jasmine.JQuery.browserTagCaseIndependentHtml(html);
return (actualHtml.indexOf(expectedHtml)>=0);
}
something like this, or an expansion of how toHaveHtml
should be included... spent about an hour trying to get toHaveHtml working for this HTML:
<div>
<ul></ul>
<h1>foo</h1>
</div>
with this test:
expect($el).toHaveHtml("<ul></ul>");
which doesn't work. but the above toContainHtml does work:
expect($el).toContainHtml("<ul></ul>");
Hello,
I am running into a problem with the matcher toHaveAttr()
. I cannot get the attributeValue to match, which is causing my test to fail. If I leave the attributeValue blank or nil, then the test will pass.
Here is my Jasmine test.
describe("should display a div that immediately follow an ahref with openClose class, once it has been clicked", function() {
var anchor, div;
beforeEach(function () {
loadFixtures("orders_show.html"),
anchor = $("a#update-completed-word-count"),
div = $(".update-completed-word-count");
anchor.click(),
$(".close-edit").openClose()
}),
it("anchor tag should not have class open-edit", function(){
expect(anchor).not.toHaveClass('open-edit');
}),
it("div with class update-completed-word-count should be displayed", function(){
expect(div).toHaveAttr('style','display:block');
});
});
Here is the fixture file orders_show.html:
<a href="#" id="update-completed-word-count" class="open-edit close-edit"></a>
<div class="update-completed-word-count">
<form action="#">
<label for="inputbox4">Input Box 1</label>
<input type="text" id="inputbox4" />
</form>
</div>
The first test anchor tag should not have class open-edit passes as expected, but the second test does not pass, even though <div class="update-completed-word-count">
has the attribute style="display: block"
. If I remove the attributeValue, than the test will pass.
Here is the openClose() function that I am testing:
(function($){
$.fn.openClose = function() {
$(this).live('click', (function() {
$(this).next().toggle(),
$(this).toggleClass("open-edit");
return false
}))
}
})(jQuery);
Here is what Jasmine is reporting:
div with class update-completed-word-count should be displayed
Expected '<div class="update-completed-word-count" style="display: block; "> <form action="#">
<label for="inputbox4">Input Box 1</label> <input type="text" id="inputbox4"> </form>
</div>' to have attr 'style', 'display:block'.
JQuery v1.8.0 is out now, but when trying to use it, I'm getting test failures that might be a result of breaking changes.
The $("<div />").append(...)
tactic used in jasmine.JQuery.elementToString
will cause any <script>
tags that happened to have been matched to be reloaded by the browser.
The reason a <script>
tag may have been matched is that the <html>
tag may have been matched, for example:
expect($(":contains(foo)")).toBeVisible()
Maybe not so much an issue as a clarification: jQuery's 'events' object (1.6.2, anyway) stores information differently when using delegate, so that toHandleWith won't accurately report matches. Testing for click, you'll find a match in the events object but it's not the right place to look, as the handler you're looking for will be in the 'live' property.
Solutions:
It may also be counterintuitive for some to test the delegator instead of the delegatee.
I've been trying to track down this issue for a while, but without success, I'm hoping someone has either seen something similar or has an idea on how to track it down better.
When I run my entire jasmine test suite I get a number of failing test cases, a few are real failing tests, but the others give the following error:
Fixture could not be loaded: jasmine/fixtures/activity_header.html (status: error, message: undefined)
Then when I run a subset of those same tests and the fixture error goes away giving me a green status bar. Running the full suite again brings back the error for tests that previously passed. I'm not editing the tests in any way.
The odd thing is that when I get the error above, the browser isn't sending the ajax request (nothing appears in the Network tab of the Safari or Chrome development panel), and the server console isn't reporting any requests for those fixtures (I'm running a Rails server with jasminerice). It's as if something internal to javascript is preventing them from loading and returning the error. While debugging I've examined the error object and it has a 404 status, but I can't see how that's possible as nothing was ever sent out according to the browser and the server. The url of the request is fine, and if I make the request in a different browser window, it works fine.
Also interesting is that the fixtures associated with the last test case to run do load correctly (and their requests appear in the Network console of the browser as expected). The fixtures for the previous test cases do not however, though they all generate this error. I suspect that's why when I run a subset of tests the fixtures work, because there is only one test running the fixture in that context.
Any ideas on what could be causing these errors?
Fixture loading does not seem to work with Jasmine 0.8
Hey Wojciech,
I saw that you were looking for someone to help you maintain the project and I'd be interested. I use the project both at work and in personal projects so I'm definitely enthusiastic about making sure it's up-to date.
You can check out my GitHub @travisjeffery or my technical blog at http://travisjeffery.com/b/ to see that I'm very active, know what I'm doing, love JavaScript/jQuery and testing/TDD, and would be a good maintainer for the project.
If you want to know more you can get me here or [email protected]
Thanks,
Travis
Hi,
I'm thinking it would be better if you could load fixtures from /src/test... Is that possible?
thanks,
adam
I'm using JsTestDriver.
Console output:
setting runnermode QUIET Chrome: Reset Chrome: Reset F Total 1 tests (Passed: 0; Fails: 1; Errors: 0) (187.00 ms) Chrome 23.0.1271.95 Windows: Run 1 tests (Passed: 0; Fails: 1; Errors 0) (187.00 ms) blockquote highlighter.doesn't change the scroll depth to the top of the first blockquote when jumpToFirstQuote is not true failed (187.00 ms): RangeError: RangeError: Maximum call stack size exceeded TypeError: TypeError: Object #<Object> has no method 'getFixtures' TypeError: Object #<Object> has no method 'getFixtures'
All I'm doing is setting the fixture path in beforeEach
and I've one empty test.
jasmine.getFixtures().fixturesPath = 'fixtures';
My JsTestDriver config:
server: http://localhost:9876
load:
- Jasmine/lib/jasmine-1.2.0/jasmine.js
- JasmineAdapter/src/*
- jquery/1.8.3/jquery.min.js
- jasmine-jquery/jasmine-jquery.js
- ../bootstrap/*.js #sets up the testing environment
- ../util/*.js #reusable JS functions
- ../../source/js/*.js #source code to test
- ../*.js #test specs
serve:
- ../fixtures/html/*.html
- ../fixtures/styling/*.css
timeout: 90
(To be honest, I'm not sure if I need serve
, added it after seeing @justlaputa's config in #95)
What's strange is that when I console.debug(jasmine)
in the beforeEach
, it does contain getFixtures
;
See/get the code, I set up a repo for this issue.
To run the tests:
/usr/bin/google-chrome
.sh run-tests.sh
in the command-line (cygwin is fine).If I do this early in my load order:
$j = jQuery.noConflict();
then jQuery
will not be available as $
when jquery-jasmine loads. Though jquery-jasmine is not technically a jQuery plugin, it should probably follow the jQuery plugin best practice of passing jQuery
into a self-executing function.
Hi velesin
I'm using jasmine and jasmine-jquery to test-drive a small jQuery plugin I'm writing (this is the first I ever write, and the first tests I ever write in my life ! w00t !).
With this code
$('li', this).on('click', function() { });
the following spec works perfectly :
it("should bind click events to each media element", function() {
$('.media-grid').myGallery();
expect($('.media-grid > li')).toHandle('click');
});
But if I namespace my event (as permitted and advised in jQuery's Plugin authoring) like this
$('li', this).on('click.myGallery', function() { });
this spec fails :
expect($('.media-grid > li')).toHandle('click.myGallery');
});
The error is :
TypeError: events[eventName] is undefined in file:///***/myGallery.jQuery/test/lib/jasmine-jquery.js (line 224)
But doesn't fail with :
expect($('.media-grid > li')).toHandle('click');
The difference being that I namespace the event, but not the matcher. Not sure if it's a bug or a normal behaviour.
I've looked line 224, and if I suppose it has to do with jasmine-jquery being able to work only with core js events (click, submit etc.), I see nothing there that prevents non-core events to work. Basically I have no idea why it doesn't work...
Matchers in jasmine-jquery when executed on document.documentElement break jasmine engine.
f.x. this one:
expect($(document.documentElement)).toHaveClass("buka");
This is because of jasmine.JQuery.elementToString(element) method. When the document element is appended to DOM all its scripts are executed thus overwriting jasmine's state.
Thanks
When I use the matchers in the following ways (which may be wrong), they pass when they should fail. In fact, I think these always pass:
describe('toHaveText', function() {
it('should just work', function() {
setFixtures($("<div id='foo'>bar</div>"));
expect('#foo').toHaveText('bar2');
expect($('#foo')).toHaveText('bar2');
});
});
describe('toExist', function() {
it('should work', function() {
setFixtures($("<div id='foo'>bar</div>"));
expect('#foo2').toExist();
expect($('#foo2')).toExist();
});
});
Any thoughts?
it("should bind to the window resize event", function() {
$(window).bind('resize',function(){});
console.debug($(window).data('events').resize[0]); // 1 (or >1)
expect($(window)).toHandle('resize'); // TypeError: Object [object DOMWindow] has no method 'cloneNode'
});
i'm playing around with jasmine and try to find the best approach to fixtures. i'm in a rails3 project and doing my views with HAML so it'd be awesome to be able to write the fixtures in HAML, too.
any thoughts on that?
When trying to use loadFixtures() to load a local html file, Chrome (v7.0.517.41) returns this error:
Origin null is not allowed by Access-Control-Allow-Origin.
Is there a browser setting that I can tweak to get around this error? Firefox and IE both work fine.
Not sure what I am doing wrong but doesnt seem to work with JSTestDriver
for loading fixtures in JsTestDriver a jasmine config is not necessary can you explain how we could load fixtures with JsTestDriver?
Thanks much appreciated
Issue #4 describes a major "gotcha". It was suggested 2 years ago that this be put into the README, but that was never done -- and it just cost me lots of debugging time.
I'll submit a pull request for the updated docs if I get a few minutes, but meanwhile I'm opening this issue.
just curious if jasmine-jquery is compatible with zepto
Currently there is no way to write specs that tests that expect jquery to be unavailable since jasmine-jquery relies on jquery. I can currently store jquery temporarily and remove/restore it during beforeEach and afterEach:
var temp;
beforeEach(function(){
temp = $.noConflict(true)
}
afterEach(function(){
jQuery = $ = temp;
}
However, an error occurs with any suites that have jquery removed this way, even if the tests are no longer dependent on jquery. I imagine this is so because jasmine-jquery essentially overwrites/wraps the existing jasmine implementation to be jquery-dependent.
Can a feature be added to turn on/off jasmine-jquery during these beforeEach/afterEach cycles?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.