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
721b926e
Commit
721b926e
authored
Sep 26, 2014
by
Waheed Ahmed
Committed by
Zia Fazal
Apr 06, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Converted annotation lettuce test into bok-choy test.
TNL-353
parent
1aa50ee7
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 @
721b926e
"""
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 @
721b926e
# -*- 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 @
721b926e
...
@@ -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 @
721b926e
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