Trying to write a unit test for my ember controller. It just changes a property and then opens a bootstrap modal. Having difficulty figuring out how to test that the modal actually gets opened. Not sure if this even belongs in a unit test or integration test. If it's not in my unit test it seems like it will be difficult to determine code coverage later down the line. Bootstrap version: 3.3.1, ember-cli version 0.1.5, node 0.10.33. Here is what I've tried to no avail:
1.
test('loginClick() opens modal', function(){
var controller = this.subject();
$('#login-modal').on('show.bs.modal', function(){
equal(true, true, "the show.bs.modal event fired");
});
controller.send('loginClick', 'anything');
});
no assertion error
2.
test('loginClick() opens modal', function(){
var controller = this.subject();
andThen(function(){
controller.send('loginClick', 'anything');
stop();
Ember.run.later(function(){
start();
equal($('#login-modal').hasClass('in'), true, "has the 'in' class");
}, 500);
});
});
andThen is not defined
Here is the controller:
loginClick: function(param){
this.set('provider', param);//facebook or google
$('#login-modal')
.modal();
}
Any other suggestions or best practices on how to test this kind of thing will be appreciated.
p.s. Also tried adding this before click:
$.support.transition = false;
per someone's suggestion, but it does not disable the modal transition.
I had the same problem. I’m not sure this is the best solution, but I solved it by registering an async test helper before calling App.injectTestHelpers():
Ember.Test.registerAsyncHelper 'waitForModalOpen', (app, modal) ->
# If using QUnit < 1.16, you need to add stop().
#stop()
Ember.Test.promise (resolve, reject) ->
modal.on 'shown.bs.modal', ->
resolve()
# If using QUnit < 1.16, you need to add start().
#start()
I then call it after clicking the button and before the assertions:
modal = find '#testModal'
click '#openModal'
waitForModalOpen modal
andThen ->
strictEqual modal.attr('aria-hidden'), 'false', 'modal should be visible'
strictEqual modal.hasClass('in'), true, 'modal should have .in class'
Here is a JS Bin testcase. QUnit 1.16 supports returning promises from tests, so with this version, calling stop() and start() is not needed anymore: QUnit will wait for the andThen() promise to resolve.
The ember-cli documentation has a section about writing your own test helpers.
Create the helper as /tests/helpers/wait-for-modal-open.js
:
import Ember from "ember";
export default Ember.Test.registerAsyncHelper('waitForModalOpen', function(app, modal) {
return Ember.Test.promise(function(resolve, reject) {
return modal.on('shown.bs.modal', function() {
return resolve();
});
});
});
Then, add this line in /tests/helpers/start-app.js
:
import waitForModalOpen from './wait-for-modal-open';
You also have to add "waitForModalOpen"
in the "predef"
array in /tests/.jshintrc
to avoid JSHint errors.
Finally, create the test as a file in /tests/integration
:
import Ember from "ember";
import { test } from 'ember-qunit';
import startApp from '../helpers/start-app';
var App;
module('Bootstrap Modal Open', {
setup: function() {
App = startApp();
return visit('/');
},
teardown: function() {
Ember.run(App, App.destroy);
}
});
test('clicking the button should open a modal', function() {
var modal;
modal = find('#testModal');
click('#openModal');
waitForModalOpen(modal);
return andThen(function() {
strictEqual(modal.attr('aria-hidden'), 'false', 'modal should be visible');
return strictEqual(modal.hasClass('in'), true, 'modal should have .in class');
});
});