Giter VIP home page Giter VIP logo

jasmine-jquery's Introduction

!!! IMPORTANT: WE NEED A NEW MAINTAINER !!!

Neither me (the original lib author) nor Travis (the current lib maintainer) can maintain this library any longer as actively as the GREAT community around it deserves.

So, we're looking for a new maintainer for this lib - if you're interested, ping me on Twitter or through a comment in this GitHub issue.

jasmine-jquery Build Status

jasmine-jquery provides two extensions for the Jasmine JavaScript Testing Framework:

  • a set of custom matchers for jQuery framework
  • an API for handling HTML, CSS, and JSON fixtures in your specs

Installation

Choose one of the following options:

  • Simply download jasmine-jquery.js from here and include it in your Jasmine's test runner file (or add it to jasmine.yml file if you're using Ruby with jasmine-gem). Remember to also include the jQuery library as jasmine-jquery relies on it.
  • Using bower by running bower install jasmine-jquery --save
  • For Ruby on Rails, use this gem or I recommend complying with the standard RSpec and Jasmine frameworks dir structure and keep your tests in spec/javascripts/ dir. I put jasmine-jquery (and other libraries like jasmine-ajax) into spec/javascripts/helpers dir (so they are automatically loaded) and fixtures into spec/javascripts/fixtures dir.

jQuery matchers

jasmine-jquery provides the following custom matchers (in alphabetical order):

  • toBeChecked()
    • only for tags that have checked attribute
    • e.g. expect($('<input type="checkbox" checked="checked"/>')).toBeChecked()
  • toBeDisabled()
    • e.g. expect('<input type="submit" disabled="disabled"/>').toBeDisabled()
  • toBeEmpty()
    • Checks for child DOM elements or text.
  • toBeFocused()
    • e.g. expect($('<input type="text" />').focus()).toBeFocused()
  • toBeHidden() Elements can be considered hidden for several reasons:
    • They have a CSS display value of none.
    • They are form elements with type equal to hidden.
    • Their width and height are explicitly set to 0.
    • An ancestor element is hidden, so the element is not shown on the page.
  • toBeInDOM()
    • Checks to see if the matched element is attached to the DOM
    • e.g. expect($('#id-name')[0]).toBeInDOM()
  • toBeMatchedBy(jQuerySelector)
    • Check to see if the set of matched elements matches the given selector
    • e.g. expect($('<span></span>').addClass('js-something')).toBeMatchedBy('.js-something')
    • true if the dom contains the element
  • toBeSelected()
    • only for tags that have selected attribute
    • e.g. expect($('<option selected="selected"></option>')).toBeSelected()
  • toBeVisible()
    • Elements are considered visible if they consume space in the document. Visible elements have a width or height that is greater than zero.
  • toContain(string)
    • e.g. expect($('<div><span class="some-class"></span></div>')).toContain('some-class')
  • toContainElement(jQuerySelector)
    • e.g. expect($('<div><span class="some-class"></span></div>')).toContainElement('span.some-class')
  • toContainHtml(string)
    • e.g. expect($('<div><ul></ul><h1>header</h1></div>')).toContainHtml('<ul></ul>')
  • toContainText(string)
    • e.g. expect($('<div><ul></ul><h1>header</h1></div>')).toContainText('header')
  • toEqual(jQuerySelector)
    • e.g. expect($('<div id="some-id"></div>')).toEqual('div')
    • e.g. expect($('<div id="some-id"></div>')).toEqual('div#some-id')
  • toExist()
    • true if element exists in or out of the dom
  • toHandle(eventName)
    • e.g. expect($form).toHandle("submit")
  • toHandleWith(eventName, eventHandler)
    • e.g. expect($form).toHandleWith("submit", yourSubmitCallback)
  • toHaveAttr(attributeName, attributeValue)
    • attribute value is optional, if omitted it will check only if attribute exists
  • toHaveBeenTriggeredOn(selector)
    • if event has been triggered on selector (see "Event Spies", below)
  • toHaveBeenTriggered()
    • if event has been triggered on selector (see "Event Spies", below)
  • toHaveBeenTriggeredOnAndWith(selector, extraParameters)
    • if event has been triggered on selector and with extraParameters
  • toHaveBeenPreventedOn(selector)
    • if event has been prevented on selector (see "Event Spies", below)
  • toHaveBeenPrevented()
    • if event has been prevented on selector (see "Event Spies", below)
  • toHaveClass(className)
    • e.g. expect($('<div class="some-class"></div>')).toHaveClass("some-class")
  • toHaveCss(css)
    • e.g. expect($('<div style="display: none; margin: 10px;"></div>')).toHaveCss({display: "none", margin: "10px"})
    • e.g. expect($('<div style="display: none; margin: 10px;"></div>')).toHaveCss({margin: "10px"})
  • toHaveData(key, value)
    • value is optional, if omitted it will check only if an entry for that key exists
  • toHaveHtml(string)
    • e.g. expect($('<div><span></span></div>')).toHaveHtml('<span></span>')
  • toHaveId(id)
    • e.g. expect($('<div id="some-id"></div>')).toHaveId("some-id")
  • toHaveLength(value)
    • e.g. expect($('ul > li')).toHaveLength(3)
  • toHaveProp(propertyName, propertyValue)
    • property value is optional, if omitted it will check only if property exists
  • toHaveText(string)
    • accepts a String or regular expression
    • e.g. expect($('<div>some text</div>')).toHaveText('some text')
  • toHaveValue(value)
    • only for elements on which val can be called (input, textarea, etc)
    • e.g. expect($('<input type="text" value="some text"/>')).toHaveValue('some text')

The same as with standard Jasmine matchers, all of the above custom matchers may be inverted by using .not prefix, e.g.:

expect($('<div>some text</div>')).not.toHaveText(/other/)

HTML Fixtures

The Fixture module of jasmine-jquery allows you to load HTML content to be used by your tests. The overall workflow is as follows:

In myfixture.html file:

<div id="my-fixture">some complex content here</div>

Inside your test:

loadFixtures('myfixture.html')
$('#my-fixture').myTestedPlugin()
expect($('#my-fixture')).to...

By default, fixtures are loaded from spec/javascripts/fixtures. You can configure this path: jasmine.getFixtures().fixturesPath = 'my/new/path';.

Note: If you are running your test with Karma, remember that your files are served from a base/ directory, so your path should be configured to: jasmine.getFixtures().fixturesPath = 'base/my/new/path';.

Your fixture is being loaded into the <div id="jasmine-fixtures"></div> container that is automatically added to the DOM by the Fixture module (If you REALLY must change the id of this container, try: jasmine.getFixtures().containerId = 'my-new-id'; in your test runner). To make tests fully independent, fixtures container is automatically cleaned-up between tests, so you don't have to worry about left-overs from fixtures loaded in preceeding test. Also, fixtures are internally cached by the Fixture module, so you can load the same fixture file in several tests without penalty to your test suite's speed.

To invoke fixture related methods, obtain Fixtures singleton through a factory and invoke a method on it:

jasmine.getFixtures().load(...)

There are also global shortcut functions available for the most used methods, so the above example can be rewritten to just:

loadFixtures(...)

Several methods for loading fixtures are provided:

  • load(fixtureUrl[, fixtureUrl, ...])
    • Loads fixture(s) from one or more files and automatically appends them to the DOM (to the fixtures container).
  • appendLoad(fixtureUrl[, fixtureUrl, ...])
    • Same as load, but adds the fixtures to the pre-existing fixture container.
  • read(fixtureUrl[, fixtureUrl, ...])
    • Loads fixture(s) from one or more files but instead of appending them to the DOM returns them as a string (useful if you want to process fixture's content directly in your test).
  • set(html)
    • Doesn't load fixture from file, but instead gets it directly as a parameter (html parameter may be a string or a jQuery element, so both set('<div></div>') and set($('<div/>')) will work). Automatically appends fixture to the DOM (to the fixtures container). It is useful if your fixture is too simple to keep it in an external file or is constructed procedurally, but you still want Fixture module to automatically handle DOM insertion and clean-up between tests for you.
  • appendSet(html)
    • Same as set, but adds the fixtures to the pre-existing fixture container.
  • preload(fixtureUrl[, fixtureUrl, ...])
    • Pre-loads fixture(s) from one or more files and stores them into cache, without returning them or appending them to the DOM. All subsequent calls to load or read methods will then get fixtures content from cache, without making any AJAX calls (unless cache is manually purged by using clearCache method). Pre-loading all fixtures before a test suite is run may be useful when working with libraries like jasmine-ajax that block or otherwise modify the inner workings of JS or jQuery AJAX calls.

All of above methods have matching global shortcuts:

  • loadFixtures(fixtureUrl[, fixtureUrl, ...])
  • appendLoadFixtures(fixtureUrl[, fixtureUrl, ...])
  • readFixtures(fixtureUrl[, fixtureUrl, ...])
  • setFixtures(html)
  • appendSetFixtures(html)
var fixture = setFixtures('<div class="post">foo</div>')
var post = fixture.find('.post')

Also, a helper method for creating HTML elements for your tests is provided:

  • sandbox([{attributeName: value[, attributeName: value, ...]}])

It creates an empty DIV element with a default id="sandbox". If a hash of attributes is provided, they will be set for this DIV tag. If a hash of attributes contains id attribute it will override the default value. Custom attributes can also be set. So e.g.:

sandbox()

Will return:

<div id="sandbox"></div>

And:

sandbox({
  id: 'my-id',
  class: 'my-class',
  myattr: 'my-attr'
})

Will return:

<div id="my-id" class="my-class" myattr="my-attr"></div>

Sandbox method is useful if you want to quickly create simple fixtures in your tests without polluting them with HTML strings:

setFixtures(sandbox({class: 'my-class'}))
$('#sandbox').myTestedClassRemoverPlugin()
expect($('#sandbox')).not.toHaveClass('my-class')

This method also has a global shortcut available:

  • sandbox([{attributeName: value[, attributeName: value, ...]}])

Additionally, two clean up methods are provided:

  • clearCache()
    • purges Fixture module internal cache (you should need it only in very special cases; typically, if you need to use it, it may indicate a smell in your test code)
  • cleanUp()
    • cleans-up fixtures container (this is done automatically between tests by Fixtures module, so there is no need to ever invoke this manually, unless you're testing a really fancy special case and need to clean-up fixtures in the middle of your test)

These two methods do not have global shortcut functions.

Style Fixtures

The StyleFixtures module is pretty much like the Fixtures module, but it allows you to load CSS content on the page while testing. It may be useful if your tests expect that certain css rules are applied to elements that you are testing. The overall workflow is typically the same:

In mycssfixture.css file:

.elem { position: absolute }

Inside your test:

loadStyleFixtures('mycssfixture.css')
$('#my-fixture').myTestedPlugin()
expect($('#my-fixture .elem')).toHaveCss({left: "300px"})

Notice that if you haven't applied the position: absolute rule to the .elem and try to test its left position in some browsers (e.g. GoogleChrome) you will allways get the value auto even if your plugin did everything correct and applied positioning. So that's why you might need to load style fixtures. In Firefox though you will get the correct value even without the position: absolute.

By default, style fixtures are loaded from spec/javascripts/fixtures. You can configure this path: jasmine.getStyleFixtures().fixturesPath = 'my/new/path';.

Like in Fixtures module, StyleFixtures are also automatically cleaned-up between tests and are internally cached, so you can load the same fixture file in several tests without penalty to your test suite's speed.

To invoke fixture related methods, obtain StyleFixtures singleton through a factory and invoke a method on it:

jasmine.getStyleFixtures().load(...)

There are also global shortcut functions available for the most used methods, so the above example can be rewritten to just:

loadStyleFixtures(...)

Several methods for loading fixtures are provided:

  • load(fixtureUrl[, fixtureUrl, ...])
    • Loads fixture(s) from one or more files and automatically appends them to the DOM into the HEAD element. This method will remove all existing fixtures loaded previously, if any.
  • appendLoad(fixtureUrl[, fixtureUrl, ...])
    • Same as load, but it won't remove fixtures you added earlier.
  • set(css)
    • Doesn't load fixture from file, but instead gets it directly as a parameter (e.g. set('body {background: red}')). Automatically appends style to the DOM. It is useful if your css fixture is too simple to keep it in an external file. This method will remove all existing fixtures loaded previously, if any.
  • appendSet(css)
    • Same as set, but it won't remove fixtures you added earlier.
  • preload(fixtureUrl[, fixtureUrl, ...])
    • Pre-loads fixture(s) from one or more files and stores them into cache, without returning them or appending them to the DOM. All subsequent calls to load methods will then get fixtures content from cache, without making any AJAX calls (unless cache is manually purged by using clearCache method).

All of above methods have matching global shortcuts:

  • loadStyleFixtures(fixtureUrl[, fixtureUrl, ...])
  • appendLoadStyleFixtures(fixtureUrl[, fixtureUrl, ...])
  • setStyleFixtures(css)
  • appendSetStyleFixtures(css)

Additionally, two clean up methods are provided:

  • clearCache()
    • purges StyleFixture module internal cache (you should need it only in very special cases; typically, if you need to use it, it may indicate a smell in your test code)
  • cleanUp()
    • cleans-up all existing style fixtures (this is done automatically between tests, so there is no need to ever invoke this manually, unless you're testing a really fancy special case and need to clean-up fixtures in the middle of your test)

These two methods do not have global shortcut functions.

JSON Fixtures

The JSONFixtures modules allows you to load JSON data from file (instead of putting huge blocks of data in the spec files).

In myjsonfixture.json file:

{"property1":"value1", "array1":[1,2,3]}

Inside your test:

var data = getJSONFixture('myjsonfixture.json')
// or load and get the JSON two-step
var fixtures = loadJSONFixtures('myjsonfixture.json')
var data = fixtures['myjsonfixture.json']

expect(myDataManipulator.processData(test_data)).to...)

By default, fixtures are loaded from spec/javascripts/fixtures/json. You can configure this path: jasmine.getJSONFixtures().fixturesPath = 'my/new/path';.

Your fixture data is loaded into an object stashed by the JSONFixtures structure. You fetch the data using the filename as the key. This allows you to load multiple chunks of test data in a spec.

Because a deep copy of Javascript objects can be a little tricky, this module will refetch data each time you call load. If you modify the data within a spec, you must call load or loadJSONFixtures again to repopulate the data.

To invoke fixture related methods, obtain Fixtures singleton through a factory and invoke a method on it:

jasmine.getJSONFixtures().load(...)

There are also global shortcut functions available for the most used methods, so the above example can be rewritten to just:

loadJSONFixtures(...)

Several methods for loading fixtures are provided:

  • load(fixtureUrl[, fixtureUrl, ...])
    • Loads fixture(s) from one or more files and automatically adds them to the fixture list. This method returns the entire set of fixtures keyed by their filename.

All of above methods have matching global shortcuts:

  • loadJSONFixtures(fixtureUrl[, fixtureUrl, ...])

  • getJSONFixture(fixtureUrl)

    • After you've loaded fixture files, this global helper will retrieve the fixture data given the fixtureUrl

Event Spies

Spying on jQuery events can be done with spyOnEvent and expect(eventName).toHaveBeenTriggeredOn(selector) or expect(spyEvent).toHaveBeenTriggered() . First, spy on the event:

var spyEvent = spyOnEvent('#some_element', 'click')
$('#some_element').click()
expect('click').toHaveBeenTriggeredOn('#some_element')
expect(spyEvent).toHaveBeenTriggered()

You can reset spy events

var spyEvent = spyOnEvent('#some_element', 'click')
$('#some_element').click()
expect('click').toHaveBeenTriggeredOn('#some_element')
expect(spyEvent).toHaveBeenTriggered()
// reset spy events
spyEvent.reset()
expect('click').not.toHaveBeenTriggeredOn('#some_element')
expect(spyEvent).not.toHaveBeenTriggered()

You can similarly check if triggered event was prevented:

var spyEvent = spyOnEvent('#some_element', 'click')
$('#some_element').click(function (event){event.preventDefault();})
$('#some_element').click()
expect('click').toHaveBeenPreventedOn('#some_element')
expect(spyEvent).toHaveBeenPrevented()

You can also check if the triggered event was stopped:

var spyEvent = spyOnEvent('#some_element', 'click')
$('#some_element').click(function (event){event.stopPropagation();})
$('#some_element').click()
expect('click').toHaveBeenStoppedOn('#some_element')
expect(spyEvent).toHaveBeenStopped()

Many thanks to Luiz Fernando Ribeiro for his article on Jasmine event spies.

Dependencies

jasmine-jquery v2.0.0+ is to be used with jasmine v2.0.0+. jasmine-jquery v1.7.0 is to be used with jasmine < v2.0.0.

jasmine-jquery is tested with jQuery 2.0 on IE, FF, Chrome, and Safari. There is a high chance it will work with older versions and other browsers as well, but I don't typically run test suite against them when adding new features.

Cross domain policy problems under Chrome

Newer versions of Chrome don't allow file:// URIs read other file:// URIs. In effect, jasmine-jquery cannot properly load fixtures under some versions of Chrome. An override for this is to run Chrome with a switch --allow-file-access-from-files. (#4). Quit open Chromes before running Chrome with that switch. (#179).

Under Windows 7, you have to launch C:\Users\[UserName]\AppData\Local\Google\Chrome[ SxS]\Application\chrome.exe --allow-file-access-from-files

Mocking with jasmine-ajax

jasmine-ajax library doesn't let user to manually start / stop XMLHttpRequest mocking, but instead it overrides XMLHttpRequest automatically when loaded. This breaks jasmine-jquery fixtures as fixture loading mechanism uses jQuery.ajax, that stops to function the very moment jasmine-ajax is loaded. A workaround for this may be to invoke jasmine-jquery preloadFixtures function (specifying all required fixtures) before jasmine-ajax is loaded. This way subsequent calls to loadFixtures or readFixtures methods will get fixtures content from cache, without need to use jQuery.ajax and thus will work correctly even after jasmine-ajax is loaded.

Testing with Javascript Test Driver

When using jstd and the jasmine adapter you will need to include jasmine-jquery.js after your jasmine-jstd-adapter files, otherwise jasmine-jquery matchers will not be available when tests are executed. Check out this issue for a thorough configuration example too.

Maintainer

Travis Jeffery: Twitter, GitHub.

jasmine-jquery's People

Contributors

bnadlerjr avatar bsingr avatar craigbrett17 avatar cs09g avatar dhamidi avatar elijahmanor avatar evizitei avatar f1sherman avatar fojas avatar garrypolley avatar gfranko avatar glenngillen avatar guyroyse avatar hrs avatar jandudulski avatar jcouyang avatar jivagoalves avatar jorgemanrubia avatar kkirsche avatar lalunamel avatar lin4ipsum avatar ljharb avatar mackuba avatar r4j4h avatar richardiux avatar samcrang avatar travisjeffery avatar velesin avatar wbotelhos avatar wireframe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jasmine-jquery's Issues

jasmine.Fixtures using real AJAX call - when fixture file does not exist - should throw an exception Expected function to throw an exception.

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

loadFixtures('my-fixture.htm') not finding URL

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();
    });

});

Issue

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"});

Adding jasmine-jquery to a rails project fails all tests with TypeError: Cannot call method 'remove' of null

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.

spyOnEvent & toHaveBeenTriggeredOn work with jQuery objects, NOT selectors

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?

toHandle doesn't work with $(window)

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'
});

Test use cases where jQuery is unavailable

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?

Handle colors when using toHaveCss() matcher

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

Default path for fixtures

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

jasmin-jquery should be usable with jQuery.noConflict

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.

loadFixtures() doesn't warn when fixture file does not exist

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!

jasmine does not have method getFixtures

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;

does contain getFixtures.

Replicate

See/get the code, I set up a repo for this issue.
To run the tests:

  1. Update the browser path in test/run-tests.sh (at the end) to your own path to Chrome. If you're on Linux, it's probably /usr/bin/google-chrome.
  2. Run sh run-tests.sh in the command-line (cygwin is fine).

Issue loading multiple fixtures when running multiple specs

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?

fixtures and haml

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?

Conflict with jasmine-ajax

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.

jasmine.JQuery.elementToString reloads <script> tags

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()

toContainHtml

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>");

TypeError: Cannot call method 'cleanUp' of undefined

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();

toHaveBeenTriggeredOn succeeds even if non-existing event was triggered

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.

Can't kill the server

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

Issue with loading fixture

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(...)
      })

})

Please mention issue #4 in documentation

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.

How to test an event handlers that calls stopImmediatePropagation()

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.

toExist doesn't work as I'd expect

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;
}

strange issue where jquery .show('fast') works when called the first time but not when called again

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);

toBeVisible does not work with display:inline

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.

loadFixtures erroring with JSTD

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.

toHandleWith won't work with delegate

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:

  1. Test for live in your spec instead of click.
  2. Modify toHandleWith to iterate over live if found, looking for your tested event in origType. (Preferred method)

It may also be counterintuitive for some to test the delegator instead of the delegatee.

jquery matchers on document.documentElement break jasmine engine

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

toHaveCss test in jasmin-jquery-spec fails

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

Update to JQuery 1.8.0

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.

Chrome XMLHttpRequest cannot load

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.

How about toHaveCss?

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?

Request to add toBeEnabled

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

toHandle doesn't work with namespaced click events

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...

toHandle throws an error if event is not present in data("events")

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;
},

Play nice with Prototype

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 $.

Requesting best practices suggestion for fixture path

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

Matchers always passing?

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?

toBe rewritten to use 'is', but only works with a selector string when jquery can accept element or jquery object

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.

Maintainer

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

toHaveAttr(attributeName, attributeValue)

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'.

JsTestDriver integration

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

TypeError: Cannot call method 'isDefaultPrevented' of undefined

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.