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
7130c14f
Commit
7130c14f
authored
Aug 15, 2014
by
cahrens
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add tests that verify Studio can still render with bad HTML content.
parent
cbffcd2f
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
192 additions
and
93 deletions
+192
-93
common/test/acceptance/pages/studio/container.py
+12
-6
common/test/acceptance/tests/base_studio_test.py
+75
-1
common/test/acceptance/tests/test_studio_bad_data.py
+104
-0
common/test/acceptance/tests/test_studio_container.py
+1
-86
No files found.
common/test/acceptance/pages/studio/container.py
View file @
7130c14f
...
...
@@ -39,12 +39,18 @@ class ContainerPage(PageObject):
def
is_browser_on_page
(
self
):
def
_is_finished_loading
():
# Wait until all components have been loaded.
# See common/static/coffee/src/xblock/core.coffee which adds the
# class "xblock-initialized" at the end of initializeBlock
num_wrappers
=
len
(
self
.
q
(
css
=
XBlockWrapper
.
BODY_SELECTOR
)
.
results
)
num_xblocks_init
=
len
(
self
.
q
(
css
=
'{} .xblock.xblock-initialized'
.
format
(
XBlockWrapper
.
BODY_SELECTOR
))
.
results
)
is_done
=
num_wrappers
==
num_xblocks_init
is_done
=
False
# Get the request token of the first xblock rendered on the page and assume it is correct.
data_request_elements
=
self
.
q
(
css
=
'[data-request-token]'
)
if
len
(
data_request_elements
)
>
0
:
request_token
=
data_request_elements
.
first
.
attrs
(
'data-request-token'
)[
0
]
# Then find the number of Studio xblock wrappers on the page with that request token.
num_wrappers
=
len
(
self
.
q
(
css
=
'{} [data-request-token="{}"]'
.
format
(
XBlockWrapper
.
BODY_SELECTOR
,
request_token
))
.
results
)
# Wait until all components have been loaded.
# See common/static/coffee/src/xblock/core.coffee which adds the
# class "xblock-initialized" at the end of initializeBlock
num_xblocks_init
=
len
(
self
.
q
(
css
=
'{} .xblock.xblock-initialized[data-request-token="{}"]'
.
format
(
XBlockWrapper
.
BODY_SELECTOR
,
request_token
))
.
results
)
is_done
=
num_wrappers
==
num_xblocks_init
return
(
is_done
,
is_done
)
# First make sure that an element with the view-container class is present on the page,
...
...
common/test/acceptance/tests/base_studio_test.py
View file @
7130c14f
from
..pages.studio.auto_auth
import
AutoAuthPage
from
..fixtures.course
import
CourseFixture
from
.helpers
import
UniqueCourseTest
from
..pages.studio.overview
import
CourseOutlinePage
class
StudioCourseTest
(
UniqueCourseTest
):
...
...
@@ -45,3 +45,77 @@ class StudioCourseTest(UniqueCourseTest):
password
=
user
.
get
(
'password'
)
)
self
.
auth_page
.
visit
()
class
ContainerBase
(
StudioCourseTest
):
"""
Base class for tests that do operations on the container page.
"""
def
setUp
(
self
):
"""
Create a unique identifier for the course used in this test.
"""
# Ensure that the superclass sets up
super
(
ContainerBase
,
self
)
.
setUp
()
self
.
outline
=
CourseOutlinePage
(
self
.
browser
,
self
.
course_info
[
'org'
],
self
.
course_info
[
'number'
],
self
.
course_info
[
'run'
]
)
def
go_to_nested_container_page
(
self
):
"""
Go to the nested container page.
"""
unit
=
self
.
go_to_unit_page
()
# The 0th entry is the unit page itself.
container
=
unit
.
xblocks
[
1
]
.
go_to_container
()
return
container
def
go_to_unit_page
(
self
,
section_name
=
'Test Section'
,
subsection_name
=
'Test Subsection'
,
unit_name
=
'Test Unit'
):
"""
Go to the test unit page.
If make_draft is true, the unit page will be put into draft mode.
"""
self
.
outline
.
visit
()
subsection
=
self
.
outline
.
section
(
section_name
)
.
subsection
(
subsection_name
)
return
subsection
.
toggle_expand
()
.
unit
(
unit_name
)
.
go_to
()
def
verify_ordering
(
self
,
container
,
expected_orderings
):
"""
Verifies the expected ordering of xblocks on the page.
"""
xblocks
=
container
.
xblocks
blocks_checked
=
set
()
for
expected_ordering
in
expected_orderings
:
for
xblock
in
xblocks
:
parent
=
expected_ordering
.
keys
()[
0
]
if
xblock
.
name
==
parent
:
blocks_checked
.
add
(
parent
)
children
=
xblock
.
children
expected_length
=
len
(
expected_ordering
.
get
(
parent
))
self
.
assertEqual
(
expected_length
,
len
(
children
),
"Number of children incorrect for group {0}. Expected {1} but got {2}."
.
format
(
parent
,
expected_length
,
len
(
children
)))
for
idx
,
expected
in
enumerate
(
expected_ordering
.
get
(
parent
)):
self
.
assertEqual
(
expected
,
children
[
idx
]
.
name
)
blocks_checked
.
add
(
expected
)
break
self
.
assertEqual
(
len
(
blocks_checked
),
len
(
xblocks
))
def
do_action_and_verify
(
self
,
action
,
expected_ordering
):
"""
Perform the supplied action and then verify the resulting ordering.
"""
container
=
self
.
go_to_nested_container_page
()
action
(
container
)
self
.
verify_ordering
(
container
,
expected_ordering
)
# Reload the page to see that the change was persisted.
container
=
self
.
go_to_nested_container_page
()
self
.
verify_ordering
(
container
,
expected_ordering
)
common/test/acceptance/tests/test_studio_bad_data.py
0 → 100644
View file @
7130c14f
from
nose.plugins.attrib
import
attr
from
.base_studio_test
import
ContainerBase
from
..fixtures.course
import
XBlockFixtureDesc
@attr
(
'shard_1'
)
class
BadComponentTest
(
ContainerBase
):
"""
Tests that components with bad content do not break the Unit page.
"""
__test__
=
False
def
get_bad_html_content
(
self
):
"""
Return the "bad" HTML content that has been problematic for Studio.
"""
pass
def
populate_course_fixture
(
self
,
course_fixture
):
"""
Sets up a course structure with a unit and a HTML component with bad data and a properly constructed problem.
"""
course_fixture
.
add_children
(
XBlockFixtureDesc
(
'chapter'
,
'Test Section'
)
.
add_children
(
XBlockFixtureDesc
(
'sequential'
,
'Test Subsection'
)
.
add_children
(
XBlockFixtureDesc
(
'vertical'
,
'Test Unit'
)
.
add_children
(
XBlockFixtureDesc
(
'html'
,
'Unit HTML'
,
data
=
self
.
get_bad_html_content
()),
XBlockFixtureDesc
(
'problem'
,
'Unit Problem'
,
data
=
'<problem></problem>'
)
)
)
)
)
def
test_html_comp_visible
(
self
):
"""
Tests that bad HTML data within an HTML component doesn't prevent Studio from
displaying the components on the unit page.
"""
unit
=
self
.
go_to_unit_page
()
self
.
verify_ordering
(
unit
,
[{
""
:
[
"Unit HTML"
,
"Unit Problem"
]}])
@attr
(
'shard_1'
)
class
CopiedFromLmsBadContentTest
(
BadComponentTest
):
"""
Tests that components with HTML copied from the LMS (LmsRuntime) do not break the Unit page.
"""
__test__
=
True
def
get_bad_html_content
(
self
):
"""
Return the "bad" HTML content that has been problematic for Studio.
"""
return
"""
<div class="xblock xblock-student_view xmodule_display xmodule_HtmlModule xblock-initialized"
data-runtime-class="LmsRuntime" data-init="XBlockToXModuleShim" data-block-type="html"
data-runtime-version="1" data-type="HTMLModule" data-course-id="GeorgetownX/HUMW-421-01"
data-request-token="thisIsNotARealRequestToken"
data-usage-id="i4x:;_;_GeorgetownX;_HUMW-421-01;_html;_3010cbbecaa1484da6cf8ba01362346a">
<p>Copied from LMS HTML component</p></div>
"""
@attr
(
'shard_1'
)
class
CopiedFromStudioBadContentTest
(
BadComponentTest
):
"""
Tests that components with HTML copied from the Studio (containing "ui-sortable" class) do not break the Unit page.
"""
__test__
=
True
def
get_bad_html_content
(
self
):
"""
Return the "bad" HTML content that has been problematic for Studio.
"""
return
"""
<ol class="components ui-sortable">
<li class="component" data-locator="i4x://Wellesley_College/100/html/6390f1fd3fe640d49580b8415fe1330b"
data-course-key="Wellesley_College/100/2014_Summer">
<div class="xblock xblock-student_view xmodule_display xmodule_HtmlModule xblock-initialized"
data-runtime-class="PreviewRuntime" data-init="XBlockToXModuleShim" data-runtime-version="1"
data-request-token="thisIsNotARealRequestToken"
data-usage-id="i4x://Wellesley_College/100/html/6390f1fd3fe640d49580b8415fe1330b"
data-type="HTMLModule" data-block-type="html">
<h2>VOICE COMPARISON </h2>
<p>You can access the experimental <strong >Voice Comparison</strong> tool at the link below.</p>
</div>
</li>
</ol>
"""
@attr
(
'shard_1'
)
class
JSErrorBadContentTest
(
BadComponentTest
):
"""
Tests that components that throw JS errors do not break the Unit page.
"""
__test__
=
True
def
get_bad_html_content
(
self
):
"""
Return the "bad" HTML content that has been problematic for Studio.
"""
return
"<script>var doesNotExist = BadGlobal.foo;</script>"
common/test/acceptance/tests/test_studio_container.py
View file @
7130c14f
...
...
@@ -5,8 +5,6 @@ displaying containers within units.
"""
from
nose.plugins.attrib
import
attr
from
..pages.studio.overview
import
CourseOutlinePage
from
..fixtures.course
import
XBlockFixtureDesc
from
..pages.studio.component_editor
import
ComponentEditorView
from
..pages.studio.html_component_editor
import
HtmlComponentEditorView
...
...
@@ -16,87 +14,10 @@ from ..pages.lms.staff_view import StaffPage
import
datetime
from
bok_choy.promise
import
Promise
,
EmptyPromise
from
.base_studio_test
import
StudioCourseTest
@attr
(
'shard_1'
)
class
ContainerBase
(
StudioCourseTest
):
"""
Base class for tests that do operations on the container page.
"""
__test__
=
False
def
setUp
(
self
):
"""
Create a unique identifier for the course used in this test.
"""
# Ensure that the superclass sets up
super
(
ContainerBase
,
self
)
.
setUp
()
self
.
outline
=
CourseOutlinePage
(
self
.
browser
,
self
.
course_info
[
'org'
],
self
.
course_info
[
'number'
],
self
.
course_info
[
'run'
]
)
def
go_to_nested_container_page
(
self
):
"""
Go to the nested container page.
"""
unit
=
self
.
go_to_unit_page
()
# The 0th entry is the unit page itself.
container
=
unit
.
xblocks
[
1
]
.
go_to_container
()
return
container
def
go_to_unit_page
(
self
,
section_name
=
'Test Section'
,
subsection_name
=
'Test Subsection'
,
unit_name
=
'Test Unit'
):
"""
Go to the test unit page.
If make_draft is true, the unit page will be put into draft mode.
"""
self
.
outline
.
visit
()
subsection
=
self
.
outline
.
section
(
section_name
)
.
subsection
(
subsection_name
)
return
subsection
.
toggle_expand
()
.
unit
(
unit_name
)
.
go_to
()
def
verify_ordering
(
self
,
container
,
expected_orderings
):
"""
Verifies the expected ordering of xblocks on the page.
"""
xblocks
=
container
.
xblocks
blocks_checked
=
set
()
for
expected_ordering
in
expected_orderings
:
for
xblock
in
xblocks
:
parent
=
expected_ordering
.
keys
()[
0
]
if
xblock
.
name
==
parent
:
blocks_checked
.
add
(
parent
)
children
=
xblock
.
children
expected_length
=
len
(
expected_ordering
.
get
(
parent
))
self
.
assertEqual
(
expected_length
,
len
(
children
),
"Number of children incorrect for group {0}. Expected {1} but got {2}."
.
format
(
parent
,
expected_length
,
len
(
children
)))
for
idx
,
expected
in
enumerate
(
expected_ordering
.
get
(
parent
)):
self
.
assertEqual
(
expected
,
children
[
idx
]
.
name
)
blocks_checked
.
add
(
expected
)
break
self
.
assertEqual
(
len
(
blocks_checked
),
len
(
xblocks
))
def
do_action_and_verify
(
self
,
action
,
expected_ordering
):
"""
Perform the supplied action and then verify the resulting ordering.
"""
container
=
self
.
go_to_nested_container_page
()
action
(
container
)
self
.
verify_ordering
(
container
,
expected_ordering
)
# Reload the page to see that the change was persisted.
container
=
self
.
go_to_nested_container_page
()
self
.
verify_ordering
(
container
,
expected_ordering
)
from
.base_studio_test
import
ContainerBase
class
NestedVerticalTest
(
ContainerBase
):
__test__
=
False
def
populate_course_fixture
(
self
,
course_fixture
):
"""
...
...
@@ -151,7 +72,6 @@ class DragAndDropTest(NestedVerticalTest):
"""
Tests of reordering within the container page.
"""
__test__
=
True
def
drag_and_verify
(
self
,
source
,
target
,
expected_ordering
):
self
.
do_action_and_verify
(
...
...
@@ -232,7 +152,6 @@ class AddComponentTest(NestedVerticalTest):
"""
Tests of adding a component to the container page.
"""
__test__
=
True
def
add_and_verify
(
self
,
menu_index
,
expected_ordering
):
self
.
do_action_and_verify
(
...
...
@@ -273,7 +192,6 @@ class DuplicateComponentTest(NestedVerticalTest):
"""
Tests of duplicating a component on the container page.
"""
__test__
=
True
def
duplicate_and_verify
(
self
,
source_index
,
expected_ordering
):
self
.
do_action_and_verify
(
...
...
@@ -320,7 +238,6 @@ class DeleteComponentTest(NestedVerticalTest):
"""
Tests of deleting a component from the container page.
"""
__test__
=
True
def
delete_and_verify
(
self
,
source_index
,
expected_ordering
):
self
.
do_action_and_verify
(
...
...
@@ -344,7 +261,6 @@ class EditContainerTest(NestedVerticalTest):
"""
Tests of editing a container.
"""
__test__
=
True
def
modify_display_name_and_verify
(
self
,
component
):
"""
...
...
@@ -377,7 +293,6 @@ class UnitPublishingTest(ContainerBase):
"""
Tests of the publishing control and related widgets on the Unit page.
"""
__test__
=
True
PUBLISHED_STATUS
=
"Publishing Status
\n
Published (not yet released)"
PUBLISHED_LIVE_STATUS
=
"Publishing Status
\n
Published and Live"
...
...
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