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
936bd4d5
Commit
936bd4d5
authored
Aug 11, 2014
by
Muhammad Ammar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Bok-Choy CMS Video Tests
parent
619f72f3
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
398 additions
and
162 deletions
+398
-162
cms/djangoapps/contentstore/features/video.feature
+2
-78
common/djangoapps/terrain/stubs/youtube.py
+4
-1
common/test/acceptance/pages/lms/video/video.py
+21
-18
common/test/acceptance/pages/studio/video/video.py
+104
-10
common/test/acceptance/tests/helpers.py
+75
-0
common/test/acceptance/tests/video/test_studio_video_module.py
+189
-8
common/test/acceptance/tests/video/test_video_module.py
+3
-47
No files found.
cms/djangoapps/contentstore/features/video.feature
View file @
936bd4d5
...
...
@@ -2,83 +2,7 @@
Feature
:
CMS Video Component
As a course author, I want to be able to view my created videos in Studio
# 1
Scenario
:
YouTube stub server proxies YouTube API correctly
Given
youtube stub server proxies YouTube API
And
I have created a Video component
Then
I can see video button
"play"
And
I click video button
"play"
Then
I can see video button
"pause"
# 2
Scenario
:
YouTube stub server can block YouTube API
Given
youtube stub server blocks YouTube API
And
I have created a Video component
And
I wait for
"3"
seconds
Then
I do not see video button
"play"
# 3
Scenario
:
Autoplay is disabled in Studio
Given
I have created a Video component
Then
when I view the video it does not have autoplay enabled
# 4
Scenario
:
Creating a video takes a single click
Given
I have clicked the new unit button
Then
creating a video takes a single click
# 5
# Sauce Labs cannot delete cookies
@skip_sauce
Scenario
:
Captions are hidden correctly
Given
I have created a Video component with subtitles
And
I have hidden captions
Then
when I view the video it does not show the captions
# 6
# Sauce Labs cannot delete cookies
@skip_sauce
Scenario
:
Captions are shown correctly
Given
I have created a Video component with subtitles
Then
when I view the video it does show the captions
# 7
# Sauce Labs cannot delete cookies
@skip_sauce
Scenario
:
Captions are toggled correctly
Given
I have created a Video component with subtitles
And
I have toggled captions
Then
when I view the video it does show the captions
# 8
Scenario
:
Video data is shown correctly
Given
I have created a video with only XML data
And
I reload the page
Then
the correct Youtube video is shown
# 9
# Disabled 11/26 due to flakiness in master.
# Enabled back on 11/29.
Scenario
:
When
enter key is pressed on a caption shows an outline around it
Given
I have created a Video component with subtitles
And
Make sure captions are opened
Then
I focus on caption line with data-index
"0"
Then
I press
"enter"
button on caption line with data-index
"0"
And
I see caption line with data-index
"0"
has class
"focused"
# 10
Scenario
:
When
start and end times are specified, a range on slider is shown
Given
I have created a Video component with subtitles
And
Make sure captions are closed
And
I edit the component
And
I open tab
"Advanced"
And I set value "00
:
00
:
12"
to
the
field
"Video
Start
Time"
And I set value "00
:
00
:
24"
to
the
field
"Video
Stop
Time"
And
I save changes
And
I click video button
"play"
Then
I see a range on slider
# 11
# Disabled 2/19/14 after intermittent failures in master
#Scenario: Check that position is stored on page refresh, position within start-end range
# Given I have created a Video component with subtitles
...
...
@@ -96,7 +20,7 @@ Feature: CMS Video Component
# And I click video button "play"
# Then I see video starts playing from "0:16" position
#
12
#
3
# Disabled 2/18/14 after intermittent failures in master
# Scenario: Check that position is stored on page refresh, position before start-end range
# Given I have created a Video component with subtitles
...
...
@@ -114,7 +38,7 @@ Feature: CMS Video Component
# And I click video button "play"
# Then I see video starts playing from "0:12" position
#
13
#
4
# Disabled 2/18/14 after intermittent failures in master
# Scenario: Check that position is stored on page refresh, position after start-end range
# Given I have created a Video component with subtitles
...
...
common/djangoapps/terrain/stubs/youtube.py
View file @
936bd4d5
...
...
@@ -55,7 +55,10 @@ class StubYouTubeHandler(StubHttpRequestHandler):
"Youtube provider received GET request to path {}"
.
format
(
self
.
path
)
)
if
'test_transcripts_youtube'
in
self
.
path
:
if
'get_config'
in
self
.
path
:
self
.
send_json_response
(
self
.
server
.
config
)
elif
'test_transcripts_youtube'
in
self
.
path
:
if
't__eq_exist'
in
self
.
path
:
status_message
=
""
.
join
([
...
...
common/test/acceptance/pages/lms/video/video.py
View file @
936bd4d5
...
...
@@ -122,20 +122,24 @@ class VideoPage(PageObject):
else
:
return
'.vert.vert-0'
def
get_element_selector
(
self
,
class_name
):
def
get_element_selector
(
self
,
class_name
,
vertical
=
True
):
"""
Construct unique element selector.
Arguments:
class_name (str): css class name for an element.
vertical (bool): do we need vertical css selector or not. vertical css selector is not present in Studio
Returns:
str: Element Selector.
"""
return
'{vertical} {video_element}'
.
format
(
vertical
=
self
.
get_video_vertical_selector
(
self
.
current_video_display_name
),
video_element
=
class_name
)
if
vertical
:
return
'{vertical} {video_element}'
.
format
(
vertical
=
self
.
get_video_vertical_selector
(
self
.
current_video_display_name
),
video_element
=
class_name
)
else
:
return
class_name
def
use_video
(
self
,
video_display_name
):
"""
...
...
@@ -253,6 +257,17 @@ class VideoPage(PageObject):
"""
self
.
_captions_visibility
(
False
)
def
is_captions_visible
(
self
):
"""
Get current visibility sate of captions.
Returns:
bool: True means captions are visible, False means captions are not visible
"""
caption_state_selector
=
self
.
get_element_selector
(
CSS_CLASS_NAMES
[
'closed_captions'
])
return
not
self
.
q
(
css
=
caption_state_selector
)
.
present
@wait_for_js
def
_captions_visibility
(
self
,
captions_new_state
):
"""
...
...
@@ -265,28 +280,16 @@ class VideoPage(PageObject):
states
=
{
True
:
'Shown'
,
False
:
'Hidden'
}
state
=
states
[
captions_new_state
]
caption_state_selector
=
self
.
get_element_selector
(
CSS_CLASS_NAMES
[
'closed_captions'
])
def
_captions_current_state
():
"""
Get current visibility sate of captions.
Returns:
bool: True means captions are visible, False means captions are not visible
"""
return
not
self
.
q
(
css
=
caption_state_selector
)
.
present
# Make sure that the CC button is there
EmptyPromise
(
lambda
:
self
.
is_button_shown
(
'CC'
),
"CC button is shown"
)
.
fulfill
()
# toggle captions visibility state if needed
if
_captions_current_stat
e
()
!=
captions_new_state
:
if
self
.
is_captions_visibl
e
()
!=
captions_new_state
:
self
.
click_player_button
(
'CC'
)
# Verify that captions state is toggled/changed
EmptyPromise
(
lambda
:
_captions_current_stat
e
()
==
captions_new_state
,
EmptyPromise
(
lambda
:
self
.
is_captions_visibl
e
()
==
captions_new_state
,
"Captions are {state}"
.
format
(
state
=
state
))
.
fulfill
()
@property
...
...
common/test/acceptance/pages/studio/video/video.py
View file @
936bd4d5
...
...
@@ -4,20 +4,27 @@ CMS Video
import
os
import
requests
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
YouTubeStubConfig
from
...lms.video.video
import
VideoPage
from
selenium.webdriver.common.keys
import
Keys
CLASS_SELECTORS
=
{
'video_container'
:
'div.video'
,
'video_init'
:
'.is-initialized'
,
'video_xmodule'
:
'.xmodule_VideoModule'
,
'video_spinner'
:
'.video-wrapper .spinner'
,
'video_controls'
:
'section.video-controls'
,
'attach_handout'
:
'.upload-dialog > input[type="file"]'
,
'upload_dialog'
:
'.wrapper-modal-window-assetupload'
,
'xblock'
:
'.add-xblock-component'
,
'slider_range'
:
'.slider-range'
,
}
BUTTON_SELECTORS
=
{
'create_video'
:
'a[data-category="video"]'
,
'handout_download'
:
'.video-handout.video-download-button a'
,
'handout_download_editor'
:
'.wrapper-comp-setting.file-uploader .download-action'
,
'upload_handout'
:
'.upload-action'
,
...
...
@@ -28,7 +35,7 @@ BUTTON_SELECTORS = {
@js_defined
(
'window.Video'
,
'window.RequireJS.require'
,
'window.jQuery'
,
'window.XModule'
,
'window.XBlock'
,
'window.MathJax.isReady'
)
class
Vid
oComponentPage
(
PageObject
):
class
Vid
eoComponentPage
(
VideoPage
):
"""
CMS Video Component Page
"""
...
...
@@ -37,7 +44,11 @@ class VidoComponentPage(PageObject):
@wait_for_js
def
is_browser_on_page
(
self
):
return
self
.
q
(
css
=
'div{0}'
.
format
(
CLASS_SELECTORS
[
'video_xmodule'
]))
.
present
return
self
.
q
(
css
=
'div{0}'
.
format
(
CLASS_SELECTORS
[
'video_xmodule'
]))
.
present
or
self
.
q
(
css
=
'div{0}'
.
format
(
CLASS_SELECTORS
[
'xblock'
]))
.
present
def
get_element_selector
(
self
,
class_name
,
vertical
=
False
):
return
super
(
VideoComponentPage
,
self
)
.
get_element_selector
(
class_name
,
vertical
=
vertical
)
def
_wait_for
(
self
,
check_func
,
desc
,
result
=
False
,
timeout
=
30
):
"""
...
...
@@ -59,9 +70,10 @@ class VidoComponentPage(PageObject):
"""
Wait until video component rendered completely
"""
self
.
_wait_for
(
lambda
:
self
.
q
(
css
=
CLASS_SELECTORS
[
'video_init'
])
.
present
,
'Video Player Initialized'
)
self
.
_wait_for
(
lambda
:
not
self
.
q
(
css
=
CLASS_SELECTORS
[
'video_spinner'
])
.
visible
,
'Video Buffering Completed'
)
self
.
_wait_for
(
lambda
:
self
.
q
(
css
=
CLASS_SELECTORS
[
'video_controls'
])
.
visible
,
'Player Controls are Visible'
)
if
not
YouTubeStubConfig
.
get_configuration
()
.
get
(
'youtube_api_blocked'
):
self
.
_wait_for
(
lambda
:
self
.
q
(
css
=
CLASS_SELECTORS
[
'video_init'
])
.
present
,
'Video Player Initialized'
)
self
.
_wait_for
(
lambda
:
not
self
.
q
(
css
=
CLASS_SELECTORS
[
'video_spinner'
])
.
visible
,
'Video Buffering Completed'
)
self
.
_wait_for
(
lambda
:
self
.
q
(
css
=
CLASS_SELECTORS
[
'video_controls'
])
.
visible
,
'Player Controls are Visible'
)
def
click_button
(
self
,
button_name
):
"""
...
...
@@ -74,6 +86,17 @@ class VidoComponentPage(PageObject):
self
.
q
(
css
=
BUTTON_SELECTORS
[
button_name
])
.
first
.
click
()
self
.
wait_for_ajax
()
@staticmethod
def
file_path
(
filename
):
"""
Construct file path to be uploaded to assets.
Arguments:
filename (str): asset filename
"""
return
os
.
sep
.
join
(
__file__
.
split
(
os
.
sep
)[:
-
5
])
+
'/data/uploads/'
+
filename
def
upload_handout
(
self
,
handout_filename
):
"""
Upload a handout file to assets
...
...
@@ -82,7 +105,7 @@ class VidoComponentPage(PageObject):
handout_filename (str): handout file name
"""
handout_path
=
os
.
sep
.
join
(
__file__
.
split
(
os
.
sep
)[:
-
5
])
+
'/data/uploads/'
+
handout_filename
handout_path
=
self
.
file_path
(
handout_filename
)
self
.
click_button
(
'upload_handout'
)
...
...
@@ -137,6 +160,77 @@ class VidoComponentPage(PageObject):
"""
Check if handout download button is visible
"""
# TODO! Remove .present below after bok-choy is updated to latest commit, Only .visible is enough
return
self
.
q
(
css
=
BUTTON_SELECTORS
[
'handout_download'
])
.
present
and
self
.
q
(
css
=
BUTTON_SELECTORS
[
'handout_download'
])
.
visible
return
self
.
q
(
css
=
BUTTON_SELECTORS
[
'handout_download'
])
.
visible
def
create_video
(
self
):
"""
Create a Video Component by clicking on Video button and wait for rendering to complete.
"""
# Create video
self
.
click_button
(
'create_video'
)
self
.
wait_for_video_component_render
()
def
xblocks
(
self
):
"""
Tells the total number of video xblocks present on current unit page.
Returns:
(int): total video xblocks
"""
return
len
(
self
.
q
(
css
=
'.xblock-header'
)
.
filter
(
lambda
el
:
'xblock-header-video'
in
el
.
get_attribute
(
'class'
))
.
results
)
def
focus_caption_line
(
self
,
line_number
):
"""
Focus a caption line as specified by `line_number`
Arguments:
line_number (int): caption line number
"""
caption_line_selector
=
".subtitles > li[data-index='{index}']"
.
format
(
index
=
line_number
-
1
)
self
.
q
(
css
=
caption_line_selector
)
.
results
[
0
]
.
send_keys
(
Keys
.
ENTER
)
def
is_caption_line_focused
(
self
,
line_number
):
"""
Check if a caption line focused
Arguments:
line_number (int): caption line number
"""
caption_line_selector
=
".subtitles > li[data-index='{index}']"
.
format
(
index
=
line_number
-
1
)
attributes
=
self
.
q
(
css
=
caption_line_selector
)
.
attrs
(
'class'
)
return
'focused'
in
attributes
def
set_settings_field_value
(
self
,
field
,
value
):
"""
In Advanced Tab set `field` with `value`
Arguments:
field (str): field name
value (str): field value
"""
query
=
'.wrapper-comp-setting > label:nth-child(1)'
field_id
=
''
for
index
,
_
in
enumerate
(
self
.
q
(
css
=
query
)):
if
field
in
self
.
q
(
css
=
query
)
.
nth
(
index
)
.
text
[
0
]:
field_id
=
self
.
q
(
css
=
query
)
.
nth
(
index
)
.
attrs
(
'for'
)[
0
]
break
self
.
q
(
css
=
'#{}'
.
format
(
field_id
))
.
fill
(
value
)
@property
def
is_slider_range_visible
(
self
):
"""
Check if slider range visible.
Returns:
bool: slider range is visible or not
"""
return
self
.
q
(
css
=
CLASS_SELECTORS
[
'slider_range'
])
.
visible
common/test/acceptance/tests/helpers.py
View file @
936bd4d5
"""
Test helper functions and base classes.
"""
import
json
import
unittest
import
functools
import
requests
...
...
@@ -194,3 +195,77 @@ class UniqueCourseTest(WebAppTest):
self
.
course_info
[
'number'
],
self
.
course_info
[
'run'
]
])
class
YouTubeConfigError
(
Exception
):
"""
Error occurred while configuring YouTube Stub Server.
"""
pass
class
YouTubeStubConfig
(
object
):
"""
Configure YouTube Stub Server.
"""
PORT
=
9080
URL
=
'http://127.0.0.1:{}/'
.
format
(
PORT
)
@classmethod
def
configure
(
cls
,
config
):
"""
Allow callers to configure the stub server using the /set_config URL.
Arguments:
config (dict): Configuration dictionary.
Raises:
YouTubeConfigError
"""
youtube_stub_config_url
=
cls
.
URL
+
'set_config'
config_data
=
{
param
:
json
.
dumps
(
value
)
for
param
,
value
in
config
.
items
()}
response
=
requests
.
put
(
youtube_stub_config_url
,
data
=
config_data
)
if
not
response
.
ok
:
raise
YouTubeConfigError
(
'YouTube Server Configuration Failed. URL {0}, Configuration Data: {1}, Status was {2}'
.
format
(
youtube_stub_config_url
,
config
,
response
.
status_code
))
@classmethod
def
reset
(
cls
):
"""
Reset YouTube Stub Server Configurations using the /del_config URL.
Raises:
YouTubeConfigError
"""
youtube_stub_config_url
=
cls
.
URL
+
'del_config'
response
=
requests
.
delete
(
youtube_stub_config_url
)
if
not
response
.
ok
:
raise
YouTubeConfigError
(
'YouTube Server Configuration Failed. URL: {0} Status was {1}'
.
format
(
youtube_stub_config_url
,
response
.
status_code
))
@classmethod
def
get_configuration
(
cls
):
"""
Allow callers to get current stub server configuration.
Returns:
dict
"""
youtube_stub_config_url
=
cls
.
URL
+
'get_config'
response
=
requests
.
get
(
youtube_stub_config_url
)
if
response
.
ok
:
return
json
.
loads
(
response
.
content
)
else
:
return
{}
common/test/acceptance/tests/video/test_studio_video_module.py
View file @
936bd4d5
...
...
@@ -7,9 +7,9 @@ Acceptance tests for CMS Video Module.
from
unittest
import
skipIf
from
...pages.studio.auto_auth
import
AutoAuthPage
from
...pages.studio.overview
import
CourseOutlinePage
from
...pages.studio.video.video
import
VidoComponentPage
from
...pages.studio.video.video
import
Vid
e
oComponentPage
from
...fixtures.course
import
CourseFixture
,
XBlockFixtureDesc
from
..helpers
import
UniqueCourseTest
,
is_youtube_available
from
..helpers
import
UniqueCourseTest
,
is_youtube_available
,
YouTubeStubConfig
@skipIf
(
is_youtube_available
()
is
False
,
'YouTube is not available!'
)
...
...
@@ -24,7 +24,7 @@ class CMSVideoBaseTest(UniqueCourseTest):
"""
super
(
CMSVideoBaseTest
,
self
)
.
setUp
()
self
.
video
=
VidoComponentPage
(
self
.
browser
)
self
.
video
=
Vid
e
oComponentPage
(
self
.
browser
)
# This will be initialized later
self
.
unit_page
=
None
...
...
@@ -41,6 +41,8 @@ class CMSVideoBaseTest(UniqueCourseTest):
self
.
course_info
[
'run'
],
self
.
course_info
[
'display_name'
]
)
self
.
assets
=
[]
def
_install_course_fixture
(
self
):
"""
Prepare for tests by creating a course with a section, subsection, and unit.
...
...
@@ -49,13 +51,15 @@ class CMSVideoBaseTest(UniqueCourseTest):
Create a user and make that user a course author
Log the user into studio
"""
if
self
.
assets
:
self
.
course_fixture
.
add_asset
(
self
.
assets
)
# Create course with Video component
self
.
course_fixture
.
add_children
(
XBlockFixtureDesc
(
'chapter'
,
'Test Section'
)
.
add_children
(
XBlockFixtureDesc
(
'sequential'
,
'Test Subsection'
)
.
add_children
(
XBlockFixtureDesc
(
"vertical"
,
"Test Unit"
)
.
add_children
(
XBlockFixtureDesc
(
'video'
,
'Video'
)
,
XBlockFixtureDesc
(
'vertical'
,
'Test Unit'
)
.
add_children
(
XBlockFixtureDesc
(
'video'
,
'Video'
)
)
)
)
...
...
@@ -95,17 +99,194 @@ class CMSVideoBaseTest(UniqueCourseTest):
"""
Open component Edit Dialog for first component on page.
"""
self
.
unit_page
.
xblocks
[
0
]
.
edit
()
# The 0th entry is the unit page itself.
self
.
unit_page
.
xblocks
[
1
]
.
edit
()
def
open_advanced_tab
(
self
):
"""
Open components advanced tab.
"""
self
.
unit_page
.
xblocks
[
0
]
.
open_advanced_tab
()
# The 0th entry is the unit page itself.
self
.
unit_page
.
xblocks
[
1
]
.
open_advanced_tab
()
def
save_unit_settings
(
self
):
"""
Save component settings.
"""
self
.
unit_page
.
xblocks
[
0
]
.
save_settings
()
# The 0th entry is the unit page itself.
self
.
unit_page
.
xblocks
[
1
]
.
save_settings
()
class
CMSVideoTest
(
CMSVideoBaseTest
):
"""
CMS Video Test Class
"""
def
setUp
(
self
):
super
(
CMSVideoTest
,
self
)
.
setUp
()
self
.
addCleanup
(
YouTubeStubConfig
.
reset
)
def
_create_course_unit
(
self
,
youtube_stub_config
=
None
,
subtitles
=
False
):
"""
Create a Studio Video Course Unit and Navigate to it.
Arguments:
youtube_stub_config (dict)
subtitles (bool)
"""
if
youtube_stub_config
:
YouTubeStubConfig
.
configure
(
youtube_stub_config
)
if
subtitles
:
self
.
assets
.
append
(
'subs_OEoXaMPEzfM.srt.sjson'
)
self
.
navigate_to_course_unit
()
def
_create_video
(
self
):
"""
Create Xblock Video Component.
"""
self
.
video
.
create_video
()
video_xblocks
=
self
.
video
.
xblocks
()
# Total video xblock components count should be equals to 2
# Why 2? One video component is created by default for each test. Please see
# test_studio_video_module.py:CMSVideoTest._create_course_unit
# And we are creating second video component here.
self
.
assertTrue
(
video_xblocks
==
2
)
def
test_youtube_stub_proxy
(
self
):
"""
Scenario: YouTube stub server proxies YouTube API correctly
Given youtube stub server proxies YouTube API
And I have created a Video component
Then I can see video button "play"
And I click video button "play"
Then I can see video button "pause"
"""
self
.
_create_course_unit
(
youtube_stub_config
=
{
'youtube_api_blocked'
:
False
})
self
.
assertTrue
(
self
.
video
.
is_button_shown
(
'play'
))
self
.
video
.
click_player_button
(
'play'
)
self
.
assertTrue
(
self
.
video
.
is_button_shown
(
'pause'
))
def
test_youtube_stub_blocks_youtube_api
(
self
):
"""
Scenario: YouTube stub server can block YouTube API
Given youtube stub server blocks YouTube API
And I have created a Video component
Then I do not see video button "play"
"""
self
.
_create_course_unit
(
youtube_stub_config
=
{
'youtube_api_blocked'
:
True
})
self
.
assertFalse
(
self
.
video
.
is_button_shown
(
'play'
))
def
test_autoplay_is_disabled
(
self
):
"""
Scenario: Autoplay is disabled in Studio
Given I have created a Video component
Then when I view the video it does not have autoplay enabled
"""
self
.
_create_course_unit
()
self
.
assertFalse
(
self
.
video
.
is_autoplay_enabled
)
def
test_video_creation_takes_single_click
(
self
):
"""
Scenario: Creating a video takes a single click
And creating a video takes a single click
"""
self
.
_create_course_unit
()
# This will create a video by doing a single click and then ensure that video is created
self
.
_create_video
()
def
test_captions_hidden_correctly
(
self
):
"""
Scenario: Captions are hidden correctly
Given I have created a Video component with subtitles
And I have hidden captions
Then when I view the video it does not show the captions
"""
self
.
_create_course_unit
(
subtitles
=
True
)
self
.
video
.
hide_captions
()
self
.
assertFalse
(
self
.
video
.
is_captions_visible
())
def
test_captions_shown_correctly
(
self
):
"""
Scenario: Captions are shown correctly
Given I have created a Video component with subtitles
Then when I view the video it does show the captions
"""
self
.
_create_course_unit
(
subtitles
=
True
)
self
.
assertTrue
(
self
.
video
.
is_captions_visible
())
def
test_captions_toggling
(
self
):
"""
Scenario: Captions are toggled correctly
Given I have created a Video component with subtitles
And I have toggled captions
Then when I view the video it does show the captions
"""
self
.
_create_course_unit
(
subtitles
=
True
)
self
.
video
.
click_player_button
(
'CC'
)
self
.
assertFalse
(
self
.
video
.
is_captions_visible
())
self
.
video
.
click_player_button
(
'CC'
)
self
.
assertTrue
(
self
.
video
.
is_captions_visible
())
def
test_caption_line_focus
(
self
):
"""
Scenario: When enter key is pressed on a caption, an outline shows around it
Given I have created a Video component with subtitles
And Make sure captions are opened
Then I focus on first caption line
And I see first caption line has focused
"""
self
.
_create_course_unit
(
subtitles
=
True
)
self
.
video
.
show_captions
()
self
.
video
.
focus_caption_line
(
1
)
self
.
assertTrue
(
self
.
video
.
is_caption_line_focused
(
1
))
def
test_slider_range_works
(
self
):
"""
Scenario: When start and end times are specified, a range on slider is shown
Given I have created a Video component with subtitles
And Make sure captions are closed
And I edit the component
And I open tab "Advanced"
And I set value "00:00:12" to the field "Video Start Time"
And I set value "00:00:24" to the field "Video Stop Time"
And I save changes
And I click video button "play"
Then I see a range on slider
"""
self
.
_create_course_unit
(
subtitles
=
True
)
self
.
video
.
hide_captions
()
self
.
edit_component
()
self
.
open_advanced_tab
()
self
.
video
.
set_settings_field_value
(
'Video Start Time'
,
'00:00:12'
)
self
.
video
.
set_settings_field_value
(
'Video Stop Time'
,
'00:00:24'
)
self
.
save_unit_settings
()
self
.
video
.
click_player_button
(
'play'
)
self
.
assertTrue
(
self
.
video
.
is_slider_range_visible
)
common/test/acceptance/tests/video/test_video_module.py
View file @
936bd4d5
...
...
@@ -4,10 +4,8 @@
Acceptance tests for Video.
"""
import
json
from
unittest
import
skipIf
,
skip
import
requests
from
..helpers
import
UniqueCourseTest
,
is_youtube_available
from
..helpers
import
UniqueCourseTest
,
is_youtube_available
,
YouTubeStubConfig
from
...pages.lms.video.video
import
VideoPage
from
...pages.lms.tab_nav
import
TabNavPage
from
...pages.lms.course_nav
import
CourseNavPage
...
...
@@ -18,8 +16,6 @@ from ..helpers import skip_if_browser
VIDEO_SOURCE_PORT
=
8777
YOUTUBE_STUB_PORT
=
9080
YOUTUBE_STUB_URL
=
'http://127.0.0.1:{}/'
.
format
(
YOUTUBE_STUB_PORT
)
HTML5_SOURCES
=
[
'http://localhost:{0}/gizmo.mp4'
.
format
(
VIDEO_SOURCE_PORT
),
...
...
@@ -32,13 +28,6 @@ HTML5_SOURCES_INCORRECT = [
]
class
YouTubeConfigError
(
Exception
):
"""
Error occurred while configuring YouTube Stub Server.
"""
pass
@skipIf
(
is_youtube_available
()
is
False
,
'YouTube is not available!'
)
class
VideoBaseTest
(
UniqueCourseTest
):
"""
...
...
@@ -68,7 +57,7 @@ class VideoBaseTest(UniqueCourseTest):
self
.
youtube_configuration
=
{}
# reset youtube stub server
self
.
addCleanup
(
self
.
_reset_youtube_stub_server
)
self
.
addCleanup
(
YouTubeStubConfig
.
reset
)
def
navigate_to_video
(
self
):
""" Prepare the course and get to the video and render it """
...
...
@@ -96,7 +85,7 @@ class VideoBaseTest(UniqueCourseTest):
self
.
course_fixture
.
install
()
if
len
(
self
.
youtube_configuration
)
>
0
:
self
.
_configure_youtube_stub_server
(
self
.
youtube_configuration
)
YouTubeStubConfig
.
configure
(
self
.
youtube_configuration
)
def
_add_course_verticals
(
self
):
"""
...
...
@@ -148,39 +137,6 @@ class VideoBaseTest(UniqueCourseTest):
self
.
_navigate_to_courseware_video
()
self
.
video
.
wait_for_video_class
()
def
_configure_youtube_stub_server
(
self
,
config
):
"""
Allow callers to configure the stub server using the /set_config URL.
:param config: Configuration dictionary.
The request should have PUT data, such that:
Each PUT parameter is the configuration key.
Each PUT value is a JSON-encoded string value for the configuration.
:raise YouTubeConfigError:
"""
youtube_stub_config_url
=
YOUTUBE_STUB_URL
+
'set_config'
config_data
=
{
param
:
json
.
dumps
(
value
)
for
param
,
value
in
config
.
items
()}
response
=
requests
.
put
(
youtube_stub_config_url
,
data
=
config_data
)
if
not
response
.
ok
:
raise
YouTubeConfigError
(
'YouTube Server Configuration Failed. URL {0}, Configuration Data: {1}, Status was {2}'
.
format
(
youtube_stub_config_url
,
config
,
response
.
status_code
))
def
_reset_youtube_stub_server
(
self
):
"""
Reset YouTube Stub Server Configurations using the /del_config URL.
:raise YouTubeConfigError:
"""
youtube_stub_config_url
=
YOUTUBE_STUB_URL
+
'del_config'
response
=
requests
.
delete
(
youtube_stub_config_url
)
if
not
response
.
ok
:
raise
YouTubeConfigError
(
'YouTube Server Configuration Failed. URL: {0} Status was {1}'
.
format
(
youtube_stub_config_url
,
response
.
status_code
))
def
metadata_for_mode
(
self
,
player_mode
,
additional_data
=
None
):
"""
Create a dictionary for video player configuration according to `player_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