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
1bbfbedb
Commit
1bbfbedb
authored
Apr 15, 2014
by
Muhammad Ammar
Committed by
Jay Zoldak
Apr 23, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Bok-Choy video tests batch2
parent
3b49c17c
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
545 additions
and
178 deletions
+545
-178
common/test/acceptance/fixtures/course.py
+2
-2
common/test/acceptance/pages/lms/video.py
+207
-27
common/test/acceptance/tests/helpers.py
+10
-3
common/test/acceptance/tests/test_video_module.py
+315
-37
lms/djangoapps/courseware/features/video.feature
+11
-109
No files found.
common/test/acceptance/fixtures/course.py
View file @
1bbfbedb
...
...
@@ -221,7 +221,7 @@ class CourseFixture(StudioApiFixture):
"""
Add the asset to the list of assets to be uploaded when the install method is called.
"""
self
.
_assets
.
app
end
(
asset_name
)
self
.
_assets
.
ext
end
(
asset_name
)
def
install
(
self
):
"""
...
...
@@ -312,7 +312,7 @@ class CourseFixture(StudioApiFixture):
details
=
response
.
json
()
except
ValueError
:
raise
CourseFixtureError
(
"Could not decode course details as JSON: '{0}'"
.
format
(
old_
details
)
"Could not decode course details as JSON: '{0}'"
.
format
(
details
)
)
# Update the old details with our overrides
...
...
common/test/acceptance/pages/lms/video.py
View file @
1bbfbedb
...
...
@@ -2,11 +2,15 @@
Video player in the courseware.
"""
import
time
import
requests
from
selenium.webdriver.common.action_chains
import
ActionChains
from
bok_choy.page_object
import
PageObject
from
bok_choy.promise
import
EmptyPromise
,
Promise
from
bok_choy.javascript
import
wait_for_js
,
js_defined
from
...tests.helpers
import
wait_for_ajax
VIDEO_BUTTONS
=
{
'CC'
:
'.hide-subtitles'
,
'volume'
:
'.volume'
,
...
...
@@ -18,12 +22,16 @@ VIDEO_BUTTONS = {
CSS_CLASS_NAMES
=
{
'closed_captions'
:
'.closed .subtitles'
,
'captions_rendered'
:
'.video.is-captions-rendered'
,
'captions'
:
'.subtitles'
,
'captions_text'
:
'.subtitles > li'
,
'error_message'
:
'.video .video-player h3'
,
'video_container'
:
'div.video'
,
'video_sources'
:
'.video-player video source'
,
'video_spinner'
:
'.video-wrapper .spinner'
,
'video_xmodule'
:
'.xmodule_VideoModule'
'video_xmodule'
:
'.xmodule_VideoModule'
,
'video_init'
:
'.is-initialized'
,
'video_time'
:
'div.vidtime'
}
VIDEO_MODES
=
{
...
...
@@ -31,6 +39,14 @@ VIDEO_MODES = {
'youtube'
:
'iframe'
}
VIDEO_MENUS
=
{
'language'
:
'.lang .menu'
,
'speed'
:
'.speed .menu'
,
'download_transcript'
:
'.video-tracks .a11y-menu-list'
,
'transcript-format'
:
'.video-tracks .a11y-menu-button'
}
@js_defined
(
'window.Video'
,
'window.RequireJS.require'
,
'window.jQuery'
)
class
VideoPage
(
PageObject
):
...
...
@@ -45,20 +61,42 @@ class VideoPage(PageObject):
return
self
.
q
(
css
=
'div{0}'
.
format
(
CSS_CLASS_NAMES
[
'video_xmodule'
]))
.
present
@wait_for_js
def
_wait_for_element
(
self
,
element_css_selector
,
promise_desc
):
"""
Wait for element specified by `element_css_selector` is present in DOM.
:param element_css_selector: css selector of the element
:param promise_desc: Description of the Promise, used in log messages.
:return: BrokenPromise: the `Promise` was not satisfied within the time or attempt limits.
"""
def
_is_element_present
():
"""
Check if web-element present in DOM
:return: bool
"""
return
self
.
q
(
css
=
element_css_selector
)
.
present
EmptyPromise
(
_is_element_present
,
promise_desc
,
timeout
=
200
)
.
fulfill
()
@wait_for_js
def
wait_for_video_class
(
self
):
"""
Wait until element with class name `video` appeared in DOM.
"""
video_css
=
'{0}'
.
format
(
CSS_CLASS_NAMES
[
'video_container'
])
wait_for_ajax
(
self
.
browser
)
return
EmptyPromise
(
lambda
:
self
.
q
(
css
=
video_css
)
.
present
,
"Video is initialized"
)
.
fulfill
()
video_css
=
'{0}'
.
format
(
CSS_CLASS_NAMES
[
'video_container'
])
self
.
_wait_for_element
(
video_css
,
'Video is initialized'
)
@wait_for_js
def
wait_for_video_player_render
(
self
):
"""
Wait until Video Player Rendered Completely.
"""
self
.
wait_for_video_class
()
self
.
_wait_for_element
(
CSS_CLASS_NAMES
[
'video_init'
],
'Video Player Initialized'
)
self
.
_wait_for_element
(
CSS_CLASS_NAMES
[
'video_time'
],
'Video Player Initialized'
)
def
_is_finished_loading
():
"""
Check if video loading completed
...
...
@@ -66,9 +104,9 @@ class VideoPage(PageObject):
"""
return
not
self
.
q
(
css
=
CSS_CLASS_NAMES
[
'video_spinner'
])
.
visible
self
.
wait_for_video_class
()
return
EmptyPromise
(
_is_finished_loading
,
'Finished loading the video'
,
try_limit
=
10
,
timeout
=
60
,
try_interval
=
10
)
.
fulfill
(
)
EmptyPromise
(
_is_finished_loading
,
'Finished loading the video'
,
timeout
=
200
)
.
fulfill
()
wait_for_ajax
(
self
.
browser
)
def
is_video_rendered
(
self
,
mode
):
"""
...
...
@@ -89,14 +127,6 @@ class VideoPage(PageObject):
return
Promise
(
_is_element_present
,
'Video Rendering Failed in {0} mode.'
.
format
(
mode
))
.
fulfill
()
@property
def
all_video_sources
(
self
):
"""
Extract all video source urls on current page.
"""
return
self
.
q
(
css
=
CSS_CLASS_NAMES
[
'video_sources'
])
.
map
(
lambda
el
:
el
.
get_attribute
(
'src'
)
.
split
(
'?'
)[
0
])
.
results
@property
def
is_autoplay_enabled
(
self
):
"""
Extract `data-autoplay` attribute to check video autoplay is enabled or disabled.
...
...
@@ -137,6 +167,7 @@ class VideoPage(PageObject):
"""
Show the video captions.
"""
def
_is_subtitles_open
():
"""
Check if subtitles are opened
...
...
@@ -163,19 +194,168 @@ class VideoPage(PageObject):
Extract captions text.
:return: str
"""
captions_css
=
CSS_CLASS_NAMES
[
'captions'
]
# wait until captions rendered completely
self
.
_wait_for_element
(
CSS_CLASS_NAMES
[
'captions_rendered'
],
'Captions Rendered'
)
def
_captions_text
():
"""
Extract captions text.
:return: tuple
"""
is_present
=
self
.
q
(
css
=
captions_css
)
.
present
result
=
None
captions_css
=
CSS_CLASS_NAMES
[
'captions_text'
]
subs
=
self
.
q
(
css
=
captions_css
)
.
html
return
' '
.
join
(
subs
)
def
set_speed
(
self
,
speed
):
"""
Change the video play speed.
:param speed: speed value in str
"""
self
.
browser
.
execute_script
(
"$('.speeds').addClass('is-opened')"
)
speed_css
=
'li[data-speed="{0}"] a'
.
format
(
speed
)
EmptyPromise
(
lambda
:
self
.
q
(
css
=
'.speeds'
)
.
visible
,
'Video Speed Control Shown'
)
.
fulfill
()
self
.
q
(
css
=
speed_css
)
.
first
.
click
()
if
is_present
:
result
=
self
.
q
(
css
=
captions_css
)
.
text
[
0
]
def
get_speed
(
self
):
"""
Get current video speed value.
:return: str
"""
speed_css
=
'.speeds .value'
return
self
.
q
(
css
=
speed_css
)
.
text
[
0
]
speed
=
property
(
get_speed
,
set_speed
)
def
click_player_button
(
self
,
button
):
"""
Click on `button`.
:param button: key in VIDEO_BUTTONS dictionary, its value will give us the css selector for `button`
"""
self
.
q
(
css
=
VIDEO_BUTTONS
[
button
])
.
first
.
click
()
wait_for_ajax
(
self
.
browser
)
def
_get_element_dimensions
(
self
,
selector
):
"""
Gets the width and height of element specified by `selector`
:param selector: str, css selector of a web element
:return: dict
"""
element
=
self
.
q
(
css
=
selector
)
.
results
[
0
]
return
element
.
size
def
_get_dimensions
(
self
):
"""
Gets the video player dimensions
:return: tuple
"""
video
=
self
.
_get_element_dimensions
(
'.video-player iframe, .video-player video'
)
wrapper
=
self
.
_get_element_dimensions
(
'.tc-wrapper'
)
controls
=
self
.
_get_element_dimensions
(
'.video-controls'
)
progress_slider
=
self
.
_get_element_dimensions
(
'.video-controls > .slider'
)
expected
=
dict
(
wrapper
)
expected
[
'height'
]
-=
controls
[
'height'
]
+
0.5
*
progress_slider
[
'height'
]
return
video
,
expected
def
is_aligned
(
self
,
is_transcript_visible
):
"""
Check if video is aligned properly.
:param is_transcript_visible: bool
:return: bool
"""
# Width of the video container in css equal 75% of window if transcript enabled
wrapper_width
=
75
if
is_transcript_visible
else
100
initial
=
self
.
browser
.
get_window_size
()
self
.
browser
.
set_window_size
(
300
,
600
)
# Wait for browser to resize completely
# Currently there is no other way to wait instead of explicit wait
time
.
sleep
(
0.2
)
real
,
expected
=
self
.
_get_dimensions
()
width
=
round
(
100
*
real
[
'width'
]
/
expected
[
'width'
])
==
wrapper_width
self
.
browser
.
set_window_size
(
600
,
300
)
# Wait for browser to resize completely
# Currently there is no other way to wait instead of explicit wait
time
.
sleep
(
0.2
)
real
,
expected
=
self
.
_get_dimensions
()
height
=
abs
(
expected
[
'height'
]
-
real
[
'height'
])
<=
5
# Restore initial window size
self
.
browser
.
set_window_size
(
initial
[
'width'
],
initial
[
'height'
]
)
return
all
([
width
,
height
])
def
_get_transcript
(
self
,
url
):
"""
Sends a http get request.
"""
kwargs
=
dict
()
session_id
=
[{
i
[
'name'
]:
i
[
'value'
]}
for
i
in
self
.
browser
.
get_cookies
()
if
i
[
'name'
]
==
u'sessionid'
]
if
session_id
:
kwargs
.
update
({
'cookies'
:
session_id
[
0
]
})
response
=
requests
.
get
(
url
,
**
kwargs
)
return
response
.
status_code
<
400
,
response
.
headers
,
response
.
content
def
downloaded_transcript_contains_text
(
self
,
transcript_format
,
text_to_search
):
"""
Download the transcript in format `transcript_format` and check that it contains the text `text_to_search`
:param transcript_format: `srt` or `txt`
:param text_to_search: str
:return: bool
"""
# check if we have a transcript with correct format
assert
'.'
+
transcript_format
in
self
.
q
(
css
=
VIDEO_MENUS
[
'transcript-format'
])
.
text
[
0
]
formats
=
{
'srt'
:
'application/x-subrip'
,
'txt'
:
'text/plain'
,
}
url
=
self
.
q
(
css
=
VIDEO_BUTTONS
[
'download_transcript'
])
.
attrs
(
'href'
)[
0
]
result
,
headers
,
content
=
self
.
_get_transcript
(
url
)
assert
result
assert
formats
[
transcript_format
]
in
headers
.
get
(
'content-type'
,
''
)
assert
text_to_search
in
content
.
decode
(
'utf-8'
)
def
select_language
(
self
,
code
):
"""
Select captions for language `code`
:param code: str, two character language code like `en`, `zh`
:return: bool, True for Success, False for Failure or BrokenPromise
"""
wait_for_ajax
(
self
.
browser
)
selector
=
VIDEO_MENUS
[
"language"
]
+
' li[data-lang-code="{code}"]'
.
format
(
code
=
code
)
# mouse over to CC button
element_to_hover_over
=
self
.
q
(
css
=
VIDEO_BUTTONS
[
"CC"
])
.
results
[
0
]
hover
=
ActionChains
(
self
.
browser
)
.
move_to_element
(
element_to_hover_over
)
hover
.
perform
()
self
.
q
(
css
=
selector
)
.
first
.
click
()
assert
'is-active'
==
self
.
q
(
css
=
selector
)
.
attrs
(
'class'
)[
0
]
assert
len
(
self
.
q
(
css
=
VIDEO_MENUS
[
"language"
]
+
' li.is-active'
)
.
results
)
==
1
# Make sure that all ajax requests that affects the display of captions are finished.
# For example, request to get new translation etc.
wait_for_ajax
(
self
.
browser
)
return
is_present
,
result
EmptyPromise
(
lambda
:
self
.
q
(
css
=
CSS_CLASS_NAMES
[
'captions'
])
.
visible
,
'Subtitles Visible'
)
.
fulfill
()
return
Promise
(
_captions_text
,
'Captions Text'
)
.
fulfill
()
# wait until captions rendered completely
self
.
_wait_for_element
(
CSS_CLASS_NAMES
[
'captions_rendered'
],
'Captions Rendered'
)
common/test/acceptance/tests/helpers.py
View file @
1bbfbedb
...
...
@@ -6,8 +6,13 @@ from bok_choy.web_app_test import WebAppTest
from
bok_choy.promise
import
EmptyPromise
def
wait_for_ajax
(
browser
):
""" Make sure that all ajax requests are finished.
def
wait_for_ajax
(
browser
,
try_limit
=
None
,
try_interval
=
0.5
,
timeout
=
60
):
"""
Make sure that all ajax requests are finished.
:param try_limit (int or None): Number of attempts to make to satisfy the `Promise`. Can be `None` to
disable the limit.
:param try_interval (float): Number of seconds to wait between attempts.
:param timeout (float): Maximum number of seconds to wait for the `Promise` to be satisfied before timing out.
:param browser: selenium.webdriver, The Selenium-controlled browser that this page is loaded in.
"""
def
_is_ajax_finished
():
...
...
@@ -17,7 +22,9 @@ def wait_for_ajax(browser):
"""
return
browser
.
execute_script
(
"return jQuery.active"
)
==
0
EmptyPromise
(
_is_ajax_finished
,
"Finished waiting for ajax requests."
)
.
fulfill
()
EmptyPromise
(
_is_ajax_finished
,
"Finished waiting for ajax requests."
,
try_limit
=
try_limit
,
try_interval
=
try_interval
,
timeout
=
timeout
)
.
fulfill
()
def
load_data_str
(
rel_path
):
"""
...
...
common/test/acceptance/tests/test_video_module.py
View file @
1bbfbedb
...
...
@@ -7,6 +7,7 @@ Acceptance tests for Video.
from
.helpers
import
UniqueCourseTest
from
..pages.lms.video
import
VideoPage
from
..pages.lms.tab_nav
import
TabNavPage
from
..pages.lms.course_nav
import
CourseNavPage
from
..pages.studio.auto_auth
import
AutoAuthPage
from
..pages.lms.course_info
import
CourseInfoPage
from
..fixtures.course
import
CourseFixture
,
XBlockFixtureDesc
...
...
@@ -23,18 +24,6 @@ HTML5_SOURCES_INCORRECT = [
'http://localhost:{0}/gizmo.mp99'
.
format
(
VIDEO_SOURCE_PORT
),
]
HTML5_METADATA
=
{
'youtube_id_1_0'
:
''
,
'youtube_id_0_75'
:
''
,
'youtube_id_1_25'
:
''
,
'youtube_id_1_5'
:
''
,
'html5_sources'
:
HTML5_SOURCES
}
YT_HTML5_METADATA
=
{
'html5_sources'
:
HTML5_SOURCES
}
class
VideoBaseTest
(
UniqueCourseTest
):
"""
...
...
@@ -50,6 +39,7 @@ class VideoBaseTest(UniqueCourseTest):
self
.
video
=
VideoPage
(
self
.
browser
)
self
.
tab_nav
=
TabNavPage
(
self
.
browser
)
self
.
course_nav
=
CourseNavPage
(
self
.
browser
)
self
.
course_info_page
=
CourseInfoPage
(
self
.
browser
,
self
.
course_id
)
self
.
course_fixture
=
CourseFixture
(
...
...
@@ -57,8 +47,9 @@ class VideoBaseTest(UniqueCourseTest):
self
.
course_info
[
'run'
],
self
.
course_info
[
'display_name'
]
)
self
.
metadata
=
{}
self
.
assets
=
None
self
.
metadata
=
None
self
.
assets
=
[]
self
.
verticals
=
None
def
navigate_to_video
(
self
):
""" Prepare the course and get to the video and render it """
...
...
@@ -79,16 +70,44 @@ class VideoBaseTest(UniqueCourseTest):
if
self
.
assets
:
self
.
course_fixture
.
add_asset
(
self
.
assets
)
# If you are not sending any metadata then `None` should be send as metadata to XBlockFixtureDesc
# instead of empty dictionary otherwise test will not produce correct results.
_metadata
=
self
.
metadata
if
self
.
metadata
else
None
chapter_sequential
=
XBlockFixtureDesc
(
'sequential'
,
'Test Section'
)
chapter_sequential
.
add_children
(
*
self
.
_add_course_verticals
())
chapter
=
XBlockFixtureDesc
(
'chapter'
,
'Test Chapter'
)
.
add_children
(
chapter_sequential
)
self
.
course_fixture
.
add_children
(
chapter
)
self
.
course_fixture
.
install
()
def
_add_course_verticals
(
self
):
"""
Create XBlockFixtureDesc verticals
:return: a list of XBlockFixtureDesc
"""
xblock_verticals
=
[]
_verticals
=
self
.
verticals
# Video tests require at least one vertical with a single video.
if
not
_verticals
:
_verticals
=
[[{
'display_name'
:
'Video'
,
'metadata'
:
self
.
metadata
}]]
for
vertical_index
,
vertical
in
enumerate
(
_verticals
):
xblock_verticals
.
append
(
self
.
_create_single_vertical
(
vertical
,
vertical_index
))
self
.
course_fixture
.
add_children
(
XBlockFixtureDesc
(
'chapter'
,
'Test Chapter'
)
.
add_children
(
XBlockFixtureDesc
(
'sequential'
,
'Test Section'
)
.
add_children
(
XBlockFixtureDesc
(
'vertical'
,
'Test Vertical-0'
)
.
add_children
(
XBlockFixtureDesc
(
'video'
,
'Video'
,
metadata
=
_metadata
)
))))
.
install
()
return
xblock_verticals
def
_create_single_vertical
(
self
,
vertical
,
vertical_index
):
"""
Create a single course vertical of type XBlockFixtureDesc with category `vertical`.
A single course vertical can contain single or multiple video modules.
:param vertical: vertical data list
:param vertical_index: index for the vertical display name
:return: XBlockFixtureDesc
"""
xblock_course_vertical
=
XBlockFixtureDesc
(
'vertical'
,
'Test Vertical-{0}'
.
format
(
vertical_index
))
for
video
in
vertical
:
xblock_course_vertical
.
add_children
(
XBlockFixtureDesc
(
'video'
,
video
[
'display_name'
],
metadata
=
video
.
get
(
'metadata'
)))
return
xblock_course_vertical
def
_navigate_to_courseware_video
(
self
):
""" Register for the course and navigate to the video unit """
...
...
@@ -107,6 +126,56 @@ class VideoBaseTest(UniqueCourseTest):
self
.
_navigate_to_courseware_video
()
self
.
video
.
wait_for_video_class
()
def
metadata_for_mode
(
self
,
player_mode
,
additional_data
=
None
):
"""
Create a dictionary for video player configuration according to `player_mode`
:param player_mode (str): Video player mode
:param additional_data (dict): Optional additional metadata.
:return: dict
"""
metadata
=
{}
if
player_mode
==
'html5'
:
metadata
.
update
({
'youtube_id_1_0'
:
''
,
'youtube_id_0_75'
:
''
,
'youtube_id_1_25'
:
''
,
'youtube_id_1_5'
:
''
,
'html5_sources'
:
HTML5_SOURCES
})
if
player_mode
==
'youtube_html5'
:
metadata
.
update
({
'html5_sources'
:
HTML5_SOURCES
,
})
if
player_mode
==
'youtube_html5_unsupported_video'
:
metadata
.
update
({
'html5_sources'
:
HTML5_SOURCES_INCORRECT
})
if
player_mode
==
'html5_unsupported_video'
:
metadata
.
update
({
'youtube_id_1_0'
:
''
,
'youtube_id_0_75'
:
''
,
'youtube_id_1_25'
:
''
,
'youtube_id_1_5'
:
''
,
'html5_sources'
:
HTML5_SOURCES_INCORRECT
})
if
additional_data
:
metadata
.
update
(
additional_data
)
return
metadata
def
open_video
(
self
,
video_display_name
):
"""
Navigate to sequential specified by `video_display_name`
:param video_display_name (str): Sequential Title
"""
self
.
course_nav
.
go_to_sequential
(
video_display_name
)
self
.
video
.
wait_for_video_player_render
()
class
YouTubeVideoTest
(
VideoBaseTest
):
""" Test YouTube Video Player """
...
...
@@ -114,7 +183,7 @@ class YouTubeVideoTest(VideoBaseTest):
def
setUp
(
self
):
super
(
YouTubeVideoTest
,
self
)
.
setUp
()
def
test_
video_component_rendered_in_youtube_without
_html5_sources
(
self
):
def
test_
youtube_video_rendering_wo
_html5_sources
(
self
):
"""
Scenario: Video component is rendered in the LMS in Youtube mode without HTML5 sources
Given the course has a Video component in "Youtube" mode
...
...
@@ -125,7 +194,7 @@ class YouTubeVideoTest(VideoBaseTest):
# Verify that video has rendered in "Youtube" mode
self
.
assertTrue
(
self
.
video
.
is_video_rendered
(
'youtube'
))
def
test_cc_button_w
ithout_english_transcript_youtube_mod
e
(
self
):
def
test_cc_button_w
o_english_transcript_youtub
e
(
self
):
"""
Scenario: CC button works correctly w/o english transcript in Youtube mode of Video component
Given the course has a Video component in "Youtube" mode
...
...
@@ -133,8 +202,9 @@ class YouTubeVideoTest(VideoBaseTest):
And I have uploaded a non-english transcript file to assets
Then I see the correct text in the captions
"""
self
.
metadata
[
'transcripts'
]
=
{
'zh'
:
'chinese_transcripts.srt'
}
self
.
assets
=
'chinese_transcripts.srt'
data
=
{
'transcripts'
:
{
'zh'
:
'chinese_transcripts.srt'
}}
self
.
metadata
=
self
.
metadata_for_mode
(
'youtube'
,
data
)
self
.
assets
.
append
(
'chinese_transcripts.srt'
)
self
.
navigate_to_video
()
self
.
video
.
show_captions
()
...
...
@@ -150,14 +220,14 @@ class YouTubeVideoTest(VideoBaseTest):
And I have uploaded a .srt.sjson file to assets
Then I see the correct english text in the captions
"""
self
.
assets
=
'subs_OEoXaMPEzfM.srt.sjson'
self
.
assets
.
append
(
'subs_OEoXaMPEzfM.srt.sjson'
)
self
.
navigate_to_video
()
self
.
video
.
show_captions
()
# Verify that we see "Hi, welcome to Edx." text in the captions
self
.
assertIn
(
'Hi, welcome to Edx.'
,
self
.
video
.
captions_text
)
def
test_cc_button_hidden_
if_
no_translations
(
self
):
def
test_cc_button_hidden_no_translations
(
self
):
"""
Scenario: CC button is hidden if no translations
Given the course has a Video component in "Youtube" mode
...
...
@@ -166,22 +236,111 @@ class YouTubeVideoTest(VideoBaseTest):
self
.
navigate_to_video
()
self
.
assertFalse
(
self
.
video
.
is_button_shown
(
'CC'
))
def
test_fullscreen_video_alignment_with_transcript_hidden
(
self
):
"""
Scenario: Video is aligned correctly if transcript is hidden in fullscreen mode
Given the course has a Video component in "Youtube" mode
"""
self
.
navigate_to_video
()
# click video button "fullscreen"
self
.
video
.
click_player_button
(
'fullscreen'
)
# check if video aligned correctly without enabled transcript
self
.
assertTrue
(
self
.
video
.
is_aligned
(
False
))
def
test_download_button_wo_english_transcript
(
self
):
"""
Scenario: Download button works correctly w/o english transcript in Youtube mode of Video component
Given
I have a "chinese_transcripts.srt" transcript file in assets
And it has a video in "Youtube" mode
"""
data
=
{
'download_track'
:
True
,
'transcripts'
:
{
'zh'
:
'chinese_transcripts.srt'
}}
self
.
metadata
=
self
.
metadata_for_mode
(
'youtube'
,
additional_data
=
data
)
self
.
assets
.
append
(
'chinese_transcripts.srt'
)
# go to video
self
.
navigate_to_video
()
# check if we can download transcript in "srt" format that has text "好 各位同学"
unicode_text
=
"好 各位同学"
.
decode
(
'utf-8'
)
self
.
video
.
downloaded_transcript_contains_text
(
'srt'
,
unicode_text
)
def
test_download_button_two_transcript_languages_youtube
(
self
):
"""
Scenario: Download button works correctly for non-english transcript in Youtube mode of Video component
Given
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
"""
self
.
assets
.
extend
([
'chinese_transcripts.srt'
,
'subs_OEoXaMPEzfM.srt.sjson'
])
data
=
{
'download_track'
:
True
,
'transcripts'
:
{
'zh'
:
'chinese_transcripts.srt'
},
'sub'
:
'OEoXaMPEzfM'
}
self
.
metadata
=
self
.
metadata_for_mode
(
'youtube'
,
additional_data
=
data
)
# go to video
self
.
navigate_to_video
()
# check if "Hi, welcome to Edx." text in the captions
self
.
assertIn
(
'Hi, welcome to Edx.'
,
self
.
video
.
captions_text
)
# check if we can download transcript in "srt" format that has text "Hi, welcome to Edx."
self
.
video
.
downloaded_transcript_contains_text
(
'srt'
,
'Hi, welcome to Edx.'
)
# select language with code "zh"
self
.
video
.
select_language
(
'zh'
)
# check if we see "好 各位同学" text in the captions
unicode_text
=
"好 各位同学"
.
decode
(
'utf-8'
)
self
.
assertIn
(
unicode_text
,
self
.
video
.
captions_text
)
# check if we can download transcript in "srt" format that has text "好 各位同学"
unicode_text
=
"好 各位同学"
.
decode
(
'utf-8'
)
self
.
video
.
downloaded_transcript_contains_text
(
'srt'
,
unicode_text
)
def
test_fullscreen_video_alignment_on_transcript_toggle
(
self
):
"""
Tests that Video is aligned correctly on transcript toggle in fullscreen mode Given I have a
"subs_OEoXaMPEzfM.srt.sjson" transcript file in assets And it has a video in "Youtube" mode.
"""
self
.
assets
.
append
(
'subs_OEoXaMPEzfM.srt.sjson'
)
data
=
{
'sub'
:
'OEoXaMPEzfM'
}
self
.
metadata
=
self
.
metadata_for_mode
(
'youtube'
,
additional_data
=
data
)
# go to video
self
.
navigate_to_video
()
# make sure captions are opened
self
.
video
.
show_captions
()
# click video button "fullscreen"
self
.
video
.
click_player_button
(
'fullscreen'
)
# check if video aligned correctly with enabled transcript
self
.
assertTrue
(
self
.
video
.
is_aligned
(
True
))
# click video button "CC"
self
.
video
.
click_player_button
(
'CC'
)
# check if video aligned correctly without enabled transcript
self
.
assertTrue
(
self
.
video
.
is_aligned
(
False
))
class
YouTubeHtml5VideoTest
(
VideoBaseTest
):
""" Test YouTube HTML5 Video Player """
def
setUp
(
self
):
super
(
YouTubeHtml5VideoTest
,
self
)
.
setUp
()
self
.
metadata
=
YT_HTML5_METADATA
def
test_
video_component_rendered_in_youtube_with_unsupported_html5
_sources
(
self
):
def
test_
youtube_video_rendering_with_unsupported
_sources
(
self
):
"""
Scenario: Video component is rendered in the LMS in Youtube mode
with HTML5 sources that doesn't supported by browser
with HTML5 sources that doesn't supported by browser
Given the course has a Video component in "Youtube_HTML5_Unsupported_Video" mode
Then the video has rendered in "Youtube" mode
"""
self
.
metadata
[
'html5_sources'
]
=
HTML5_SOURCES_INCORRECT
self
.
metadata
=
self
.
metadata_for_mode
(
'youtube_html5_unsupported_video'
)
self
.
navigate_to_video
()
# Verify that the video has rendered in "Youtube" mode
...
...
@@ -193,7 +352,6 @@ class Html5VideoTest(VideoBaseTest):
def
setUp
(
self
):
super
(
Html5VideoTest
,
self
)
.
setUp
()
self
.
metadata
=
HTML5_METADATA
def
test_autoplay_disabled_for_video_component
(
self
):
"""
...
...
@@ -201,19 +359,20 @@ class Html5VideoTest(VideoBaseTest):
Given the course has a Video component in "HTML5" mode
Then it does not have autoplay enabled
"""
self
.
metadata
=
self
.
metadata_for_mode
(
'html5'
)
self
.
navigate_to_video
()
# Verify that the video has autoplay mode disabled
self
.
assertFalse
(
self
.
video
.
is_autoplay_enabled
)
def
test_
video_component_rendered_in_html5_with_unsupported_html5
_sources
(
self
):
def
test_
html5_video_rendering_with_unsupported
_sources
(
self
):
"""
Scenario: Video component is rendered in
the
LMS in HTML5 mode with HTML5 sources that doesn't supported by browser
Scenario: Video component is rendered in LMS in HTML5 mode with HTML5 sources that doesn't supported by browser
Given the course has a Video component in "HTML5_Unsupported_Video" mode
Then error message is shown
And error message has correct text
"""
self
.
metadata
[
'html5_sources'
]
=
HTML5_SOURCES_INCORRECT
self
.
metadata
=
self
.
metadata_for_mode
(
'html5_unsupported_video'
)
self
.
navigate_to_video_no_render
()
# Verify that error message is shown
...
...
@@ -222,3 +381,122 @@ class Html5VideoTest(VideoBaseTest):
# Verify that error message has correct text
correct_error_message_text
=
'ERROR: No playable video sources found!'
self
.
assertIn
(
correct_error_message_text
,
self
.
video
.
error_message_text
)
def
test_download_button_wo_english_transcript
(
self
):
"""
Scenario: Download button works correctly w/o english transcript in HTML5 mode of Video component
Given
I have a "chinese_transcripts.srt" transcript file in assets
And it has a video in "HTML5" mode
"""
data
=
{
'download_track'
:
True
,
'transcripts'
:
{
'zh'
:
'chinese_transcripts.srt'
}}
self
.
metadata
=
self
.
metadata_for_mode
(
'html5'
,
additional_data
=
data
)
self
.
assets
.
append
(
'chinese_transcripts.srt'
)
# go to video
self
.
navigate_to_video
()
# check if we see "好 各位同学" text in the captions
unicode_text
=
"好 各位同学"
.
decode
(
'utf-8'
)
self
.
assertIn
(
unicode_text
,
self
.
video
.
captions_text
)
# check if we can download transcript in "srt" format that has text "好 各位同学"
unicode_text
=
"好 各位同学"
.
decode
(
'utf-8'
)
self
.
video
.
downloaded_transcript_contains_text
(
'srt'
,
unicode_text
)
def
test_download_button_two_transcript_languages_html5
(
self
):
"""
Scenario: Download button works correctly for non-english transcript in HTML5 mode of Video component
Given
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
"""
self
.
assets
.
extend
([
'chinese_transcripts.srt'
,
'subs_OEoXaMPEzfM.srt.sjson'
])
data
=
{
'download_track'
:
True
,
'transcripts'
:
{
'zh'
:
'chinese_transcripts.srt'
},
'sub'
:
'OEoXaMPEzfM'
}
self
.
metadata
=
self
.
metadata_for_mode
(
'html5'
,
additional_data
=
data
)
# go to video
self
.
navigate_to_video
()
# check if "Hi, welcome to Edx." text in the captions
self
.
assertIn
(
'Hi, welcome to Edx.'
,
self
.
video
.
captions_text
)
# check if we can download transcript in "srt" format that has text "Hi, welcome to Edx."
self
.
video
.
downloaded_transcript_contains_text
(
'srt'
,
'Hi, welcome to Edx.'
)
# select language with code "zh"
self
.
video
.
select_language
(
'zh'
)
# check if we see "好 各位同学" text in the captions
unicode_text
=
"好 各位同学"
.
decode
(
'utf-8'
)
self
.
assertIn
(
unicode_text
,
self
.
video
.
captions_text
)
#Then I can download transcript in "srt" format that has text "好 各位同学"
unicode_text
=
"好 各位同学"
.
decode
(
'utf-8'
)
self
.
video
.
downloaded_transcript_contains_text
(
'srt'
,
unicode_text
)
def
test_full_screen_video_alignment_with_transcript_visible
(
self
):
"""
Scenario: Video is aligned correctly if transcript is visible in fullscreen mode
Given
I have a "subs_OEoXaMPEzfM.srt.sjson" transcript file in assets
And it has a video in "HTML5" mode
"""
self
.
assets
.
append
(
'subs_OEoXaMPEzfM.srt.sjson'
)
data
=
{
'sub'
:
'OEoXaMPEzfM'
}
self
.
metadata
=
self
.
metadata_for_mode
(
'html5'
,
additional_data
=
data
)
# go to video
self
.
navigate_to_video
()
# make sure captions are opened
self
.
video
.
show_captions
()
# click video button "fullscreen"
self
.
video
.
click_player_button
(
'fullscreen'
)
# check if video aligned correctly with enabled transcript
self
.
assertTrue
(
self
.
video
.
is_aligned
(
True
))
def
test_cc_button_with_english_transcript
(
self
):
"""
Scenario: CC button works correctly only w/ english transcript in HTML5 mode of Video component
Given
I have a "subs_OEoXaMPEzfM.srt.sjson" transcript file in assets
And it has a video in "HTML5" mode
"""
self
.
assets
.
append
(
'subs_OEoXaMPEzfM.srt.sjson'
)
data
=
{
'sub'
:
'OEoXaMPEzfM'
}
self
.
metadata
=
self
.
metadata_for_mode
(
'html5'
,
additional_data
=
data
)
# go to video
self
.
navigate_to_video
()
# make sure captions are opened
self
.
video
.
show_captions
()
# check if we see "Hi, welcome to Edx." text in the captions
self
.
assertIn
(
"Hi, welcome to Edx."
,
self
.
video
.
captions_text
)
def
test_cc_button_wo_english_transcript_html5
(
self
):
"""
Scenario: CC button works correctly w/o english transcript in HTML5 mode of Video component
Given
I have a "chinese_transcripts.srt" transcript file in assets
And it has a video in "HTML5" mode
"""
self
.
assets
.
append
(
'chinese_transcripts.srt'
)
data
=
{
'transcripts'
:
{
'zh'
:
'chinese_transcripts.srt'
}}
self
.
metadata
=
self
.
metadata_for_mode
(
'html5'
,
additional_data
=
data
)
# go to video
self
.
navigate_to_video
()
# make sure captions are opened
self
.
video
.
show_captions
()
# check if we see "好 各位同学" text in the captions
unicode_text
=
"好 各位同学"
.
decode
(
'utf-8'
)
self
.
assertIn
(
unicode_text
,
self
.
video
.
captions_text
)
lms/djangoapps/courseware/features/video.feature
View file @
1bbfbedb
...
...
@@ -89,56 +89,6 @@ Feature: LMS.Video component
And
I see
"Hi, welcome to Edx."
text in the captions
# 8
Scenario
:
CC button works correctly w/o 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 it has a video in "HTML5" mode
:
|
transcripts
|
|
{"zh":
"chinese_transcripts.srt"}
|
And
I make sure captions are opened
Then
I see
"好 各位同学"
text in the captions
# 9
Scenario
:
CC button works correctly only w/ english transcript in HTML5 mode of Video component
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 "HTML5" mode
:
|
sub
|
|
OEoXaMPEzfM
|
And
I make sure captions are opened
Then
I see
"Hi, welcome to Edx."
text in the captions
# 10
Scenario
:
Video is aligned correctly if transcript is visible in fullscreen 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 "HTML5" mode
:
|
sub
|
|
OEoXaMPEzfM
|
And
I make sure captions are opened
And
I click video button
"fullscreen"
Then
I see video aligned correctly with enabled transcript
# 11
Scenario
:
Video is aligned correctly if transcript is hidden in fullscreen mode
Given
the course has a Video component in
"Youtube"
mode
And
I click video button
"fullscreen"
Then
I see video aligned correctly without enabled transcript
# 12
Scenario
:
Video is aligned correctly on transcript toggle in fullscreen 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 "Youtube" mode
:
|
sub
|
|
OEoXaMPEzfM
|
And
I make sure captions are opened
And
I click video button
"fullscreen"
Then
I see video aligned correctly with enabled transcript
And
I click video button
"CC"
Then
I see video aligned correctly without enabled transcript
# 13
Scenario
:
Download Transcript button works correctly in Video component
Given
I am registered for the course
"test_course"
And
I have a
"subs_OEoXaMPEzfM.srt.sjson"
transcript file in assets
...
...
@@ -160,7 +110,7 @@ Feature: LMS.Video component
When
I open video
"C"
Then
menu
"download_transcript"
doesn't exist
#
14
#
9
Scenario
:
Youtube video has correct transcript if fields for other speeds are filled.
Given
I am registered for the course
"test_course"
And
I have a
"subs_OEoXaMPEzfM.srt.sjson"
transcript file in assets
...
...
@@ -178,55 +128,7 @@ Feature: LMS.Video component
# "1:56" is the duration in the VCR timer before the video plays.
And I see duration "1
:
56"
# 15
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
:
|
transcripts
|
sub
|
download_track
|
|
{"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."
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
"好 各位同学"
# 16
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
:
|
transcripts
|
sub
|
download_track
|
|
{"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."
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
"好 各位同学"
# 17
Scenario
:
Download button works correctly w/o 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 it has a video in "HTML5" mode
:
|
transcripts
|
download_track
|
|
{"zh":
"chinese_transcripts.srt"}
|
true
|
And
I see
"好 各位同学"
text in the captions
Then
I can download transcript in
"srt"
format that has text
"好 各位同学"
# 18
Scenario
:
Download button works correctly w/o 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 it has a video in "Youtube" mode
:
|
transcripts
|
download_track
|
|
{"zh":
"chinese_transcripts.srt"}
|
true
|
And
I see
"好 各位同学"
text in the captions
Then
I can download transcript in
"srt"
format that has text
"好 各位同学"
# 19
# 10
Scenario
:
Verify that each video in each sub-section includes a transcript for non-Youtube countries.
Given
youtube server is up and response time is 2 seconds
And
I am registered for the course
"test_course"
...
...
@@ -255,7 +157,7 @@ Feature: LMS.Video component
Then
the video has rendered in
"HTML5"
mode
And
the video does not show the captions
#
20
#
11
Scenario
:
Start time works for Youtube video
Given
I am registered for the course
"test_course"
And it has a video in "Youtube" mode
:
...
...
@@ -264,7 +166,7 @@ Feature: LMS.Video component
And
I click video button
"play"
Then I see video slider at "0
:
10"
position
#
21
#
12
Scenario
:
End time works for Youtube video
Given
I am registered for the course
"test_course"
And it has a video in "Youtube" mode
:
...
...
@@ -274,7 +176,7 @@ Feature: LMS.Video component
And
I wait
"5"
seconds
Then I see video slider at "0
:
02"
position
#
22
#
13
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
:
...
...
@@ -286,7 +188,7 @@ Feature: LMS.Video component
And
I wait
"5"
seconds
Then I see video slider at "1
:
00"
position
#
23
#
14
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
:
...
...
@@ -297,7 +199,7 @@ Feature: LMS.Video component
And
I wait
"5"
seconds
Then I see video slider at "0
:
12"
position
#
24
#
15
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
:
...
...
@@ -312,7 +214,7 @@ Feature: LMS.Video component
# The default video length is 00:01:55.
Then I see video slider at "1
:
55"
position
#
25
#
16
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
:
...
...
@@ -324,7 +226,7 @@ Feature: LMS.Video component
And
I wait
"8"
seconds
Then I see video slider at "0
:
32"
position
#
26
#
17
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
:
...
...
@@ -337,7 +239,7 @@ Feature: LMS.Video component
# Video stops at the end.
Then I see video slider at "1
:
55"
position
#
27
#
18
@skip_firefox
Scenario
:
Quality button appears on play
Given
the course has a Video component in
"Youtube"
mode
...
...
@@ -345,7 +247,7 @@ Feature: LMS.Video component
And
I click video button
"play"
Then
I see video button
"quality"
is visible
#
28
#
19
@skip_firefox
Scenario
:
Quality button works correctly
Given
the course has a Video component in
"Youtube"
mode
...
...
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