diff --git a/common/lib/xmodule/xmodule/js/spec/helper.coffee b/common/lib/xmodule/xmodule/js/spec/helper.coffee index 1a4f4cbb28..026ff1133b 100644 --- a/common/lib/xmodule/xmodule/js/spec/helper.coffee +++ b/common/lib/xmodule/xmodule/js/spec/helper.coffee @@ -144,6 +144,23 @@ jasmine.stubVideoPlayer = (context, enableParts, html5=false) -> jasmine.stubYoutubePlayer() return new Video '#example', '.75:7tqY6eQzVhE,1.0:cogebirgzzM' +# Add custom matchers +beforeEach -> + @addMatchers + toHaveAttrs: (attrs) -> + element = @.actual + result = true + if $.isEmptyObject attrs + return false + $.each attrs, (name, value) -> + result = result && element.attr(name) == value + return result + + toBeInRange: (min, max) -> + return min <= @.actual && @.actual <= max + + toBeInArray: (array) -> + return $.inArray(@.actual, array) > -1 # Stub jQuery.cookie $.cookie = jasmine.createSpy('jQuery.cookie').andReturn '1.0' 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 56973fe10d..29f4567c8a 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 @@ -46,6 +46,15 @@ expect($('.video')).toContain('a.hide-subtitles'); }); + it('add ARIA attributes to caption control', function () { + var captionControl = $('a.hide-subtitles'); + expect(captionControl).toHaveAttrs({ + 'role': 'button', + 'title': 'Turn off captions', + 'aria-disabled': 'false' + }); + }); + it('fetch the caption', function () { waitsFor(function () { if (videoCaption.loaded === true) { @@ -640,6 +649,11 @@ it('hide the caption', function () { expect(state.el).toHaveClass('closed'); }); + + it('changes ARIA attribute of caption control', function () { + expect($('a.hide-subtitles')) + .toHaveAttr('title', 'Turn on captions'); + }); }); describe('when the caption is hidden', function () { @@ -663,6 +677,11 @@ expect(state.el).not.toHaveClass('closed'); }); + it('changes ARIA attribute of caption control', function () { + expect($('a.hide-subtitles')) + .toHaveAttr('title', 'Turn off captions'); + }); + // Test turned off due to flakiness (30.10.2013). xit('scroll the caption', function () { // After transcripts are shown, and the video plays for a diff --git a/common/lib/xmodule/xmodule/js/spec/video/video_control_spec.js b/common/lib/xmodule/xmodule/js/spec/video/video_control_spec.js index b10210283a..1c6912cb79 100644 --- a/common/lib/xmodule/xmodule/js/spec/video/video_control_spec.js +++ b/common/lib/xmodule/xmodule/js/spec/video/video_control_spec.js @@ -30,6 +30,34 @@ expect($('.video-controls').find('.vidtime')).toHaveText('0:00 / 0:00'); }); + it('add ARIA attributes to time control', function () { + var timeControl = $('div.slider>a'); + expect(timeControl).toHaveAttrs({ + 'role': 'slider', + 'title': 'video position', + 'aria-disabled': 'false' + }); + expect(timeControl).toHaveAttr('aria-valuetext'); + }); + + it('add ARIA attributes to play control', function () { + var playControl = $('ul.vcr a'); + expect(playControl).toHaveAttrs({ + 'role': 'button', + 'title': 'Play', + 'aria-disabled': 'false' + }); + }); + + it('add ARIA attributes to fullscreen control', function () { + var fullScreenControl = $('a.add-fullscreen'); + expect(fullScreenControl).toHaveAttrs({ + 'role': 'button', + 'title': 'Fill browser', + 'aria-disabled': 'false' + }); + }); + it('bind the playback button', function() { expect($('.video_control')).toHandleWith('click', videoControl.togglePlayback); }); diff --git a/common/lib/xmodule/xmodule/js/spec/video/video_quality_control_spec.js b/common/lib/xmodule/xmodule/js/spec/video/video_quality_control_spec.js index 48f46a4ac2..d1749b48f1 100644 --- a/common/lib/xmodule/xmodule/js/spec/video/video_quality_control_spec.js +++ b/common/lib/xmodule/xmodule/js/spec/video/video_quality_control_spec.js @@ -22,8 +22,7 @@ }); describe('constructor', function() { - var oldYT = window.YT, - SELECTOR = 'a.quality_control'; + var oldYT = window.YT; beforeEach(function() { window.YT = { @@ -41,12 +40,21 @@ it('render the quality control', function() { var container = videoControl.secondaryControlsEl; - expect(container).toContain(SELECTOR); + expect(container).toContain('a.quality_control'); + }); + + it('add ARIA attributes to quality control', function () { + var qualityControl = $('a.quality_control'); + expect(qualityControl).toHaveAttrs({ + 'role': 'button', + 'title': 'HD off', + 'aria-disabled': 'false' + }); }); it('bind the quality control', function() { var handler = videoQualityControl.toggleQuality; - expect($(SELECTOR)).toHandleWith('click', handler); + expect($('a.quality_control')).toHandleWith('click', handler); }); }); }); diff --git a/common/lib/xmodule/xmodule/js/spec/video/video_speed_control_spec.js b/common/lib/xmodule/xmodule/js/spec/video/video_speed_control_spec.js index 2684fb738e..6836b2fcf6 100644 --- a/common/lib/xmodule/xmodule/js/spec/video/video_speed_control_spec.js +++ b/common/lib/xmodule/xmodule/js/spec/video/video_speed_control_spec.js @@ -42,6 +42,15 @@ }); }); + it('add ARIA attributes to speed control', function () { + var speedControl = $('div.speeds>a'); + expect(speedControl).toHaveAttrs({ + 'role': 'button', + 'title': 'Speeds', + 'aria-disabled': 'false' + }); + }); + it('bind to change video speed link', function() { expect($('.video_speeds a')).toHandleWith('click', videoSpeedControl.changeVideoSpeed); }); diff --git a/common/lib/xmodule/xmodule/js/spec/video/video_volume_control_spec.js b/common/lib/xmodule/xmodule/js/spec/video/video_volume_control_spec.js index 3412af2922..9e64a63b4d 100644 --- a/common/lib/xmodule/xmodule/js/spec/video/video_volume_control_spec.js +++ b/common/lib/xmodule/xmodule/js/spec/video/video_volume_control_spec.js @@ -45,6 +45,31 @@ }); }); + it('add ARIA attributes to slider handle', function () { + var sliderHandle = $('div.volume-slider>a.ui-slider-handle'), + arr = ['muted', 'very low', 'low', 'average', 'loud', 'very loud', + 'maximum']; + expect(sliderHandle).toHaveAttrs({ + 'role': 'slider', + 'title': 'volume', + 'aria-disabled': 'false', + 'aria-valuemin': '0', + 'aria-valuemax': '100' + }); + expect(sliderHandle.attr('aria-valuenow')).toBeInRange(0, 100); + expect(sliderHandle.attr('aria-valuetext')).toBeInArray(arr); + + }); + + it('add ARIA attributes to volume control', function () { + var volumeControl = $('div.volume>a'); + expect(volumeControl).toHaveAttrs({ + 'role': 'button', + 'title': 'Volume', + 'aria-disabled': 'false' + }); + }); + it('bind the volume control', function() { expect($('.volume>a')).toHandleWith('click', videoVolumeControl.toggleMute); expect($('.volume')).not.toHaveClass('open'); @@ -91,6 +116,62 @@ expect($('.volume')).toHaveClass('muted'); }); }); + + var initialData = [ + { + range: 'muted', + value: 0, + expectation: 'muted' + }, + { + range: 'in ]0,20]', + value: 10, + expectation: 'very low' + }, + { + range: 'in ]20,40]', + value: 30, + expectation: 'low' + }, + { + range: 'in ]40,60]', + value: 50, + expectation: 'average' + }, + { + range: 'in ]60,80]', + value: 70, + expectation: 'loud' + }, + { + range: 'in ]80,100[', + value: 90, + expectation: 'very loud' + }, + { + range: 'maximum', + value: 100, + expectation: 'maximum' + } + ]; + + $.each(initialData, function(index, data) { + describe('when the new volume is ' + data.range, function() { + beforeEach(function() { + videoVolumeControl.onChange(void 0, { + value: data.value + }); + }); + + it('changes ARIA attributes', function () { + var sliderHandle = $('div.volume-slider>a.ui-slider-handle'); + expect(sliderHandle).toHaveAttrs({ + 'aria-valuenow': data.value.toString(10), + 'aria-valuetext': data.expectation + }); + }); + }); + }); }); describe('toggleMute', function() {