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
0df36241
Commit
0df36241
authored
Mar 01, 2017
by
Mushtaq Ali
Committed by
GitHub
Mar 01, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #14465 from edx/ammar/bokchoy-tests
bokchoy tests for move xblocks
parents
485ffb1b
83de1eb9
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
362 additions
and
8 deletions
+362
-8
cms/static/js/views/move_xblock_breadcrumb.js
+1
-5
cms/templates/js/move-xblock-list.underscore
+1
-1
common/test/acceptance/pages/studio/container.py
+53
-2
common/test/acceptance/pages/studio/move_xblock.py
+78
-0
common/test/acceptance/tests/studio/test_studio_container.py
+229
-0
No files found.
cms/static/js/views/move_xblock_breadcrumb.js
View file @
0df36241
...
...
@@ -13,10 +13,6 @@ function($, Backbone, _, gettext, HtmlUtils, StringUtils, MoveXBlockBreadcrumbVi
var
MoveXBlockBreadcrumb
=
Backbone
.
View
.
extend
({
el
:
'.breadcrumb-container'
,
defaultRenderOptions
:
{
breadcrumbs
:
[
'Course Outline'
]
},
events
:
{
'click .parent-nav-button'
:
'handleBreadcrumbButtonPress'
},
...
...
@@ -29,7 +25,7 @@ function($, Backbone, _, gettext, HtmlUtils, StringUtils, MoveXBlockBreadcrumbVi
render
:
function
(
options
)
{
HtmlUtils
.
setHtml
(
this
.
$el
,
this
.
template
(
_
.
extend
({},
this
.
defaultRenderOptions
,
options
)
)
this
.
template
(
options
)
);
Backbone
.
trigger
(
'move:breadcrumbRendered'
);
return
this
;
...
...
cms/templates/js/move-xblock-list.underscore
View file @
0df36241
...
...
@@ -13,7 +13,7 @@
<%- categoryText %>:
</span>
</div>
<ul class="xblock-items-container">
<ul class="xblock-items-container"
data-items-category="<%- XBlocksCategory %>"
>
<% for (var i = 0; i < xblocks.length; i++) {
var xblock = xblocks[i];
%>
...
...
common/test/acceptance/pages/studio/container.py
View file @
0df36241
...
...
@@ -63,11 +63,16 @@ class ContainerPage(PageObject, HelpMixin):
is_done
=
num_wrappers
==
(
num_initialized_xblocks
+
num_failed_xblocks
)
return
(
is_done
,
is_done
)
def
_loading_spinner_hidden
():
""" promise function to check loading spinner state """
is_spinner_hidden
=
self
.
q
(
css
=
'div.ui-loading.is-hidden'
)
.
present
return
is_spinner_hidden
,
is_spinner_hidden
# First make sure that an element with the view-container class is present on the page,
# and then wait for the loading spinner to go away and all the xblocks to be initialized.
return
(
self
.
q
(
css
=
'body.view-container'
)
.
present
and
self
.
q
(
css
=
'div.ui-loading.is-hidden'
)
.
present
and
Promise
(
_loading_spinner_hidden
,
'loading spinner is hidden.'
)
.
fulfill
()
and
Promise
(
_is_finished_loading
,
'Finished rendering the xblock wrappers.'
)
.
fulfill
()
)
...
...
@@ -102,6 +107,13 @@ class ContainerPage(PageObject, HelpMixin):
return
self
.
_get_xblocks
(
".is-active "
)
@property
def
displayed_children
(
self
):
"""
Return a list of displayed xblocks loaded on the container page.
"""
return
self
.
_get_xblocks
()[
0
]
.
children
@property
def
publish_title
(
self
):
"""
Returns the title as displayed on the publishing sidebar component.
...
...
@@ -262,6 +274,29 @@ class ContainerPage(PageObject, HelpMixin):
"""
return
_click_edit
(
self
,
'.edit-button'
,
'.xblock-studio_view'
)
def
verify_confirmation_message
(
self
,
message
):
"""
Verify for confirmation message.
"""
def
_verify_message
():
""" promise function to check confirmation message state """
text
=
self
.
q
(
css
=
'#page-alert .alert.confirmation #alert-confirmation-title'
)
.
text
return
text
and
message
in
text
[
0
]
self
.
wait_for
(
_verify_message
,
description
=
'confirmation message present'
)
def
click_undo_move_link
(
self
):
"""
Click undo move link.
"""
click_css
(
self
,
'#page-alert .alert.confirmation .nav-actions .action-primary'
)
def
click_take_me_there_link
(
self
):
"""
Click take me there link.
"""
click_css
(
self
,
'#page-alert .alert.confirmation .nav-actions .action-secondary'
,
require_notification
=
False
)
def
add_missing_groups
(
self
):
"""
Click the "add missing groups" link.
...
...
@@ -382,7 +417,7 @@ class XBlockWrapper(PageObject):
"""
Will return any first-generation descendant xblocks of this xblock.
"""
descendants
=
self
.
q
(
css
=
self
.
_bounded_selector
(
self
.
BODY_SELECTOR
))
.
map
(
descendants
=
self
.
q
(
css
=
self
.
_bounded_selector
(
self
.
BODY_SELECTOR
))
.
filter
(
lambda
el
:
el
.
is_displayed
())
.
map
(
lambda
el
:
XBlockWrapper
(
self
.
browser
,
el
.
get_attribute
(
'data-locator'
)))
.
results
# Now remove any non-direct descendants.
...
...
@@ -468,6 +503,13 @@ class XBlockWrapper(PageObject):
"""
return
self
.
q
(
css
=
self
.
_bounded_selector
(
'.visibility-button'
))
.
is_present
()
@property
def
has_move_modal_button
(
self
):
"""
Returns True if this xblock has move modal button else False
"""
return
self
.
q
(
css
=
self
.
_bounded_selector
(
'.move-button'
))
.
is_present
()
def
go_to_container
(
self
):
"""
Open the container page linked to by this xblock, and return
...
...
@@ -505,6 +547,15 @@ class XBlockWrapper(PageObject):
"""
self
.
_click_button
(
'settings_tab'
)
def
open_move_modal
(
self
):
"""
Opens the move modal.
"""
click_css
(
self
,
'.move-button'
,
require_notification
=
False
)
self
.
wait_for
(
lambda
:
self
.
q
(
css
=
'.modal-window.move-modal'
)
.
visible
,
description
=
'move modal is visible'
)
def
set_field_val
(
self
,
field_display_name
,
field_value
):
"""
If editing, set the value of a field.
...
...
common/test/acceptance/pages/studio/move_xblock.py
0 → 100644
View file @
0df36241
"""
Move XBlock Modal Page Object
"""
from
bok_choy.page_object
import
PageObject
from
common.test.acceptance.pages.common.utils
import
click_css
class
MoveModalView
(
PageObject
):
"""
A base class for move xblock
"""
def
__init__
(
self
,
browser
):
"""
Arguments:
browser (selenium.webdriver): The Selenium-controlled browser that this page is loaded in.
"""
super
(
MoveModalView
,
self
)
.
__init__
(
browser
)
def
is_browser_on_page
(
self
):
return
self
.
q
(
css
=
'.modal-window.move-modal'
)
.
present
def
url
(
self
):
"""
Returns None because this is not directly accessible via URL.
"""
return
None
def
save
(
self
):
"""
Clicks save button.
"""
click_css
(
self
,
'a.action-save'
)
def
cancel
(
self
):
"""
Clicks cancel button.
"""
click_css
(
self
,
'a.action-cancel'
,
require_notification
=
False
)
def
click_forward_button
(
self
,
source_index
):
"""
Click forward button at specified `source_index`.
"""
css
=
'.move-modal .xblock-items-container .xblock-item'
self
.
q
(
css
=
'.button-forward'
)
.
nth
(
source_index
)
.
click
()
self
.
wait_for
(
lambda
:
len
(
self
.
q
(
css
=
css
)
.
results
)
>
0
,
description
=
'children are visible'
)
def
click_move_button
(
self
):
"""
Click move button.
"""
self
.
q
(
css
=
'.modal-actions .action-move'
)
.
first
.
click
()
@property
def
is_move_button_enabled
(
self
):
"""
Returns True if move button on modal is enabled else False.
"""
return
not
self
.
q
(
css
=
'.modal-actions .action-move.is-disabled'
)
.
present
@property
def
children_category
(
self
):
"""
Get displayed children category.
"""
return
self
.
q
(
css
=
'.xblock-items-container'
)
.
attrs
(
'data-items-category'
)[
0
]
def
navigate_to_category
(
self
,
category
,
navigation_options
):
"""
Navigates to specifec `category` for a specified `source_index`.
"""
child_category
=
self
.
children_category
while
child_category
!=
category
:
self
.
click_forward_button
(
navigation_options
[
child_category
])
child_category
=
self
.
children_category
common/test/acceptance/tests/studio/test_studio_container.py
View file @
0df36241
...
...
@@ -10,6 +10,7 @@ from common.test.acceptance.fixtures.course import XBlockFixtureDesc
from
common.test.acceptance.pages.studio.component_editor
import
ComponentEditorView
,
ComponentVisibilityEditorView
from
common.test.acceptance.pages.studio.container
import
ContainerPage
from
common.test.acceptance.pages.studio.html_component_editor
import
HtmlComponentEditorView
from
common.test.acceptance.pages.studio.move_xblock
import
MoveModalView
from
common.test.acceptance.pages.studio.utils
import
add_discussion
,
drag
from
common.test.acceptance.pages.lms.courseware
import
CoursewarePage
from
common.test.acceptance.pages.lms.staff_view
import
StaffPage
...
...
@@ -1136,3 +1137,231 @@ class ProblemCategoryTabsTest(ContainerBase):
"Text Input with Hints and Feedback"
,
]
self
.
assertEqual
(
page
.
get_category_tab_components
(
'problem'
,
1
),
expected_components
)
@attr
(
shard
=
1
)
class
MoveComponentTest
(
ContainerBase
):
"""
Tests of moving an XBlock to another XBlock.
"""
def
setUp
(
self
,
is_staff
=
True
):
super
(
MoveComponentTest
,
self
)
.
setUp
(
is_staff
=
is_staff
)
self
.
container
=
ContainerPage
(
self
.
browser
,
None
)
self
.
move_modal_view
=
MoveModalView
(
self
.
browser
)
self
.
navigation_options
=
{
'section'
:
0
,
'subsection'
:
0
,
'unit'
:
1
,
}
self
.
source_component_display_name
=
'HTML 11'
self
.
source_xblock_category
=
'component'
self
.
message_move
=
'Success! "{display_name}" has been moved.'
self
.
message_undo
=
'Move cancelled. "{display_name}" has been moved back to its original location.'
def
populate_course_fixture
(
self
,
course_fixture
):
"""
Sets up a course structure.
"""
# pylint: disable=attribute-defined-outside-init
self
.
unit_page1
=
XBlockFixtureDesc
(
'vertical'
,
'Test Unit 1'
)
.
add_children
(
XBlockFixtureDesc
(
'html'
,
'HTML 11'
),
XBlockFixtureDesc
(
'html'
,
'HTML 12'
)
)
self
.
unit_page2
=
XBlockFixtureDesc
(
'vertical'
,
'Test Unit 2'
)
.
add_children
(
XBlockFixtureDesc
(
'html'
,
'HTML 21'
),
XBlockFixtureDesc
(
'html'
,
'HTML 22'
)
)
course_fixture
.
add_children
(
XBlockFixtureDesc
(
'chapter'
,
'Test Section'
)
.
add_children
(
XBlockFixtureDesc
(
'sequential'
,
'Test Subsection'
)
.
add_children
(
self
.
unit_page1
,
self
.
unit_page2
)
)
)
def
verify_move_opertions
(
self
,
unit_page
,
source_component
,
operation
,
component_display_names_after_operation
):
"""
Verify move operations.
Arguments:
unit_page (Object) Unit container page.
source_component (Object) source XBlock object to be moved.
operation (str), `move` or `undo move` operation.
component_display_names_after_operation (dict) display names of components after operation in source/dest
"""
source_component
.
open_move_modal
()
self
.
move_modal_view
.
navigate_to_category
(
self
.
source_xblock_category
,
self
.
navigation_options
)
self
.
assertEqual
(
self
.
move_modal_view
.
is_move_button_enabled
,
True
)
self
.
move_modal_view
.
click_move_button
()
self
.
container
.
verify_confirmation_message
(
self
.
message_move
.
format
(
display_name
=
self
.
source_component_display_name
)
)
self
.
assertEqual
(
len
(
unit_page
.
displayed_children
),
1
)
if
operation
==
'move'
:
self
.
container
.
click_take_me_there_link
()
elif
operation
==
'undo_move'
:
self
.
container
.
click_undo_move_link
()
self
.
container
.
verify_confirmation_message
(
self
.
message_undo
.
format
(
display_name
=
self
.
source_component_display_name
)
)
unit_page
=
ContainerPage
(
self
.
browser
,
None
)
components
=
unit_page
.
displayed_children
self
.
assertEqual
(
[
component
.
name
for
component
in
components
],
component_display_names_after_operation
)
def
test_move_component_successfully
(
self
):
"""
Test if we can move a component successfully.
Given I am a staff user
And I go to unit page in first section
And I open the move modal
And I navigate to unit in second section
And I see move button is enabled
When I click on the move button
Then I see move operation success message
And When I click on take me there link
Then I see moved component there.
"""
unit_page
=
self
.
go_to_unit_page
(
unit_name
=
'Test Unit 1'
)
components
=
unit_page
.
displayed_children
self
.
assertEqual
(
len
(
components
),
2
)
self
.
verify_move_opertions
(
unit_page
=
unit_page
,
source_component
=
components
[
0
],
operation
=
'move'
,
component_display_names_after_operation
=
[
'HTML 21'
,
'HTML 22'
,
'HTML 11'
]
)
def
test_undo_move_component_successfully
(
self
):
"""
Test if we can undo move a component successfully.
Given I am a staff user
And I go to unit page in first section
And I open the move modal
When I click on the move button
Then I see move operation successful message
And When I clicked on undo move link
Then I see that undo move operation is successful
"""
unit_page
=
self
.
go_to_unit_page
(
unit_name
=
'Test Unit 1'
)
components
=
unit_page
.
displayed_children
self
.
assertEqual
(
len
(
components
),
2
)
self
.
verify_move_opertions
(
unit_page
=
unit_page
,
source_component
=
components
[
0
],
operation
=
'undo_move'
,
component_display_names_after_operation
=
[
'HTML 11'
,
'HTML 12'
]
)
def
test_content_experiment
(
self
):
"""
Test if we can move a component of content experiment successfully.
Given that I am a staff user
And I go to content experiment page
And I open the move dialogue modal
When I navigate to the unit in second section
Then I see move button is enabled
And when I click on the move button
Then I see move operation success message
And when I click on take me there link
Then I see moved component there
And when I undo move a component
Then I see that undo move operation success message
"""
# Add content experiment support to course.
self
.
course_fixture
.
add_advanced_settings
({
u'advanced_modules'
:
{
'value'
:
[
'split_test'
]},
})
# Create group configurations
# pylint: disable=protected-access
self
.
course_fixture
.
_update_xblock
(
self
.
course_fixture
.
_course_location
,
{
'metadata'
:
{
u'user_partitions'
:
[
create_user_partition_json
(
0
,
'Test Group Configuration'
,
'Description of the group configuration.'
,
[
Group
(
'0'
,
'Group A'
),
Group
(
'1'
,
'Group B'
)]
),
],
},
})
# Add split test to unit_page1 and assign newly created group configuration to it
split_test
=
XBlockFixtureDesc
(
'split_test'
,
'Test Content Experiment'
,
metadata
=
{
'user_partition_id'
:
0
})
self
.
course_fixture
.
create_xblock
(
self
.
unit_page1
.
locator
,
split_test
)
# Visit content experiment container page.
unit_page
=
ContainerPage
(
self
.
browser
,
split_test
.
locator
)
unit_page
.
visit
()
group_a_locator
=
unit_page
.
displayed_children
[
0
]
.
locator
# Add some components to Group A.
self
.
course_fixture
.
create_xblock
(
group_a_locator
,
XBlockFixtureDesc
(
'html'
,
'HTML 311'
)
)
self
.
course_fixture
.
create_xblock
(
group_a_locator
,
XBlockFixtureDesc
(
'html'
,
'HTML 312'
)
)
# Go to group page to move it's component.
group_container_page
=
ContainerPage
(
self
.
browser
,
group_a_locator
)
group_container_page
.
visit
()
# Verify content experiment block has correct groups and components.
components
=
group_container_page
.
displayed_children
self
.
assertEqual
(
len
(
components
),
2
)
self
.
source_component_display_name
=
'HTML 311'
# Verify undo move operation for content experiment.
self
.
verify_move_opertions
(
unit_page
=
group_container_page
,
source_component
=
components
[
0
],
operation
=
'undo_move'
,
component_display_names_after_operation
=
[
'HTML 311'
,
'HTML 312'
]
)
# Verify move operation for content experiment.
self
.
verify_move_opertions
(
unit_page
=
group_container_page
,
source_component
=
components
[
0
],
operation
=
'move'
,
component_display_names_after_operation
=
[
'HTML 21'
,
'HTML 22'
,
'HTML 311'
]
)
def
test_a11y
(
self
):
"""
Verify move modal a11y.
"""
unit_page
=
self
.
go_to_unit_page
(
unit_name
=
'Test Unit 1'
)
unit_page
.
a11y_audit
.
config
.
set_scope
(
include
=
[
".modal-window.move-modal"
]
)
unit_page
.
a11y_audit
.
config
.
set_rules
({
'ignore'
:
[
'color-contrast'
,
# TODO: AC-716
'link-href'
,
# TODO: AC-716
]
})
unit_page
.
displayed_children
[
0
]
.
open_move_modal
()
for
category
in
[
'section'
,
'subsection'
,
'component'
]:
self
.
move_modal_view
.
navigate_to_category
(
category
,
self
.
navigation_options
)
unit_page
.
a11y_audit
.
check_for_accessibility_errors
()
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