Commit 9d9f28da by Valera Rozuvan

Merge pull request #3275 from edx/valera/l52a

TESTS: Add tests for fix of end-time functionality in the video player
parents dc373f22 450dfe17
......@@ -117,7 +117,7 @@
runs(function () {
expect(state.videoPlayer.player.getPlayerState())
.toBe(STATUS.PLAYING);
.toBe(STATUS.BUFFERING);
});
});
......
......@@ -366,19 +366,22 @@ function (VideoPlayer) {
});
it('Slider event causes log update', function () {
runs(function () {
var currentTime = state.videoPlayer.currentTime;
spyOn(state.videoPlayer, 'log');
state.videoProgressSlider.onSlide(
jQuery.Event('slide'), { value: 2 }
);
});
waitsFor(function () {
return state.videoPlayer.currentTime >= 2;
}, 'currentTime is less than 2 seconds', WAIT_TIMEOUT);
runs(function () {
expect(state.videoPlayer.log).toHaveBeenCalledWith(
'seek_video',
{
old_time: currentTime,
old_time: jasmine.any(Number),
new_time: 2,
type: 'onSlideSeek'
}
......@@ -388,25 +391,37 @@ function (VideoPlayer) {
it('seek the player', function () {
runs(function () {
spyOn(state.videoPlayer.player, 'seekTo');
spyOn(state.videoPlayer.player, 'seekTo').andCallThrough();
state.videoProgressSlider.onSlide(
jQuery.Event('slide'), { value: 60 }
jQuery.Event('slide'), { value: 30 }
);
});
waitsFor(function () {
return state.videoPlayer.currentTime >= 30;
}, 'currentTime is less than 30 seconds', WAIT_TIMEOUT);
runs(function () {
expect(state.videoPlayer.player.seekTo)
.toHaveBeenCalledWith(60, true);
.toHaveBeenCalledWith(30, true);
});
});
it('call updatePlayTime on player', function () {
runs(function () {
spyOn(state.videoPlayer, 'updatePlayTime');
spyOn(state.videoPlayer, 'updatePlayTime').andCallThrough();
state.videoProgressSlider.onSlide(
jQuery.Event('slide'), { value: 60 }
jQuery.Event('slide'), { value: 30 }
);
});
waitsFor(function () {
return state.videoPlayer.currentTime >= 30;
}, 'currentTime is less than 30 seconds', WAIT_TIMEOUT);
runs(function () {
expect(state.videoPlayer.updatePlayTime)
.toHaveBeenCalledWith(60);
.toHaveBeenCalledWith(jasmine.any(Number));
});
});
......@@ -1070,6 +1085,7 @@ function (VideoPlayer) {
youtubeId: jasmine.createSpy().andReturn('videoId'),
isFlashMode: jasmine.createSpy().andReturn(false),
isHtml5Mode: jasmine.createSpy().andReturn(true),
isYoutubeType: jasmine.createSpy().andReturn(true),
setPlayerMode: jasmine.createSpy(),
videoPlayer: {
currentTime: 60,
......@@ -1104,12 +1120,12 @@ function (VideoPlayer) {
});
it('in HTML5 mode', function () {
state.isYoutubeType.andReturn(false);
VideoPlayer.prototype.setPlaybackRate.call(state, '0.75');
expect(state.videoPlayer.player.setPlaybackRate).toHaveBeenCalledWith('0.75');
});
it('Youtube video in FF, with new speed equal 1.0', function () {
state.videoType = 'youtube';
state.browserIsFirefox = true;
state.videoPlayer.isPlaying.andReturn(false);
......
......@@ -68,6 +68,7 @@ function (VideoPlayer, VideoStorage) {
initialize: initialize,
isHtml5Mode: isHtml5Mode,
isFlashMode: isFlashMode,
isYoutubeType: isYoutubeType,
parseSpeed: parseSpeed,
parseVideoSources: parseVideoSources,
parseYoutubeStreams: parseYoutubeStreams,
......@@ -847,6 +848,10 @@ function (VideoPlayer, VideoStorage) {
return this.getPlayerMode() === 'html5';
}
function isYoutubeType() {
return this.videoType === 'youtube';
}
function speedToString(speed) {
return parseFloat(speed).toFixed(2).replace(/\.00$/, '.0');
}
......
......@@ -275,12 +275,13 @@ function () {
// Register the 'play' event.
this.video.addEventListener('play', function () {
_this.playerState = HTML5Video.PlayerState.PLAYING;
_this.playerState = HTML5Video.PlayerState.BUFFERING;
_this.callStateChangeCallback();
}, false);
this.video.addEventListener('playing', function () {
_this.playerState = HTML5Video.PlayerState.PLAYING;
_this.callStateChangeCallback();
}, false);
// Register the 'pause' event.
......
......@@ -177,15 +177,26 @@ function () {
}
function onSlide(event, ui) {
var time = ui.value,
duration = this.videoPlayer.duration();
this.videoProgressSlider.frozen = true;
// Remember the seek to value so that we don't repeat ourselves on the
// 'stop' slider event.
this.videoProgressSlider.lastSeekValue = ui.value;
this.videoProgressSlider.lastSeekValue = time;
this.trigger(
'videoControl.updateVcrVidTime',
{
time: time,
duration: duration
}
);
this.trigger(
'videoPlayer.onSlideSeek',
{'type': 'onSlideSeek', 'time': ui.value}
{'type': 'onSlideSeek', 'time': time}
);
// ARIA
......
......@@ -35,7 +35,7 @@ def configure_screenshots_for_all_steps(_step, action):
else:
raise ValueError('Parameter `action` should be one of "enable" or "disable".')
@world.absorb
def capture_screenshot_before_after(func):
"""
A decorator that will take a screenshot before and after the applied
......
......@@ -2,18 +2,6 @@
Feature: LMS.Video component
As a student, I want to view course videos in LMS
# 1 Disabled 4/8/14 after intermittent failures in master
#Scenario: Video component stores position correctly when page is reloaded
# Given the course has a Video component in "Youtube" mode
# When the video has rendered in "Youtube" mode
# And I click video button "play"
# And I click video button "pause"
# Then I seek video to "10" seconds
# And I click video button "play"
# And I click video button "pause"
# And I reload the page with video
# Then I see video slider at "10" seconds
# 1
Scenario: Video component is fully rendered in the LMS in HTML5 mode
Given the course has a Video component in "HTML5" mode
......@@ -267,7 +255,106 @@ Feature: LMS.Video component
Then the video has rendered in "HTML5" mode
And the video does not show the captions
# 20 Disabled 4/8/14 after intermittent failures in master
# 20
Scenario: Start time works for Youtube video
Given I am registered for the course "test_course"
And it has a video in "Youtube" mode:
| start_time |
| 00:00:10 |
And I click video button "play"
Then I see video slider at "0:10" position
# 21
Scenario: End time works for Youtube video
Given I am registered for the course "test_course"
And it has a video in "Youtube" mode:
| end_time |
| 00:00:02 |
And I click video button "play"
And I wait "5" seconds
Then I see video slider at "0:02" position
# 22
Scenario: Youtube video with end-time at 1:00 and the video starts playing at 0:58
Given I am registered for the course "test_course"
And it has a video in "Youtube" mode:
| end_time |
| 00:01:00 |
And I wait for video controls appear
And I seek video to "0:58" position
And I click video button "play"
And I wait "5" seconds
Then I see video slider at "1:00" position
# 23
Scenario: Start time and end time work together for Youtube video
Given I am registered for the course "test_course"
And it has a video in "Youtube" mode:
| start_time | end_time |
| 00:00:10 | 00:00:12 |
And I click video button "play"
Then I see video slider at "0:10" position
And I wait "5" seconds
Then I see video slider at "0:12" position
# 24
Scenario: Youtube video after pausing at end time video plays to the end from end time
Given I am registered for the course "test_course"
And it has a video in "Youtube" mode:
| start_time | end_time |
| 00:01:51 | 00:01:52 |
And I click video button "play"
And I wait "5" seconds
# The end time is 00:01:52.
Then I see video slider at "1:52" position
And I click video button "play"
And I wait "8" seconds
# The default video length is 00:01:55.
Then I see video slider at "1:55" position
# 25
Scenario: Youtube video with end-time at 0:32 and start-time at 0:30, the video starts playing from 0:28
Given I am registered for the course "test_course"
And it has a video in "Youtube" mode:
| start_time | end_time |
| 00:00:30 | 00:00:32 |
And I wait for video controls appear
And I seek video to "0:28" position
And I click video button "play"
And I wait "8" seconds
Then I see video slider at "0:32" position
# 26
Scenario: Youtube video with end-time at 1:00, the video starts playing from 1:52
Given I am registered for the course "test_course"
And it has a video in "Youtube" mode:
| end_time |
| 00:01:00 |
And I wait for video controls appear
And I seek video to "1:52" position
And I click video button "play"
And I wait "5" seconds
# Video stops at the end.
Then I see video slider at "1:55" position
# 27
@skip_firefox
Scenario: Quality button appears on play
Given the course has a Video component in "Youtube" mode
Then I see video button "quality" is hidden
And I click video button "play"
Then I see video button "quality" is visible
# 28
@skip_firefox
Scenario: Quality button works correctly
Given the course has a Video component in "Youtube" mode
And I click video button "play"
And I see video button "quality" is inactive
And I click video button "quality"
Then I see video button "quality" is active
# 29 Disabled 4/8/14 after intermittent failures in master
#Scenario: Transcripts are available on different speeds of Flash mode
# Given I am registered for the course "test_course"
# And I have a "subs_OEoXaMPEzfM.srt.sjson" transcript file in assets
......@@ -282,7 +369,7 @@ Feature: LMS.Video component
# Then I select the "1.25" speed
# And I see "Hi, welcome to Edx." text in the captions
# 21 Disabled 4/8/14 after intermittent failures in master
# 30 Disabled 4/8/14 after intermittent failures in master
#Scenario: Elapsed time calculates correctly on different speeds of Flash mode
# Given I am registered for the course "test_course"
# And I have a "subs_OEoXaMPEzfM.srt.sjson" transcript file in assets
......@@ -298,19 +385,14 @@ Feature: LMS.Video component
# And I click video button "pause"
# And I click on caption line "2", video module shows elapsed time "4"
# 27
@skip_firefox
Scenario: Quality button appears on play
Given the course has a Video component in "Youtube" mode
Then I see video button "quality" is hidden
And I click video button "play"
Then I see video button "quality" is visible
# 28
@skip_firefox
Scenario: Quality button works correctly
Given the course has a Video component in "Youtube" mode
And I click video button "play"
And I see video button "quality" is inactive
And I click video button "quality"
Then I see video button "quality" is active
# 31 Disabled 4/8/14 after intermittent failures in master
#Scenario: Video component stores position correctly when page is reloaded
# Given the course has a Video component in "Youtube" mode
# When the video has rendered in "Youtube" mode
# And I click video button "play"
# And I click video button "pause"
# Then I seek video to "0:10" position
# And I click video button "play"
# And I click video button "pause"
# And I reload the page with video
# Then I see video slider at "0:10" position
......@@ -482,6 +482,7 @@ def check_captions(_step):
@step('I select language with code "([^"]*)"$')
def select_language(_step, code):
world.wait_for_visible('.video-controls')
# Make sure that all ajax requests that affects the language menu are finished.
# For example, request to get new translation etc.
world.wait_for_ajax_complete()
......@@ -506,16 +507,19 @@ def select_language(_step, code):
@step('I click video button "([^"]*)"$')
def click_button(_step, button):
world.css_click(VIDEO_BUTTONS[button])
world.wait_for_ajax_complete()
if button == "play":
# Needs to wait for video buffrization
world.wait_for(
func=lambda _: world.css_has_class('.video', 'is-playing') and world.is_css_present(VIDEO_BUTTONS['pause']),
timeout=30
)
world.wait_for_ajax_complete()
@step('I see video slider at "([^"]*)" seconds$')
def start_playing_video_from_n_seconds(_step, position):
world.wait_for(
func=lambda _: elapsed_time() > 0,
timeout=30
)
@step('I see video slider at "([^"]*)" position$')
def start_playing_video_from_n_seconds(_step, time_str):
position = parse_time_str(time_str)
actual_position = elapsed_time()
assert_equal(actual_position, int(position), "Current position is {}, but should be {}".format(actual_position, position))
......@@ -530,12 +534,21 @@ def i_see_duration(_step, position):
assert duration() == parse_time_str(position)
@step('I seek video to "([^"]*)" seconds$')
def seek_video_to_n_seconds(_step, seconds):
time = float(seconds.strip())
jsCode = "$('.video').data('video-player-state').videoPlayer.onSlideSeek({{time: {0:f}}})".format(time)
@step('I wait for video controls appear$')
def controls_appear(_step):
world.wait_for_visible('.video-controls')
@step('I seek video to "([^"]*)" position$')
def seek_video_to_n_seconds(_step, time_str):
time = parse_time_str(time_str)
jsCode = "$('.video').data('video-player-state').videoPlayer.onSlideSeek({{time: {0}}})".format(time)
world.browser.execute_script(jsCode)
_step.given('I see video slider at "{}" seconds'.format(seconds))
world.wait_for(
func=lambda _: world.retry_on_exception(lambda: elapsed_time() == time and not world.css_has_class('.video', 'is-buffering')),
timeout=30
)
_step.given('I see video slider at "{0}" position'.format(time_str))
@step('I have a "([^"]*)" transcript file in assets$')
......
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