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
29aa9331
Commit
29aa9331
authored
Sep 26, 2014
by
Waheed Ahmed
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Converted annotation lettuce test into bok-choy test.
TNL-353
parent
c57f1c81
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
231 additions
and
88 deletions
+231
-88
common/test/acceptance/pages/lms/annotation_component.py
+91
-0
common/test/acceptance/tests/test_annotatable.py
+139
-0
lms/djangoapps/courseware/features/annotatable.feature
+0
-19
lms/djangoapps/courseware/features/annotatable.py
+1
-69
No files found.
common/test/acceptance/pages/lms/annotation_component.py
0 → 100644
View file @
29aa9331
"""
Annotation Component Page.
"""
from
bok_choy.page_object
import
PageObject
from
selenium.webdriver
import
ActionChains
class
AnnotationComponentPage
(
PageObject
):
"""
View of annotation component page.
"""
url
=
None
active_problem
=
0
def
is_browser_on_page
(
self
):
return
self
.
q
(
css
=
'.annotatable-title'
)
.
present
@property
def
component_name
(
self
):
"""
Return the current problem name.
"""
return
self
.
q
(
css
=
'.annotatable-title'
)
.
text
[
0
]
def
click_reply_annotation
(
self
,
problem
):
"""
Mouse over on annotation selector and click on "Reply to Annotation".
"""
annotation_span_selector
=
'.annotatable-span[data-problem-id="{}"]'
.
format
(
problem
)
self
.
mouse_hover
(
self
.
browser
.
find_element_by_css_selector
(
annotation_span_selector
))
self
.
wait_for_element_visibility
(
annotation_span_selector
,
"Reply to Annotation link is visible"
)
annotation_reply_selector
=
'.annotatable-reply[data-problem-id="{}"]'
.
format
(
problem
)
self
.
q
(
css
=
annotation_reply_selector
)
.
click
()
self
.
active_problem
=
problem
def
active_problem_selector
(
self
,
sub_selector
):
"""
Return css selector for current active problem with sub_selector.
"""
return
'div[data-problem-id="{}"] {}'
.
format
(
self
.
q
(
css
=
'.vert-{}'
.
format
(
self
.
active_problem
+
1
))
.
map
(
lambda
el
:
el
.
get_attribute
(
'data-id'
))
.
results
[
0
],
sub_selector
,
)
def
mouse_hover
(
self
,
element
):
"""
Mouse over on given element.
"""
mouse_hover_action
=
ActionChains
(
self
.
browser
)
.
move_to_element
(
element
)
mouse_hover_action
.
perform
()
def
check_scroll_to_problem
(
self
):
"""
Return visibility of active problem's input selector.
"""
annotation_input_selector
=
self
.
active_problem_selector
(
'.annotation-input'
)
return
self
.
q
(
css
=
annotation_input_selector
)
.
visible
def
answer_problem
(
self
):
"""
Submit correct answer for active problem.
"""
self
.
q
(
css
=
self
.
active_problem_selector
(
'.comment'
))
.
fill
(
'Test Response'
)
self
.
q
(
css
=
self
.
active_problem_selector
(
'.tag[data-id="{}"]'
.
format
(
self
.
active_problem
)))
.
click
()
self
.
q
(
css
=
self
.
active_problem_selector
(
'.check'
))
.
click
()
def
check_feedback
(
self
):
"""
Return visibility of active problem's feedback.
"""
self
.
wait_for_element_visibility
(
self
.
active_problem_selector
(
'.tag-status.correct'
),
"Correct is visible"
)
return
self
.
q
(
css
=
self
.
active_problem_selector
(
'.tag-status.correct'
))
.
visible
def
click_return_to_annotation
(
self
):
"""
Click on active problem's "Return to Annotation" link.
"""
self
.
q
(
css
=
self
.
active_problem_selector
(
'.annotation-return'
))
.
click
()
def
check_scroll_to_annotation
(
self
):
"""
Return visibility of active annotation component header.
"""
annotation_header_selector
=
'.annotation-header'
return
self
.
q
(
css
=
annotation_header_selector
)
.
visible
common/test/acceptance/tests/test_annotatable.py
0 → 100644
View file @
29aa9331
# -*- coding: utf-8 -*-
"""
E2E tests for the LMS.
"""
import
time
from
.helpers
import
UniqueCourseTest
from
..pages.studio.auto_auth
import
AutoAuthPage
from
..pages.lms.courseware
import
CoursewarePage
from
..pages.lms.annotation_component
import
AnnotationComponentPage
from
..fixtures.course
import
CourseFixture
,
XBlockFixtureDesc
from
..fixtures.xqueue
import
XQueueResponseFixture
from
textwrap
import
dedent
def
_correctness
(
choice
,
target
):
if
choice
==
target
:
return
"correct"
elif
abs
(
choice
-
target
)
==
1
:
return
"partially-correct"
else
:
return
"incorrect"
class
AnnotatableProblemTest
(
UniqueCourseTest
):
"""
Tests for annotation components.
"""
USERNAME
=
"STAFF_TESTER"
EMAIL
=
"johndoe@example.com"
DATA_TEMPLATE
=
dedent
(
"""
\
<annotatable>
<instructions>Instruction text</instructions>
<p>{}</p>
</annotatable>
"""
)
ANNOTATION_TEMPLATE
=
dedent
(
"""
\
Before {0}.
<annotation title="region {0}" body="Comment {0}" highlight="yellow" problem="{0}">
Region Contents {0}
</annotation>
After {0}.
"""
)
PROBLEM_TEMPLATE
=
dedent
(
"""
\
<problem max_attempts="1" weight="">
<annotationresponse>
<annotationinput>
<title>Question {number}</title>
<text>Region Contents {number}</text>
<comment>What number is this region?</comment>
<comment_prompt>Type your response below:</comment_prompt>
<tag_prompt>What number is this region?</tag_prompt>
<options>
{options}
</options>
</annotationinput>
</annotationresponse>
<solution>
This problem is checking region {number}
</solution>
</problem>
"""
)
OPTION_TEMPLATE
=
"""<option choice="{correctness}">{number}</option>"""
def
setUp
(
self
):
super
(
AnnotatableProblemTest
,
self
)
.
setUp
()
self
.
courseware_page
=
CoursewarePage
(
self
.
browser
,
self
.
course_id
)
# Install a course with two annotations and two annotations problems.
course_fix
=
CourseFixture
(
self
.
course_info
[
'org'
],
self
.
course_info
[
'number'
],
self
.
course_info
[
'run'
],
self
.
course_info
[
'display_name'
]
)
self
.
annotation_count
=
2
course_fix
.
add_children
(
XBlockFixtureDesc
(
'chapter'
,
'Test Section'
)
.
add_children
(
XBlockFixtureDesc
(
'sequential'
,
'Test Subsection'
)
.
add_children
(
XBlockFixtureDesc
(
'vertical'
,
'Test Annotation Vertical'
)
.
add_children
(
XBlockFixtureDesc
(
'annotatable'
,
'Test Annotation Module'
,
data
=
self
.
DATA_TEMPLATE
.
format
(
"
\n
"
.
join
(
self
.
ANNOTATION_TEMPLATE
.
format
(
i
)
for
i
in
xrange
(
self
.
annotation_count
)
))),
XBlockFixtureDesc
(
'problem'
,
'Test Annotation Problem 0'
,
data
=
self
.
PROBLEM_TEMPLATE
.
format
(
number
=
0
,
options
=
"
\n
"
.
join
(
self
.
OPTION_TEMPLATE
.
format
(
number
=
k
,
correctness
=
_correctness
(
k
,
0
))
for
k
in
xrange
(
self
.
annotation_count
)
))),
XBlockFixtureDesc
(
'problem'
,
'Test Annotation Problem 1'
,
data
=
self
.
PROBLEM_TEMPLATE
.
format
(
number
=
1
,
options
=
"
\n
"
.
join
(
self
.
OPTION_TEMPLATE
.
format
(
number
=
k
,
correctness
=
_correctness
(
k
,
1
))
for
k
in
xrange
(
self
.
annotation_count
)
)))
)
)
)
)
.
install
()
# Auto-auth register for the course.
AutoAuthPage
(
self
.
browser
,
username
=
self
.
USERNAME
,
email
=
self
.
EMAIL
,
course_id
=
self
.
course_id
,
staff
=
False
)
.
visit
()
def
_goto_annotation_component_page
(
self
):
"""
Open annotation component page with assertion.
"""
self
.
courseware_page
.
visit
()
annotation_component_page
=
AnnotationComponentPage
(
self
.
browser
)
self
.
assertEqual
(
annotation_component_page
.
component_name
,
'TEST ANNOTATION MODULE'
.
format
()
)
return
annotation_component_page
def
test_annotation_component
(
self
):
"""
Test annotation components links to annotation problems.
"""
annotation_component_page
=
self
.
_goto_annotation_component_page
()
for
i
in
xrange
(
self
.
annotation_count
):
annotation_component_page
.
click_reply_annotation
(
i
)
self
.
assertTrue
(
annotation_component_page
.
check_scroll_to_problem
())
annotation_component_page
.
answer_problem
()
self
.
assertTrue
(
annotation_component_page
.
check_feedback
())
annotation_component_page
.
click_return_to_annotation
()
self
.
assertTrue
(
annotation_component_page
.
check_scroll_to_annotation
())
lms/djangoapps/courseware/features/annotatable.feature
View file @
29aa9331
...
@@ -7,22 +7,3 @@ Feature: LMS.Annotatable Component
...
@@ -7,22 +7,3 @@ Feature: LMS.Annotatable Component
When
I view the annotatable component
When
I view the annotatable component
Then
the annotatable component has rendered
Then
the annotatable component has rendered
And
the annotatable component has 2 highlighted passages
And
the annotatable component has 2 highlighted passages
# Disabling due to frequent intermittent failures. TNL-353
# This features's acceptance tests should be rewritten in bok-choy, rather than fixed here.
#
# Scenario: An Annotatable component links to annonation problems in the LMS
# Given that a course has an annotatable component with 2 annotations
# And the course has 2 annotatation problems
# When I view the annotatable component
# And I click "Reply to annotation" on passage <problem>
# Then I am scrolled to that annotation problem
# When I answer that annotation problem
# Then I receive feedback on that annotation problem
# When I click "Return to annotation" on that problem
# Then I am scrolled to the annotatable component
#
# Examples:
# | problem |
# | 0 |
# | 1 |
lms/djangoapps/courseware/features/annotatable.py
View file @
29aa9331
import
textwrap
import
textwrap
from
lettuce
import
world
,
steps
from
lettuce
import
world
,
steps
from
nose.tools
import
assert_in
,
assert_equals
,
assert_true
from
nose.tools
import
assert_in
,
assert_equals
from
common
import
i_am_registered_for_the_course
,
visit_scenario_item
from
common
import
i_am_registered_for_the_course
,
visit_scenario_item
...
@@ -100,74 +100,6 @@ class AnnotatableSteps(object):
...
@@ -100,74 +100,6 @@ class AnnotatableSteps(object):
assert_equals
(
len
(
world
.
css_find
(
'.annotatable-span.highlight'
)),
count
)
assert_equals
(
len
(
world
.
css_find
(
'.annotatable-span.highlight'
)),
count
)
assert_equals
(
len
(
world
.
css_find
(
'.annotatable-span.highlight-yellow'
)),
count
)
assert_equals
(
len
(
world
.
css_find
(
'.annotatable-span.highlight-yellow'
)),
count
)
def
add_problems
(
self
,
step
,
count
):
r"""the course has (?P<count>\d+) annotatation problems$"""
count
=
int
(
count
)
for
i
in
xrange
(
count
):
world
.
scenario_dict
.
setdefault
(
'PROBLEMS'
,
[])
.
append
(
world
.
ItemFactory
(
parent_location
=
world
.
scenario_dict
[
'ANNOTATION_VERTICAL'
]
.
location
,
category
=
'problem'
,
display_name
=
"Test Annotation Problem {}"
.
format
(
i
),
data
=
PROBLEM_TEMPLATE
.
format
(
number
=
i
,
options
=
"
\n
"
.
join
(
OPTION_TEMPLATE
.
format
(
number
=
k
,
correctness
=
_correctness
(
k
,
i
)
)
for
k
in
xrange
(
count
)
)
)
)
)
def
click_reply
(
self
,
step
,
problem
):
r"""I click "Reply to annotation" on passage (?P<problem>\d+)$"""
problem
=
int
(
problem
)
annotation_span_selector
=
'.annotatable-span[data-problem-id="{}"]'
.
format
(
problem
)
world
.
css_find
(
annotation_span_selector
)
.
first
.
mouse_over
()
annotation_reply_selector
=
'.annotatable-reply[data-problem-id="{}"]'
.
format
(
problem
)
assert_equals
(
len
(
world
.
css_find
(
annotation_reply_selector
)),
1
)
world
.
css_click
(
annotation_reply_selector
)
self
.
active_problem
=
problem
def
active_problem_selector
(
self
,
subselector
):
return
'div[data-problem-id="{}"] {}'
.
format
(
world
.
scenario_dict
[
'PROBLEMS'
][
self
.
active_problem
]
.
location
.
to_deprecated_string
(),
subselector
,
)
def
check_scroll_to_problem
(
self
,
step
):
r"""I am scrolled to that annotation problem$"""
annotation_input_selector
=
self
.
active_problem_selector
(
'.annotation-input'
)
assert_true
(
world
.
css_visible
(
annotation_input_selector
))
def
answer_problem
(
self
,
step
):
r"""I answer that annotation problem$"""
world
.
css_fill
(
self
.
active_problem_selector
(
'.comment'
),
'Test Response'
)
world
.
css_click
(
self
.
active_problem_selector
(
'.tag[data-id="{}"]'
.
format
(
self
.
active_problem
)))
world
.
css_click
(
self
.
active_problem_selector
(
'.check'
))
def
check_feedback
(
self
,
step
):
r"""I receive feedback on that annotation problem$"""
world
.
wait_for_visible
(
self
.
active_problem_selector
(
'.tag-status.correct'
))
assert_equals
(
len
(
world
.
css_find
(
self
.
active_problem_selector
(
'.tag-status.correct'
))),
1
)
assert_equals
(
len
(
world
.
css_find
(
self
.
active_problem_selector
(
'.show'
))),
1
)
def
click_return_to
(
self
,
step
):
r"""I click "Return to annotation" on that problem$"""
world
.
css_click
(
self
.
active_problem_selector
(
'.annotation-return'
))
def
check_scroll_to_annotatable
(
self
,
step
):
r"""I am scrolled to the annotatable component$"""
assert_true
(
world
.
css_visible
(
'.annotation-header'
))
# This line is required by @steps in order to actually bind the step
# This line is required by @steps in order to actually bind the step
# regexes
# regexes
AnnotatableSteps
()
AnnotatableSteps
()
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