Commit e3c0bb83 by Valera Rozuvan

Merge pull request #1183 from edx/valera/add_option_transcripts_remove_onhover

Valera/add option transcripts remove onhover
parents 009deb7d 2cc25873
...@@ -2,15 +2,18 @@ ...@@ -2,15 +2,18 @@
Feature: CMS.Video Component Feature: CMS.Video Component
As a course author, I want to be able to view my created videos in Studio. As a course author, I want to be able to view my created videos in Studio.
# 1
# Video Alpha Features will work in Firefox only when Firefox is the active window # Video Alpha Features will work in Firefox only when Firefox is the active window
Scenario: Autoplay is disabled in Studio Scenario: Autoplay is disabled in Studio
Given I have created a Video component Given I have created a Video component
Then when I view the video it does not have autoplay enabled Then when I view the video it does not have autoplay enabled
# 2
Scenario: Creating a video takes a single click Scenario: Creating a video takes a single click
Given I have clicked the new unit button Given I have clicked the new unit button
Then creating a video takes a single click Then creating a video takes a single click
# 3
# Sauce Labs cannot delete cookies # Sauce Labs cannot delete cookies
@skip_sauce @skip_sauce
Scenario: Captions are hidden correctly Scenario: Captions are hidden correctly
...@@ -18,12 +21,14 @@ Feature: CMS.Video Component ...@@ -18,12 +21,14 @@ Feature: CMS.Video Component
And I have hidden captions And I have hidden captions
Then when I view the video it does not show the captions Then when I view the video it does not show the captions
# 4
# Sauce Labs cannot delete cookies # Sauce Labs cannot delete cookies
@skip_sauce @skip_sauce
Scenario: Captions are shown correctly Scenario: Captions are shown correctly
Given I have created a Video component with subtitles Given I have created a Video component with subtitles
Then when I view the video it does show the captions Then when I view the video it does show the captions
# 5
# Sauce Labs cannot delete cookies # Sauce Labs cannot delete cookies
@skip_sauce @skip_sauce
Scenario: Captions are toggled correctly Scenario: Captions are toggled correctly
...@@ -31,7 +36,36 @@ Feature: CMS.Video Component ...@@ -31,7 +36,36 @@ Feature: CMS.Video Component
And I have toggled captions And I have toggled captions
Then when I view the video it does show the captions Then when I view the video it does show the captions
# 6
Scenario: Video data is shown correctly Scenario: Video data is shown correctly
Given I have created a video with only XML data Given I have created a video with only XML data
And I reload the page And I reload the page
Then the correct Youtube video is shown Then the correct Youtube video is shown
# 7
Scenario: Closed captions become visible when the mouse hovers over CC button
Given I have created a Video component with subtitles
And Make sure captions are closed
Then Captions become "invisible" after 3 seconds
And I hover over button "CC"
Then Captions become "visible"
And I hover over button "volume"
Then Captions become "invisible" after 3 seconds
# 8
Scenario: Open captions never become invisible
Given I have created a Video component with subtitles
And Make sure captions are open
Then Captions are "visible"
And I hover over button "CC"
Then Captions are "visible"
And I hover over button "volume"
Then Captions are "visible"
# 9
Scenario: Closed captions are invisible when mouse doesn't hover on CC button
Given I have created a Video component with subtitles
And Make sure captions are closed
Then Captions become "invisible" after 3 seconds
And I hover over button "volume"
Then Captions are "invisible"
...@@ -4,6 +4,11 @@ from lettuce import world, step ...@@ -4,6 +4,11 @@ from lettuce import world, step
from xmodule.modulestore import Location from xmodule.modulestore import Location
from contentstore.utils import get_modulestore from contentstore.utils import get_modulestore
BUTTONS = {
'CC': '.hide-subtitles',
'volume': '.volume',
}
@step('I have created a Video component$') @step('I have created a Video component$')
def i_created_a_video_component(step): def i_created_a_video_component(step):
...@@ -19,6 +24,7 @@ def i_created_a_video_component(step): ...@@ -19,6 +24,7 @@ def i_created_a_video_component(step):
def i_created_a_video_with_subs(_step): def i_created_a_video_with_subs(_step):
_step.given('I have created a Video component with subtitles "OEoXaMPEzfM"') _step.given('I have created a Video component with subtitles "OEoXaMPEzfM"')
@step('I have created a Video component with subtitles "([^"]*)"$') @step('I have created a Video component with subtitles "([^"]*)"$')
def i_created_a_video_with_subs_with_name(_step, sub_id): def i_created_a_video_with_subs_with_name(_step, sub_id):
_step.given('I have created a Video component') _step.given('I have created a Video component')
...@@ -115,3 +121,38 @@ def the_youtube_video_is_shown(_step): ...@@ -115,3 +121,38 @@ def the_youtube_video_is_shown(_step):
world.wait_for_xmodule() world.wait_for_xmodule()
ele = world.css_find('.video').first ele = world.css_find('.video').first
assert ele['data-streams'].split(':')[1] == world.scenario_dict['YOUTUBE_ID'] assert ele['data-streams'].split(':')[1] == world.scenario_dict['YOUTUBE_ID']
@step('Make sure captions are (.+)$')
def set_captions_visibility_state(_step, captions_state):
if captions_state == 'closed':
if world.css_visible('.subtitles'):
world.browser.find_by_css('.hide-subtitles').click()
else:
if not world.css_visible('.subtitles'):
world.browser.find_by_css('.hide-subtitles').click()
@step('I hover over button "([^"]*)"$')
def hover_over_button(_step, button):
world.css_find(BUTTONS[button.strip()]).mouse_over()
@step('Captions (?:are|become) "([^"]*)"$')
def are_captions_visibile(_step, visibility_state):
_step.given('Captions become "{0}" after 0 seconds'.format(visibility_state))
@step('Captions (?:are|become) "([^"]*)" after (.+) seconds$')
def check_captions_visibility_state(_step, visibility_state, timeout):
timeout = int(timeout.strip())
# Captions become invisible by fading out. We must wait by a specified
# time.
world.wait(timeout)
if visibility_state == 'visible':
assert world.css_visible('.subtitles')
else:
assert not world.css_visible('.subtitles')
...@@ -392,7 +392,7 @@ div.video { ...@@ -392,7 +392,7 @@ div.video {
@include transition(none); @include transition(none);
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
width: 30px; width: 30px;
&:hover, &:active { &:hover, &:active {
background-color: #444; background-color: #444;
color: #fff; color: #fff;
...@@ -457,7 +457,7 @@ div.video { ...@@ -457,7 +457,7 @@ div.video {
text-indent: -9999px; text-indent: -9999px;
@include transition(none); @include transition(none);
width: 30px; width: 30px;
&:hover, &:active { &:hover, &:active {
background-color: #444; background-color: #444;
color: #fff; color: #fff;
...@@ -611,6 +611,7 @@ div.video { ...@@ -611,6 +611,7 @@ div.video {
ol.subtitles { ol.subtitles {
width: 0; width: 0;
height: 0; height: 0;
visibility: hidden; visibility: hidden;
} }
...@@ -645,6 +646,7 @@ div.video { ...@@ -645,6 +646,7 @@ div.video {
ol.subtitles { ol.subtitles {
right: -(flex-grid(4)); right: -(flex-grid(4));
width: auto; width: auto;
visibility: hidden; visibility: hidden;
} }
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
data-autoplay="False" data-autoplay="False"
data-yt-test-timeout="1500" data-yt-test-timeout="1500"
data-yt-test-url="https://gdata.youtube.com/feeds/api/videos/" data-yt-test-url="https://gdata.youtube.com/feeds/api/videos/"
data-autohide-html5="True"
> >
<div class="focus_grabber first"></div> <div class="focus_grabber first"></div>
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
data-autoplay="False" data-autoplay="False"
data-yt-test-timeout="1500" data-yt-test-timeout="1500"
data-yt-test-url="https://gdata.youtube.com/feeds/api/videos/" data-yt-test-url="https://gdata.youtube.com/feeds/api/videos/"
data-autohide-html5="True"
> >
<div class="focus_grabber first"></div> <div class="focus_grabber first"></div>
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
data-autoplay="False" data-autoplay="False"
data-yt-test-timeout="1500" data-yt-test-timeout="1500"
data-yt-test-url="https://gdata.youtube.com/feeds/api/videos/" data-yt-test-url="https://gdata.youtube.com/feeds/api/videos/"
data-autohide-html5="True"
> >
<div class="focus_grabber first"></div> <div class="focus_grabber first"></div>
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
data-autoplay="False" data-autoplay="False"
data-yt-test-timeout="1500" data-yt-test-timeout="1500"
data-yt-test-url="https://gdata.youtube.com/feeds/api/videos/" data-yt-test-url="https://gdata.youtube.com/feeds/api/videos/"
data-autohide-html5="True"
> >
<div class="focus_grabber first"></div> <div class="focus_grabber first"></div>
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
data-autoplay="False" data-autoplay="False"
data-yt-test-timeout="1500" data-yt-test-timeout="1500"
data-yt-test-url="https://gdata.youtube.com/feeds/api/videos/" data-yt-test-url="https://gdata.youtube.com/feeds/api/videos/"
data-autohide-html5="True"
> >
<div class="focus_grabber first"></div> <div class="focus_grabber first"></div>
...@@ -73,6 +74,8 @@ ...@@ -73,6 +74,8 @@
data-autoplay="False" data-autoplay="False"
data-yt-test-timeout="1500" data-yt-test-timeout="1500"
data-yt-test-url="https://gdata.youtube.com/feeds/api/videos/" data-yt-test-url="https://gdata.youtube.com/feeds/api/videos/"
data-autohide-html5="True"
> >
<div class="tc-wrapper"> <div class="tc-wrapper">
<article class="video-wrapper"> <article class="video-wrapper">
...@@ -130,6 +133,8 @@ ...@@ -130,6 +133,8 @@
data-autoplay="False" data-autoplay="False"
data-yt-test-timeout="1500" data-yt-test-timeout="1500"
data-yt-test-url="https://gdata.youtube.com/feeds/api/videos/" data-yt-test-url="https://gdata.youtube.com/feeds/api/videos/"
data-autohide-html5="True"
> >
<div class="tc-wrapper"> <div class="tc-wrapper">
<article class="video-wrapper"> <article class="video-wrapper">
......
...@@ -264,15 +264,21 @@ function (VideoPlayer) { ...@@ -264,15 +264,21 @@ function (VideoPlayer) {
// The function set initial configuration and preparation. // The function set initial configuration and preparation.
function initialize(element) { function initialize(element) {
var _this = this, tempYtTestTimeout; var _this = this,
regExp = /^true$/i,
data, tempYtTestTimeout;
// This is used in places where we instead would have to check if an // This is used in places where we instead would have to check if an
// element has a CSS class 'fullscreen'. // element has a CSS class 'fullscreen'.
this.isFullScreen = false; this.isFullScreen = false;
// The parent element of the video, and the ID. // The parent element of the video, and the ID.
this.el = $(element).find('.video'); this.el = $(element).find('.video');
this.elVideoWrapper = this.el.find('.video-wrapper');
this.id = this.el.attr('id').replace(/video_/, ''); this.id = this.el.attr('id').replace(/video_/, '');
// jQuery .data() return object with keys in lower camelCase format.
data = this.el.data();
console.log( console.log(
'[Video info]: Initializing video with id "' + this.id + '".' '[Video info]: Initializing video with id "' + this.id + '".'
); );
...@@ -283,32 +289,26 @@ function (VideoPlayer) { ...@@ -283,32 +289,26 @@ function (VideoPlayer) {
this.config = { this.config = {
element: element, element: element,
start: this.el.data('start'), start: data['start'],
end: this.el.data('end'), end: data['end'],
caption_data_dir: data['captionDataDir'],
caption_data_dir: this.el.data('caption-data-dir'), caption_asset_path: data['captionAssetPath'],
caption_asset_path: this.el.data('caption-asset-path'), show_captions: regExp.test(data['showCaptions'].toString()),
show_captions: ( youtubeStreams: data['streams'],
this.el.data('show-captions') autohideHtml5: regExp.test(data['autohideHtml5'].toString()),
.toString().toLowerCase() === 'true' sub: data['sub'],
), mp4Source: data['mp4Source'],
youtubeStreams: this.el.data('streams'), webmSource: data['webmSource'],
oggSource: data['oggSource'],
sub: this.el.data('sub'), ytTestUrl: data['ytTestUrl'],
mp4Source: this.el.data('mp4-source'),
webmSource: this.el.data('webm-source'),
oggSource: this.el.data('ogg-source'),
ytTestUrl: this.el.data('yt-test-url'),
fadeOutTimeout: 1400, fadeOutTimeout: 1400,
captionsFreezeTime: 10000,
availableQualities: ['hd720', 'hd1080', 'highres'] availableQualities: ['hd720', 'hd1080', 'highres']
}; };
// Check if the YT test timeout has been set. If not, or it is in // Check if the YT test timeout has been set. If not, or it is in
// improper format, then set to default value. // improper format, then set to default value.
tempYtTestTimeout = parseInt(this.el.data('yt-test-timeout'), 10); tempYtTestTimeout = parseInt(data['ytTestTimeout'], 10);
if (!isFinite(tempYtTestTimeout)) { if (!isFinite(tempYtTestTimeout)) {
tempYtTestTimeout = 1500; tempYtTestTimeout = 1500;
} }
......
...@@ -57,7 +57,7 @@ function () { ...@@ -57,7 +57,7 @@ function () {
state.videoControl.play(); state.videoControl.play();
} }
if (state.videoType === 'html5') { if ((state.videoType === 'html5') && (state.config.autohideHtml5)) {
state.videoControl.fadeOutTimeout = state.config.fadeOutTimeout; state.videoControl.fadeOutTimeout = state.config.fadeOutTimeout;
state.videoControl.el.addClass('html5'); state.videoControl.el.addClass('html5');
...@@ -81,7 +81,7 @@ function () { ...@@ -81,7 +81,7 @@ function () {
state.videoControl.fullScreenEl.on('click', state.videoControl.toggleFullScreen); state.videoControl.fullScreenEl.on('click', state.videoControl.toggleFullScreen);
$(document).on('keyup', state.videoControl.exitFullScreen); $(document).on('keyup', state.videoControl.exitFullScreen);
if (state.videoType === 'html5') { if ((state.videoType === 'html5') && (state.config.autohideHtml5)) {
state.el.on('mousemove', state.videoControl.showControls); state.el.on('mousemove', state.videoControl.showControls);
state.el.on('keydown', state.videoControl.showControls); state.el.on('keydown', state.videoControl.showControls);
} }
......
...@@ -2,38 +2,45 @@ ...@@ -2,38 +2,45 @@
Feature: LMS.Video component Feature: LMS.Video component
As a student, I want to view course videos in LMS. As a student, I want to view course videos in LMS.
# 1
Scenario: Video component is fully rendered in the LMS in HTML5 mode Scenario: Video component is fully rendered in the LMS in HTML5 mode
Given the course has a Video component in HTML5 mode Given the course has a Video component in HTML5 mode
Then when I view the video it has rendered in HTML5 mode Then when I view the video it has rendered in HTML5 mode
And all sources are correct And all sources are correct
# 2
# Firefox doesn't have HTML5 (only mp4 - fix here) # Firefox doesn't have HTML5 (only mp4 - fix here)
@skip_firefox @skip_firefox
Scenario: Autoplay is disabled in LMS for a Video component Scenario: Autoplay is disabled in LMS for a Video component
Given the course has a Video component in HTML5 mode Given the course has a Video component in HTML5 mode
Then when I view the video it does not have autoplay enabled Then when I view the video it does not have autoplay enabled
# 3
# Youtube testing # Youtube testing
Scenario: Video component is fully rendered in the LMS in Youtube mode with HTML5 sources Scenario: Video component is fully rendered in the LMS in Youtube mode with HTML5 sources
Given youtube server is up and response time is 0.4 seconds Given youtube server is up and response time is 0.4 seconds
And the course has a Video component in Youtube_HTML5 mode And the course has a Video component in Youtube_HTML5 mode
Then when I view the video it has rendered in Youtube mode Then when I view the video it has rendered in Youtube mode
# 4
Scenario: Video component is not rendered in the LMS in Youtube mode with HTML5 sources Scenario: Video component is not rendered in the LMS in Youtube mode with HTML5 sources
Given youtube server is up and response time is 2 seconds Given youtube server is up and response time is 2 seconds
And the course has a Video component in Youtube_HTML5 mode And the course has a Video component in Youtube_HTML5 mode
Then when I view the video it has rendered in HTML5 mode Then when I view the video it has rendered in HTML5 mode
# 5
Scenario: Video component is rendered in the LMS in Youtube mode without HTML5 sources Scenario: Video component is rendered in the LMS in Youtube mode without HTML5 sources
Given youtube server is up and response time is 2 seconds Given youtube server is up and response time is 2 seconds
And the course has a Video component in Youtube mode And the course has a Video component in Youtube mode
Then when I view the video it has rendered in Youtube mode Then when I view the video it has rendered in Youtube mode
# 6
Scenario: Video component is rendered in the LMS in Youtube mode with HTML5 sources that doesn't supported by browser Scenario: Video component is rendered in the LMS in Youtube mode with HTML5 sources that doesn't supported by browser
Given youtube server is up and response time is 2 seconds Given youtube server is up and response time is 2 seconds
And the course has a Video component in Youtube_HTML5_Unsupported_Video mode And the course has a Video component in Youtube_HTML5_Unsupported_Video mode
Then when I view the video it has rendered in Youtube mode Then when I view the video it has rendered in Youtube mode
# 7
Scenario: Video component is rendered in the LMS in HTML5 mode with HTML5 sources that doesn't supported by browser Scenario: Video component is rendered in the LMS in HTML5 mode with HTML5 sources that doesn't supported by browser
Given the course has a Video component in HTML5_Unsupported_Video mode Given the course has a Video component in HTML5_Unsupported_Video mode
Then error message is shown Then error message is shown
......
...@@ -26,6 +26,19 @@ ...@@ -26,6 +26,19 @@
data-yt-test-timeout="${yt_test_timeout}" data-yt-test-timeout="${yt_test_timeout}"
data-yt-test-url="${yt_test_url}" data-yt-test-url="${yt_test_url}"
## For now, the option "data-autohide-html5" is hard coded. This option
## either enables or disables autohiding of controls and captions on mouse
## inactivity. If set to true, controls and captions will autohide for
## HTML5 sources (non-YouTube) after a period of mouse inactivity over the
## whole video. When the mouse moves (or a key is pressed while any part of
## the video player is focused), the captions and controls will be shown
## once again.
##
## There is no option in the "Advanced Editor" to set this option. However,
## this option will have an effect if changed to "True". The code on
## front-end exists.
data-autohide-html5="False"
tabindex="-1" tabindex="-1"
> >
<div class="focus_grabber first"></div> <div class="focus_grabber first"></div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment