bok choy tests for persistent grades
This commit is contained in:
@@ -1011,6 +1011,7 @@ class StudentAdminPage(PageObject):
|
||||
"""
|
||||
url = None
|
||||
EE_CONTAINER = ".entrance-exam-grade-container"
|
||||
CS_CONTAINER = ".course-specific-container"
|
||||
|
||||
def is_browser_on_page(self):
|
||||
"""
|
||||
@@ -1025,6 +1026,13 @@ class StudentAdminPage(PageObject):
|
||||
"""
|
||||
return self.q(css='{} input[name=entrance-exam-student-select-grade]'.format(self.EE_CONTAINER))
|
||||
|
||||
@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):
|
||||
"""
|
||||
@@ -1039,6 +1047,20 @@ class StudentAdminPage(PageObject):
|
||||
"""
|
||||
return self.q(css='{} input[name=rescore-entrance-exam]'.format(self.EE_CONTAINER))
|
||||
|
||||
@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):
|
||||
"""
|
||||
@@ -1115,6 +1137,18 @@ class StudentAdminPage(PageObject):
|
||||
"""
|
||||
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):
|
||||
"""
|
||||
clicks let student skip entrance exam button.
|
||||
@@ -1133,12 +1167,19 @@ class StudentAdminPage(PageObject):
|
||||
"""
|
||||
return self.background_task_history_button.click()
|
||||
|
||||
def set_student_email(self, email_addres):
|
||||
def set_student_email(self, email_address):
|
||||
"""
|
||||
Sets given email address as value of student email address/username input box.
|
||||
"""
|
||||
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):
|
||||
|
||||
@@ -14,9 +14,12 @@ from capa.tests.response_xml_factory import MultipleChoiceResponseXMLFactory
|
||||
from ..helpers import UniqueCourseTest, EventsTestMixin
|
||||
from ...pages.studio.auto_auth import AutoAuthPage
|
||||
from ...pages.lms.create_mode import ModeCreationPage
|
||||
from ...pages.studio.component_editor import ComponentEditorView
|
||||
from ...pages.studio.overview import CourseOutlinePage
|
||||
from ...pages.studio.utils import type_in_codemirror
|
||||
from ...pages.lms.courseware import CoursewarePage, CoursewareSequentialTabPage
|
||||
from ...pages.lms.course_nav import CourseNavPage
|
||||
from ...pages.lms.instructor_dashboard import InstructorDashboardPage
|
||||
from ...pages.lms.problem import ProblemPage
|
||||
from ...pages.common.logout import LogoutPage
|
||||
from ...pages.lms.staff_view import StaffPage
|
||||
@@ -912,16 +915,20 @@ class SubsectionHiddenAfterDueDateTest(UniqueCourseTest):
|
||||
self.assertEqual(self.progress_page.scores('Test Section 1', 'Test Subsection 1'), [(0, 1)])
|
||||
|
||||
|
||||
class ProgressPageTest(UniqueCourseTest):
|
||||
class ProgressPageBaseTest(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"
|
||||
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):
|
||||
super(ProgressPageTest, self).setUp()
|
||||
|
||||
super(ProgressPageBaseTest, self).setUp()
|
||||
self.courseware_page = CoursewarePage(self.browser, self.course_id)
|
||||
self.problem_page = ProblemPage(self.browser) # pylint: disable=attribute-defined-outside-init
|
||||
self.progress_page = ProgressPage(self.browser, self.course_id)
|
||||
@@ -943,9 +950,11 @@ class ProgressPageTest(UniqueCourseTest):
|
||||
)
|
||||
|
||||
course_fix.add_children(
|
||||
XBlockFixtureDesc('chapter', 'Test Section 1').add_children(
|
||||
XBlockFixtureDesc('sequential', 'Test Subsection 1').add_children(
|
||||
create_multiple_choice_problem('Test Problem 1')
|
||||
XBlockFixtureDesc('chapter', self.SECTION_NAME).add_children(
|
||||
XBlockFixtureDesc('sequential', self.SUBSECTION_NAME).add_children(
|
||||
XBlockFixtureDesc('vertical', self.UNIT_NAME).add_children(
|
||||
create_multiple_choice_problem(self.PROBLEM_NAME)
|
||||
)
|
||||
)
|
||||
)
|
||||
).install()
|
||||
@@ -953,15 +962,6 @@ class ProgressPageTest(UniqueCourseTest):
|
||||
# Auto-auth register for the course.
|
||||
_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):
|
||||
"""
|
||||
Submit a correct answer to the problem.
|
||||
@@ -975,24 +975,156 @@ class ProgressPageTest(UniqueCourseTest):
|
||||
Return a list of scores from the progress page.
|
||||
"""
|
||||
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):
|
||||
"""
|
||||
Return a list of scores from the progress page.
|
||||
"""
|
||||
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
|
||||
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
|
||||
and end of the current test.
|
||||
"""
|
||||
self.logout_page.visit()
|
||||
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
|
||||
finally:
|
||||
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))
|
||||
|
||||
Reference in New Issue
Block a user