From d4343309f86baf850e8dc9a669efd469379cd44d Mon Sep 17 00:00:00 2001 From: Valera Rozuvan Date: Wed, 18 Sep 2013 16:58:47 +0300 Subject: [PATCH] Fixing tests. Turned off jQuery animations. Went through all of the XModule tests and checked that all spying on window.setTimeout() function is done properly. --- .../combinedopenended/display_spec.coffee | 42 ++++++++++++++++--- .../js/spec/video/video_caption_spec.js | 15 +++++++ .../js/spec/video/video_focus_grabber_spec.js | 30 +++++++++---- .../spec/video/video_progress_slider_spec.js | 18 ++++++++ 4 files changed, 92 insertions(+), 13 deletions(-) diff --git a/common/lib/xmodule/xmodule/js/spec/combinedopenended/display_spec.coffee b/common/lib/xmodule/xmodule/js/spec/combinedopenended/display_spec.coffee index 293d6405ad..ef2c3cf0f9 100644 --- a/common/lib/xmodule/xmodule/js/spec/combinedopenended/display_spec.coffee +++ b/common/lib/xmodule/xmodule/js/spec/combinedopenended/display_spec.coffee @@ -48,17 +48,32 @@ describe 'CombinedOpenEnded', -> expect(@combined.task_count).toEqual 2 expect(@combined.task_number).toEqual 1 - it 'subelements are made collapsible', -> + it 'subelements are made collapsible', -> expect(Collapsible.setCollapsibles).toHaveBeenCalled() describe 'poll', -> + # We will store default window.setTimeout() function here. + oldSetTimeout = null + beforeEach => # setup the spies @combined = new CombinedOpenEnded @element spyOn(@combined, 'reload').andCallFake -> return 0 + + # Store original window.setTimeout() function. If we do not do this, then + # all other tests that rely on code which uses window.setTimeout() + # function might (and probably will) fail. + oldSetTimeout = window.setTimeout + # Redefine window.setTimeout() function as a spy. window.setTimeout = jasmine.createSpy().andCallFake (callback, timeout) -> return 5 + afterEach => + # Reset the default window.setTimeout() function. If we do not do this, + # then all other tests that rely on code which uses window.setTimeout() + # function might (and probably will) fail. + window.setTimeout = oldSetTimeout + it 'polls at the correct intervals', => fakeResponseContinue = state: 'not done' spyOn($, 'postWithPrefix').andCallFake (url, callback) -> callback(fakeResponseContinue) @@ -67,19 +82,34 @@ describe 'CombinedOpenEnded', -> expect(window.queuePollerID).toBe(5) it 'polling stops properly', => - fakeResponseDone = state: "done" + fakeResponseDone = state: "done" spyOn($, 'postWithPrefix').andCallFake (url, callback) -> callback(fakeResponseDone) @combined.poll() expect(window.queuePollerID).toBeUndefined() expect(window.setTimeout).not.toHaveBeenCalled() describe 'rebind', -> + # We will store default window.setTimeout() function here. + oldSetTimeout = null + beforeEach -> @combined = new CombinedOpenEnded @element spyOn(@combined, 'queueing').andCallFake -> return 0 spyOn(@combined, 'skip_post_assessment').andCallFake -> return 0 + + # Store original window.setTimeout() function. If we do not do this, then + # all other tests that rely on code which uses window.setTimeout() + # function might (and probably will) fail. + oldSetTimeout = window.setTimeout + # Redefine window.setTimeout() function as a spy. window.setTimeout = jasmine.createSpy().andCallFake (callback, timeout) -> return 5 + afterEach => + # Reset the default window.setTimeout() function. If we do not do this, + # then all other tests that rely on code which uses window.setTimeout() + # function might (and probably will) fail. + window.setTimeout = oldSetTimeout + it 'when our child is in an assessing state', -> @combined.child_state = 'assessing' @combined.rebind() @@ -87,19 +117,19 @@ describe 'CombinedOpenEnded', -> expect(@combined.submit_button.val()).toBe("Submit assessment") expect(@combined.queueing).toHaveBeenCalled() - it 'when our child state is initial', -> + it 'when our child state is initial', -> @combined.child_state = 'initial' @combined.rebind() expect(@combined.answer_area.attr("disabled")).toBeUndefined() expect(@combined.submit_button.val()).toBe("Submit") - it 'when our child state is post_assessment', -> + it 'when our child state is post_assessment', -> @combined.child_state = 'post_assessment' @combined.rebind() expect(@combined.answer_area.attr("disabled")).toBe("disabled") expect(@combined.submit_button.val()).toBe("Submit post-assessment") - it 'when our child state is done', -> + it 'when our child state is done', -> spyOn(@combined, 'next_problem').andCallFake -> @combined.child_state = 'done' @combined.rebind() @@ -112,7 +142,7 @@ describe 'CombinedOpenEnded', -> @combined.child_state = 'done' it 'handling a successful call', -> - fakeResponse = + fakeResponse = success: true html: "dummy html" allow_reset: false diff --git a/common/lib/xmodule/xmodule/js/spec/video/video_caption_spec.js b/common/lib/xmodule/xmodule/js/spec/video/video_caption_spec.js index 0b26573568..7751b80e51 100644 --- a/common/lib/xmodule/xmodule/js/spec/video/video_caption_spec.js +++ b/common/lib/xmodule/xmodule/js/spec/video/video_caption_spec.js @@ -146,12 +146,27 @@ }); describe('mouse movement', function() { + // We will store default window.setTimeout() function here. + var oldSetTimeout = null; + beforeEach(function() { + // Store original window.setTimeout() function. If we do not do this, then + // all other tests that rely on code which uses window.setTimeout() + // function might (and probably will) fail. + oldSetTimeout = window.setTimeout; + // Redefine window.setTimeout() function as a spy. window.setTimeout = jasmine.createSpy().andCallFake(function(callback, timeout) { return 5; }) window.setTimeout.andReturn(100); spyOn(window, 'clearTimeout'); }); + afterEach(function () { + // Reset the default window.setTimeout() function. If we do not do this, + // then all other tests that rely on code which uses window.setTimeout() + // function might (and probably will) fail. + window.setTimeout = oldSetTimeout; + }); + describe('when cursor is outside of the caption box', function() { beforeEach(function() { $(window).trigger(jQuery.Event('mousemove')); diff --git a/common/lib/xmodule/xmodule/js/spec/video/video_focus_grabber_spec.js b/common/lib/xmodule/xmodule/js/spec/video/video_focus_grabber_spec.js index 7a719bc62d..b2e8b6438b 100644 --- a/common/lib/xmodule/xmodule/js/spec/video/video_focus_grabber_spec.js +++ b/common/lib/xmodule/xmodule/js/spec/video/video_focus_grabber_spec.js @@ -3,6 +3,18 @@ var state; beforeEach(function () { + // https://github.com/pivotal/jasmine/issues/184 + // + // This is a known issue. jQuery animations depend on setTimeout + // and the jasmine mock clock stubs that function. You need to turn + // off jQuery animations ($.fx.off()) in a global beforeEach. + // + // I think this is a good pattern - you don't want animations + // messing with your tests. If you need to test with animations on + // I suggest you add incremental browser-based testing to your + // stack. + jQuery.fx.off = true; + loadFixtures('video_html5.html'); state = new Video('#example'); @@ -11,6 +23,11 @@ spyOn(state.focusGrabber, 'enableFocusGrabber').andCallThrough(); }); + afterEach(function () { + // Turn jQuery animations back on. + jQuery.fx.off = true; + }); + it('check existence of focus grabber elements and their position', function () { var firstFGEl = state.el.find('.focus_grabber.first'), lastFGEl = state.el.find('.focus_grabber.last'), @@ -31,28 +48,27 @@ }); it('when first focus grabber is focused "mousemove" event is triggered, grabbers are disabled', function () { - state.focusGrabber.elFirst.focus(); + state.focusGrabber.elFirst.triggerHandler('focus'); expect('mousemove').toHaveBeenTriggeredOn(state.el); expect(state.focusGrabber.disableFocusGrabber).toHaveBeenCalled(); }); it('when last focus grabber is focused "mousemove" event is triggered, grabbers are disabled', function () { - state.focusGrabber.elLast.focus(); + state.focusGrabber.elLast.triggerHandler('focus'); expect('mousemove').toHaveBeenTriggeredOn(state.el); expect(state.focusGrabber.disableFocusGrabber).toHaveBeenCalled(); }); - it('after controls autohide focus grabbers are enabled', function () { + it('after controls hide focus grabbers are enabled', function () { + runs(function () { - console.log('focus 1: a'); state.videoCaption.hideCaptions(true); - state.el.trigger('mousemove'); - console.log('focus 1: b'); + state.el.triggerHandler('mousemove'); }); - waits(2 * (state.videoControl.fadeOutTimeout + 100)); + waits(state.videoControl.fadeOutTimeout + 100); runs(function () { expect(state.focusGrabber.enableFocusGrabber).toHaveBeenCalled(); diff --git a/common/lib/xmodule/xmodule/js/spec/video/video_progress_slider_spec.js b/common/lib/xmodule/xmodule/js/spec/video/video_progress_slider_spec.js index 09a74e8e25..56481027a7 100644 --- a/common/lib/xmodule/xmodule/js/spec/video/video_progress_slider_spec.js +++ b/common/lib/xmodule/xmodule/js/spec/video/video_progress_slider_spec.js @@ -145,7 +145,18 @@ }); describe('onStop', function() { + // We will store default window.setTimeout() function here. + var oldSetTimeout = null; + beforeEach(function() { + // Store original window.setTimeout() function. If we do not do this, then + // all other tests that rely on code which uses window.setTimeout() + // function might (and probably will) fail. + oldSetTimeout = window.setTimeout; + // Redefine window.setTimeout() function as a spy. + window.setTimeout = jasmine.createSpy().andCallFake(function(callback, timeout) { return 5; }) + window.setTimeout.andReturn(100); + initialize(); spyOn(videoPlayer, 'onSlideSeek').andCallThrough(); videoProgressSlider.onStop({}, { @@ -153,6 +164,13 @@ }); }); + afterEach(function () { + // Reset the default window.setTimeout() function. If we do not do this, + // then all other tests that rely on code which uses window.setTimeout() + // function might (and probably will) fail. + window.setTimeout = oldSetTimeout; + }); + it('freeze the slider', function() { expect(videoProgressSlider.frozen).toBeTruthy(); });