Merge pull request #10115 from edx/ziafazal/SOL-1254
ziafazal/SOL-1254: Student should see rest of courseware as soon as Entrance Exam is passed
This commit is contained in:
@@ -222,6 +222,27 @@ class CourseFixture(XBlockContainerFixture):
|
||||
"""
|
||||
self._configure_course()
|
||||
|
||||
@property
|
||||
def course_outline(self):
|
||||
"""
|
||||
Retrieves course outline in JSON format.
|
||||
"""
|
||||
url = STUDIO_BASE_URL + '/course/' + self._course_key + "?format=json"
|
||||
response = self.session.get(url, headers=self.headers)
|
||||
|
||||
if not response.ok:
|
||||
raise FixtureError(
|
||||
"Could not retrieve course outline json. Status was {0}".format(
|
||||
response.status_code))
|
||||
|
||||
try:
|
||||
course_outline_json = response.json()
|
||||
except ValueError:
|
||||
raise FixtureError(
|
||||
"Could not decode course outline as JSON: '{0}'".format(response)
|
||||
)
|
||||
return course_outline_json
|
||||
|
||||
@property
|
||||
def _course_location(self):
|
||||
"""
|
||||
|
||||
@@ -127,6 +127,33 @@ class CoursewarePage(CoursePage):
|
||||
# Wait for the unique exam code to appear.
|
||||
# elf.wait_for_element_presence(".proctored-exam-code", "unique exam code")
|
||||
|
||||
@property
|
||||
def entrance_exam_message_selector(self):
|
||||
"""
|
||||
Return the entrance exam status message selector on the top of courseware page.
|
||||
"""
|
||||
return self.q(css='#content .container section.course-content .sequential-status-message')
|
||||
|
||||
def has_entrance_exam_message(self):
|
||||
"""
|
||||
Returns boolean indicating presence entrance exam status message container div.
|
||||
"""
|
||||
return self.entrance_exam_message_selector.is_present()
|
||||
|
||||
def has_passed_message(self):
|
||||
"""
|
||||
Returns boolean indicating presence of passed message.
|
||||
"""
|
||||
return self.entrance_exam_message_selector.is_present() \
|
||||
and "You have passed the entrance exam" in self.entrance_exam_message_selector.text[0]
|
||||
|
||||
@property
|
||||
def chapter_count_in_navigation(self):
|
||||
"""
|
||||
Returns count of chapters available on LHS navigation.
|
||||
"""
|
||||
return len(self.q(css='nav.course-navigation a.chapter'))
|
||||
|
||||
@property
|
||||
def is_timer_bar_present(self):
|
||||
"""
|
||||
|
||||
@@ -84,6 +84,13 @@ class ProblemPage(PageObject):
|
||||
self.q(css='div.problem button.hint-button').click()
|
||||
self.wait_for_ajax()
|
||||
|
||||
def click_choice(self, choice_value):
|
||||
"""
|
||||
Click the choice input(radio, checkbox or option) where value matches `choice_value` in choice group.
|
||||
"""
|
||||
self.q(css='div.problem .choicegroup input[value="' + choice_value + '"]').click()
|
||||
self.wait_for_ajax()
|
||||
|
||||
def is_correct(self):
|
||||
"""
|
||||
Is there a "correct" status showing?
|
||||
|
||||
105
common/test/acceptance/tests/lms/test_lms_entrance_exams.py
Normal file
105
common/test/acceptance/tests/lms/test_lms_entrance_exams.py
Normal file
@@ -0,0 +1,105 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Bok choy acceptance tests for Entrance exams in the LMS
|
||||
"""
|
||||
from textwrap import dedent
|
||||
|
||||
from ..helpers import UniqueCourseTest
|
||||
from ...pages.studio.auto_auth import AutoAuthPage
|
||||
from ...pages.lms.courseware import CoursewarePage
|
||||
from ...pages.lms.problem import ProblemPage
|
||||
from ...fixtures.course import CourseFixture, XBlockFixtureDesc
|
||||
|
||||
|
||||
class EntranceExamTest(UniqueCourseTest):
|
||||
"""
|
||||
Base class for tests of Entrance Exams in the LMS.
|
||||
"""
|
||||
USERNAME = "joe_student"
|
||||
EMAIL = "joe@example.com"
|
||||
|
||||
def setUp(self):
|
||||
super(EntranceExamTest, self).setUp()
|
||||
|
||||
self.xqueue_grade_response = None
|
||||
|
||||
self.courseware_page = CoursewarePage(self.browser, self.course_id)
|
||||
|
||||
# Install a course with a hierarchy and problems
|
||||
course_fixture = CourseFixture(
|
||||
self.course_info['org'], self.course_info['number'],
|
||||
self.course_info['run'], self.course_info['display_name'],
|
||||
settings={
|
||||
'entrance_exam_enabled': 'true',
|
||||
'entrance_exam_minimum_score_pct': '50'
|
||||
}
|
||||
)
|
||||
|
||||
problem = self.get_problem()
|
||||
course_fixture.add_children(
|
||||
XBlockFixtureDesc('chapter', 'Test Section').add_children(
|
||||
XBlockFixtureDesc('sequential', 'Test Subsection').add_children(problem)
|
||||
)
|
||||
).install()
|
||||
|
||||
entrance_exam_subsection = None
|
||||
outline = course_fixture.course_outline
|
||||
for child in outline['child_info']['children']:
|
||||
if child.get('display_name') == "Entrance Exam":
|
||||
entrance_exam_subsection = child['child_info']['children'][0]
|
||||
|
||||
if entrance_exam_subsection:
|
||||
course_fixture.create_xblock(entrance_exam_subsection['id'], problem)
|
||||
|
||||
# Auto-auth register for the course.
|
||||
AutoAuthPage(self.browser, username=self.USERNAME, email=self.EMAIL,
|
||||
course_id=self.course_id, staff=False).visit()
|
||||
|
||||
def get_problem(self):
|
||||
""" Subclasses should override this to complete the fixture """
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class EntranceExamPassTest(EntranceExamTest):
|
||||
"""
|
||||
Tests the scenario when a student passes entrance exam.
|
||||
"""
|
||||
|
||||
def get_problem(self):
|
||||
"""
|
||||
Create a multiple choice problem
|
||||
"""
|
||||
xml = dedent("""
|
||||
<problem>
|
||||
<p>What is height of eiffel tower without the antenna?.</p>
|
||||
<multiplechoiceresponse>
|
||||
<choicegroup label="What is height of eiffel tower without the antenna?" type="MultipleChoice">
|
||||
<choice correct="false">324 meters<choicehint>Antenna is 24 meters high</choicehint></choice>
|
||||
<choice correct="true">300 meters</choice>
|
||||
<choice correct="false">224 meters</choice>
|
||||
<choice correct="false">400 meters</choice>
|
||||
</choicegroup>
|
||||
</multiplechoiceresponse>
|
||||
</problem>
|
||||
""")
|
||||
return XBlockFixtureDesc('problem', 'HEIGHT OF EIFFEL TOWER', data=xml)
|
||||
|
||||
def test_course_is_unblocked_as_soon_as_student_passes_entrance_exam(self):
|
||||
"""
|
||||
Scenario: Ensure that entrance exam status message is updated and courseware is unblocked as soon as
|
||||
student passes entrance exam.
|
||||
Given I have a course with entrance exam as pre-requisite
|
||||
When I pass entrance exam
|
||||
Then I can see complete TOC of course
|
||||
And I can see message indicating my pass status
|
||||
"""
|
||||
self.courseware_page.visit()
|
||||
problem_page = ProblemPage(self.browser)
|
||||
self.assertEqual(problem_page.wait_for_page().problem_name, 'HEIGHT OF EIFFEL TOWER')
|
||||
self.assertTrue(self.courseware_page.has_entrance_exam_message())
|
||||
self.assertFalse(self.courseware_page.has_passed_message())
|
||||
problem_page.click_choice('choice_1')
|
||||
problem_page.click_check()
|
||||
self.courseware_page.wait_for_page()
|
||||
self.assertTrue(self.courseware_page.has_passed_message())
|
||||
self.assertEqual(self.courseware_page.chapter_count_in_navigation, 2)
|
||||
Reference in New Issue
Block a user