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
c3301e2a
Commit
c3301e2a
authored
Jan 09, 2015
by
cahrens
Committed by
Zia Fazal
Apr 07, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
End-to-end bok choy test for cohorted courseware.
parent
b7f23834
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
274 additions
and
25 deletions
+274
-25
common/test/acceptance/pages/lms/courseware.py
+8
-1
common/test/acceptance/pages/lms/instructor_dashboard.py
+8
-1
common/test/acceptance/tests/lms/test_lms_user_preview.py
+29
-20
common/test/acceptance/tests/studio/base_studio_test.py
+2
-2
common/test/acceptance/tests/studio/test_studio_split_test.py
+0
-1
common/test/acceptance/tests/test_cohorted_courseware.py
+227
-0
No files found.
common/test/acceptance/pages/lms/courseware.py
View file @
c3301e2a
...
@@ -34,11 +34,18 @@ class CoursewarePage(CoursePage):
...
@@ -34,11 +34,18 @@ class CoursewarePage(CoursePage):
return
len
(
self
.
q
(
css
=
self
.
subsection_selector
))
return
len
(
self
.
q
(
css
=
self
.
subsection_selector
))
@property
@property
def
xblock_components
(
self
):
"""
Return the xblock components within the unit on the page.
"""
return
self
.
q
(
css
=
self
.
xblock_component_selector
)
@property
def
num_xblock_components
(
self
):
def
num_xblock_components
(
self
):
"""
"""
Return the number of rendered xblocks within the unit on the page
Return the number of rendered xblocks within the unit on the page
"""
"""
return
len
(
self
.
q
(
css
=
self
.
xblock_component_selector
)
)
return
len
(
self
.
xblock_components
)
def
xblock_component_type
(
self
,
index
=
0
):
def
xblock_component_type
(
self
,
index
=
0
):
"""
"""
...
...
common/test/acceptance/pages/lms/instructor_dashboard.py
View file @
c3301e2a
...
@@ -133,6 +133,10 @@ class MembershipPageCohortManagementSection(PageObject):
...
@@ -133,6 +133,10 @@ class MembershipPageCohortManagementSection(PageObject):
"""
"""
Returns the name of the selected cohort.
Returns the name of the selected cohort.
"""
"""
EmptyPromise
(
lambda
:
len
(
self
.
_get_cohort_options
()
.
results
)
>
0
,
"Waiting for cohort selector to populate"
)
.
fulfill
()
return
self
.
_cohort_name
(
return
self
.
_cohort_name
(
self
.
_get_cohort_options
()
.
filter
(
lambda
el
:
el
.
is_selected
())
.
first
.
text
[
0
]
self
.
_get_cohort_options
()
.
filter
(
lambda
el
:
el
.
is_selected
())
.
first
.
text
[
0
]
)
)
...
@@ -163,7 +167,10 @@ class MembershipPageCohortManagementSection(PageObject):
...
@@ -163,7 +167,10 @@ class MembershipPageCohortManagementSection(PageObject):
Adds a new manual cohort with the specified name.
Adds a new manual cohort with the specified name.
If a content group should also be associated, the name of the content group should be specified.
If a content group should also be associated, the name of the content group should be specified.
"""
"""
self
.
q
(
css
=
self
.
_bounded_selector
(
"div.cohort-management-nav .action-create"
))
.
first
.
click
()
create_buttons
=
self
.
q
(
css
=
self
.
_bounded_selector
(
".action-create"
))
# There are 2 create buttons on the page. The second one is only present when no cohort yet exists
# (in which case the first is not visible). Click on the last present create button.
create_buttons
.
results
[
len
(
create_buttons
.
results
)
-
1
]
.
click
()
textinput
=
self
.
q
(
css
=
self
.
_bounded_selector
(
"#cohort-name"
))
.
results
[
0
]
textinput
=
self
.
q
(
css
=
self
.
_bounded_selector
(
"#cohort-name"
))
.
results
[
0
]
textinput
.
send_keys
(
cohort_name
)
textinput
.
send_keys
(
cohort_name
)
if
content_group
:
if
content_group
:
...
...
common/test/acceptance/tests/lms/test_lms_user_preview.py
View file @
c3301e2a
...
@@ -266,28 +266,26 @@ class CourseWithContentGroupsTest(StaffViewTest):
...
@@ -266,28 +266,26 @@ class CourseWithContentGroupsTest(StaffViewTest):
</problem>
</problem>
"""
)
"""
)
self
.
alpha_text
=
"VISIBLE TO ALPHA"
self
.
beta_text
=
"VISIBLE TO BETA"
self
.
everyone_text
=
"VISIBLE TO EVERYONE"
course_fixture
.
add_children
(
course_fixture
.
add_children
(
XBlockFixtureDesc
(
'chapter'
,
'Test Section'
)
.
add_children
(
XBlockFixtureDesc
(
'chapter'
,
'Test Section'
)
.
add_children
(
XBlockFixtureDesc
(
'sequential'
,
'Test Subsection'
)
.
add_children
(
XBlockFixtureDesc
(
'sequential'
,
'Test Subsection'
)
.
add_children
(
XBlockFixtureDesc
(
XBlockFixtureDesc
(
'vertical'
,
'Test Unit'
)
.
add_children
(
'problem'
,
'Visible to alpha'
,
data
=
problem_data
,
metadata
=
{
"group_access"
:
{
0
:
[
0
]}}
XBlockFixtureDesc
(
),
'problem'
,
self
.
alpha_text
,
data
=
problem_data
,
metadata
=
{
"group_access"
:
{
0
:
[
0
]}}
XBlockFixtureDesc
(
),
'problem'
,
'Visible to beta'
,
data
=
problem_data
,
metadata
=
{
"group_access"
:
{
0
:
[
1
]}}
XBlockFixtureDesc
(
),
'problem'
,
self
.
beta_text
,
data
=
problem_data
,
metadata
=
{
"group_access"
:
{
0
:
[
1
]}}
XBlockFixtureDesc
(
'problem'
,
'Visible to everyone'
,
data
=
problem_data
)
),
XBlockFixtureDesc
(
'problem'
,
self
.
everyone_text
,
data
=
problem_data
)
)
)
)
)
)
)
)
def
_verify_visible_problems
(
self
,
expected_items
):
"""
Verify that the expected problems are visible.
"""
course_nav
=
CourseNavPage
(
self
.
browser
)
actual_items
=
course_nav
.
sequence_items
self
.
assertItemsEqual
(
expected_items
,
actual_items
)
def
test_staff_sees_all_problems
(
self
):
def
test_staff_sees_all_problems
(
self
):
"""
"""
Scenario: Staff see all problems
Scenario: Staff see all problems
...
@@ -296,8 +294,8 @@ class CourseWithContentGroupsTest(StaffViewTest):
...
@@ -296,8 +294,8 @@ class CourseWithContentGroupsTest(StaffViewTest):
When I view the courseware in the LMS with staff access
When I view the courseware in the LMS with staff access
Then I see all the problems, regardless of their group_access property
Then I see all the problems, regardless of their group_access property
"""
"""
self
.
_goto_staff_page
()
course_page
=
self
.
_goto_staff_page
()
self
.
_verify_visible_problems
([
'Visible to alpha'
,
'Visible to beta'
,
'Visible to everyone'
])
verify_expected_problem_visibility
(
self
,
course_page
,
[
self
.
alpha_text
,
self
.
beta_text
,
self
.
everyone_text
])
def
test_student_not_in_content_group
(
self
):
def
test_student_not_in_content_group
(
self
):
"""
"""
...
@@ -310,7 +308,7 @@ class CourseWithContentGroupsTest(StaffViewTest):
...
@@ -310,7 +308,7 @@ class CourseWithContentGroupsTest(StaffViewTest):
"""
"""
course_page
=
self
.
_goto_staff_page
()
course_page
=
self
.
_goto_staff_page
()
course_page
.
set_staff_view_mode
(
'Student'
)
course_page
.
set_staff_view_mode
(
'Student'
)
self
.
_verify_visible_problems
([
'Visible to everyone'
])
verify_expected_problem_visibility
(
self
,
course_page
,
[
self
.
everyone_text
])
def
test_as_student_in_alpha
(
self
):
def
test_as_student_in_alpha
(
self
):
"""
"""
...
@@ -323,7 +321,7 @@ class CourseWithContentGroupsTest(StaffViewTest):
...
@@ -323,7 +321,7 @@ class CourseWithContentGroupsTest(StaffViewTest):
"""
"""
course_page
=
self
.
_goto_staff_page
()
course_page
=
self
.
_goto_staff_page
()
course_page
.
set_staff_view_mode
(
'Student in alpha'
)
course_page
.
set_staff_view_mode
(
'Student in alpha'
)
self
.
_verify_visible_problems
([
'Visible to alpha'
,
'Visible to everyone'
])
verify_expected_problem_visibility
(
self
,
course_page
,
[
self
.
alpha_text
,
self
.
everyone_text
])
def
test_as_student_in_beta
(
self
):
def
test_as_student_in_beta
(
self
):
"""
"""
...
@@ -336,4 +334,15 @@ class CourseWithContentGroupsTest(StaffViewTest):
...
@@ -336,4 +334,15 @@ class CourseWithContentGroupsTest(StaffViewTest):
"""
"""
course_page
=
self
.
_goto_staff_page
()
course_page
=
self
.
_goto_staff_page
()
course_page
.
set_staff_view_mode
(
'Student in beta'
)
course_page
.
set_staff_view_mode
(
'Student in beta'
)
self
.
_verify_visible_problems
([
'Visible to beta'
,
'Visible to everyone'
])
verify_expected_problem_visibility
(
self
,
course_page
,
[
self
.
beta_text
,
self
.
everyone_text
])
def
verify_expected_problem_visibility
(
test
,
courseware_page
,
expected_problems
):
"""
Helper method that checks that the expected problems are visible on the current page.
"""
test
.
assertEqual
(
len
(
expected_problems
),
courseware_page
.
num_xblock_components
,
"Incorrect number of visible problems"
)
for
index
,
expected_problem
in
enumerate
(
expected_problems
):
test
.
assertIn
(
expected_problem
,
courseware_page
.
xblock_components
[
index
]
.
text
)
common/test/acceptance/tests/studio/base_studio_test.py
View file @
c3301e2a
...
@@ -58,12 +58,12 @@ class ContainerBase(StudioCourseTest):
...
@@ -58,12 +58,12 @@ class ContainerBase(StudioCourseTest):
Base class for tests that do operations on the container page.
Base class for tests that do operations on the container page.
"""
"""
def
setUp
(
self
):
def
setUp
(
self
,
is_staff
=
False
):
"""
"""
Create a unique identifier for the course used in this test.
Create a unique identifier for the course used in this test.
"""
"""
# Ensure that the superclass sets up
# Ensure that the superclass sets up
super
(
ContainerBase
,
self
)
.
setUp
()
super
(
ContainerBase
,
self
)
.
setUp
(
is_staff
=
is_staff
)
self
.
outline
=
CourseOutlinePage
(
self
.
outline
=
CourseOutlinePage
(
self
.
browser
,
self
.
browser
,
...
...
common/test/acceptance/tests/studio/test_studio_split_test.py
View file @
c3301e2a
...
@@ -14,7 +14,6 @@ from bok_choy.promise import Promise, EmptyPromise
...
@@ -14,7 +14,6 @@ from bok_choy.promise import Promise, EmptyPromise
from
...fixtures.course
import
XBlockFixtureDesc
from
...fixtures.course
import
XBlockFixtureDesc
from
...pages.studio.component_editor
import
ComponentEditorView
from
...pages.studio.component_editor
import
ComponentEditorView
from
...pages.studio.overview
import
CourseOutlinePage
,
CourseOutlineUnit
from
...pages.studio.overview
import
CourseOutlinePage
,
CourseOutlineUnit
from
...pages.studio.settings_advanced
import
AdvancedSettingsPage
from
...pages.studio.container
import
ContainerPage
from
...pages.studio.container
import
ContainerPage
from
...pages.studio.settings_group_configurations
import
GroupConfigurationsPage
from
...pages.studio.settings_group_configurations
import
GroupConfigurationsPage
from
...pages.studio.utils
import
add_advanced_component
from
...pages.studio.utils
import
add_advanced_component
...
...
common/test/acceptance/tests/test_cohorted_courseware.py
0 → 100644
View file @
c3301e2a
"""
End-to-end test for cohorted courseware. This uses both Studio and LMS.
"""
from
nose.plugins.attrib
import
attr
import
json
from
studio.base_studio_test
import
ContainerBase
from
..pages.studio.settings_group_configurations
import
GroupConfigurationsPage
from
..pages.studio.settings_advanced
import
AdvancedSettingsPage
from
..pages.studio.auto_auth
import
AutoAuthPage
as
StudioAutoAuthPage
from
..fixtures.course
import
XBlockFixtureDesc
from
..pages.studio.component_editor
import
ComponentVisibilityEditorView
from
..pages.lms.instructor_dashboard
import
InstructorDashboardPage
from
..pages.lms.course_nav
import
CourseNavPage
from
..pages.lms.courseware
import
CoursewarePage
from
..pages.lms.auto_auth
import
AutoAuthPage
as
LmsAutoAuthPage
from
..tests.lms.test_lms_user_preview
import
verify_expected_problem_visibility
from
bok_choy.promise
import
EmptyPromise
@attr
(
'shard_1'
)
class
EndToEndCohortedCoursewareTest
(
ContainerBase
):
def
setUp
(
self
,
is_staff
=
True
):
super
(
EndToEndCohortedCoursewareTest
,
self
)
.
setUp
(
is_staff
=
is_staff
)
self
.
staff_user
=
self
.
user
self
.
content_group_a
=
"Content Group A"
self
.
content_group_b
=
"Content Group B"
# Create a student who will be in "Cohort A"
self
.
cohort_a_student_username
=
"cohort_a_student"
self
.
cohort_a_student_email
=
"cohort_a_student@example.com"
StudioAutoAuthPage
(
self
.
browser
,
username
=
self
.
cohort_a_student_username
,
email
=
self
.
cohort_a_student_email
,
no_login
=
True
)
.
visit
()
# Create a student who will be in "Cohort B"
self
.
cohort_b_student_username
=
"cohort_b_student"
self
.
cohort_b_student_email
=
"cohort_b_student@example.com"
StudioAutoAuthPage
(
self
.
browser
,
username
=
self
.
cohort_b_student_username
,
email
=
self
.
cohort_b_student_email
,
no_login
=
True
)
.
visit
()
# Create a student who will end up in the default cohort group
self
.
cohort_default_student_username
=
"cohort default student"
self
.
cohort_default_student_email
=
"cohort_default_student@example.com"
StudioAutoAuthPage
(
self
.
browser
,
username
=
self
.
cohort_default_student_username
,
email
=
self
.
cohort_default_student_email
,
no_login
=
True
)
.
visit
()
# Start logged in as the staff user.
StudioAutoAuthPage
(
self
.
browser
,
username
=
self
.
staff_user
[
"username"
],
email
=
self
.
staff_user
[
"email"
]
)
.
visit
()
def
populate_course_fixture
(
self
,
course_fixture
):
"""
Populate the children of the test course fixture.
"""
self
.
group_a_problem
=
'GROUP A CONTENT'
self
.
group_b_problem
=
'GROUP B CONTENT'
self
.
group_a_and_b_problem
=
'GROUP A AND B CONTENT'
self
.
visible_to_all_problem
=
'VISIBLE TO ALL CONTENT'
course_fixture
.
add_children
(
XBlockFixtureDesc
(
'chapter'
,
'Test Section'
)
.
add_children
(
XBlockFixtureDesc
(
'sequential'
,
'Test Subsection'
)
.
add_children
(
XBlockFixtureDesc
(
'vertical'
,
'Test Unit'
)
.
add_children
(
XBlockFixtureDesc
(
'problem'
,
self
.
group_a_problem
,
data
=
'<problem></problem>'
),
XBlockFixtureDesc
(
'problem'
,
self
.
group_b_problem
,
data
=
'<problem></problem>'
),
XBlockFixtureDesc
(
'problem'
,
self
.
group_a_and_b_problem
,
data
=
'<problem></problem>'
),
XBlockFixtureDesc
(
'problem'
,
self
.
visible_to_all_problem
,
data
=
'<problem></problem>'
)
)
)
)
)
def
enable_cohorts_in_course
(
self
):
"""
This turns on cohorts for the course. Currently this is still done through Advanced
Settings. Eventually it will be done in the LMS Instructor Dashboard.
"""
advanced_settings
=
AdvancedSettingsPage
(
self
.
browser
,
self
.
course_info
[
'org'
],
self
.
course_info
[
'number'
],
self
.
course_info
[
'run'
]
)
advanced_settings
.
visit
()
cohort_config
=
'{"cohorted": true}'
advanced_settings
.
set
(
'Cohort Configuration'
,
cohort_config
)
advanced_settings
.
refresh_and_wait_for_load
()
self
.
assertEquals
(
json
.
loads
(
cohort_config
),
json
.
loads
(
advanced_settings
.
get
(
'Cohort Configuration'
)),
'Wrong input for Cohort Configuration'
)
def
create_content_groups
(
self
):
"""
Creates two content groups in Studio Group Configurations Settings.
"""
group_configurations_page
=
GroupConfigurationsPage
(
self
.
browser
,
self
.
course_info
[
'org'
],
self
.
course_info
[
'number'
],
self
.
course_info
[
'run'
]
)
group_configurations_page
.
visit
()
group_configurations_page
.
create_first_content_group
()
config
=
group_configurations_page
.
content_groups
[
0
]
config
.
name
=
self
.
content_group_a
config
.
save
()
group_configurations_page
.
add_content_group
()
config
=
group_configurations_page
.
content_groups
[
1
]
config
.
name
=
self
.
content_group_b
config
.
save
()
def
link_problems_to_content_groups_and_publish
(
self
):
"""
Updates 3 of the 4 existing problems to limit their visibility by content group.
Publishes the modified units.
"""
container_page
=
self
.
go_to_unit_page
()
def
set_visibility
(
problem_index
,
content_group
,
second_content_group
=
None
):
problem
=
container_page
.
xblocks
[
problem_index
]
problem
.
edit_visibility
()
if
second_content_group
:
ComponentVisibilityEditorView
(
self
.
browser
,
problem
.
locator
)
.
select_option
(
second_content_group
,
save
=
False
)
ComponentVisibilityEditorView
(
self
.
browser
,
problem
.
locator
)
.
select_option
(
content_group
)
set_visibility
(
1
,
self
.
content_group_a
)
set_visibility
(
2
,
self
.
content_group_b
)
set_visibility
(
3
,
self
.
content_group_a
,
self
.
content_group_b
)
container_page
.
publish_action
.
click
()
def
create_cohorts_and_assign_students
(
self
):
"""
Adds 2 manual cohorts, linked to content groups, to the course.
Each cohort is assigned one student.
"""
instructor_dashboard_page
=
InstructorDashboardPage
(
self
.
browser
,
self
.
course_id
)
instructor_dashboard_page
.
visit
()
membership_page
=
instructor_dashboard_page
.
select_membership
()
cohort_management_page
=
membership_page
.
select_cohort_management_section
()
def
add_cohort_with_student
(
cohort_name
,
content_group
,
student
):
cohort_management_page
.
add_cohort
(
cohort_name
,
content_group
=
content_group
)
# After adding the cohort, it should automatically be selected
EmptyPromise
(
lambda
:
cohort_name
==
cohort_management_page
.
get_selected_cohort
(),
"Waiting for new cohort"
)
.
fulfill
()
cohort_management_page
.
add_students_to_selected_cohort
([
student
])
add_cohort_with_student
(
"Cohort A"
,
self
.
content_group_a
,
self
.
cohort_a_student_username
)
add_cohort_with_student
(
"Cohort B"
,
self
.
content_group_b
,
self
.
cohort_b_student_username
)
def
view_cohorted_content_as_different_users
(
self
):
"""
View content as staff, student in Cohort A, student in Cohort B, and student in Default Cohort.
"""
courseware_page
=
CoursewarePage
(
self
.
browser
,
self
.
course_id
)
def
login_and_verify_visible_problems
(
username
,
email
,
expected_problems
):
LmsAutoAuthPage
(
self
.
browser
,
username
=
username
,
email
=
email
,
course_id
=
self
.
course_id
)
.
visit
()
courseware_page
.
visit
()
verify_expected_problem_visibility
(
self
,
courseware_page
,
expected_problems
)
login_and_verify_visible_problems
(
self
.
staff_user
[
"username"
],
self
.
staff_user
[
"email"
],
[
self
.
group_a_problem
,
self
.
group_b_problem
,
self
.
group_a_and_b_problem
,
self
.
visible_to_all_problem
]
)
login_and_verify_visible_problems
(
self
.
cohort_a_student_username
,
self
.
cohort_a_student_email
,
[
self
.
group_a_problem
,
self
.
group_a_and_b_problem
,
self
.
visible_to_all_problem
]
)
login_and_verify_visible_problems
(
self
.
cohort_b_student_username
,
self
.
cohort_b_student_email
,
[
self
.
group_b_problem
,
self
.
group_a_and_b_problem
,
self
.
visible_to_all_problem
]
)
login_and_verify_visible_problems
(
self
.
cohort_default_student_username
,
self
.
cohort_default_student_email
,
[
self
.
visible_to_all_problem
]
)
def
test_cohorted_courseware
(
self
):
"""
Scenario: Can create content that is only visible to students in particular cohorts
Given that I have course with 4 problems, 1 staff member, and 3 students
When I enable cohorts in the course
And I create two content groups, Content Group A, and Content Group B, in the course
And I link one problem to Content Group A
And I link one problem to Content Group B
And I link one problem to both Content Group A and Content Group B
And one problem remains unlinked to any Content Group
And I create two manual cohorts, Cohort A and Cohort B,
linked to Content Group A and Content Group B, respectively
And I assign one student to each manual cohort
And one student remains in the default cohort
Then the staff member can see all 4 problems
And the student in Cohort A can see all the problems except the one linked to Content Group B
And the student in Cohort B can see all the problems except the one linked to Content Group A
And the student in the default cohort can ony see the problem that is unlinked to any Content Group
"""
self
.
enable_cohorts_in_course
()
self
.
create_content_groups
()
self
.
link_problems_to_content_groups_and_publish
()
self
.
create_cohorts_and_assign_students
()
self
.
view_cohorted_content_as_different_users
()
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