Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
08538e89
Commit
08538e89
authored
Apr 01, 2014
by
Anton Stupak
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3128 from edx/anton/transcript-generation
Update captions logic on front-end.
parents
b1a0cc9d
92cd4627
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
548 additions
and
253 deletions
+548
-253
cms/djangoapps/contentstore/features/transcripts.py
+3
-1
common/lib/xmodule/xmodule/js/spec/video/async_process_spec.js
+97
-0
common/lib/xmodule/xmodule/js/spec/video/sjson_spec.js
+35
-0
common/lib/xmodule/xmodule/js/spec/video/video_caption_spec.js
+186
-95
common/lib/xmodule/xmodule/js/src/video/00_async_process.js
+59
-0
common/lib/xmodule/xmodule/js/src/video/00_sjson.js
+65
-0
common/lib/xmodule/xmodule/js/src/video/09_video_caption.js
+83
-149
common/lib/xmodule/xmodule/video_module/video_module.py
+2
-0
lms/djangoapps/courseware/features/video.feature
+6
-2
lms/djangoapps/courseware/features/video.py
+12
-6
No files found.
cms/djangoapps/contentstore/features/transcripts.py
View file @
08538e89
...
@@ -201,7 +201,9 @@ def upload_file(_step, file_name):
...
@@ -201,7 +201,9 @@ def upload_file(_step, file_name):
@step
(
'I see "([^"]*)" text in the captions'
)
@step
(
'I see "([^"]*)" text in the captions'
)
def
check_text_in_the_captions
(
_step
,
text
):
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 "([^"]*)"$'
)
@step
(
'I see value "([^"]*)" in the field "([^"]*)"$'
)
...
...
common/lib/xmodule/xmodule/js/spec/video/async_process_spec.js
0 → 100644
View file @
08538e89
(
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
));
common/lib/xmodule/xmodule/js/spec/video/sjson_spec.js
0 → 100644
View file @
08538e89
(
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
));
common/lib/xmodule/xmodule/js/spec/video/video_caption_spec.js
View file @
08538e89
...
@@ -92,7 +92,7 @@
...
@@ -92,7 +92,7 @@
});
});
expect
(
$
.
ajaxWithPrefix
.
mostRecentCall
.
args
[
0
].
data
)
expect
(
$
.
ajaxWithPrefix
.
mostRecentCall
.
args
[
0
].
data
)
.
toEqual
({
.
toEqual
({
videoId
:
'
abcdefghijkl
'
videoId
:
'
cogebirgzzM
'
});
});
});
});
});
});
...
@@ -237,10 +237,17 @@
...
@@ -237,10 +237,17 @@
describe
(
'when on a non touch-based device'
,
function
()
{
describe
(
'when on a non touch-based device'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
runs
(
function
()
{
state
=
jasmine
.
initializePlayer
();
state
=
jasmine
.
initializePlayer
();
});
});
waitsFor
(
function
()
{
return
state
.
videoCaption
.
rendered
;
},
'Captions are not rendered'
,
WAIT_TIMEOUT
);
});
it
(
'render the caption'
,
function
()
{
it
(
'render the caption'
,
function
()
{
runs
(
function
()
{
var
captionsData
;
var
captionsData
;
captionsData
=
jasmine
.
stubbedCaption
;
captionsData
=
jasmine
.
stubbedCaption
;
...
@@ -255,16 +262,20 @@
...
@@ -255,16 +262,20 @@
expect
(
$
(
link
)).
toHaveText
(
captionsData
.
text
[
index
]);
expect
(
$
(
link
)).
toHaveText
(
captionsData
.
text
[
index
]);
});
});
});
});
});
it
(
'add a padding element to caption'
,
function
()
{
it
(
'add a padding element to caption'
,
function
()
{
runs
(
function
()
{
expect
(
$
(
'.subtitles li:first'
).
hasClass
(
'spacing'
))
expect
(
$
(
'.subtitles li:first'
).
hasClass
(
'spacing'
))
.
toBe
(
true
);
.
toBe
(
true
);
expect
(
$
(
'.subtitles li:last'
).
hasClass
(
'spacing'
))
expect
(
$
(
'.subtitles li:last'
).
hasClass
(
'spacing'
))
.
toBe
(
true
);
.
toBe
(
true
);
});
});
});
it
(
'bind all the caption link'
,
function
()
{
it
(
'bind all the caption link'
,
function
()
{
runs
(
function
()
{
var
handlerList
=
[
'captionMouseOverOut'
,
'captionClick'
,
var
handlerList
=
[
'captionMouseOverOut'
,
'captionClick'
,
'captionMouseDown'
,
'captionFocus'
,
'captionBlur'
,
'captionMouseDown'
,
'captionFocus'
,
'captionBlur'
,
'captionKeyDown'
'captionKeyDown'
...
@@ -300,12 +311,22 @@
...
@@ -300,12 +311,22 @@
expect
(
state
.
videoCaption
.
captionKeyDown
).
toHaveBeenCalled
();
expect
(
state
.
videoCaption
.
captionKeyDown
).
toHaveBeenCalled
();
});
});
});
});
});
it
(
'set rendered to true'
,
function
()
{
it
(
'set rendered to true'
,
function
()
{
runs
(
function
()
{
state
=
jasmine
.
initializePlayer
();
state
=
jasmine
.
initializePlayer
();
});
waitsFor
(
function
()
{
return
state
.
videoCaption
.
rendered
;
},
'Captions are not rendered'
,
WAIT_TIMEOUT
);
runs
(
function
()
{
expect
(
state
.
videoCaption
.
rendered
).
toBeTruthy
();
expect
(
state
.
videoCaption
.
rendered
).
toBeTruthy
();
});
});
});
});
});
describe
(
'when on a touch-based device'
,
function
()
{
describe
(
'when on a touch-based device'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
...
@@ -345,52 +366,61 @@
...
@@ -345,52 +366,61 @@
beforeEach
(
function
()
{
beforeEach
(
function
()
{
jasmine
.
Clock
.
useMock
();
jasmine
.
Clock
.
useMock
();
spyOn
(
window
,
'clearTimeout'
);
spyOn
(
window
,
'clearTimeout'
);
runs
(
function
()
{
state
=
jasmine
.
initializePlayer
();
state
=
jasmine
.
initializePlayer
();
jasmine
.
Clock
.
tick
(
50
);
});
});
describe
(
'when cursor is outside of the caption box'
,
function
()
{
waitsFor
(
function
()
{
beforeEach
(
function
()
{
return
state
.
videoCaption
.
rendered
;
$
(
window
).
trigger
(
jQuery
.
Event
(
'mousemove'
));
},
'Captions are not rendered'
,
WAIT_TIMEOUT
);
jasmine
.
Clock
.
tick
(
state
.
config
.
captionsFreezeTime
);
});
});
describe
(
'when cursor is outside of the caption box'
,
function
()
{
it
(
'does not set freezing timeout'
,
function
()
{
it
(
'does not set freezing timeout'
,
function
()
{
runs
(
function
()
{
expect
(
state
.
videoCaption
.
frozen
).
toBeFalsy
();
expect
(
state
.
videoCaption
.
frozen
).
toBeFalsy
();
});
});
});
});
});
describe
(
'when cursor is in the caption box'
,
function
()
{
describe
(
'when cursor is in the caption box'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
spyOn
(
state
.
videoCaption
,
'onMouseLeave'
);
spyOn
(
state
.
videoCaption
,
'onMouseLeave'
);
runs
(
function
()
{
$
(
window
).
trigger
(
jQuery
.
Event
(
'mousemove'
));
jasmine
.
Clock
.
tick
(
state
.
config
.
captionsFreezeTime
);
$
(
'.subtitles'
).
trigger
(
jQuery
.
Event
(
'mouseenter'
));
$
(
'.subtitles'
).
trigger
(
jQuery
.
Event
(
'mouseenter'
));
jasmine
.
Clock
.
tick
(
state
.
config
.
captionsFreezeTime
);
jasmine
.
Clock
.
tick
(
state
.
config
.
captionsFreezeTime
);
});
});
});
it
(
'set the freezing timeout'
,
function
()
{
it
(
'set the freezing timeout'
,
function
()
{
runs
(
function
()
{
expect
(
state
.
videoCaption
.
frozen
).
not
.
toBeFalsy
();
expect
(
state
.
videoCaption
.
frozen
).
not
.
toBeFalsy
();
expect
(
state
.
videoCaption
.
onMouseLeave
).
toHaveBeenCalled
();
expect
(
state
.
videoCaption
.
onMouseLeave
).
toHaveBeenCalled
();
});
});
describe
(
'when the cursor is moving'
,
function
()
{
beforeEach
(
function
()
{
$
(
'.subtitles'
).
trigger
(
jQuery
.
Event
(
'mousemove'
));
});
});
describe
(
'when the cursor is moving'
,
function
()
{
it
(
'reset the freezing timeout'
,
function
()
{
it
(
'reset the freezing timeout'
,
function
()
{
runs
(
function
()
{
$
(
'.subtitles'
).
trigger
(
jQuery
.
Event
(
'mousemove'
));
expect
(
window
.
clearTimeout
).
toHaveBeenCalled
();
expect
(
window
.
clearTimeout
).
toHaveBeenCalled
();
});
});
});
});
describe
(
'when the mouse is scrolling'
,
function
()
{
beforeEach
(
function
()
{
$
(
'.subtitles'
).
trigger
(
jQuery
.
Event
(
'mousewheel'
));
});
});
describe
(
'when the mouse is scrolling'
,
function
()
{
it
(
'reset the freezing timeout'
,
function
()
{
it
(
'reset the freezing timeout'
,
function
()
{
runs
(
function
()
{
$
(
'.subtitles'
).
trigger
(
jQuery
.
Event
(
'mousewheel'
));
expect
(
window
.
clearTimeout
).
toHaveBeenCalled
();
expect
(
window
.
clearTimeout
).
toHaveBeenCalled
();
});
});
});
});
});
});
});
describe
(
describe
(
'when cursor is moving out of the caption box'
,
'when cursor is moving out of the caption box'
,
...
@@ -441,25 +471,6 @@
...
@@ -441,25 +471,6 @@
});
});
});
});
it
(
'reRenderCaption'
,
function
()
{
state
=
jasmine
.
initializePlayer
();
var
Caption
=
state
.
videoCaption
,
li
;
Caption
.
captions
=
[
'test'
];
Caption
.
start
=
[
500
];
spyOn
(
Caption
,
'addPaddings'
);
Caption
.
reRenderCaption
();
li
=
$
(
'ol.subtitles li'
);
expect
(
Caption
.
addPaddings
).
toHaveBeenCalled
();
expect
(
li
.
length
).
toBe
(
1
);
expect
(
li
).
toHaveData
(
'start'
,
'500'
);
});
describe
(
'fetchCaption'
,
function
()
{
describe
(
'fetchCaption'
,
function
()
{
var
Caption
,
msg
;
var
Caption
,
msg
;
...
@@ -467,7 +478,6 @@
...
@@ -467,7 +478,6 @@
state
=
jasmine
.
initializePlayer
();
state
=
jasmine
.
initializePlayer
();
Caption
=
state
.
videoCaption
;
Caption
=
state
.
videoCaption
;
spyOn
(
$
,
'ajaxWithPrefix'
).
andCallThrough
();
spyOn
(
$
,
'ajaxWithPrefix'
).
andCallThrough
();
spyOn
(
Caption
,
'reRenderCaption'
);
spyOn
(
Caption
,
'renderCaption'
);
spyOn
(
Caption
,
'renderCaption'
);
spyOn
(
Caption
,
'bindHandlers'
);
spyOn
(
Caption
,
'bindHandlers'
);
spyOn
(
Caption
,
'updatePlayTime'
);
spyOn
(
Caption
,
'updatePlayTime'
);
...
@@ -511,7 +521,6 @@
...
@@ -511,7 +521,6 @@
expect
(
Caption
.
bindHandlers
).
toHaveBeenCalled
();
expect
(
Caption
.
bindHandlers
).
toHaveBeenCalled
();
expect
(
Caption
.
renderCaption
).
not
.
toHaveBeenCalled
();
expect
(
Caption
.
renderCaption
).
not
.
toHaveBeenCalled
();
expect
(
Caption
.
updatePlayTime
).
not
.
toHaveBeenCalled
();
expect
(
Caption
.
updatePlayTime
).
not
.
toHaveBeenCalled
();
expect
(
Caption
.
reRenderCaption
).
not
.
toHaveBeenCalled
();
expect
(
Caption
.
loaded
).
toBeTruthy
();
expect
(
Caption
.
loaded
).
toBeTruthy
();
});
});
...
@@ -527,7 +536,6 @@
...
@@ -527,7 +536,6 @@
expect
(
Caption
.
bindHandlers
).
not
.
toHaveBeenCalled
();
expect
(
Caption
.
bindHandlers
).
not
.
toHaveBeenCalled
();
expect
(
Caption
.
renderCaption
).
not
.
toHaveBeenCalled
();
expect
(
Caption
.
renderCaption
).
not
.
toHaveBeenCalled
();
expect
(
Caption
.
updatePlayTime
).
not
.
toHaveBeenCalled
();
expect
(
Caption
.
updatePlayTime
).
not
.
toHaveBeenCalled
();
expect
(
Caption
.
reRenderCaption
).
not
.
toHaveBeenCalled
();
expect
(
Caption
.
loaded
).
toBeTruthy
();
expect
(
Caption
.
loaded
).
toBeTruthy
();
});
});
...
@@ -539,9 +547,8 @@
...
@@ -539,9 +547,8 @@
expect
(
$
.
ajaxWithPrefix
).
toHaveBeenCalled
();
expect
(
$
.
ajaxWithPrefix
).
toHaveBeenCalled
();
expect
(
Caption
.
bindHandlers
).
not
.
toHaveBeenCalled
();
expect
(
Caption
.
bindHandlers
).
not
.
toHaveBeenCalled
();
expect
(
Caption
.
renderCaption
).
not
.
toHaveBeenCalled
();
expect
(
Caption
.
renderCaption
).
toHaveBeenCalled
();
expect
(
Caption
.
updatePlayTime
).
toHaveBeenCalled
();
expect
(
Caption
.
updatePlayTime
).
toHaveBeenCalled
();
expect
(
Caption
.
reRenderCaption
).
toHaveBeenCalled
();
expect
(
Caption
.
loaded
).
toBeTruthy
();
expect
(
Caption
.
loaded
).
toBeTruthy
();
});
});
...
@@ -553,19 +560,18 @@
...
@@ -553,19 +560,18 @@
expect
(
Caption
.
bindHandlers
).
toHaveBeenCalled
();
expect
(
Caption
.
bindHandlers
).
toHaveBeenCalled
();
expect
(
Caption
.
renderCaption
).
toHaveBeenCalled
();
expect
(
Caption
.
renderCaption
).
toHaveBeenCalled
();
expect
(
Caption
.
updatePlayTime
).
not
.
toHaveBeenCalled
();
expect
(
Caption
.
updatePlayTime
).
not
.
toHaveBeenCalled
();
expect
(
Caption
.
reRenderCaption
).
not
.
toHaveBeenCalled
();
expect
(
Caption
.
loaded
).
toBeTruthy
();
expect
(
Caption
.
loaded
).
toBeTruthy
();
});
});
it
(
'on success: re-rendered correct'
,
function
()
{
it
(
'on success: re-rendered correct'
,
function
()
{
Caption
.
loaded
=
true
;
Caption
.
loaded
=
true
;
Caption
.
rendered
=
true
;
Caption
.
fetchCaption
();
Caption
.
fetchCaption
();
expect
(
$
.
ajaxWithPrefix
).
toHaveBeenCalled
();
expect
(
$
.
ajaxWithPrefix
).
toHaveBeenCalled
();
expect
(
Caption
.
bindHandlers
).
not
.
toHaveBeenCalled
();
expect
(
Caption
.
bindHandlers
).
not
.
toHaveBeenCalled
();
expect
(
Caption
.
renderCaption
).
not
.
toHaveBeenCalled
();
expect
(
Caption
.
renderCaption
).
toHaveBeenCalled
();
expect
(
Caption
.
updatePlayTime
).
toHaveBeenCalled
();
expect
(
Caption
.
updatePlayTime
).
toHaveBeenCalled
();
expect
(
Caption
.
reRenderCaption
).
toHaveBeenCalled
();
expect
(
Caption
.
loaded
).
toBeTruthy
();
expect
(
Caption
.
loaded
).
toBeTruthy
();
});
});
...
@@ -680,27 +686,23 @@
...
@@ -680,27 +686,23 @@
});
});
});
});
describe
(
'search'
,
function
()
{
it
(
'return a correct caption index'
,
function
()
{
state
=
jasmine
.
initializePlayer
();
expect
(
state
.
videoCaption
.
search
(
0
)).
toEqual
(
-
1
);
expect
(
state
.
videoCaption
.
search
(
3120
)).
toEqual
(
1
);
expect
(
state
.
videoCaption
.
search
(
6270
)).
toEqual
(
2
);
expect
(
state
.
videoCaption
.
search
(
8490
)).
toEqual
(
2
);
expect
(
state
.
videoCaption
.
search
(
21620
)).
toEqual
(
4
);
expect
(
state
.
videoCaption
.
search
(
24920
)).
toEqual
(
5
);
});
});
describe
(
'play'
,
function
()
{
describe
(
'play'
,
function
()
{
describe
(
'when the caption was not rendered'
,
function
()
{
describe
(
'when the caption was not rendered'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
window
.
onTouchBasedDevice
.
andReturn
([
'iPad'
]);
window
.
onTouchBasedDevice
.
andReturn
([
'iPad'
]);
runs
(
function
()
{
state
=
jasmine
.
initializePlayer
();
state
=
jasmine
.
initializePlayer
();
state
.
videoCaption
.
play
();
state
.
videoCaption
.
play
();
});
});
waitsFor
(
function
()
{
return
state
.
videoCaption
.
rendered
;
},
'Captions are not rendered'
,
WAIT_TIMEOUT
);
});
it
(
'render the caption'
,
function
()
{
it
(
'render the caption'
,
function
()
{
runs
(
function
()
{
var
captionsData
;
var
captionsData
;
captionsData
=
jasmine
.
stubbedCaption
;
captionsData
=
jasmine
.
stubbedCaption
;
...
@@ -716,20 +718,28 @@
...
@@ -716,20 +718,28 @@
});
});
});
});
});
it
(
'add a padding element to caption'
,
function
()
{
it
(
'add a padding element to caption'
,
function
()
{
runs
(
function
()
{
expect
(
$
(
'.subtitles li:first'
)).
toBe
(
'.spacing'
);
expect
(
$
(
'.subtitles li:first'
)).
toBe
(
'.spacing'
);
expect
(
$
(
'.subtitles li:last'
)).
toBe
(
'.spacing'
);
expect
(
$
(
'.subtitles li:last'
)).
toBe
(
'.spacing'
);
});
});
});
it
(
'set rendered to true'
,
function
()
{
it
(
'set rendered to true'
,
function
()
{
runs
(
function
()
{
expect
(
state
.
videoCaption
.
rendered
).
toBeTruthy
();
expect
(
state
.
videoCaption
.
rendered
).
toBeTruthy
();
});
});
});
it
(
'set playing to true'
,
function
()
{
it
(
'set playing to true'
,
function
()
{
runs
(
function
()
{
expect
(
state
.
videoCaption
.
playing
).
toBeTruthy
();
expect
(
state
.
videoCaption
.
playing
).
toBeTruthy
();
});
});
});
});
});
});
});
describe
(
'pause'
,
function
()
{
describe
(
'pause'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
...
@@ -745,82 +755,117 @@
...
@@ -745,82 +755,117 @@
describe
(
'updatePlayTime'
,
function
()
{
describe
(
'updatePlayTime'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
runs
(
function
()
{
state
=
jasmine
.
initializePlayer
();
state
=
jasmine
.
initializePlayer
();
});
});
describe
(
'when the video speed is 1.0x'
,
function
()
{
waitsFor
(
function
()
{
beforeEach
(
function
()
{
return
state
.
videoCaption
.
rendered
;
state
.
videoSpeedControl
.
currentSpeed
=
'1.0'
;
},
'Captions are not rendered'
,
WAIT_TIMEOUT
);
state
.
videoCaption
.
updatePlayTime
(
25.000
);
});
});
describe
(
'when the video speed is 1.0x'
,
function
()
{
it
(
'search the caption based on time'
,
function
()
{
it
(
'search the caption based on time'
,
function
()
{
runs
(
function
()
{
state
.
videoCaption
.
updatePlayTime
(
25.000
);
expect
(
state
.
videoCaption
.
currentIndex
).
toEqual
(
5
);
expect
(
state
.
videoCaption
.
currentIndex
).
toEqual
(
5
);
});
});
describe
(
'when the video speed is not 1.0x'
,
function
()
{
// Flash mode
beforeEach
(
function
()
{
spyOn
(
state
,
'isFlashMode'
).
andReturn
(
true
);
state
.
videoSpeedControl
.
currentSpeed
=
'0.75
'
;
state
.
speed
=
'1.0
'
;
state
.
videoCaption
.
updatePlayTime
(
25.000
);
state
.
videoCaption
.
updatePlayTime
(
25.000
);
expect
(
state
.
videoCaption
.
currentIndex
).
toEqual
(
5
);
});
});
});
});
describe
(
'when the video speed is not 1.0x'
,
function
()
{
it
(
'search the caption based on 1.0x speed'
,
function
()
{
it
(
'search the caption based on 1.0x speed'
,
function
()
{
runs
(
function
()
{
state
.
videoCaption
.
updatePlayTime
(
25.000
);
expect
(
state
.
videoCaption
.
currentIndex
).
toEqual
(
5
);
expect
(
state
.
videoCaption
.
currentIndex
).
toEqual
(
5
);
// Flash mode
state
.
speed
=
'2.0'
;
spyOn
(
state
,
'isFlashMode'
).
andReturn
(
true
);
state
.
videoCaption
.
updatePlayTime
(
25.000
);
expect
(
state
.
videoCaption
.
currentIndex
).
toEqual
(
9
);
state
.
speed
=
'0.75'
;
state
.
videoCaption
.
updatePlayTime
(
25.000
);
expect
(
state
.
videoCaption
.
currentIndex
).
toEqual
(
3
);
});
});
});
});
});
describe
(
'when the index is not the same'
,
function
()
{
describe
(
'when the index is not the same'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
runs
(
function
()
{
state
.
videoCaption
.
currentIndex
=
1
;
state
.
videoCaption
.
currentIndex
=
1
;
$
(
'.subtitles li[data-index=5]'
).
addClass
(
'current'
);
$
(
'.subtitles li[data-index=5]'
).
addClass
(
'current'
);
state
.
videoCaption
.
updatePlayTime
(
25.000
);
state
.
videoCaption
.
updatePlayTime
(
25.000
);
});
});
});
it
(
'deactivate the previous caption'
,
function
()
{
it
(
'deactivate the previous caption'
,
function
()
{
runs
(
function
()
{
expect
(
$
(
'.subtitles li[data-index=1]'
))
expect
(
$
(
'.subtitles li[data-index=1]'
))
.
not
.
toHaveClass
(
'current'
);
.
not
.
toHaveClass
(
'current'
);
});
});
});
it
(
'activate new caption'
,
function
()
{
it
(
'activate new caption'
,
function
()
{
runs
(
function
()
{
expect
(
$
(
'.subtitles li[data-index=5]'
))
expect
(
$
(
'.subtitles li[data-index=5]'
))
.
toHaveClass
(
'current'
);
.
toHaveClass
(
'current'
);
});
});
});
it
(
'save new index'
,
function
()
{
it
(
'save new index'
,
function
()
{
runs
(
function
()
{
expect
(
state
.
videoCaption
.
currentIndex
).
toEqual
(
5
);
expect
(
state
.
videoCaption
.
currentIndex
).
toEqual
(
5
);
});
});
});
// Disabled 11/25/13 due to flakiness in master
it
(
'scroll caption to new position'
,
function
()
{
xit
(
'scroll caption to new position'
,
function
()
{
runs
(
function
()
{
expect
(
$
.
fn
.
scrollTo
).
toHaveBeenCalled
();
expect
(
$
.
fn
.
scrollTo
).
toHaveBeenCalled
();
});
});
});
});
});
describe
(
'when the index is the same'
,
function
()
{
describe
(
'when the index is the same'
,
function
()
{
beforeEach
(
function
()
{
it
(
'does not change current subtitle'
,
function
()
{
runs
(
function
()
{
state
.
videoCaption
.
currentIndex
=
1
;
state
.
videoCaption
.
currentIndex
=
1
;
$
(
'.subtitles li[data-index=3]'
).
addClass
(
'current'
);
$
(
'.subtitles li[data-index=3]'
).
addClass
(
'current'
);
state
.
videoCaption
.
updatePlayTime
(
15.000
);
state
.
videoCaption
.
updatePlayTime
(
15.000
);
});
it
(
'does not change current subtitle'
,
function
()
{
expect
(
$
(
'.subtitles li[data-index=3]'
))
expect
(
$
(
'.subtitles li[data-index=3]'
))
.
toHaveClass
(
'current'
);
.
toHaveClass
(
'current'
);
});
});
});
});
});
});
});
describe
(
'resize'
,
function
()
{
describe
(
'resize'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
runs
(
function
()
{
state
=
jasmine
.
initializePlayer
();
state
=
jasmine
.
initializePlayer
();
});
waitsFor
(
function
()
{
return
state
.
videoCaption
.
rendered
;
},
'Captions are not rendered'
,
WAIT_TIMEOUT
);
runs
(
function
()
{
videoControl
=
state
.
videoControl
;
videoControl
=
state
.
videoControl
;
$
(
'.subtitles li[data-index=1]'
).
addClass
(
'current'
);
$
(
'.subtitles li[data-index=1]'
).
addClass
(
'current'
);
state
.
videoCaption
.
resize
();
state
.
videoCaption
.
resize
();
});
});
});
describe
(
'set the height of caption container'
,
function
()
{
describe
(
'set the height of caption container'
,
function
()
{
it
(
'when CC button is enabled'
,
function
()
{
it
(
'when CC button is enabled'
,
function
()
{
runs
(
function
()
{
var
realHeight
=
parseInt
(
var
realHeight
=
parseInt
(
$
(
'.subtitles'
).
css
(
'maxHeight'
),
10
$
(
'.subtitles'
).
css
(
'maxHeight'
),
10
),
),
...
@@ -830,8 +875,10 @@
...
@@ -830,8 +875,10 @@
// environments: Linux * Mac * FF * Chrome
// environments: Linux * Mac * FF * Chrome
expect
(
realHeight
).
toBeCloseTo
(
shouldBeHeight
,
2
);
expect
(
realHeight
).
toBeCloseTo
(
shouldBeHeight
,
2
);
});
});
});
it
(
'when CC button is disabled '
,
function
()
{
it
(
'when CC button is disabled '
,
function
()
{
runs
(
function
()
{
var
realHeight
,
videoWrapperHeight
,
progressSliderHeight
,
var
realHeight
,
videoWrapperHeight
,
progressSliderHeight
,
controlHeight
,
shouldBeHeight
;
controlHeight
,
shouldBeHeight
;
...
@@ -851,8 +898,10 @@
...
@@ -851,8 +898,10 @@
expect
(
realHeight
).
toBe
(
shouldBeHeight
);
expect
(
realHeight
).
toBe
(
shouldBeHeight
);
});
});
});
});
});
it
(
'set the height of caption spacing'
,
function
()
{
it
(
'set the height of caption spacing'
,
function
()
{
runs
(
function
()
{
var
firstSpacing
,
lastSpacing
;
var
firstSpacing
,
lastSpacing
;
firstSpacing
=
Math
.
abs
(
parseInt
(
firstSpacing
=
Math
.
abs
(
parseInt
(
...
@@ -867,100 +916,111 @@
...
@@ -867,100 +916,111 @@
expect
(
lastSpacing
-
state
.
videoCaption
.
bottomSpacingHeight
())
expect
(
lastSpacing
-
state
.
videoCaption
.
bottomSpacingHeight
())
.
toBeLessThan
(
1
);
.
toBeLessThan
(
1
);
});
});
});
it
(
'scroll caption to new position'
,
function
()
{
it
(
'scroll caption to new position'
,
function
()
{
runs
(
function
()
{
expect
(
$
.
fn
.
scrollTo
).
toHaveBeenCalled
();
expect
(
$
.
fn
.
scrollTo
).
toHaveBeenCalled
();
});
});
});
});
});
// Disabled 11/25/13 due to flakiness in master
xdescribe
(
'scrollCaption'
,
function
()
{
xdescribe
(
'scrollCaption'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
runs
(
function
()
{
state
=
jasmine
.
initializePlayer
();
state
=
jasmine
.
initializePlayer
();
});
});
waitsFor
(
function
()
{
return
state
.
videoCaption
.
rendered
;
},
'Captions are not rendered'
,
WAIT_TIMEOUT
);
});
describe
(
'when frozen'
,
function
()
{
describe
(
'when frozen'
,
function
()
{
beforeEach
(
function
()
{
it
(
'does not scroll the caption'
,
function
()
{
runs
(
function
()
{
state
.
videoCaption
.
frozen
=
true
;
state
.
videoCaption
.
frozen
=
true
;
$
(
'.subtitles li[data-index=1]'
).
addClass
(
'current'
);
$
(
'.subtitles li[data-index=1]'
).
addClass
(
'current'
);
state
.
videoCaption
.
scrollCaption
();
state
.
videoCaption
.
scrollCaption
();
});
it
(
'does not scroll the caption'
,
function
()
{
expect
(
$
.
fn
.
scrollTo
).
not
.
toHaveBeenCalled
();
expect
(
$
.
fn
.
scrollTo
).
not
.
toHaveBeenCalled
();
});
});
});
});
});
describe
(
'when not frozen'
,
function
()
{
describe
(
'when not frozen'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
runs
(
function
()
{
state
.
videoCaption
.
frozen
=
false
;
state
.
videoCaption
.
frozen
=
false
;
});
});
describe
(
'when there is no current caption'
,
function
()
{
beforeEach
(
function
()
{
state
.
videoCaption
.
scrollCaption
();
});
});
describe
(
'when there is no current caption'
,
function
()
{
it
(
'does not scroll the caption'
,
function
()
{
it
(
'does not scroll the caption'
,
function
()
{
runs
(
function
()
{
state
.
videoCaption
.
scrollCaption
();
expect
(
$
.
fn
.
scrollTo
).
not
.
toHaveBeenCalled
();
expect
(
$
.
fn
.
scrollTo
).
not
.
toHaveBeenCalled
();
});
});
});
});
});
describe
(
'when there is a current caption'
,
function
()
{
describe
(
'when there is a current caption'
,
function
()
{
beforeEach
(
function
()
{
it
(
'scroll to current caption'
,
function
()
{
runs
(
function
()
{
$
(
'.subtitles li[data-index=1]'
).
addClass
(
'current'
);
$
(
'.subtitles li[data-index=1]'
).
addClass
(
'current'
);
state
.
videoCaption
.
scrollCaption
();
state
.
videoCaption
.
scrollCaption
();
});
it
(
'scroll to current caption'
,
function
()
{
expect
(
$
.
fn
.
scrollTo
).
toHaveBeenCalled
();
expect
(
$
.
fn
.
scrollTo
).
toHaveBeenCalled
();
});
});
});
});
});
});
});
});
});
// Disabled 10/9/13 due to flakiness in master
xdescribe
(
'seekPlayer'
,
function
()
{
xdescribe
(
'seekPlayer'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
runs
(
function
()
{
state
=
jasmine
.
initializePlayer
();
state
=
jasmine
.
initializePlayer
();
});
});
describe
(
'when the video speed is 1.0x'
,
function
()
{
waitsFor
(
function
()
{
beforeEach
(
function
()
{
var
duration
=
state
.
videoPlayer
.
duration
(),
state
.
videoSpeedControl
.
currentSpeed
=
'1.0'
;
isRendered
=
state
.
videoCaption
.
rendered
;
$
(
'.subtitles li[data-start="14910"]'
).
trigger
(
'click'
);
return
isRendered
&&
duration
;
},
'Captions are not rendered'
,
WAIT_TIMEOUT
);
});
});
describe
(
'when the video speed is 1.0x'
,
function
()
{
it
(
'trigger seek event with the correct time'
,
function
()
{
it
(
'trigger seek event with the correct time'
,
function
()
{
runs
(
function
()
{
state
.
videoSpeedControl
.
currentSpeed
=
'1.0'
;
$
(
'.subtitles li[data-start="14910"]'
).
trigger
(
'click'
);
expect
(
state
.
videoPlayer
.
currentTime
).
toEqual
(
14.91
);
expect
(
state
.
videoPlayer
.
currentTime
).
toEqual
(
14.91
);
});
});
});
});
});
describe
(
'when the video speed is not 1.0x'
,
function
()
{
describe
(
'when the video speed is not 1.0x'
,
function
()
{
beforeEach
(
function
()
{
it
(
'trigger seek event with the correct time'
,
function
()
{
runs
(
function
()
{
state
.
videoSpeedControl
.
currentSpeed
=
'0.75'
;
state
.
videoSpeedControl
.
currentSpeed
=
'0.75'
;
$
(
'.subtitles li[data-start="14910"]'
).
trigger
(
'click'
);
$
(
'.subtitles li[data-start="14910"]'
).
trigger
(
'click'
);
});
it
(
'trigger seek event with the correct time'
,
function
()
{
expect
(
state
.
videoPlayer
.
currentTime
).
toEqual
(
14.91
);
expect
(
state
.
videoPlayer
.
currentTime
).
toEqual
(
14.91
);
});
});
});
});
});
describe
(
'when the player type is Flash at speed 0.75x'
,
describe
(
'when the player type is Flash at speed 0.75x'
,
function
()
{
function
()
{
it
(
'trigger seek event with the correct time'
,
function
()
{
beforeEach
(
function
()
{
runs
(
function
()
{
state
.
videoSpeedControl
.
currentSpeed
=
'0.75'
;
state
.
videoSpeedControl
.
currentSpeed
=
'0.75'
;
state
.
currentPlayerMode
=
'flash'
;
state
.
currentPlayerMode
=
'flash'
;
$
(
'.subtitles li[data-start="14910"]'
).
trigger
(
'click'
);
$
(
'.subtitles li[data-start="14910"]'
).
trigger
(
'click'
);
});
it
(
'trigger seek event with the correct time'
,
function
()
{
expect
(
state
.
videoPlayer
.
currentTime
).
toEqual
(
15
);
expect
(
state
.
videoPlayer
.
currentTime
).
toEqual
(
15
);
});
});
});
});
});
});
});
describe
(
'toggle'
,
function
()
{
describe
(
'toggle'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
...
@@ -998,7 +1058,6 @@
...
@@ -998,7 +1058,6 @@
beforeEach
(
function
()
{
beforeEach
(
function
()
{
state
.
el
.
addClass
(
'closed'
);
state
.
el
.
addClass
(
'closed'
);
state
.
videoCaption
.
toggle
(
jQuery
.
Event
(
'click'
));
state
.
videoCaption
.
toggle
(
jQuery
.
Event
(
'click'
));
jasmine
.
Clock
.
useMock
();
jasmine
.
Clock
.
useMock
();
});
});
...
@@ -1039,43 +1098,61 @@
...
@@ -1039,43 +1098,61 @@
describe
(
'caption accessibility'
,
function
()
{
describe
(
'caption accessibility'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
runs
(
function
()
{
state
=
jasmine
.
initializePlayer
();
state
=
jasmine
.
initializePlayer
();
});
});
waitsFor
(
function
()
{
return
state
.
videoCaption
.
rendered
;
},
'Captions are not rendered'
,
WAIT_TIMEOUT
);
});
describe
(
'when getting focus through TAB key'
,
function
()
{
describe
(
'when getting focus through TAB key'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
runs
(
function
()
{
state
.
videoCaption
.
isMouseFocus
=
false
;
state
.
videoCaption
.
isMouseFocus
=
false
;
$
(
'.subtitles li[data-index=0]'
).
trigger
(
$
(
'.subtitles li[data-index=0]'
).
trigger
(
jQuery
.
Event
(
'focus'
)
jQuery
.
Event
(
'focus'
)
);
);
});
});
});
it
(
'shows an outline around the caption'
,
function
()
{
it
(
'shows an outline around the caption'
,
function
()
{
runs
(
function
()
{
expect
(
$
(
'.subtitles li[data-index=0]'
))
expect
(
$
(
'.subtitles li[data-index=0]'
))
.
toHaveClass
(
'focused'
);
.
toHaveClass
(
'focused'
);
});
});
});
it
(
'has automatic scrolling disabled'
,
function
()
{
it
(
'has automatic scrolling disabled'
,
function
()
{
runs
(
function
()
{
expect
(
state
.
videoCaption
.
autoScrolling
).
toBe
(
false
);
expect
(
state
.
videoCaption
.
autoScrolling
).
toBe
(
false
);
});
});
});
});
});
describe
(
'when loosing focus through TAB key'
,
function
()
{
describe
(
'when loosing focus through TAB key'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
runs
(
function
()
{
$
(
'.subtitles li[data-index=0]'
).
trigger
(
$
(
'.subtitles li[data-index=0]'
).
trigger
(
jQuery
.
Event
(
'blur'
)
jQuery
.
Event
(
'blur'
)
);
);
});
});
});
it
(
'does not show an outline around the caption'
,
function
()
{
it
(
'does not show an outline around the caption'
,
function
()
{
runs
(
function
()
{
expect
(
$
(
'.subtitles li[data-index=0]'
))
expect
(
$
(
'.subtitles li[data-index=0]'
))
.
not
.
toHaveClass
(
'focused'
);
.
not
.
toHaveClass
(
'focused'
);
});
});
});
it
(
'has automatic scrolling enabled'
,
function
()
{
it
(
'has automatic scrolling enabled'
,
function
()
{
runs
(
function
()
{
expect
(
state
.
videoCaption
.
autoScrolling
).
toBe
(
true
);
expect
(
state
.
videoCaption
.
autoScrolling
).
toBe
(
true
);
});
});
});
});
});
describe
(
describe
(
'when same caption gets the focus through mouse after '
+
'when same caption gets the focus through mouse after '
+
...
@@ -1083,22 +1160,28 @@
...
@@ -1083,22 +1160,28 @@
function
()
{
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
runs
(
function
()
{
state
.
videoCaption
.
isMouseFocus
=
false
;
state
.
videoCaption
.
isMouseFocus
=
false
;
$
(
'.subtitles li[data-index=0]'
)
$
(
'.subtitles li[data-index=0]'
)
.
trigger
(
jQuery
.
Event
(
'focus'
));
.
trigger
(
jQuery
.
Event
(
'focus'
));
$
(
'.subtitles li[data-index=0]'
)
$
(
'.subtitles li[data-index=0]'
)
.
trigger
(
jQuery
.
Event
(
'mousedown'
));
.
trigger
(
jQuery
.
Event
(
'mousedown'
));
});
});
});
it
(
'does not show an outline around it'
,
function
()
{
it
(
'does not show an outline around it'
,
function
()
{
runs
(
function
()
{
expect
(
$
(
'.subtitles li[data-index=0]'
))
expect
(
$
(
'.subtitles li[data-index=0]'
))
.
not
.
toHaveClass
(
'focused'
);
.
not
.
toHaveClass
(
'focused'
);
});
});
});
it
(
'has automatic scrolling enabled'
,
function
()
{
it
(
'has automatic scrolling enabled'
,
function
()
{
runs
(
function
()
{
expect
(
state
.
videoCaption
.
autoScrolling
).
toBe
(
true
);
expect
(
state
.
videoCaption
.
autoScrolling
).
toBe
(
true
);
});
});
});
});
});
describe
(
describe
(
'when a second caption gets focus through mouse after '
+
'when a second caption gets focus through mouse after '
+
...
@@ -1108,6 +1191,7 @@
...
@@ -1108,6 +1191,7 @@
var
subDataLiIdx__0
,
subDataLiIdx__1
;
var
subDataLiIdx__0
,
subDataLiIdx__1
;
beforeEach
(
function
()
{
beforeEach
(
function
()
{
runs
(
function
()
{
subDataLiIdx__0
=
$
(
'.subtitles li[data-index=0]'
);
subDataLiIdx__0
=
$
(
'.subtitles li[data-index=0]'
);
subDataLiIdx__1
=
$
(
'.subtitles li[data-index=1]'
);
subDataLiIdx__1
=
$
(
'.subtitles li[data-index=1]'
);
...
@@ -1120,20 +1204,27 @@
...
@@ -1120,20 +1204,27 @@
subDataLiIdx__1
.
trigger
(
jQuery
.
Event
(
'mousedown'
));
subDataLiIdx__1
.
trigger
(
jQuery
.
Event
(
'mousedown'
));
});
});
});
it
(
'does not show an outline around the first'
,
function
()
{
it
(
'does not show an outline around the first'
,
function
()
{
runs
(
function
()
{
expect
(
subDataLiIdx__0
).
not
.
toHaveClass
(
'focused'
);
expect
(
subDataLiIdx__0
).
not
.
toHaveClass
(
'focused'
);
});
});
});
it
(
'does not show an outline around the second'
,
function
()
{
it
(
'does not show an outline around the second'
,
function
()
{
runs
(
function
()
{
expect
(
subDataLiIdx__1
).
not
.
toHaveClass
(
'focused'
);
expect
(
subDataLiIdx__1
).
not
.
toHaveClass
(
'focused'
);
});
});
});
it
(
'has automatic scrolling enabled'
,
function
()
{
it
(
'has automatic scrolling enabled'
,
function
()
{
runs
(
function
()
{
expect
(
state
.
videoCaption
.
autoScrolling
).
toBe
(
true
);
expect
(
state
.
videoCaption
.
autoScrolling
).
toBe
(
true
);
});
});
});
});
});
});
});
});
});
}).
call
(
this
);
}).
call
(
this
);
common/lib/xmodule/xmodule/js/src/video/00_async_process.js
0 → 100644
View file @
08538e89
(
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
));
common/lib/xmodule/xmodule/js/src/video/00_sjson.js
0 → 100644
View file @
08538e89
(
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
));
common/lib/xmodule/xmodule/js/src/video/09_video_caption.js
View file @
08538e89
(
function
(
requirejs
,
require
,
define
)
{
(
function
(
define
)
{
// VideoCaption module.
// VideoCaption module.
define
(
define
(
'video/09_video_caption.js'
,
'video/09_video_caption.js'
,
[],
[
'video/00_sjson.js'
,
'video/00_async_process.js'
],
function
()
{
function
(
Sjson
,
AsyncProcess
)
{
/**
/**
* @desc VideoCaption module exports a function.
* @desc VideoCaption module exports a function.
...
@@ -21,16 +21,11 @@ function () {
...
@@ -21,16 +21,11 @@ function () {
* @returns {undefined}
* @returns {undefined}
*/
*/
return
function
(
state
)
{
return
function
(
state
)
{
var
dfd
=
$
.
Deferred
();
state
.
videoCaption
=
{};
state
.
videoCaption
=
{};
_makeFunctionsPublic
(
state
);
_makeFunctionsPublic
(
state
);
state
.
videoCaption
.
renderElements
();
state
.
videoCaption
.
renderElements
();
dfd
.
resolve
();
return
$
.
Deferred
().
resolve
().
promise
();
return
dfd
.
promise
();
};
};
// ***************************************************************
// ***************************************************************
...
@@ -65,10 +60,8 @@ function () {
...
@@ -65,10 +60,8 @@ function () {
renderCaption
:
renderCaption
,
renderCaption
:
renderCaption
,
renderElements
:
renderElements
,
renderElements
:
renderElements
,
renderLanguageMenu
:
renderLanguageMenu
,
renderLanguageMenu
:
renderLanguageMenu
,
reRenderCaption
:
reRenderCaption
,
resize
:
resize
,
resize
:
resize
,
scrollCaption
:
scrollCaption
,
scrollCaption
:
scrollCaption
,
search
:
search
,
seekPlayer
:
seekPlayer
,
seekPlayer
:
seekPlayer
,
setSubtitlesHeight
:
setSubtitlesHeight
,
setSubtitlesHeight
:
setSubtitlesHeight
,
toggle
:
toggle
,
toggle
:
toggle
,
...
@@ -133,18 +126,46 @@ function () {
...
@@ -133,18 +126,46 @@ function () {
// mousemove, etc.).
// mousemove, etc.).
function
bindHandlers
()
{
function
bindHandlers
()
{
var
self
=
this
,
var
self
=
this
,
Caption
=
this
.
videoCaption
;
Caption
=
this
.
videoCaption
,
events
=
[
'mouseover'
,
'mouseout'
,
'mousedown'
,
'click'
,
'focus'
,
'blur'
,
'keydown'
].
join
(
' '
);
Caption
.
hideSubtitlesEl
.
on
({
Caption
.
hideSubtitlesEl
.
on
({
'click'
:
Caption
.
toggle
'click'
:
Caption
.
toggle
});
});
Caption
.
subtitlesEl
.
on
({
Caption
.
subtitlesEl
.
on
({
mouseenter
:
Caption
.
onMouseEnter
,
mouseenter
:
Caption
.
onMouseEnter
,
mouseleave
:
Caption
.
onMouseLeave
,
mouseleave
:
Caption
.
onMouseLeave
,
mousemove
:
Caption
.
onMovement
,
mousemove
:
Caption
.
onMovement
,
mousewheel
:
Caption
.
onMovement
,
mousewheel
:
Caption
.
onMovement
,
DOMMouseScroll
:
Caption
.
onMovement
DOMMouseScroll
:
Caption
.
onMovement
})
.
on
(
events
,
'li[data-index]'
,
function
(
event
)
{
switch
(
event
.
type
)
{
case
'mouseover'
:
case
'mouseout'
:
Caption
.
captionMouseOverOut
(
event
);
break
;
case
'mousedown'
:
Caption
.
captionMouseDown
(
event
);
break
;
case
'click'
:
Caption
.
captionClick
(
event
);
break
;
case
'focusin'
:
Caption
.
captionFocus
(
event
);
break
;
case
'focusout'
:
Caption
.
captionBlur
(
event
);
break
;
case
'keydown'
:
Caption
.
captionKeyDown
(
event
);
break
;
}
});
});
if
(
Caption
.
showLanguageMenu
)
{
if
(
Caption
.
showLanguageMenu
)
{
...
@@ -154,12 +175,6 @@ function () {
...
@@ -154,12 +175,6 @@ function () {
});
});
}
}
this
.
el
.
on
(
'speedchange'
,
function
()
{
if
(
self
.
isFlashMode
())
{
Caption
.
fetchCaption
();
}
});
if
((
this
.
videoType
===
'html5'
)
&&
(
this
.
config
.
autohideHtml5
))
{
if
((
this
.
videoType
===
'html5'
)
&&
(
this
.
config
.
autohideHtml5
))
{
Caption
.
subtitlesEl
.
on
(
'scroll'
,
this
.
videoControl
.
showControls
);
Caption
.
subtitlesEl
.
on
(
'scroll'
,
this
.
videoControl
.
showControls
);
}
}
...
@@ -241,7 +256,7 @@ function () {
...
@@ -241,7 +256,7 @@ function () {
if
(
this
.
videoType
===
'youtube'
)
{
if
(
this
.
videoType
===
'youtube'
)
{
data
=
{
data
=
{
videoId
:
this
.
youtubeId
()
videoId
:
this
.
youtubeId
(
'1.0'
)
};
};
}
}
...
@@ -251,13 +266,15 @@ function () {
...
@@ -251,13 +266,15 @@ function () {
url
:
self
.
config
.
transcriptTranslationUrl
+
'/'
+
language
,
url
:
self
.
config
.
transcriptTranslationUrl
+
'/'
+
language
,
notifyOnError
:
false
,
notifyOnError
:
false
,
data
:
data
,
data
:
data
,
success
:
function
(
captions
)
{
success
:
function
(
response
)
{
Caption
.
captions
=
captions
.
text
;
Caption
.
sjson
=
new
Sjson
(
response
);
Caption
.
start
=
captions
.
start
;
var
start
=
Caption
.
sjson
.
getStartTimes
(),
captions
=
Caption
.
sjson
.
getCaptions
();
if
(
Caption
.
loaded
)
{
if
(
Caption
.
loaded
)
{
if
(
Caption
.
rendered
)
{
if
(
Caption
.
rendered
)
{
Caption
.
re
RenderCaption
(
);
Caption
.
re
nderCaption
(
start
,
captions
);
Caption
.
updatePlayTime
(
self
.
videoPlayer
.
currentTime
);
Caption
.
updatePlayTime
(
self
.
videoPlayer
.
currentTime
);
}
}
}
else
{
}
else
{
...
@@ -269,7 +286,7 @@ function () {
...
@@ -269,7 +286,7 @@ function () {
)
)
);
);
}
else
{
}
else
{
Caption
.
renderCaption
();
Caption
.
renderCaption
(
start
,
captions
);
}
}
Caption
.
bindHandlers
();
Caption
.
bindHandlers
();
...
@@ -334,7 +351,6 @@ function () {
...
@@ -334,7 +351,6 @@ function () {
.
height
(
this
.
videoCaption
.
bottomSpacingHeight
());
.
height
(
this
.
videoCaption
.
bottomSpacingHeight
());
this
.
videoCaption
.
scrollCaption
();
this
.
videoCaption
.
scrollCaption
();
this
.
videoCaption
.
setSubtitlesHeight
();
this
.
videoCaption
.
setSubtitlesHeight
();
}
}
...
@@ -380,90 +396,53 @@ function () {
...
@@ -380,90 +396,53 @@ function () {
});
});
}
}
function
buildCaptions
(
container
,
captions
,
start
)
{
function
buildCaptions
(
container
,
start
,
captions
)
{
var
fragment
=
document
.
createDocumentFragment
();
var
process
=
function
(
text
,
index
)
{
var
liEl
=
$
(
'<li>'
,
{
$
.
each
(
captions
,
function
(
index
,
text
)
{
var
liEl
=
$
(
'<li>'
);
liEl
.
html
(
text
);
liEl
.
attr
({
'data-index'
:
index
,
'data-index'
:
index
,
'data-start'
:
start
[
index
],
'data-start'
:
start
[
index
],
'tabindex'
:
0
'tabindex'
:
0
}
);
}).
html
(
text
);
fragment
.
appendChild
(
liEl
[
0
])
;
return
liEl
[
0
]
;
})
;
}
;
container
.
append
([
fragment
]);
return
AsyncProcess
.
array
(
captions
,
process
).
done
(
function
(
list
)
{
container
.
append
(
list
);
});
}
}
function
renderCaption
()
{
function
renderCaption
(
start
,
captions
)
{
var
Caption
=
this
.
videoCaption
,
var
Caption
=
this
.
videoCaption
;
events
=
[
'mouseover'
,
'mouseout'
,
'mousedown'
,
'click'
,
'focus'
,
'blur'
,
'keydown'
].
join
(
' '
);
Caption
.
setSubtitlesHeight
();
buildCaptions
(
Caption
.
subtitlesEl
,
Caption
.
captions
,
Caption
.
start
);
Caption
.
subtitlesEl
.
on
(
events
,
'li[data-index]'
,
function
(
event
)
{
switch
(
event
.
type
)
{
case
'mouseover'
:
case
'mouseout'
:
Caption
.
captionMouseOverOut
(
event
);
break
;
case
'mousedown'
:
Caption
.
captionMouseDown
(
event
);
break
;
case
'click'
:
Caption
.
captionClick
(
event
);
break
;
case
'focusin'
:
Caption
.
captionFocus
(
event
);
break
;
case
'focusout'
:
Caption
.
captionBlur
(
event
);
break
;
case
'keydown'
:
Caption
.
captionKeyDown
(
event
);
break
;
}
});
var
onRender
=
function
()
{
Caption
.
addPaddings
();
// Enables or disables automatic scrolling of the captions when the
// Enables or disables automatic scrolling of the captions when the
// video is playing. This feature has to be disabled when tabbing
// video is playing. This feature has to be disabled when tabbing
// through them as it interferes with that action. Initially, have this
// through them as it interferes with that action. Initially, have
// flag enabled as we assume mouse use. Then, if the first caption
// this flag enabled as we assume mouse use. Then, if the first
// (through forward tabbing) or the last caption (through backwards
// caption (through forward tabbing) or the last caption (through
// tabbing) gets the focus, disable that feature. Re-enable it if tabbing
// backwards tabbing) gets the focus, disable that feature.
//
then cycles out of the the captions.
// Re-enable it if tabbing
then cycles out of the the captions.
Caption
.
autoScrolling
=
true
;
Caption
.
autoScrolling
=
true
;
// Keeps track of where the focus is situated in the array of captions.
// Keeps track of where the focus is situated in the array of
// Used to implement the automatic scrolling behavior and decide if the
// captions. Used to implement the automatic scrolling behavior and
// outline around a caption has to be hidden or shown on a mouseenter
// decide if the outline around a caption has to be hidden or shown
// or mouseleave. Initially, no caption has the focus, set
the
// on a mouseenter or mouseleave. Initially, no caption has
the
//
index to -1.
// focus, set the
index to -1.
Caption
.
currentCaptionIndex
=
-
1
;
Caption
.
currentCaptionIndex
=
-
1
;
// Used to track if the focus is coming from a click or tabbing. This
// Used to track if the focus is coming from a click or tabbing. This
// has to be known to decide if, when a caption gets the focus, an
// has to be known to decide if, when a caption gets the focus, an
// outline has to be drawn (tabbing) or not (mouse click).
// outline has to be drawn (tabbing) or not (mouse click).
Caption
.
isMouseFocus
=
false
;
Caption
.
isMouseFocus
=
false
;
Caption
.
addPaddings
();
Caption
.
rendered
=
true
;
Caption
.
rendered
=
true
;
}
};
function
reRenderCaption
()
{
var
Caption
=
this
.
videoCaption
;
Caption
.
currentIndex
=
null
;
Caption
.
rendered
=
false
;
Caption
.
rendered
=
false
;
Caption
.
subtitlesEl
.
empty
();
Caption
.
subtitlesEl
.
empty
();
buildCaptions
(
Caption
.
subtitlesEl
,
Caption
.
captions
,
Caption
.
start
);
Caption
.
setSubtitlesHeight
();
Caption
.
addPaddings
();
buildCaptions
(
Caption
.
subtitlesEl
,
start
,
captions
).
done
(
onRender
);
Caption
.
rendered
=
true
;
}
}
function
addPaddings
()
{
function
addPaddings
()
{
...
@@ -529,7 +508,7 @@ function () {
...
@@ -529,7 +508,7 @@ function () {
// off again as it may have been enabled in captionBlur.
// off again as it may have been enabled in captionBlur.
if
(
if
(
captionIndex
<=
1
||
captionIndex
<=
1
||
captionIndex
>=
this
.
videoCaption
.
captions
.
length
-
2
captionIndex
>=
this
.
videoCaption
.
sjson
.
getSize
()
-
2
)
{
)
{
this
.
videoCaption
.
autoScrolling
=
false
;
this
.
videoCaption
.
autoScrolling
=
false
;
}
}
...
@@ -547,7 +526,7 @@ function () {
...
@@ -547,7 +526,7 @@ function () {
// tabbing back out of the captions or on the last element and tabbing
// tabbing back out of the captions or on the last element and tabbing
// forward out of the captions.
// forward out of the captions.
if
(
captionIndex
===
0
||
if
(
captionIndex
===
0
||
captionIndex
===
this
.
videoCaption
.
captions
.
length
-
1
)
{
captionIndex
===
this
.
videoCaption
.
sjson
.
getSize
()
-
1
)
{
this
.
videoCaption
.
autoScrolling
=
true
;
this
.
videoCaption
.
autoScrolling
=
true
;
}
}
...
@@ -579,38 +558,13 @@ function () {
...
@@ -579,38 +558,13 @@ function () {
}
}
}
}
function
search
(
time
)
{
var
index
,
max
,
min
;
if
(
this
.
videoCaption
.
loaded
)
{
min
=
0
;
max
=
this
.
videoCaption
.
start
.
length
-
1
;
if
(
time
<
this
.
videoCaption
.
start
[
min
])
{
return
-
1
;
}
while
(
min
<
max
)
{
index
=
Math
.
ceil
((
max
+
min
)
/
2
);
if
(
time
<
this
.
videoCaption
.
start
[
index
])
{
max
=
index
-
1
;
}
if
(
time
>=
this
.
videoCaption
.
start
[
index
])
{
min
=
index
;
}
}
return
min
;
}
return
undefined
;
}
function
play
()
{
function
play
()
{
if
(
this
.
videoCaption
.
loaded
)
{
if
(
this
.
videoCaption
.
loaded
)
{
if
(
!
this
.
videoCaption
.
rendered
)
{
if
(
!
this
.
videoCaption
.
rendered
)
{
this
.
videoCaption
.
renderCaption
();
var
start
=
this
.
videoCaption
.
sjson
.
getStartTimes
(),
captions
=
this
.
videoCaption
.
sjson
.
getCaptions
();
this
.
videoCaption
.
renderCaption
(
start
,
captions
);
}
}
this
.
videoCaption
.
playing
=
true
;
this
.
videoCaption
.
playing
=
true
;
...
@@ -627,20 +581,12 @@ function () {
...
@@ -627,20 +581,12 @@ function () {
var
newIndex
;
var
newIndex
;
if
(
this
.
videoCaption
.
loaded
)
{
if
(
this
.
videoCaption
.
loaded
)
{
// Current mode === 'flash' can only be for YouTube videos. So, we
// don't have to also check for videoType === 'youtube'.
if
(
this
.
isFlashMode
())
{
if
(
this
.
isFlashMode
())
{
// Total play time changes with speed change. Also there is
time
=
Time
.
convert
(
time
,
this
.
speed
,
'1.0'
);
// a 250 ms delay we have to take into account.
time
=
Math
.
round
(
Time
.
convert
(
time
,
this
.
speed
,
'1.0'
)
*
1000
+
100
);
}
else
{
// Total play time remains constant when speed changes.
time
=
Math
.
round
(
time
*
1000
+
100
);
}
}
newIndex
=
this
.
videoCaption
.
search
(
time
);
time
=
Math
.
round
(
time
*
1000
+
100
);
newIndex
=
this
.
videoCaption
.
sjson
.
search
(
time
);
if
(
if
(
typeof
newIndex
!==
'undefined'
&&
typeof
newIndex
!==
'undefined'
&&
...
@@ -658,39 +604,27 @@ function () {
...
@@ -658,39 +604,27 @@ function () {
.
addClass
(
'current'
);
.
addClass
(
'current'
);
this
.
videoCaption
.
currentIndex
=
newIndex
;
this
.
videoCaption
.
currentIndex
=
newIndex
;
this
.
videoCaption
.
scrollCaption
();
this
.
videoCaption
.
scrollCaption
();
}
}
}
}
}
}
function
seekPlayer
(
event
)
{
function
seekPlayer
(
event
)
{
var
time
;
var
time
=
parseInt
(
$
(
event
.
target
).
data
(
'start'
),
10
)
;
event
.
preventDefault
();
// Current mode === 'flash' can only be for YouTube videos. So, we
// don't have to also check for videoType === 'youtube'.
if
(
this
.
isFlashMode
())
{
if
(
this
.
isFlashMode
())
{
// Total play time changes with speed change. Also there is
time
=
Math
.
round
(
Time
.
convert
(
time
,
'1.0'
,
this
.
speed
));
// a 250 ms delay we have to take into account.
time
=
Math
.
round
(
Time
.
convert
(
$
(
event
.
target
).
data
(
'start'
),
'1.0'
,
this
.
speed
)
/
1000
);
}
else
{
// Total play time remains constant when speed changes.
time
=
parseInt
(
$
(
event
.
target
).
data
(
'start'
),
10
)
/
1000
;
}
}
this
.
trigger
(
this
.
trigger
(
'videoPlayer.onCaptionSeek'
,
'videoPlayer.onCaptionSeek'
,
{
{
'type'
:
'onCaptionSeek'
,
'type'
:
'onCaptionSeek'
,
'time'
:
time
'time'
:
time
/
1000
}
}
);
);
event
.
preventDefault
();
}
}
function
calculateOffset
(
element
)
{
function
calculateOffset
(
element
)
{
...
@@ -801,4 +735,4 @@ function () {
...
@@ -801,4 +735,4 @@ function () {
}
}
});
});
}(
RequireJS
.
requirejs
,
RequireJS
.
require
,
RequireJS
.
define
));
}(
RequireJS
.
define
));
common/lib/xmodule/xmodule/video_module/video_module.py
View file @
08538e89
...
@@ -72,6 +72,8 @@ class VideoModule(VideoFields, VideoStudentViewHandlers, XModule):
...
@@ -72,6 +72,8 @@ class VideoModule(VideoFields, VideoStudentViewHandlers, XModule):
'js'
:
[
'js'
:
[
resource_string
(
module
,
'js/src/video/00_video_storage.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_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/01_initialize.js'
),
resource_string
(
module
,
'js/src/video/025_focus_grabber.js'
),
resource_string
(
module
,
'js/src/video/025_focus_grabber.js'
),
resource_string
(
module
,
'js/src/video/02_html5_video.js'
),
resource_string
(
module
,
'js/src/video/02_html5_video.js'
),
...
...
lms/djangoapps/courseware/features/video.feature
View file @
08538e89
...
@@ -243,6 +243,7 @@ Feature: LMS Video component
...
@@ -243,6 +243,7 @@ Feature: LMS Video component
And it has a video in "Youtube" mode
:
And it has a video in "Youtube" mode
:
|
transcripts
|
sub
|
download_track
|
|
transcripts
|
sub
|
download_track
|
|
{"zh":
"chinese_transcripts.srt"}
|
OEoXaMPEzfM
|
true
|
|
{"zh":
"chinese_transcripts.srt"}
|
OEoXaMPEzfM
|
true
|
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."
Then
I can download transcript in
"srt"
format that has text
"Hi, welcome to Edx."
And
I select language with code
"zh"
And
I select language with code
"zh"
And
I see
"好 各位同学"
text in the captions
And
I see
"好 各位同学"
text in the captions
...
@@ -256,6 +257,7 @@ Feature: LMS Video component
...
@@ -256,6 +257,7 @@ Feature: LMS Video component
And it has a video in "HTML5" mode
:
And it has a video in "HTML5" mode
:
|
transcripts
|
sub
|
download_track
|
|
transcripts
|
sub
|
download_track
|
|
{"zh":
"chinese_transcripts.srt"}
|
OEoXaMPEzfM
|
true
|
|
{"zh":
"chinese_transcripts.srt"}
|
OEoXaMPEzfM
|
true
|
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."
Then
I can download transcript in
"srt"
format that has text
"Hi, welcome to Edx."
And
I select language with code
"zh"
And
I select language with code
"zh"
And
I see
"好 各位同学"
text in the captions
And
I see
"好 各位同学"
text in the captions
...
@@ -298,8 +300,10 @@ Feature: LMS Video component
...
@@ -298,8 +300,10 @@ Feature: LMS Video component
And
a video
"D"
in
"Youtube_HTML5"
mode in position
"3"
of sequential
And
a video
"D"
in
"Youtube_HTML5"
mode in position
"3"
of sequential
And
I open the section with videos
And
I open the section with videos
Then
videos have rendered in
"HTML5"
mode
Then
videos have rendered in
"HTML5"
mode
And
I see
"Hi, welcome to Edx."
text in the captions
And I see text in the captions
:
And
I see
"Equal transcripts"
text in the captions
|
text
|
|
Hi,
welcome
to
Edx.
|
|
Equal
transcripts
|
When
I open video
"C"
When
I open video
"C"
Then
the video has rendered in
"HTML5"
mode
Then
the video has rendered in
"HTML5"
mode
And
I make sure captions are opened
And
I make sure captions are opened
...
...
lms/djangoapps/courseware/features/video.py
View file @
08538e89
...
@@ -419,7 +419,15 @@ def i_see_menu(_step, menu):
...
@@ -419,7 +419,15 @@ def i_see_menu(_step, menu):
@step
(
'I see "([^"]*)" text in the captions$'
)
@step
(
'I see "([^"]*)" text in the captions$'
)
def
check_text_in_the_captions
(
_step
,
text
):
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 "([^"]*)"$'
)
@step
(
'I select language with code "([^"]*)"$'
)
...
@@ -441,14 +449,14 @@ def select_language(_step, code):
...
@@ -441,14 +449,14 @@ def select_language(_step, code):
# Make sure that all ajax requests that affects the display of captions are finished.
# Make sure that all ajax requests that affects the display of captions are finished.
# For example, request to get new translation etc.
# For example, request to get new translation etc.
world
.
wait_for_ajax_complete
()
world
.
wait_for_ajax_complete
()
assert
world
.
css_visible
(
'.subtitles'
)
world
.
wait_for_visible
(
'.subtitles'
)
@step
(
'I click video button "([^"]*)"$'
)
@step
(
'I click video button "([^"]*)"$'
)
def
click_button
(
_step
,
button
):
def
click_button
(
_step
,
button
):
world
.
css_click
(
VIDEO_BUTTONS
[
button
])
world
.
css_click
(
VIDEO_BUTTONS
[
button
])
@step
(
'I see video starts playing from "([^"]*)" position$'
)
@step
(
'I see video starts playing from "([^"]*)" position$'
)
def
start_playing_video_from_n_seconds
(
_step
,
position
):
def
start_playing_video_from_n_seconds
(
_step
,
position
):
world
.
wait_for
(
world
.
wait_for
(
...
@@ -504,9 +512,7 @@ def video_alignment(_step, transcript_visibility):
...
@@ -504,9 +512,7 @@ def video_alignment(_step, transcript_visibility):
height
=
abs
(
expected
[
'height'
]
-
real
[
'height'
])
<=
5
height
=
abs
(
expected
[
'height'
]
-
real
[
'height'
])
<=
5
# Restore initial window size
# Restore initial window size
set_window_dimensions
(
set_window_dimensions
(
initial
[
'width'
],
initial
[
'height'
])
initial
[
'width'
],
initial
[
'height'
]
)
assert
all
([
width
,
height
])
assert
all
([
width
,
height
])
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment