TESTS: Add tests for fix of end-time in the video player.
BLD-662
This commit is contained in:
committed by
Valera Rozuvan
parent
dc373f22b1
commit
450dfe17b0
@@ -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.
|
||||
|
||||
@@ -17,13 +17,24 @@ function (HTML5Video, Resizer) {
|
||||
methodsDict = {
|
||||
duration: duration,
|
||||
handlePlaybackQualityChange: handlePlaybackQualityChange,
|
||||
|
||||
// Added for finer graded seeking control.
|
||||
// Please see:
|
||||
// https://developers.google.com/youtube/js_api_reference#Events
|
||||
isBuffering: isBuffering,
|
||||
// https://developers.google.com/youtube/js_api_reference#cueVideoById
|
||||
isCued: isCued,
|
||||
|
||||
isEnded: isEnded,
|
||||
isPlaying: isPlaying,
|
||||
isUnstarted: isUnstarted,
|
||||
log: log,
|
||||
onCaptionSeek: onSeek,
|
||||
onEnded: onEnded,
|
||||
onPause: onPause,
|
||||
onPlay: onPlay,
|
||||
runTimer: runTimer,
|
||||
stopTimer: stopTimer,
|
||||
onPlaybackQualityChange: onPlaybackQualityChange,
|
||||
onReady: onReady,
|
||||
onSlideSeek: onSeek,
|
||||
@@ -54,7 +65,17 @@ function (HTML5Video, Resizer) {
|
||||
// Functions which will be accessible via 'state' object. When called,
|
||||
// these functions will get the 'state' object as a context.
|
||||
function _makeFunctionsPublic(state) {
|
||||
var debouncedF = _.debounce(
|
||||
function (params) {
|
||||
return onSeek.call(this, params);
|
||||
}.bind(state),
|
||||
300
|
||||
);
|
||||
|
||||
state.bindTo(methodsDict, state.videoPlayer, state);
|
||||
|
||||
state.videoPlayer.onSlideSeek = debouncedF;
|
||||
state.videoPlayer.onCaptionSeek = debouncedF;
|
||||
}
|
||||
|
||||
// function _initialize(state)
|
||||
@@ -79,10 +100,10 @@ function (HTML5Video, Resizer) {
|
||||
state.videoPlayer.player.setVolume(state.currentVolume);
|
||||
});
|
||||
|
||||
if (state.videoType === 'youtube') {
|
||||
if (state.isYoutubeType()) {
|
||||
state.videoPlayer.PlayerState = YT.PlayerState;
|
||||
state.videoPlayer.PlayerState.UNSTARTED = -1;
|
||||
} else { // if (state.videoType === 'html5') {
|
||||
} else {
|
||||
state.videoPlayer.PlayerState = HTML5Video.PlayerState;
|
||||
}
|
||||
|
||||
@@ -139,7 +160,7 @@ function (HTML5Video, Resizer) {
|
||||
_updateVcrAndRegion(state);
|
||||
}, false);
|
||||
|
||||
} else { // if (state.videoType === 'youtube') {
|
||||
} else {
|
||||
youTubeId = state.youtubeId();
|
||||
|
||||
state.videoPlayer.player = new YT.Player(state.id, {
|
||||
@@ -305,8 +326,8 @@ function (HTML5Video, Resizer) {
|
||||
// This function gets the video's current play position in time
|
||||
// (currentTime) and its duration.
|
||||
// It is called at a regular interval when the video is playing.
|
||||
function update() {
|
||||
this.videoPlayer.currentTime = this.videoPlayer.player.getCurrentTime();
|
||||
function update(time) {
|
||||
this.videoPlayer.currentTime = time || this.videoPlayer.player.getCurrentTime();
|
||||
|
||||
if (isFinite(this.videoPlayer.currentTime)) {
|
||||
this.videoPlayer.updatePlayTime(this.videoPlayer.currentTime);
|
||||
@@ -339,7 +360,7 @@ function (HTML5Video, Resizer) {
|
||||
!(
|
||||
this.browserIsFirefox &&
|
||||
newSpeed === '1.0' &&
|
||||
this.videoType === 'youtube'
|
||||
this.isYoutubeType()
|
||||
)
|
||||
) {
|
||||
this.videoPlayer.player.setPlaybackRate(newSpeed);
|
||||
@@ -404,6 +425,7 @@ function (HTML5Video, Resizer) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.el.off('play.seek');
|
||||
this.videoPlayer.log(
|
||||
'seek_video',
|
||||
{
|
||||
@@ -420,24 +442,49 @@ function (HTML5Video, Resizer) {
|
||||
this.videoPlayer.stopAtEndTime = false;
|
||||
}
|
||||
|
||||
this.videoPlayer.player.seekTo(newTime, true);
|
||||
|
||||
if (this.videoPlayer.isPlaying()) {
|
||||
clearInterval(this.videoPlayer.updateInterval);
|
||||
this.videoPlayer.updateInterval = setInterval(
|
||||
this.videoPlayer.update, 200
|
||||
);
|
||||
|
||||
setTimeout(this.videoPlayer.update, 0);
|
||||
this.videoPlayer.stopTimer();
|
||||
} else {
|
||||
this.videoPlayer.currentTime = newTime;
|
||||
}
|
||||
var isUnplayed = this.videoPlayer.isUnstarted() ||
|
||||
this.videoPlayer.isCued();
|
||||
|
||||
this.videoPlayer.updatePlayTime(newTime);
|
||||
// Use `cueVideoById` method for youtube video that is not played before.
|
||||
if (isUnplayed && this.isYoutubeType()) {
|
||||
this.videoPlayer.player.cueVideoById(this.youtubeId(), newTime);
|
||||
} else {
|
||||
// Youtube video cannot be rewinded during bufferization, so wait to
|
||||
// finish bufferization and then rewind the video.
|
||||
if (this.isYoutubeType() && this.videoPlayer.isBuffering()) {
|
||||
this.el.on('play.seek', function () {
|
||||
this.videoPlayer.player.seekTo(newTime, true);
|
||||
}.bind(this));
|
||||
} else {
|
||||
// Otherwise, just seek the video
|
||||
this.videoPlayer.player.seekTo(newTime, true);
|
||||
}
|
||||
}
|
||||
|
||||
this.videoPlayer.updatePlayTime(newTime, true);
|
||||
this.el.trigger('seek', arguments);
|
||||
}
|
||||
|
||||
function runTimer() {
|
||||
if (!this.videoPlayer.updateInterval) {
|
||||
this.videoPlayer.updateInterval = window.setInterval(
|
||||
this.videoPlayer.update, 200
|
||||
);
|
||||
|
||||
this.videoPlayer.update();
|
||||
}
|
||||
}
|
||||
|
||||
function stopTimer() {
|
||||
window.clearInterval(this.videoPlayer.updateInterval);
|
||||
delete this.videoPlayer.updateInterval;
|
||||
}
|
||||
|
||||
function onEnded() {
|
||||
var time = this.videoPlayer.duration();
|
||||
|
||||
@@ -466,8 +513,7 @@ function (HTML5Video, Resizer) {
|
||||
}
|
||||
);
|
||||
|
||||
clearInterval(this.videoPlayer.updateInterval);
|
||||
delete this.videoPlayer.updateInterval;
|
||||
this.videoPlayer.stopTimer();
|
||||
|
||||
this.trigger('videoControl.pause', null);
|
||||
this.saveState(true);
|
||||
@@ -482,14 +528,7 @@ function (HTML5Video, Resizer) {
|
||||
}
|
||||
);
|
||||
|
||||
if (!this.videoPlayer.updateInterval) {
|
||||
this.videoPlayer.updateInterval = setInterval(
|
||||
this.videoPlayer.update, 200
|
||||
);
|
||||
|
||||
this.videoPlayer.update();
|
||||
}
|
||||
|
||||
this.videoPlayer.runTimer();
|
||||
this.trigger('videoControl.play', null);
|
||||
this.trigger('videoProgressSlider.notifyThroughHandleEnd', {
|
||||
end: false
|
||||
@@ -558,7 +597,7 @@ function (HTML5Video, Resizer) {
|
||||
// https://github.com/edx/edx-platform/pull/2841
|
||||
if (
|
||||
(this.isHtml5Mode() || availablePlaybackRates.length > 1) &&
|
||||
this.videoType === 'youtube'
|
||||
this.isYoutubeType()
|
||||
) {
|
||||
if (availablePlaybackRates.length === 1 && !this.isTouch) {
|
||||
// This condition is needed in cases when Firefox version is
|
||||
@@ -620,20 +659,34 @@ function (HTML5Video, Resizer) {
|
||||
}
|
||||
|
||||
function onStateChange(event) {
|
||||
this.el.removeClass([
|
||||
'is-unstarted', 'is-playing', 'is-paused', 'is-buffered',
|
||||
'is-ended', 'is-cued'
|
||||
].join(' '));
|
||||
|
||||
switch (event.data) {
|
||||
case this.videoPlayer.PlayerState.UNSTARTED:
|
||||
this.el.addClass('is-unstarted');
|
||||
this.videoPlayer.onUnstarted();
|
||||
break;
|
||||
case this.videoPlayer.PlayerState.PLAYING:
|
||||
this.el.addClass('is-playing');
|
||||
this.videoPlayer.onPlay();
|
||||
break;
|
||||
case this.videoPlayer.PlayerState.PAUSED:
|
||||
this.el.addClass('is-paused');
|
||||
this.videoPlayer.onPause();
|
||||
break;
|
||||
case this.videoPlayer.PlayerState.BUFFERING:
|
||||
this.el.addClass('is-buffered');
|
||||
this.el.trigger('buffering');
|
||||
break;
|
||||
case this.videoPlayer.PlayerState.ENDED:
|
||||
this.el.addClass('is-ended');
|
||||
this.videoPlayer.onEnded();
|
||||
break;
|
||||
case this.videoPlayer.PlayerState.CUED:
|
||||
this.el.addClass('is-cued');
|
||||
this.videoPlayer.player.seekTo(this.videoPlayer.seekToTimeOnCued, true);
|
||||
// We need to call play() explicitly because after the call
|
||||
// to functions cueVideoById() followed by seekTo() the video
|
||||
@@ -711,12 +764,12 @@ function (HTML5Video, Resizer) {
|
||||
return time;
|
||||
}
|
||||
|
||||
function updatePlayTime(time) {
|
||||
function updatePlayTime(time, skip_seek) {
|
||||
var videoPlayer = this.videoPlayer,
|
||||
duration = this.videoPlayer.duration(),
|
||||
youTubeId;
|
||||
|
||||
if (duration > 0 && videoPlayer.goToStartTime) {
|
||||
if (duration > 0 && videoPlayer.goToStartTime && !skip_seek) {
|
||||
videoPlayer.goToStartTime = false;
|
||||
|
||||
// The duration might have changed. Update the start-end time region to
|
||||
@@ -746,7 +799,7 @@ function (HTML5Video, Resizer) {
|
||||
//
|
||||
// HTML5 video sources play fine from start-time in both Chrome
|
||||
// and Firefox.
|
||||
if (this.browserIsFirefox && this.videoType === 'youtube') {
|
||||
if (this.browserIsFirefox && this.isYoutubeType()) {
|
||||
youTubeId = this.youtubeId();
|
||||
|
||||
// When we will call cueVideoById() for some strange reason
|
||||
@@ -794,10 +847,27 @@ function (HTML5Video, Resizer) {
|
||||
}
|
||||
|
||||
function isPlaying() {
|
||||
var playerState = this.videoPlayer.player.getPlayerState(),
|
||||
PLAYING = this.videoPlayer.PlayerState.PLAYING;
|
||||
var playerState = this.videoPlayer.player.getPlayerState();
|
||||
|
||||
return playerState === PLAYING;
|
||||
return playerState === this.videoPlayer.PlayerState.PLAYING;
|
||||
}
|
||||
|
||||
function isBuffering() {
|
||||
var playerState = this.videoPlayer.player.getPlayerState();
|
||||
|
||||
return playerState === this.videoPlayer.PlayerState.BUFFERING;
|
||||
}
|
||||
|
||||
function isCued() {
|
||||
var playerState = this.videoPlayer.player.getPlayerState();
|
||||
|
||||
return playerState === this.videoPlayer.PlayerState.CUED;
|
||||
}
|
||||
|
||||
function isUnstarted() {
|
||||
var playerState = this.videoPlayer.player.getPlayerState();
|
||||
|
||||
return playerState === this.videoPlayer.PlayerState.UNSTARTED;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -844,7 +914,7 @@ function (HTML5Video, Resizer) {
|
||||
// might differ by one or two seconds against the actual time as will
|
||||
// be reported later on by the player.getDuration() API function.
|
||||
if (!isFinite(dur) || dur <= 0) {
|
||||
if (this.videoType === 'youtube') {
|
||||
if (this.isYoutubeType()) {
|
||||
dur = this.getDuration();
|
||||
}
|
||||
}
|
||||
@@ -873,9 +943,9 @@ function (HTML5Video, Resizer) {
|
||||
});
|
||||
}
|
||||
|
||||
if (this.videoType === 'youtube') {
|
||||
if (this.isYoutubeType()) {
|
||||
logInfo.code = this.youtubeId();
|
||||
} else if (this.videoType === 'html5') {
|
||||
} else {
|
||||
logInfo.code = 'html5';
|
||||
}
|
||||
|
||||
|
||||
@@ -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,36 +255,87 @@ 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
|
||||
#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
|
||||
# And it has a video in "Flash" mode
|
||||
# Then the video has rendered in "Flash" mode
|
||||
# And I make sure captions are opened
|
||||
# And I see "Hi, welcome to Edx." text in the captions
|
||||
# Then I select the "1.50" speed
|
||||
# And I see "Hi, welcome to Edx." text in the captions
|
||||
# Then I select the "0.75" speed
|
||||
# And I see "Hi, welcome to Edx." text in the captions
|
||||
# Then I select the "1.25" speed
|
||||
# And I see "Hi, welcome to Edx." text in the captions
|
||||
# 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 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
|
||||
# And it has a video in "Flash" mode
|
||||
# And I make sure captions are opened
|
||||
# Then I select the "1.50" speed
|
||||
# And I click video button "pause"
|
||||
# And I click on caption line "4", video module shows elapsed time "7"
|
||||
# Then I select the "0.75" speed
|
||||
# And I click video button "pause"
|
||||
# And I click on caption line "3", video module shows elapsed time "9"
|
||||
# Then I select the "1.25" speed
|
||||
# And I click video button "pause"
|
||||
# And I click on caption line "2", video module shows elapsed time "4"
|
||||
# 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
|
||||
@@ -314,3 +353,46 @@ Feature: LMS.Video component
|
||||
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
|
||||
# And it has a video in "Flash" mode
|
||||
# Then the video has rendered in "Flash" mode
|
||||
# And I make sure captions are opened
|
||||
# And I see "Hi, welcome to Edx." text in the captions
|
||||
# Then I select the "1.50" speed
|
||||
# And I see "Hi, welcome to Edx." text in the captions
|
||||
# Then I select the "0.75" speed
|
||||
# And I see "Hi, welcome to Edx." text in the captions
|
||||
# Then I select the "1.25" speed
|
||||
# And I see "Hi, welcome to Edx." text in the captions
|
||||
|
||||
# 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
|
||||
# And it has a video in "Flash" mode
|
||||
# And I make sure captions are opened
|
||||
# Then I select the "1.50" speed
|
||||
# And I click video button "pause"
|
||||
# And I click on caption line "4", video module shows elapsed time "7"
|
||||
# Then I select the "0.75" speed
|
||||
# And I click video button "pause"
|
||||
# And I click on caption line "3", video module shows elapsed time "9"
|
||||
# Then I select the "1.25" speed
|
||||
# And I click video button "pause"
|
||||
# And I click on caption line "2", video module shows elapsed time "4"
|
||||
|
||||
# 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])
|
||||
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$')
|
||||
|
||||
Reference in New Issue
Block a user