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
134e764c
Commit
134e764c
authored
Sep 15, 2016
by
sanfordstudent
Committed by
GitHub
Sep 15, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #13447 from edx/sstudent/TNL-5466
bok choy tests for persistent grades
parents
bf47486b
bf1fcc68
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
195 additions
and
22 deletions
+195
-22
common/test/acceptance/pages/lms/instructor_dashboard.py
+43
-2
common/test/acceptance/tests/lms/test_lms_courseware.py
+152
-20
No files found.
common/test/acceptance/pages/lms/instructor_dashboard.py
View file @
134e764c
...
@@ -1011,6 +1011,7 @@ class StudentAdminPage(PageObject):
...
@@ -1011,6 +1011,7 @@ class StudentAdminPage(PageObject):
"""
"""
url
=
None
url
=
None
EE_CONTAINER
=
".entrance-exam-grade-container"
EE_CONTAINER
=
".entrance-exam-grade-container"
CS_CONTAINER
=
".course-specific-container"
def
is_browser_on_page
(
self
):
def
is_browser_on_page
(
self
):
"""
"""
...
@@ -1026,6 +1027,13 @@ class StudentAdminPage(PageObject):
...
@@ -1026,6 +1027,13 @@ class StudentAdminPage(PageObject):
return
self
.
q
(
css
=
'{} input[name=entrance-exam-student-select-grade]'
.
format
(
self
.
EE_CONTAINER
))
return
self
.
q
(
css
=
'{} input[name=entrance-exam-student-select-grade]'
.
format
(
self
.
EE_CONTAINER
))
@property
@property
def
rescore_problem_input
(
self
):
"""
Returns input box for rescore/reset all on a problem
"""
return
self
.
q
(
css
=
'{} input[name=problem-select-all]'
.
format
(
self
.
CS_CONTAINER
))
@property
def
reset_attempts_button
(
self
):
def
reset_attempts_button
(
self
):
"""
"""
Returns reset student attempts button.
Returns reset student attempts button.
...
@@ -1040,6 +1048,20 @@ class StudentAdminPage(PageObject):
...
@@ -1040,6 +1048,20 @@ class StudentAdminPage(PageObject):
return
self
.
q
(
css
=
'{} input[name=rescore-entrance-exam]'
.
format
(
self
.
EE_CONTAINER
))
return
self
.
q
(
css
=
'{} input[name=rescore-entrance-exam]'
.
format
(
self
.
EE_CONTAINER
))
@property
@property
def
rescore_all_submissions_button
(
self
):
"""
Returns rescore student submission button.
"""
return
self
.
q
(
css
=
'{} input[name=rescore-problem-all]'
.
format
(
self
.
CS_CONTAINER
))
@property
def
show_background_tasks_button
(
self
):
"""
Return Show Background Tasks button.
"""
return
self
.
q
(
css
=
'{} input[name=task-history-all]'
.
format
(
self
.
CS_CONTAINER
))
@property
def
skip_entrance_exam_button
(
self
):
def
skip_entrance_exam_button
(
self
):
"""
"""
Return Let Student Skip Entrance Exam button.
Return Let Student Skip Entrance Exam button.
...
@@ -1115,6 +1137,18 @@ class StudentAdminPage(PageObject):
...
@@ -1115,6 +1137,18 @@ class StudentAdminPage(PageObject):
"""
"""
return
self
.
rescore_submission_button
.
click
()
return
self
.
rescore_submission_button
.
click
()
def
click_rescore_all_button
(
self
):
"""
clicks rescore all for problem button.
"""
return
self
.
rescore_all_submissions_button
.
click
()
def
click_show_background_tasks_button
(
self
):
"""
clicks show background tasks button.
"""
return
self
.
show_background_tasks_button
.
click
()
def
click_skip_entrance_exam_button
(
self
):
def
click_skip_entrance_exam_button
(
self
):
"""
"""
clicks let student skip entrance exam button.
clicks let student skip entrance exam button.
...
@@ -1133,12 +1167,19 @@ class StudentAdminPage(PageObject):
...
@@ -1133,12 +1167,19 @@ class StudentAdminPage(PageObject):
"""
"""
return
self
.
background_task_history_button
.
click
()
return
self
.
background_task_history_button
.
click
()
def
set_student_email
(
self
,
email_addres
):
def
set_student_email
(
self
,
email_addres
s
):
"""
"""
Sets given email address as value of student email address/username input box.
Sets given email address as value of student email address/username input box.
"""
"""
input_box
=
self
.
student_email_input
.
first
.
results
[
0
]
input_box
=
self
.
student_email_input
.
first
.
results
[
0
]
input_box
.
send_keys
(
email_addres
)
input_box
.
send_keys
(
email_address
)
def
set_problem_to_rescore
(
self
,
problem_locator
):
"""
Sets the problem for which to rescore/reset all scores.
"""
input_box
=
self
.
rescore_problem_input
.
first
.
results
[
0
]
input_box
.
send_keys
(
problem_locator
)
class
CertificatesPage
(
PageObject
):
class
CertificatesPage
(
PageObject
):
...
...
common/test/acceptance/tests/lms/test_lms_courseware.py
View file @
134e764c
...
@@ -14,9 +14,12 @@ from capa.tests.response_xml_factory import MultipleChoiceResponseXMLFactory
...
@@ -14,9 +14,12 @@ from capa.tests.response_xml_factory import MultipleChoiceResponseXMLFactory
from
..helpers
import
UniqueCourseTest
,
EventsTestMixin
from
..helpers
import
UniqueCourseTest
,
EventsTestMixin
from
...pages.studio.auto_auth
import
AutoAuthPage
from
...pages.studio.auto_auth
import
AutoAuthPage
from
...pages.lms.create_mode
import
ModeCreationPage
from
...pages.lms.create_mode
import
ModeCreationPage
from
...pages.studio.component_editor
import
ComponentEditorView
from
...pages.studio.overview
import
CourseOutlinePage
from
...pages.studio.overview
import
CourseOutlinePage
from
...pages.studio.utils
import
type_in_codemirror
from
...pages.lms.courseware
import
CoursewarePage
,
CoursewareSequentialTabPage
from
...pages.lms.courseware
import
CoursewarePage
,
CoursewareSequentialTabPage
from
...pages.lms.course_nav
import
CourseNavPage
from
...pages.lms.course_nav
import
CourseNavPage
from
...pages.lms.instructor_dashboard
import
InstructorDashboardPage
from
...pages.lms.problem
import
ProblemPage
from
...pages.lms.problem
import
ProblemPage
from
...pages.common.logout
import
LogoutPage
from
...pages.common.logout
import
LogoutPage
from
...pages.lms.staff_view
import
StaffPage
from
...pages.lms.staff_view
import
StaffPage
...
@@ -912,16 +915,20 @@ class SubsectionHiddenAfterDueDateTest(UniqueCourseTest):
...
@@ -912,16 +915,20 @@ class SubsectionHiddenAfterDueDateTest(UniqueCourseTest):
self
.
assertEqual
(
self
.
progress_page
.
scores
(
'Test Section 1'
,
'Test Subsection 1'
),
[(
0
,
1
)])
self
.
assertEqual
(
self
.
progress_page
.
scores
(
'Test Section 1'
,
'Test Subsection 1'
),
[(
0
,
1
)])
class
ProgressPageTest
(
UniqueCourseTest
):
class
ProgressPage
Base
Test
(
UniqueCourseTest
):
"""
"""
Test that the progress page reports scores from completed assessments.
Provides utility methods for tests retrieving
scores from the progress page.
"""
"""
USERNAME
=
"STUDENT_TESTER"
USERNAME
=
"STUDENT_TESTER"
EMAIL
=
"student101@example.com"
EMAIL
=
"student101@example.com"
SECTION_NAME
=
'Test Section 1'
SUBSECTION_NAME
=
'Test Subsection 1'
UNIT_NAME
=
'Test Unit 1'
PROBLEM_NAME
=
'Test Problem 1'
def
setUp
(
self
):
def
setUp
(
self
):
super
(
ProgressPageTest
,
self
)
.
setUp
()
super
(
ProgressPageBaseTest
,
self
)
.
setUp
()
self
.
courseware_page
=
CoursewarePage
(
self
.
browser
,
self
.
course_id
)
self
.
courseware_page
=
CoursewarePage
(
self
.
browser
,
self
.
course_id
)
self
.
problem_page
=
ProblemPage
(
self
.
browser
)
# pylint: disable=attribute-defined-outside-init
self
.
problem_page
=
ProblemPage
(
self
.
browser
)
# pylint: disable=attribute-defined-outside-init
self
.
progress_page
=
ProgressPage
(
self
.
browser
,
self
.
course_id
)
self
.
progress_page
=
ProgressPage
(
self
.
browser
,
self
.
course_id
)
...
@@ -943,9 +950,11 @@ class ProgressPageTest(UniqueCourseTest):
...
@@ -943,9 +950,11 @@ class ProgressPageTest(UniqueCourseTest):
)
)
course_fix
.
add_children
(
course_fix
.
add_children
(
XBlockFixtureDesc
(
'chapter'
,
'Test Section 1'
)
.
add_children
(
XBlockFixtureDesc
(
'chapter'
,
self
.
SECTION_NAME
)
.
add_children
(
XBlockFixtureDesc
(
'sequential'
,
'Test Subsection 1'
)
.
add_children
(
XBlockFixtureDesc
(
'sequential'
,
self
.
SUBSECTION_NAME
)
.
add_children
(
create_multiple_choice_problem
(
'Test Problem 1'
)
XBlockFixtureDesc
(
'vertical'
,
self
.
UNIT_NAME
)
.
add_children
(
create_multiple_choice_problem
(
self
.
PROBLEM_NAME
)
)
)
)
)
)
)
.
install
()
)
.
install
()
...
@@ -953,15 +962,6 @@ class ProgressPageTest(UniqueCourseTest):
...
@@ -953,15 +962,6 @@ class ProgressPageTest(UniqueCourseTest):
# Auto-auth register for the course.
# Auto-auth register for the course.
_auto_auth
(
self
.
browser
,
self
.
USERNAME
,
self
.
EMAIL
,
False
,
self
.
course_id
)
_auto_auth
(
self
.
browser
,
self
.
USERNAME
,
self
.
EMAIL
,
False
,
self
.
course_id
)
def
test_progress_page_shows_scored_problems
(
self
):
with
self
.
_logged_in_session
():
self
.
assertEqual
(
self
.
_get_scores
(),
[(
0
,
1
)])
self
.
assertEqual
(
self
.
_get_section_score
(),
(
0
,
1
))
self
.
courseware_page
.
visit
()
self
.
_answer_problem_correctly
()
self
.
assertEqual
(
self
.
_get_scores
(),
[(
1
,
1
)])
self
.
assertEqual
(
self
.
_get_section_score
(),
(
1
,
1
))
def
_answer_problem_correctly
(
self
):
def
_answer_problem_correctly
(
self
):
"""
"""
Submit a correct answer to the problem.
Submit a correct answer to the problem.
...
@@ -975,24 +975,156 @@ class ProgressPageTest(UniqueCourseTest):
...
@@ -975,24 +975,156 @@ class ProgressPageTest(UniqueCourseTest):
Return a list of scores from the progress page.
Return a list of scores from the progress page.
"""
"""
self
.
progress_page
.
visit
()
self
.
progress_page
.
visit
()
return
self
.
progress_page
.
section_score
(
'Test Section 1'
,
'Test Subsection 1'
)
return
self
.
progress_page
.
section_score
(
self
.
SECTION_NAME
,
self
.
SUBSECTION_NAME
)
def
_get_scores
(
self
):
def
_get_scores
(
self
):
"""
"""
Return a list of scores from the progress page.
Return a list of scores from the progress page.
"""
"""
self
.
progress_page
.
visit
()
self
.
progress_page
.
visit
()
return
self
.
progress_page
.
scores
(
'Test Section 1'
,
'Test Subsection 1'
)
return
self
.
progress_page
.
scores
(
self
.
SECTION_NAME
,
self
.
SUBSECTION_NAME
)
@contextmanager
@contextmanager
def
_logged_in_session
(
self
):
def
_logged_in_session
(
self
,
staff
=
False
):
"""
"""
Ensure that the user is logged in and out appropriately at the beginning
Ensure that the user is logged in and out appropriately at the beginning
and end of the current test.
and end of the current test.
"""
"""
self
.
logout_page
.
visit
()
self
.
logout_page
.
visit
()
try
:
try
:
_auto_auth
(
self
.
browser
,
self
.
USERNAME
,
self
.
EMAIL
,
False
,
self
.
course_id
)
if
staff
:
_auto_auth
(
self
.
browser
,
"STAFF_TESTER"
,
"staff101@example.com"
,
True
,
self
.
course_id
)
else
:
_auto_auth
(
self
.
browser
,
self
.
USERNAME
,
self
.
EMAIL
,
False
,
self
.
course_id
)
yield
yield
finally
:
finally
:
self
.
logout_page
.
visit
()
self
.
logout_page
.
visit
()
class
ProgressPageTest
(
ProgressPageBaseTest
):
"""
Test that the progress page reports scores from completed assessments.
"""
def
test_progress_page_shows_scored_problems
(
self
):
with
self
.
_logged_in_session
():
self
.
assertEqual
(
self
.
_get_scores
(),
[(
0
,
1
)])
self
.
assertEqual
(
self
.
_get_section_score
(),
(
0
,
1
))
self
.
courseware_page
.
visit
()
self
.
_answer_problem_correctly
()
self
.
assertEqual
(
self
.
_get_scores
(),
[(
1
,
1
)])
self
.
assertEqual
(
self
.
_get_section_score
(),
(
1
,
1
))
@ddt.ddt
class
PersistentGradesTest
(
ProgressPageBaseTest
):
"""
Test that grades for completed assessments are persisted
when various edits are made.
"""
def
setUp
(
self
):
super
(
PersistentGradesTest
,
self
)
.
setUp
()
self
.
instructor_dashboard_page
=
InstructorDashboardPage
(
self
.
browser
,
self
.
course_id
)
def
_change_subsection_structure
(
self
):
"""
Adds a unit to the subsection, which
should not affect a persisted subsectiong grade.
"""
with
self
.
_logged_in_session
(
staff
=
True
):
self
.
course_outline
.
visit
()
subsection
=
self
.
course_outline
.
section
(
self
.
SECTION_NAME
)
.
subsection
(
self
.
SUBSECTION_NAME
)
subsection
.
expand_subsection
()
subsection
.
add_unit
()
def
_set_staff_lock_on_subsection
(
self
,
locked
):
"""
Sets staff lock for a subsection, which should hide the
subsection score from students on the progress page.
"""
with
self
.
_logged_in_session
(
staff
=
True
):
self
.
course_outline
.
visit
()
subsection
=
self
.
course_outline
.
section_at
(
0
)
.
subsection_at
(
0
)
subsection
.
set_staff_lock
(
locked
)
self
.
assertEqual
(
subsection
.
has_staff_lock_warning
,
locked
)
def
_change_weight_for_problem
(
self
):
"""
Changes the weight of the problem, which should not affect
persisted grades.
"""
with
self
.
_logged_in_session
(
staff
=
True
):
self
.
course_outline
.
visit
()
self
.
course_outline
.
section_at
(
0
)
.
subsection_at
(
0
)
.
expand_subsection
()
unit
=
self
.
course_outline
.
section_at
(
0
)
.
subsection_at
(
0
)
.
unit
(
self
.
UNIT_NAME
)
.
go_to
()
container
=
unit
.
xblocks
[
0
]
.
go_to_container
()
component
=
container
.
xblocks
[
0
]
.
children
[
0
]
component
.
edit
()
component_editor
=
ComponentEditorView
(
self
.
browser
,
component
.
locator
)
component_editor
.
set_field_value_and_save
(
'Problem Weight'
,
5
)
def
_rescore_for_all
(
self
):
"""
Triggers a rescore for all students. Currently unimplemented.
"""
pass
def
_edit_problem_content
(
self
):
"""
Replaces the content of a problem with other html.
Should not affect persisted grades.
"""
with
self
.
_logged_in_session
(
staff
=
True
):
self
.
course_outline
.
visit
()
self
.
course_outline
.
section_at
(
0
)
.
subsection_at
(
0
)
.
expand_subsection
()
unit
=
self
.
course_outline
.
section_at
(
0
)
.
subsection_at
(
0
)
.
unit
(
self
.
UNIT_NAME
)
.
go_to
()
component
=
unit
.
xblocks
[
1
]
edit_view
=
component
.
edit
()
modified_content
=
"<p>modified content</p>"
# Set content in the CodeMirror editor.
type_in_codemirror
(
self
,
0
,
modified_content
)
edit_view
.
q
(
css
=
'.action-save'
)
.
click
()
@ddt.data
(
_edit_problem_content
,
_change_subsection_structure
,
_change_weight_for_problem
,
_rescore_for_all
)
def
test_content_changes_do_not_change_score
(
self
,
edit
):
with
self
.
_logged_in_session
():
self
.
assertEqual
(
self
.
_get_scores
(),
[(
0
,
1
)])
self
.
assertEqual
(
self
.
_get_section_score
(),
(
0
,
1
))
self
.
courseware_page
.
visit
()
self
.
_answer_problem_correctly
()
self
.
assertEqual
(
self
.
_get_scores
(),
[(
1
,
1
)])
self
.
assertEqual
(
self
.
_get_section_score
(),
(
1
,
1
))
edit
(
self
)
with
self
.
_logged_in_session
():
self
.
assertEqual
(
self
.
_get_scores
(),
[(
1
,
1
)])
self
.
assertEqual
(
self
.
_get_section_score
(),
(
1
,
1
))
def
test_visibility_change_does_affect_score
(
self
):
with
self
.
_logged_in_session
():
self
.
assertEqual
(
self
.
_get_scores
(),
[(
0
,
1
)])
self
.
assertEqual
(
self
.
_get_section_score
(),
(
0
,
1
))
self
.
courseware_page
.
visit
()
self
.
_answer_problem_correctly
()
self
.
assertEqual
(
self
.
_get_scores
(),
[(
1
,
1
)])
self
.
assertEqual
(
self
.
_get_section_score
(),
(
1
,
1
))
self
.
_set_staff_lock_on_subsection
(
True
)
with
self
.
_logged_in_session
():
self
.
assertEqual
(
self
.
_get_scores
(),
None
)
self
.
assertEqual
(
self
.
_get_section_score
(),
None
)
self
.
_set_staff_lock_on_subsection
(
False
)
with
self
.
_logged_in_session
():
self
.
assertEqual
(
self
.
_get_scores
(),
[(
1
,
1
)])
self
.
assertEqual
(
self
.
_get_section_score
(),
(
1
,
1
))
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