Commit 92cd4627 by polesye

BLD-950: Update captions logic on front-end.

parent 52ca4226
......@@ -201,7 +201,9 @@ def upload_file(_step, file_name):
@step('I see "([^"]*)" text in the captions')
def check_text_in_the_captions(_step, text):
assert world.browser.is_text_present(text.strip(), 5)
world.wait_for(lambda _: world.css_text('.subtitles'))
actual_text = world.css_text('.subtitles')
assert (text in actual_text)
@step('I see value "([^"]*)" in the field "([^"]*)"$')
......
(function (require) {
require(
['video/00_async_process.js'],
function (AsyncProcess) {
var getArrayNthLength = function (n, multiplier) {
var result = [],
mul = multiplier || 1;
for (var i = 0; i < n; i++) {
result[i] = i * mul;
}
return result;
},
items = getArrayNthLength(1000);
describe('AsyncProcess', function () {
it ('Array is processed successfully', function () {
var processedArray,
expectedArray = getArrayNthLength(1000, 2),
process = function (item) {
return 2 * item;
};
runs(function () {
AsyncProcess.array(items, process).done(function (result) {
processedArray = result;
});
});
waitsFor(function () {
return processedArray;
}, 'Array processing takes too much time', WAIT_TIMEOUT);
runs(function () {
expect(processedArray).toEqual(expectedArray);
});
});
it ('If non-array is passed, error callback is called', function () {
var isError,
process = function () {};
runs(function () {
AsyncProcess.array('string', process).fail(function () {
isError = true;
});
});
waitsFor(function () {
return isError;
}, 'Error callback wasn\'t called', WAIT_TIMEOUT);
runs(function () {
expect(isError).toBeTruthy();
});
});
it ('If an empty array is passed, returns initial array', function () {
var processedArray,
process = function () {};
runs(function () {
AsyncProcess.array([], process).done(function (result) {
processedArray = result;
});
});
waitsFor(function () {
return processedArray;
}, 'Array processing takes too much time', WAIT_TIMEOUT);
runs(function () {
expect(processedArray).toEqual([]);
});
});
it ('If no process function passed, returns initial array', function () {
var processedArray;
runs(function () {
AsyncProcess.array(items).done(function (result) {
processedArray = result;
});
});
waitsFor(function () {
return processedArray;
}, 'Array processing takes too much time', WAIT_TIMEOUT);
runs(function () {
expect(processedArray).toEqual(items);
});
});
});
});
}(RequireJS.require));
(function (require) {
require(
['video/00_sjson.js'],
function (Sjson) {
describe('Sjson', function () {
var data = jasmine.stubbedCaption,
sjson;
beforeEach(function() {
sjson = new Sjson(data);
});
it ('returns captions', function () {
expect(sjson.getCaptions()).toEqual(data.text);
});
it ('returns start times', function () {
expect(sjson.getStartTimes()).toEqual(data.start);
});
it ('returns correct length', function () {
expect(sjson.getSize()).toEqual(data.text.length);
});
it('search returns a correct caption index', function () {
expect(sjson.search(0)).toEqual(-1);
expect(sjson.search(3120)).toEqual(1);
expect(sjson.search(6270)).toEqual(2);
expect(sjson.search(8490)).toEqual(2);
expect(sjson.search(21620)).toEqual(4);
expect(sjson.search(24920)).toEqual(5);
});
});
});
}(RequireJS.require));
(function (define) {
define(
'video/00_async_process.js',
[],
function() {
"use strict";
/**
* Provides convenient way to process big amount of data without UI blocking.
*
* @param {array} list Array to process.
* @param {function} process Calls this function on each item in the list.
* @return {array} Returns a Promise object to observe when all actions of a
certain type bound to the collection, queued or not, have finished.
*/
var AsyncProcess = {
array: function (list, process) {
if (!_.isArray(list)) {
return $.Deferred().reject().promise();
}
if (!_.isFunction(process) || !list.length) {
return $.Deferred().resolve(list).promise();
}
var MAX_DELAY = 50, // maximum amount of time that js code should be allowed to run continuously
dfd = $.Deferred(),
result = [],
index = 0,
len = list.length;
var getCurrentTime = function () {
return (new Date()).getTime();
};
var handler = function () {
var start = getCurrentTime();
do {
result[index] = process(list[index], index);
index++;
} while (index < len && getCurrentTime() - start < MAX_DELAY);
if (index < len) {
setTimeout(handler, 25);
} else {
dfd.resolve(result);
}
};
setTimeout(handler, 25);
return dfd.promise();
}
};
return AsyncProcess;
});
}(RequireJS.define));
(function (define) {
define(
'video/00_sjson.js',
[],
function() {
"use strict";
var Sjson = function (data) {
var sjson = {
start: data.start.concat(),
text: data.text.concat()
},
module = {};
var getter = function (propertyName) {
return function () {
return sjson[propertyName];
};
};
var getStartTimes = getter('start');
var getCaptions = getter('text');
var size = function () {
return sjson.text.length;
};
var search = function (time) {
var start = getStartTimes(),
max = size() - 1,
min = 0,
index;
if (time < start[min]) {
return -1;
}
while (min < max) {
index = Math.ceil((max + min) / 2);
if (time < start[index]) {
max = index - 1;
}
if (time >= start[index]) {
min = index;
}
}
return min;
};
return {
getCaptions: getCaptions,
getStartTimes: getStartTimes,
getSize: size,
search: search
};
};
return Sjson;
});
}(RequireJS.define));
......@@ -72,6 +72,8 @@ class VideoModule(VideoFields, VideoStudentViewHandlers, XModule):
'js': [
resource_string(module, 'js/src/video/00_video_storage.js'),
resource_string(module, 'js/src/video/00_resizer.js'),
resource_string(module, 'js/src/video/00_async_process.js'),
resource_string(module, 'js/src/video/00_sjson.js'),
resource_string(module, 'js/src/video/01_initialize.js'),
resource_string(module, 'js/src/video/025_focus_grabber.js'),
resource_string(module, 'js/src/video/02_html5_video.js'),
......
......@@ -111,18 +111,18 @@ Feature: LMS Video component
# 11
Scenario: Language menu works correctly in Video component
Given I am registered for the course "test_course"
And I have a "chinese_transcripts.srt" transcript file in assets
And I have a "subs_OEoXaMPEzfM.srt.sjson" transcript file in assets
And it has a video in "Youtube" mode:
Given I am registered for the course "test_course"
And I have a "chinese_transcripts.srt" transcript file in assets
And I have a "subs_OEoXaMPEzfM.srt.sjson" transcript file in assets
And it has a video in "Youtube" mode:
| transcripts | sub |
| {"zh": "chinese_transcripts.srt"} | OEoXaMPEzfM |
And I make sure captions are closed
And I see video menu "language" with correct items
And I select language with code "zh"
Then I see "好 各位同学" text in the captions
And I select language with code "en"
And I see "Hi, welcome to Edx." text in the captions
And I make sure captions are closed
And I see video menu "language" with correct items
And I select language with code "zh"
Then I see "好 各位同学" text in the captions
And I select language with code "en"
And I see "Hi, welcome to Edx." text in the captions
# 12
Scenario: CC button works correctly w/o english transcript in HTML5 mode of Video component
......@@ -237,29 +237,31 @@ Feature: LMS Video component
# 21
Scenario: Download button works correctly for non-english transcript in Youtube mode of Video component
Given I am registered for the course "test_course"
And I have a "chinese_transcripts.srt" transcript file in assets
And I have a "subs_OEoXaMPEzfM.srt.sjson" transcript file in assets
And it has a video in "Youtube" mode:
Given I am registered for the course "test_course"
And I have a "chinese_transcripts.srt" transcript file in assets
And I have a "subs_OEoXaMPEzfM.srt.sjson" transcript file in assets
And it has a video in "Youtube" mode:
| transcripts | sub | download_track |
| {"zh": "chinese_transcripts.srt"} | OEoXaMPEzfM | true |
Then I can download transcript in "srt" format that has text "Hi, welcome to Edx."
And I select language with code "zh"
And I see "好 各位同学" text in the captions
Then I can download transcript in "srt" format that has text "好 各位同学"
And I see "Hi, welcome to Edx." text in the captions
Then I can download transcript in "srt" format that has text "Hi, welcome to Edx."
And I select language with code "zh"
And I see "好 各位同学" text in the captions
Then I can download transcript in "srt" format that has text "好 各位同学"
# 22
Scenario: Download button works correctly for non-english transcript in HTML5 mode of Video component
Given I am registered for the course "test_course"
And I have a "chinese_transcripts.srt" transcript file in assets
And I have a "subs_OEoXaMPEzfM.srt.sjson" transcript file in assets
And it has a video in "HTML5" mode:
Given I am registered for the course "test_course"
And I have a "chinese_transcripts.srt" transcript file in assets
And I have a "subs_OEoXaMPEzfM.srt.sjson" transcript file in assets
And it has a video in "HTML5" mode:
| transcripts | sub | download_track |
| {"zh": "chinese_transcripts.srt"} | OEoXaMPEzfM | true |
Then I can download transcript in "srt" format that has text "Hi, welcome to Edx."
And I select language with code "zh"
And I see "好 各位同学" text in the captions
Then I can download transcript in "srt" format that has text "好 各位同学"
And I see "Hi, welcome to Edx." text in the captions
Then I can download transcript in "srt" format that has text "Hi, welcome to Edx."
And I select language with code "zh"
And I see "好 各位同学" text in the captions
Then I can download transcript in "srt" format that has text "好 各位同学"
# 23
Scenario: Download button works correctly w/o english transcript in HTML5 mode of Video component
......@@ -298,8 +300,10 @@ Feature: LMS Video component
And a video "D" in "Youtube_HTML5" mode in position "3" of sequential
And I open the section with videos
Then videos have rendered in "HTML5" mode
And I see "Hi, welcome to Edx." text in the captions
And I see "Equal transcripts" text in the captions
And I see text in the captions:
| text |
| Hi, welcome to Edx. |
| Equal transcripts |
When I open video "C"
Then the video has rendered in "HTML5" mode
And I make sure captions are opened
......
......@@ -240,25 +240,25 @@ def set_window_dimensions(width, height):
def duration():
"""
Total duration of the video, in seconds.
"""
elapsed_time, duration = video_time()
return duration
"""
Total duration of the video, in seconds.
"""
elapsed_time, duration = video_time()
return duration
def video_time():
"""
Return a tuple `(elapsed_time, duration)`, each in seconds.
"""
# The full time has the form "0:32 / 3:14"
full_time = world.css_text('div.vidtime')
"""
Return a tuple `(elapsed_time, duration)`, each in seconds.
"""
# The full time has the form "0:32 / 3:14"
full_time = world.css_text('div.vidtime')
# Split the time at the " / ", to get ["0:32", "3:14"]
elapsed_str, duration_str = full_time.split(' / ')
# Split the time at the " / ", to get ["0:32", "3:14"]
elapsed_str, duration_str = full_time.split(' / ')
# Convert each string to seconds
return (parse_time_str(elapsed_str), parse_time_str(duration_str))
# Convert each string to seconds
return (parse_time_str(elapsed_str), parse_time_str(duration_str))
def parse_time_str(time_str):
......@@ -316,13 +316,13 @@ def visit_video_section(_step):
@step('I select the "([^"]*)" speed$')
def i_select_video_speed(_step, speed):
change_video_speed(speed)
change_video_speed(speed)
@step('I select the "([^"]*)" speed on video "([^"]*)"$')
def change_video_speed_on_video(_step, speed, player_id):
navigate_to_an_item_in_a_sequence(world.video_sequences[player_id])
change_video_speed(speed)
navigate_to_an_item_in_a_sequence(world.video_sequences[player_id])
change_video_speed(speed)
@step('I open video "([^"]*)"$')
......@@ -419,7 +419,15 @@ def i_see_menu(_step, menu):
@step('I see "([^"]*)" text in the captions$')
def check_text_in_the_captions(_step, text):
assert world.browser.is_text_present(text.strip())
world.wait_for(lambda _: world.css_text('.subtitles'))
actual_text = world.css_text('.subtitles')
assert (text in actual_text)
@step('I see text in the captions:')
def check_captions(_step):
for index, video in enumerate(_step.hashes):
assert (video.get('text') in world.css_text('.subtitles', index=index))
@step('I select language with code "([^"]*)"$')
......@@ -441,14 +449,14 @@ def select_language(_step, code):
# Make sure that all ajax requests that affects the display of captions are finished.
# For example, request to get new translation etc.
world.wait_for_ajax_complete()
assert world.css_visible('.subtitles')
world.wait_for_visible('.subtitles')
@step('I click video button "([^"]*)"$')
def click_button(_step, button):
world.css_click(VIDEO_BUTTONS[button])
@step('I see video starts playing from "([^"]*)" position$')
def start_playing_video_from_n_seconds(_step, position):
world.wait_for(
......@@ -504,9 +512,7 @@ def video_alignment(_step, transcript_visibility):
height = abs(expected['height'] - real['height']) <= 5
# Restore initial window size
set_window_dimensions(
initial['width'], initial['height']
)
set_window_dimensions(initial['width'], initial['height'])
assert all([width, height])
......
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