Bok-Choy CMS Video Tests

This commit is contained in:
Muhammad Ammar
2014-08-11 07:50:02 +00:00
parent 619f72f39c
commit 936bd4d5ad
7 changed files with 398 additions and 162 deletions

View File

@@ -1,6 +1,7 @@
"""
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 {}

View File

@@ -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 VideoComponentPage
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 = VideoComponentPage(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)

View File

@@ -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`