Commit 7fca5e8b by brianhw

Merge pull request #1360 from edx/valera/carry_over_of_add_option_transcripts_remove_onhover_2

Valera/carry over of add option transcripts remove onhover 2
parents 5c883993 4b371d47
...@@ -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,6 +36,35 @@ Feature: CMS.Video Component ...@@ -31,6 +36,35 @@ 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
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"
...@@ -5,6 +5,11 @@ from terrain.steps import reload_the_page ...@@ -5,6 +5,11 @@ from terrain.steps import reload_the_page
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):
...@@ -17,8 +22,13 @@ def i_created_a_video_component(step): ...@@ -17,8 +22,13 @@ def i_created_a_video_component(step):
@step('I have created a Video component with subtitles$') @step('I have created a Video component with subtitles$')
def i_created_a_video_component_subtitles(step): def i_created_a_video_with_subs(_step):
step.given('I have created a Video component') _step.given('I have created a Video component with subtitles "OEoXaMPEzfM"')
@step('I have created a Video component with subtitles "([^"]*)"$')
def i_created_a_video_with_subs_with_name(_step, sub_id):
_step.given('I have created a Video component')
# Store the current URL so we can return here # Store the current URL so we can return here
video_url = world.browser.url video_url = world.browser.url
...@@ -108,3 +118,37 @@ def the_youtube_video_is_shown(_step): ...@@ -108,3 +118,37 @@ def the_youtube_video_is_shown(_step):
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')
...@@ -610,6 +610,8 @@ div.video { ...@@ -610,6 +610,8 @@ div.video {
ol.subtitles { ol.subtitles {
width: 0; width: 0;
height: 0; height: 0;
visibility: hidden;
} }
ol.subtitles.html5 { ol.subtitles.html5 {
...@@ -643,6 +645,8 @@ div.video { ...@@ -643,6 +645,8 @@ div.video {
ol.subtitles { ol.subtitles {
right: -(flex-grid(4)); right: -(flex-grid(4));
width: auto; width: auto;
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