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:
Matt Drayer
2015-10-15 10:18:21 -04:00
9 changed files with 249 additions and 10 deletions

View File

@@ -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):
"""

View File

@@ -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):
"""

View File

@@ -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?

View 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)