Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-ora2
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-ora2
Commits
665020d0
Commit
665020d0
authored
Nov 12, 2015
by
cahrens
Committed by
Andy Armstrong
Dec 15, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add acceptance and a11y tests for regrading UI
parent
5a530dab
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
209 additions
and
44 deletions
+209
-44
test/acceptance/accessibility.py
+1
-0
test/acceptance/pages.py
+132
-39
test/acceptance/tests.py
+76
-5
No files found.
test/acceptance/accessibility.py
View file @
665020d0
...
...
@@ -110,6 +110,7 @@ class StaffAreaA11yTest(OpenAssessmentA11yTest):
# Click on staff tools and search for the user.
self
.
staff_area_page
.
show_learner
(
username
)
self
.
staff_area_page
.
expand_learner_report_sections
()
self
.
_check_a11y
(
self
.
staff_area_page
)
...
...
test/acceptance/pages.py
View file @
665020d0
...
...
@@ -32,6 +32,14 @@ class OpenAssessmentPage(PageObject):
super
(
OpenAssessmentPage
,
self
)
.
__init__
(
browser
)
self
.
_problem_location
=
problem_location
def
_bounded_selector
(
self
,
selector
):
"""
Allows scoping to a portion of the page.
The default implementation just returns the selector
"""
return
selector
@property
def
url
(
self
):
return
"{base}/{loc}"
.
format
(
...
...
@@ -39,19 +47,19 @@ class OpenAssessmentPage(PageObject):
loc
=
self
.
_problem_location
)
def
submit
(
self
):
def
submit
(
self
,
button_css
=
".action--submit"
):
"""
Click the submit button on the page.
This relies on the fact that we use the same CSS styles for submit buttons
in all problem steps.
in all problem steps
(unless custom value for button_css is passed in)
.
"""
EmptyPromise
(
lambda
:
'is--disabled'
not
in
" "
.
join
(
self
.
q
(
css
=
".action--submit"
)
.
attrs
(
'class'
)),
lambda
:
'is--disabled'
not
in
" "
.
join
(
self
.
q
(
css
=
self
.
_bounded_selector
(
button_css
)
)
.
attrs
(
'class'
)),
"Submit button is enabled."
)
.
fulfill
()
with
self
.
handle_alert
():
self
.
q
(
css
=
".action--submit"
)
.
first
.
click
()
self
.
q
(
css
=
self
.
_bounded_selector
(
button_css
)
)
.
first
.
click
()
def
hide_django_debug_tool
(
self
):
if
self
.
q
(
css
=
'#djDebug'
)
.
visible
:
...
...
@@ -155,7 +163,42 @@ class SubmissionPage(OpenAssessmentPage):
return
self
.
q
(
css
=
"#submission__custom__upload"
)
.
visible
class
AssessmentPage
(
OpenAssessmentPage
):
class
AssessmentMixin
(
object
):
"""
Mixin for interacting with the assessment rubric.
"""
def
assess
(
self
,
options_selected
):
"""
Create an assessment.
Args:
options_selected (list of int): list of the indices (starting from 0)
of each option to select in the rubric.
Returns:
AssessmentPage
Example usage:
>>> page.assess([0, 2, 1])
"""
for
criterion_num
,
option_num
in
enumerate
(
options_selected
):
sel
=
"#assessment__rubric__question--{criterion_num}__{option_num}"
.
format
(
criterion_num
=
criterion_num
,
option_num
=
option_num
)
self
.
q
(
css
=
self
.
_bounded_selector
(
sel
))
.
first
.
click
()
self
.
submit_assessment
()
return
self
def
submit_assessment
(
self
):
"""
Submit an assessment of the problem.
"""
self
.
submit
()
class
AssessmentPage
(
OpenAssessmentPage
,
AssessmentMixin
):
"""
Page object representing an "assessment" step in an ORA problem.
"""
...
...
@@ -193,30 +236,6 @@ class AssessmentPage(OpenAssessmentPage):
# self.wait_for_element_visibility(".chapter.is-open", "Chapter heading is on visible", timeout=10)
return
self
.
q
(
css
=
".chapter.is-open"
)
.
visible
def
assess
(
self
,
options_selected
):
"""
Create an assessment.
Args:
options_selected (list of int): list of the indices (starting from 0)
of each option to select in the rubric.
Returns:
AssessmentPage
Example usage:
>>> page.assess([0, 2, 1])
"""
for
criterion_num
,
option_num
in
enumerate
(
options_selected
):
sel
=
"#assessment__rubric__question--{criterion_num}__{option_num}"
.
format
(
criterion_num
=
criterion_num
,
option_num
=
option_num
)
self
.
q
(
css
=
sel
)
.
first
.
click
()
self
.
submit
()
return
self
@property
def
response_text
(
self
):
"""
...
...
@@ -341,11 +360,17 @@ class GradePage(OpenAssessmentPage):
return
score_candidates
[
0
]
if
len
(
score_candidates
)
>
0
else
None
class
StaffAreaPage
(
OpenAssessmentPage
):
class
StaffAreaPage
(
OpenAssessmentPage
,
AssessmentMixin
):
"""
Page object representing the tabbed staff area.
"""
def
_bounded_selector
(
self
,
selector
):
"""
Return `selector`, but limited to the staff area management area.
"""
return
'.openassessment__staff-area {}'
.
format
(
selector
)
def
is_browser_on_page
(
self
):
return
self
.
q
(
css
=
".openassessment__staff-area"
)
.
is_present
()
...
...
@@ -354,7 +379,7 @@ class StaffAreaPage(OpenAssessmentPage):
"""
Returns the names of the selected toolbar buttons.
"""
buttons
=
self
.
q
(
css
=
".ui-staff__button"
)
buttons
=
self
.
q
(
css
=
self
.
_bounded_selector
(
".ui-staff__button"
)
)
return
[
button
.
text
for
button
in
buttons
if
u'is--active'
in
button
.
get_attribute
(
'class'
)]
@property
...
...
@@ -362,7 +387,7 @@ class StaffAreaPage(OpenAssessmentPage):
"""
Returns the classes of the visible staff panels
"""
panels
=
self
.
q
(
css
=
".wrapper--ui-staff"
)
panels
=
self
.
q
(
css
=
self
.
_bounded_selector
(
".wrapper--ui-staff"
)
)
return
[
panel
.
get_attribute
(
'class'
)
for
panel
in
panels
if
u'is--hidden'
not
in
panel
.
get_attribute
(
'class'
)]
def
click_staff_toolbar_button
(
self
,
button_name
):
...
...
@@ -370,7 +395,7 @@ class StaffAreaPage(OpenAssessmentPage):
Presses the button to show the panel with the specified name.
:return:
"""
buttons
=
self
.
q
(
css
=
".button-{button_name}"
.
format
(
button_name
=
button_name
))
buttons
=
self
.
q
(
css
=
self
.
_bounded_selector
(
".button-{button_name}"
.
format
(
button_name
=
button_name
)
))
buttons
.
first
.
click
()
def
click_staff_panel_close_button
(
self
,
panel_name
):
...
...
@@ -378,16 +403,19 @@ class StaffAreaPage(OpenAssessmentPage):
Presses the close button on the staff panel with the specified name.
:return:
"""
self
.
q
(
css
=
".wrapper--{panel_name} .ui-staff_close_button"
.
format
(
panel_name
=
panel_name
))
.
click
()
self
.
q
(
css
=
self
.
_bounded_selector
(
".wrapper--{panel_name} .ui-staff_close_button"
.
format
(
panel_name
=
panel_name
))
)
.
click
()
def
show_learner
(
self
,
username
):
"""
Clicks the staff tools panel and and searches for learner information about the given username.
"""
self
.
click_staff_toolbar_button
(
"staff-tools"
)
self
.
wait_for_element_visibility
(
"input.openassessment__student_username"
,
"Input is present"
)
self
.
q
(
css
=
"input.openassessment__student_username"
)
.
fill
(
username
)
submit_button
=
self
.
q
(
css
=
".action--submit-username"
)
student_input_css
=
self
.
_bounded_selector
(
"input.openassessment__student_username"
)
self
.
wait_for_element_visibility
(
student_input_css
,
"Input is present"
)
self
.
q
(
css
=
student_input_css
)
.
fill
(
username
)
submit_button
=
self
.
q
(
css
=
self
.
_bounded_selector
(
".action--submit-username"
))
submit_button
.
first
.
click
()
self
.
wait_for_element_visibility
(
".staff-info__student__report"
,
"Student report is present"
)
...
...
@@ -396,12 +424,77 @@ class StaffAreaPage(OpenAssessmentPage):
"""
Returns the text present in the learner report (useful for case where there is no response).
"""
return
self
.
q
(
css
=
".staff-info__student__report"
)
.
text
[
0
]
return
self
.
q
(
css
=
self
.
_bounded_selector
(
".staff-info__student__report"
))
.
text
[
0
]
def
verify_learner_report_text
(
self
,
expectedText
):
"""
Verifies the learner report text is as expected.
"""
EmptyPromise
(
lambda
:
self
.
learner_report_text
==
expectedText
,
"Learner report text correct"
)
.
fulfill
()
@property
def
learner_report_sections
(
self
):
"""
Returns the titles of the collapsible learner report sections present on the page.
"""
sections
=
self
.
q
(
css
=
".ui-staff__subtitle"
)
self
.
wait_for_section_titles
()
sections
=
self
.
q
(
css
=
self
.
_bounded_selector
(
".ui-staff__subtitle"
))
return
[
section
.
text
for
section
in
sections
]
def
wait_for_section_titles
(
self
):
"""
Wait for section titles to appear.
"""
EmptyPromise
(
lambda
:
len
(
self
.
q
(
css
=
self
.
_bounded_selector
(
".ui-staff__subtitle"
)))
>
0
,
"Section titles appeared"
)
.
fulfill
()
def
expand_learner_report_sections
(
self
):
"""
Expands all the sections in the learner report.
"""
self
.
wait_for_section_titles
()
self
.
q
(
css
=
self
.
_bounded_selector
(
".ui-staff__subtitle"
))
.
click
()
@property
def
learner_final_score
(
self
):
"""
Returns the final score displayed in the learner report.
"""
score
=
self
.
q
(
css
=
self
.
_bounded_selector
(
".staff-info__student__grade .ui-toggle-visibility__content"
))
if
len
(
score
)
==
0
:
return
None
return
score
.
text
[
0
]
def
verify_learner_final_score
(
self
,
expected_score
):
"""
Verifies that the final score in the learner report is equal to the expected value.
"""
EmptyPromise
(
lambda
:
self
.
learner_final_score
==
expected_score
,
"Learner score is updated"
)
.
fulfill
()
@property
def
learner_response
(
self
):
return
self
.
q
(
css
=
self
.
_bounded_selector
(
".staff-info__student__response .ui-toggle-visibility__content"
)
)
.
text
[
0
]
def
submit_assessment
(
self
):
"""
Submit a staff assessment of the problem.
"""
self
.
submit
(
button_css
=
".wrapper--staff-assessment .action--submit"
)
def
cancel_submission
(
self
):
"""
Cancel a learner's assessment.
"""
# Must put a comment to enable the submit button.
self
.
q
(
css
=
self
.
_bounded_selector
(
"textarea.cancel_submission_comments"
))
.
fill
(
"comment"
)
self
.
submit
(
button_css
=
".action--submit-cancel-submission"
)
test/acceptance/tests.py
View file @
665020d0
...
...
@@ -314,13 +314,14 @@ class StaffAreaTest(OpenAssessmentTest):
# Click on staff tools and search for user
self
.
staff_area_page
.
show_learner
(
username
)
self
.
assertNotIn
(
'A response was not found for this learner'
,
self
.
staff_area_page
.
learner_report_text
)
self
.
assertEqual
(
[
u'Learner Response'
,
u"Learner's Self Assessment"
,
u"Learner's Final Grade"
],
[
u'Learner Response'
,
u"Learner's Self Assessment"
,
u"Learner's Final Grade"
,
u"Submit Assessment Grade Override"
,
u"Remove Submission From Peer Grading"
],
self
.
staff_area_page
.
learner_report_sections
)
self
.
assertNotIn
(
'A response was not found for this learner'
,
self
.
staff_area_page
.
learner_report_text
)
@retry
()
@attr
(
'acceptance'
)
def
test_student_info_no_submission
(
self
):
...
...
@@ -338,9 +339,79 @@ class StaffAreaTest(OpenAssessmentTest):
# Click on staff tools and search for user
self
.
staff_area_page
.
show_learner
(
'no-submission-learner'
)
self
.
staff_area_page
.
verify_learner_report_text
(
'A response was not found for this learner.'
)
@retry
()
@attr
(
'acceptance'
)
def
test_staff_override
(
self
):
"""
Scenario: staff can override a learner's grade
Given I am viewing the staff area of an ORA problem
When I search for a learner in staff tools
And the learner has submitted a response to an ORA problem with self-assessment
Then I can submit a staff override of the self-assessment
And I see the updated final score
"""
username
=
self
.
do_self_assessment
()
self
.
staff_area_page
.
visit
()
# Click on staff tools and search for user
self
.
staff_area_page
.
show_learner
(
username
)
# Check the learner's current score.
self
.
staff_area_page
.
expand_learner_report_sections
()
self
.
staff_area_page
.
verify_learner_final_score
(
"Final grade: 6 out of 8"
)
# Do staff override and wait for final score to change.
self
.
staff_area_page
.
assess
([
0
,
1
])
# Verify that the new student score is different from the original one.
# TODO: uncomment this after hooked up to the API. Also verify other state if appropriate.
# self.staff_area_page.verify_learner_final_score("Final grade: 1 out of 8")
@retry
()
@attr
(
'acceptance'
)
def
test_cancel_submission
(
self
):
"""
Scenario: staff can cancel a learner's submission
Given I am viewing the staff area of an ORA problem
When I search for a learner in staff tools
And the learner has submitted a response to an ORA problem with self-assessment
Then I can cancel the learner's submission
And I see an updated message indicating that the submission has been canceled.
"""
username
=
self
.
do_self_assessment
()
self
.
staff_area_page
.
visit
()
# Click on staff tools and search for user
self
.
staff_area_page
.
show_learner
(
username
)
# Check the learner's current score.
self
.
staff_area_page
.
expand_learner_report_sections
()
self
.
staff_area_page
.
verify_learner_final_score
(
"Final grade: 6 out of 8"
)
# Cancel the student submission
self
.
staff_area_page
.
cancel_submission
()
self
.
staff_area_page
.
verify_learner_final_score
(
"The learner's submission has been removed from peer assessment. "
"The learner receives a grade of zero unless you reset the learner's attempts for the "
"problem to allow them to resubmit a response."
)
# Verify that the staff override and submission removal sections are now gone.
self
.
assertEqual
(
[
u'Learner Response'
,
u"Learner's Self Assessment"
,
u"Learner's Final Grade"
],
self
.
staff_area_page
.
learner_report_sections
)
self
.
assertIn
(
'A response was not found for this learner'
,
self
.
staff_area_page
.
learner_report_text
)
self
.
assertEqual
([],
self
.
staff_area_page
.
learner_report_sections
)
# Verify that the Learner Response has been replaced with a message about the removal
self
.
staff_area_page
.
expand_learner_report_sections
()
self
.
assertIn
(
"Learner submission removed"
,
self
.
staff_area_page
.
learner_response
)
class
FileUploadTest
(
OpenAssessmentTest
):
...
...
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