Commit 81a5a7b9 by Muhammad Ammar

CMS Video Handout Tests

parent 6fa96cf0
@shard_3 @requires_stub_youtube
Feature: CMS Video Component Handout
As a course author, I want to be able to create video handout
# 1
Scenario: Handout uploading works correctly
Given I have created a Video component with handout file "textbook.pdf"
And I save changes
Then I can see video button "handout"
And I can download handout file with mime type "application/pdf"
# 2
Scenario: Handout downloading works correctly w/ preliminary saving
Given I have created a Video component with handout file "textbook.pdf"
And I save changes
And I edit the component
And I open tab "Advanced"
And I can download handout file in editor with mime type "application/pdf"
# 3
Scenario: Handout downloading works correctly w/o preliminary saving
Given I have created a Video component with handout file "textbook.pdf"
And I can download handout file in editor with mime type "application/pdf"
# 4
Scenario: Handout clearing works correctly w/ preliminary saving
Given I have created a Video component with handout file "textbook.pdf"
And I save changes
And I can download handout file with mime type "application/pdf"
And I edit the component
And I open tab "Advanced"
And I clear handout
And I save changes
Then I do not see video button "handout"
# 5
Scenario: Handout clearing works correctly w/o preliminary saving
Given I have created a Video component with handout file "asset.html"
And I clear handout
And I save changes
Then I do not see video button "handout"
# 6
Scenario: User can easy replace the handout by another one w/ preliminary saving
Given I have created a Video component with handout file "asset.html"
And I save changes
Then I can see video button "handout"
And I can download handout file with mime type "text/html"
And I edit the component
And I open tab "Advanced"
And I replace handout file by "textbook.pdf"
And I save changes
Then I can see video button "handout"
And I can download handout file with mime type "application/pdf"
# 7
Scenario: User can easy replace the handout by another one w/o preliminary saving
Given I have created a Video component with handout file "asset.html"
And I replace handout file by "textbook.pdf"
And I save changes
Then I can see video button "handout"
And I can download handout file with mime type "application/pdf"
# 8
Scenario: Upload file "A" -> Remove it -> Upload file "B"
Given I have created a Video component with handout file "asset.html"
And I clear handout
And I upload handout file "textbook.pdf"
And I save changes
Then I can see video button "handout"
And I can download handout file with mime type "application/pdf"
......@@ -2,6 +2,7 @@
Fixture to create a course and course components (XBlocks).
"""
import mimetypes
import json
import re
import datetime
......@@ -407,10 +408,10 @@ class CourseFixture(StudioApiFixture):
test_dir = path(__file__).abspath().dirname().dirname().dirname()
for asset_name in self._assets:
srt_path = test_dir + '/data/uploads/' + asset_name
asset_file_path = test_dir + '/data/uploads/' + asset_name
asset_file = open(srt_path)
files = {'file': (asset_name, asset_file)}
asset_file = open(asset_file_path)
files = {'file': (asset_name, asset_file, mimetypes.guess_type(asset_file_path)[0])}
headers = {
'Accept': 'application/json',
......
......@@ -62,6 +62,22 @@ class UnitPage(PageObject):
'Wait for draft mode to be activated'
).fulfill()
def set_unit_visibility(self, visibility):
"""
Set unit visibility state
Arguments:
visibility (str): private or public
"""
self.q(css='select[name="visibility-select"] option[value="{}"]'.format(visibility)).first.click()
self.wait_for_ajax()
COMPONENT_BUTTONS = {
'advanced_tab': '.editor-tabs li.inner_tab_wrap:nth-child(2) > a',
'save_settings': '.action-save',
}
class Component(PageObject):
"""
......@@ -125,3 +141,26 @@ class Component(PageObject):
an initialized :class:`.ContainerPage` for that xblock.
"""
return ContainerPage(self.browser, self.locator).visit()
def _click_button(self, button_name):
"""
Click on a button as specified by `button_name`
Arguments:
button_name (str): button name
"""
self.q(css=COMPONENT_BUTTONS[button_name]).first.click()
self.wait_for_ajax()
def open_advanced_tab(self):
"""
Click on Advanced Tab.
"""
self._click_button('advanced_tab')
def save_settings(self):
"""
Click on settings Save button.
"""
self._click_button('save_settings')
"""
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
CLASS_SELECTORS = {
'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',
}
BUTTON_SELECTORS = {
'handout_download': '.video-handout.video-download-button a',
'handout_download_editor': '.wrapper-comp-setting.file-uploader .download-action',
'upload_handout': '.upload-action',
'handout_submit': '.action-upload',
'handout_clear': '.wrapper-comp-setting.file-uploader .setting-clear',
}
@js_defined('window.Video', 'window.RequireJS.require', 'window.jQuery', 'window.XModule', 'window.XBlock',
'window.MathJax.isReady')
class VidoComponentPage(PageObject):
"""
CMS Video Component Page
"""
url = None
@wait_for_js
def is_browser_on_page(self):
return self.q(css='div{0}'.format(CLASS_SELECTORS['video_xmodule'])).present
def _wait_for(self, check_func, desc, result=False, timeout=200):
"""
Calls the method provided as an argument until the Promise satisfied or BrokenPromise
Arguments:
check_func (callable): Promise function to be fulfilled.
desc (str): Description of the Promise, used in log messages.
result (bool): Indicates whether we need result from Promise or not
timeout (float): Maximum number of seconds to wait for the Promise to be satisfied before timing out.
"""
if result:
return Promise(check_func, desc, timeout=timeout).fulfill()
else:
return EmptyPromise(check_func, desc, timeout=timeout).fulfill()
def wait_for_video_component_render(self):
"""
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')
def click_button(self, button_name):
"""
Click on a button as specified by `button_name`
Arguments:
button_name (str): button name
"""
self.q(css=BUTTON_SELECTORS[button_name]).first.click()
self.wait_for_ajax()
def upload_handout(self, handout_filename):
"""
Upload a handout file to assets
Arguments:
handout_filename (str): handout file name
"""
handout_path = os.sep.join(__file__.split(os.sep)[:-5]) + '/data/uploads/' + handout_filename
self.click_button('upload_handout')
self.q(css=CLASS_SELECTORS['attach_handout']).results[0].send_keys(handout_path)
self.click_button('handout_submit')
# confirm upload completion
self._wait_for(lambda: not self.q(css=CLASS_SELECTORS['upload_dialog']).present, 'Upload Handout Completed')
def clear_handout(self):
"""
Clear handout from settings
"""
self.click_button('handout_clear')
def _get_handout(self, url):
"""
Download handout at `url`
"""
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
def download_handout(self, mime_type, is_editor=False):
"""
Download handout with mime type specified by `mime_type`
Arguments:
mime_type (str): mime type of handout file
Returns:
tuple: Handout download result.
"""
selector = BUTTON_SELECTORS['handout_download_editor'] if is_editor else BUTTON_SELECTORS['handout_download']
handout_url = self.q(css=selector).attrs('href')[0]
result, headers = self._get_handout(handout_url)
return result, headers['content-type'] == mime_type
@property
def is_handout_button_visible(self):
"""
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
# -*- coding: utf-8 -*-
"""
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 ...fixtures.course import CourseFixture, XBlockFixtureDesc
from ..helpers import UniqueCourseTest, is_youtube_available
@skipIf(is_youtube_available() is False, 'YouTube is not available!')
class CMSVideoBaseTest(UniqueCourseTest):
"""
CMS Video Module Base Test Class
"""
def setUp(self):
"""
Initialization of pages and course fixture for tests
"""
super(CMSVideoBaseTest, self).setUp()
self.video = VidoComponentPage(self.browser)
# This will be initialized later
self.unit_page = None
self.outline = CourseOutlinePage(
self.browser,
self.course_info['org'],
self.course_info['number'],
self.course_info['run']
)
self.course_fixture = CourseFixture(
self.course_info['org'], self.course_info['number'],
self.course_info['run'], self.course_info['display_name']
)
def _install_course_fixture(self):
"""
Prepare for tests by creating a course with a section, subsection, and unit.
Performs the following:
Create a course with a section, subsection, and unit
Create a user and make that user a course author
Log the user into studio
"""
# 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'),
)
)
)
).install()
# Auto login and register the course
AutoAuthPage(
self.browser,
staff=False,
username=self.course_fixture.user.get('username'),
email=self.course_fixture.user.get('email'),
password=self.course_fixture.user.get('password')
).visit()
def _navigate_to_course_unit_page(self):
"""
Open the course from the dashboard and expand the section and subsection and click on the Unit link
The end result is the page where the user is editing the newly created unit
"""
# Visit Course Outline page
self.outline.visit()
# Visit Unit page
self.unit_page = self.outline.section('Test Section').subsection('Test Subsection').toggle_expand().unit(
'Test Unit').go_to()
self.video.wait_for_video_component_render()
def navigate_to_course_unit(self):
"""
Install the course with required components and navigate to course unit page
"""
self._install_course_fixture()
self._navigate_to_course_unit_page()
def edit_component(self):
"""
Make component editable and open components Edit Dialog.
Arguments:
handout_filename (str): handout file name to be uploaded
save_settings (bool): save settings or not
"""
self.unit_page.set_unit_visibility('private')
self.unit_page.components[0].edit()
def open_advanced_tab(self):
"""
Open components advanced tab.
"""
self.unit_page.components[0].open_advanced_tab()
def save_unit_settings(self):
"""
Save component settings.
"""
self.unit_page.components[0].save_settings()
# -*- coding: utf-8 -*-
"""
Acceptance tests for CMS Video Handout.
"""
from .test_studio_video_module import CMSVideoBaseTest
class VideoHandoutTest(CMSVideoBaseTest):
"""
CMS Video Handout Test Class
"""
def setUp(self):
super(VideoHandoutTest, self).setUp()
def _create_course_unit_with_handout(self, handout_filename, save_settings=True):
"""
Create a course with unit and also upload handout
Arguments:
handout_filename (str): handout file name to be uploaded
save_settings (bool): save settings or not
"""
self.navigate_to_course_unit()
self.edit_component()
self.open_advanced_tab()
self.video.upload_handout(handout_filename)
if save_settings:
self.save_unit_settings()
def test_handout_uploads_correctly(self):
"""
Scenario: Handout uploading works correctly
Given I have created a Video component with handout file "textbook.pdf"
Then I can see video button "handout"
And I can download handout file with mime type "application/pdf"
"""
self._create_course_unit_with_handout('textbook.pdf')
self.assertTrue(self.video.is_handout_button_visible)
self.assertEqual(self.video.download_handout('application/pdf'), (True, True))
def test_handout_download_works_with_save(self):
"""
Scenario: Handout downloading works correctly w/ preliminary saving
Given I have created a Video component with handout file "textbook.pdf"
And I save changes
And I edit the component
And I open tab "Advanced"
And I can download handout file in editor with mime type "application/pdf"
"""
self._create_course_unit_with_handout('textbook.pdf')
self.edit_component()
self.open_advanced_tab()
self.assertEqual(self.video.download_handout('application/pdf', is_editor=True), (True, True))
def test_handout_download_works_wo_save(self):
"""
Scenario: Handout downloading works correctly w/o preliminary saving
Given I have created a Video component with handout file "textbook.pdf"
And I can download handout file in editor with mime type "application/pdf"
"""
self._create_course_unit_with_handout('textbook.pdf', save_settings=False)
self.assertEqual(self.video.download_handout('application/pdf', is_editor=True), (True, True))
def test_handout_clearing_works_w_save(self):
"""
Scenario: Handout clearing works correctly w/ preliminary saving
Given I have created a Video component with handout file "textbook.pdf"
And I save changes
And I can download handout file with mime type "application/pdf"
And I edit the component
And I open tab "Advanced"
And I clear handout
And I save changes
Then I do not see video button "handout"
"""
self._create_course_unit_with_handout('textbook.pdf')
self.assertEqual(self.video.download_handout('application/pdf'), (True, True))
self.edit_component()
self.open_advanced_tab()
self.video.clear_handout()
self.save_unit_settings()
self.assertFalse(self.video.is_handout_button_visible)
def test_handout_clearing_works_wo_save(self):
"""
Scenario: Handout clearing works correctly w/o preliminary saving
Given I have created a Video component with handout file "asset.html"
And I clear handout
And I save changes
Then I do not see video button "handout"
"""
self._create_course_unit_with_handout('asset.html', save_settings=False)
self.video.clear_handout()
self.save_unit_settings()
self.assertFalse(self.video.is_handout_button_visible)
def test_handout_replace_w_save(self):
"""
Scenario: User can easy replace the handout by another one w/ preliminary saving
Given I have created a Video component with handout file "asset.html"
And I save changes
Then I can see video button "handout"
And I can download handout file with mime type "text/html"
And I edit the component
And I open tab "Advanced"
And I replace handout file by "textbook.pdf"
And I save changes
Then I can see video button "handout"
And I can download handout file with mime type "application/pdf"
"""
self._create_course_unit_with_handout('asset.html')
self.assertTrue(self.video.is_handout_button_visible)
self.assertEqual(self.video.download_handout('text/html'), (True, True))
self.edit_component()
self.open_advanced_tab()
self.video.upload_handout('textbook.pdf')
self.save_unit_settings()
self.assertTrue(self.video.is_handout_button_visible)
self.assertEqual(self.video.download_handout('application/pdf'), (True, True))
def test_handout_replace_wo_save(self):
"""
Scenario: User can easy replace the handout by another one w/o preliminary saving
Given I have created a Video component with handout file "asset.html"
And I replace handout file by "textbook.pdf"
And I save changes
Then I can see video button "handout"
And I can download handout file with mime type "application/pdf"
"""
self._create_course_unit_with_handout('asset.html', save_settings=False)
self.video.upload_handout('textbook.pdf')
self.save_unit_settings()
self.assertTrue(self.video.is_handout_button_visible)
self.assertEqual(self.video.download_handout('application/pdf'), (True, True))
def test_handout_upload_and_clear_works(self):
"""
Scenario: Upload file "A" -> Remove it -> Upload file "B"
Given I have created a Video component with handout file "asset.html"
And I clear handout
And I upload handout file "textbook.pdf"
And I save changes
Then I can see video button "handout"
And I can download handout file with mime type "application/pdf"
"""
self._create_course_unit_with_handout('asset.html', save_settings=False)
self.video.clear_handout()
self.video.upload_handout('textbook.pdf')
self.save_unit_settings()
self.assertTrue(self.video.is_handout_button_visible)
self.assertEqual(self.video.download_handout('application/pdf'), (True, True))
<!DOCTYPE html>
<html>
<head>
<title>ASSET</title>
</head>
<body>
<div>i am a dummy asset file</div>
</body>
</html>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment