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
16847d85
Commit
16847d85
authored
Apr 04, 2014
by
Greg Price
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add bok-choy tests for inline response pagination
parent
3af90ef2
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
128 additions
and
31 deletions
+128
-31
common/djangoapps/terrain/stubs/comments.py
+12
-0
common/test/acceptance/pages/lms/courseware.py
+16
-0
common/test/acceptance/pages/lms/discussion.py
+100
-31
common/test/acceptance/tests/test_discussion.py
+0
-0
No files found.
common/djangoapps/terrain/stubs/comments.py
View file @
16847d85
...
@@ -14,6 +14,7 @@ class StubCommentsServiceHandler(StubHttpRequestHandler):
...
@@ -14,6 +14,7 @@ class StubCommentsServiceHandler(StubHttpRequestHandler):
"/api/v1/threads$"
:
self
.
do_threads
,
"/api/v1/threads$"
:
self
.
do_threads
,
"/api/v1/threads/(?P<thread_id>
\\
w+)$"
:
self
.
do_thread
,
"/api/v1/threads/(?P<thread_id>
\\
w+)$"
:
self
.
do_thread
,
"/api/v1/comments/(?P<comment_id>
\\
w+)$"
:
self
.
do_comment
,
"/api/v1/comments/(?P<comment_id>
\\
w+)$"
:
self
.
do_comment
,
"/api/v1/(?P<commentable_id>
\\
w+)/threads$"
:
self
.
do_commentable
,
}
}
path
=
urlparse
.
urlparse
(
self
.
path
)
.
path
path
=
urlparse
.
urlparse
(
self
.
path
)
.
path
for
pattern
in
pattern_handlers
:
for
pattern
in
pattern_handlers
:
...
@@ -63,6 +64,17 @@ class StubCommentsServiceHandler(StubHttpRequestHandler):
...
@@ -63,6 +64,17 @@ class StubCommentsServiceHandler(StubHttpRequestHandler):
comment
=
self
.
server
.
config
[
'comments'
][
comment_id
]
comment
=
self
.
server
.
config
[
'comments'
][
comment_id
]
self
.
send_json_response
(
comment
)
self
.
send_json_response
(
comment
)
def
do_commentable
(
self
,
commentable_id
):
self
.
send_json_response
({
"collection"
:
[
thread
for
thread
in
self
.
server
.
config
.
get
(
'threads'
,
{})
.
values
()
if
thread
.
get
(
'commentable_id'
)
==
commentable_id
],
"page"
:
1
,
"num_pages"
:
1
,
})
class
StubCommentsService
(
StubHttpService
):
class
StubCommentsService
(
StubHttpService
):
HANDLER_CLASS
=
StubCommentsServiceHandler
HANDLER_CLASS
=
StubCommentsServiceHandler
common/test/acceptance/pages/lms/courseware.py
0 → 100644
View file @
16847d85
"""
Courseware page.
"""
from
.course_page
import
CoursePage
class
CoursewarePage
(
CoursePage
):
"""
Course info.
"""
url_path
=
"courseware"
def
is_browser_on_page
(
self
):
return
self
.
q
(
css
=
'body.courseware'
)
.
present
common/test/acceptance/pages/lms/discussion
_single_thread
.py
→
common/test/acceptance/pages/lms/discussion.py
View file @
16847d85
from
bok_choy.page_object
import
unguarded
from
bok_choy.page_object
import
PageObject
from
bok_choy.promise
import
EmptyPromise
from
bok_choy.promise
import
EmptyPromise
from
.course_page
import
CoursePage
from
.course_page
import
CoursePage
class
DiscussionSingleThreadPage
(
CoursePage
):
class
DiscussionThreadPage
(
PageObject
):
def
__init__
(
self
,
browser
,
course_id
,
thread_id
):
url
=
None
super
(
DiscussionSingleThreadPage
,
self
)
.
__init__
(
browser
,
course_id
)
self
.
thread_id
=
thread_id
def
is_browser_on_page
(
self
):
def
__init__
(
self
,
browser
,
thread_selector
):
return
self
.
q
(
super
(
DiscussionThreadPage
,
self
)
.
__init__
(
browser
)
css
=
"body.discussion .discussion-article[data-id='{thread_id}']"
.
format
(
thread_id
=
self
.
thread_id
)
self
.
thread_selector
=
thread_selector
)
.
present
def
_find_within
(
self
,
selector
):
"""
Returns a query corresponding to the given CSS selector within the scope
of this thread page
"""
return
self
.
q
(
css
=
self
.
thread_selector
+
" "
+
selector
)
@property
def
is_browser_on_page
(
self
):
@unguarded
return
self
.
q
(
css
=
self
.
thread_selector
)
.
present
def
url_path
(
self
):
return
"discussion/forum/dummy/threads/"
+
self
.
thread_id
def
_get_element_text
(
self
,
selector
):
def
_get_element_text
(
self
,
selector
):
"""
"""
Returns the text of the first element matching the given selector, or
Returns the text of the first element matching the given selector, or
None if no such element exists
None if no such element exists
"""
"""
text_list
=
self
.
q
(
css
=
selector
)
.
text
text_list
=
self
.
_find_within
(
selector
)
.
text
return
text_list
[
0
]
if
text_list
else
None
return
text_list
[
0
]
if
text_list
else
None
def
_is_element_visible
(
self
,
selector
):
query
=
self
.
_find_within
(
selector
)
return
query
.
present
and
query
.
visible
def
get_response_total_text
(
self
):
def
get_response_total_text
(
self
):
"""Returns the response count text, or None if not present"""
"""Returns the response count text, or None if not present"""
return
self
.
_get_element_text
(
".response-count"
)
return
self
.
_get_element_text
(
".response-count"
)
def
get_num_displayed_responses
(
self
):
def
get_num_displayed_responses
(
self
):
"""Returns the number of responses actually rendered"""
"""Returns the number of responses actually rendered"""
return
len
(
self
.
q
(
css
=
".discussion-response"
)
.
results
)
return
len
(
self
.
_find_within
(
".discussion-response"
)
)
def
get_shown_responses_text
(
self
):
def
get_shown_responses_text
(
self
):
"""Returns the shown response count text, or None if not present"""
"""Returns the shown response count text, or None if not present"""
...
@@ -45,7 +51,7 @@ class DiscussionSingleThreadPage(CoursePage):
...
@@ -45,7 +51,7 @@ class DiscussionSingleThreadPage(CoursePage):
def
load_more_responses
(
self
):
def
load_more_responses
(
self
):
"""Clicks the load more responses button and waits for responses to load"""
"""Clicks the load more responses button and waits for responses to load"""
self
.
q
(
css
=
".load-response-button"
)
.
first
.
click
()
self
.
_find_within
(
".load-response-button"
)
.
click
()
def
_is_ajax_finished
():
def
_is_ajax_finished
():
return
self
.
browser
.
execute_script
(
"return jQuery.active"
)
==
0
return
self
.
browser
.
execute_script
(
"return jQuery.active"
)
==
0
...
@@ -64,25 +70,19 @@ class DiscussionSingleThreadPage(CoursePage):
...
@@ -64,25 +70,19 @@ class DiscussionSingleThreadPage(CoursePage):
Clicks the add response button and ensures that the response text
Clicks the add response button and ensures that the response text
field receives focus
field receives focus
"""
"""
self
.
q
(
css
=
".add-response-btn"
)
.
first
.
click
()
self
.
_find_within
(
".add-response-btn"
)
.
first
.
click
()
EmptyPromise
(
EmptyPromise
(
lambda
:
self
.
q
(
css
=
"#wmd-input-reply-body-{thread_id}:focus"
.
format
(
thread_id
=
self
.
thread_id
))
,
lambda
:
self
.
_find_within
(
".discussion-reply-new textarea:focus"
)
.
present
,
"Response field received focus"
"Response field received focus"
)
.
fulfill
()
)
.
fulfill
()
def
_is_element_visible
(
self
,
selector
):
return
(
self
.
q
(
css
=
selector
)
.
present
and
self
.
q
(
css
=
selector
)
.
visible
)
def
is_response_editor_visible
(
self
,
response_id
):
def
is_response_editor_visible
(
self
,
response_id
):
"""Returns true if the response editor is present, false otherwise"""
"""Returns true if the response editor is present, false otherwise"""
return
self
.
_is_element_visible
(
".response_{} .edit-post-body"
.
format
(
response_id
))
return
self
.
_is_element_visible
(
".response_{} .edit-post-body"
.
format
(
response_id
))
def
start_response_edit
(
self
,
response_id
):
def
start_response_edit
(
self
,
response_id
):
"""Click the edit button for the response, loading the editing view"""
"""Click the edit button for the response, loading the editing view"""
self
.
q
(
css
=
".response_{} .discussion-response .action-edit"
.
format
(
response_id
))
.
first
.
click
()
self
.
_find_within
(
".response_{} .discussion-response .action-edit"
.
format
(
response_id
))
.
first
.
click
()
EmptyPromise
(
EmptyPromise
(
lambda
:
self
.
is_response_editor_visible
(
response_id
),
lambda
:
self
.
is_response_editor_visible
(
response_id
),
"Response edit started"
"Response edit started"
...
@@ -105,7 +105,7 @@ class DiscussionSingleThreadPage(CoursePage):
...
@@ -105,7 +105,7 @@ class DiscussionSingleThreadPage(CoursePage):
def
delete_comment
(
self
,
comment_id
):
def
delete_comment
(
self
,
comment_id
):
with
self
.
handle_alert
():
with
self
.
handle_alert
():
self
.
q
(
css
=
"#comment_{} div.action-delete"
.
format
(
comment_id
))
.
first
.
click
()
self
.
_find_within
(
"#comment_{} div.action-delete"
.
format
(
comment_id
))
.
first
.
click
()
EmptyPromise
(
EmptyPromise
(
lambda
:
not
self
.
is_comment_visible
(
comment_id
),
lambda
:
not
self
.
is_comment_visible
(
comment_id
),
"Deleted comment was removed"
"Deleted comment was removed"
...
@@ -120,12 +120,12 @@ class DiscussionSingleThreadPage(CoursePage):
...
@@ -120,12 +120,12 @@ class DiscussionSingleThreadPage(CoursePage):
return
self
.
_is_element_visible
(
".edit-comment-body[data-id='{}']"
.
format
(
comment_id
))
return
self
.
_is_element_visible
(
".edit-comment-body[data-id='{}']"
.
format
(
comment_id
))
def
_get_comment_editor_value
(
self
,
comment_id
):
def
_get_comment_editor_value
(
self
,
comment_id
):
return
self
.
q
(
css
=
"#wmd-input-edit-comment-body-{}"
.
format
(
comment_id
))
.
text
[
0
]
return
self
.
_find_within
(
"#wmd-input-edit-comment-body-{}"
.
format
(
comment_id
))
.
text
[
0
]
def
start_comment_edit
(
self
,
comment_id
):
def
start_comment_edit
(
self
,
comment_id
):
"""Click the edit button for the comment, loading the editing view"""
"""Click the edit button for the comment, loading the editing view"""
old_body
=
self
.
get_comment_body
(
comment_id
)
old_body
=
self
.
get_comment_body
(
comment_id
)
self
.
q
(
css
=
"#comment_{} .action-edit"
.
format
(
comment_id
))
.
first
.
click
()
self
.
_find_within
(
"#comment_{} .action-edit"
.
format
(
comment_id
))
.
first
.
click
()
EmptyPromise
(
EmptyPromise
(
lambda
:
(
lambda
:
(
self
.
is_comment_editor_visible
(
comment_id
)
and
self
.
is_comment_editor_visible
(
comment_id
)
and
...
@@ -137,11 +137,11 @@ class DiscussionSingleThreadPage(CoursePage):
...
@@ -137,11 +137,11 @@ class DiscussionSingleThreadPage(CoursePage):
def
set_comment_editor_value
(
self
,
comment_id
,
new_body
):
def
set_comment_editor_value
(
self
,
comment_id
,
new_body
):
"""Replace the contents of the comment editor"""
"""Replace the contents of the comment editor"""
self
.
q
(
css
=
"#comment_{} .wmd-input"
.
format
(
comment_id
))
.
fill
(
new_body
)
self
.
_find_within
(
"#comment_{} .wmd-input"
.
format
(
comment_id
))
.
fill
(
new_body
)
def
submit_comment_edit
(
self
,
comment_id
,
new_comment_body
):
def
submit_comment_edit
(
self
,
comment_id
,
new_comment_body
):
"""Click the submit button on the comment editor"""
"""Click the submit button on the comment editor"""
self
.
q
(
css
=
"#comment_{} .post-update"
.
format
(
comment_id
))
.
first
.
click
()
self
.
_find_within
(
"#comment_{} .post-update"
.
format
(
comment_id
))
.
first
.
click
()
EmptyPromise
(
EmptyPromise
(
lambda
:
(
lambda
:
(
not
self
.
is_comment_editor_visible
(
comment_id
)
and
not
self
.
is_comment_editor_visible
(
comment_id
)
and
...
@@ -153,7 +153,7 @@ class DiscussionSingleThreadPage(CoursePage):
...
@@ -153,7 +153,7 @@ class DiscussionSingleThreadPage(CoursePage):
def
cancel_comment_edit
(
self
,
comment_id
,
original_body
):
def
cancel_comment_edit
(
self
,
comment_id
,
original_body
):
"""Click the cancel button on the comment editor"""
"""Click the cancel button on the comment editor"""
self
.
q
(
css
=
"#comment_{} .post-cancel"
.
format
(
comment_id
))
.
first
.
click
()
self
.
_find_within
(
"#comment_{} .post-cancel"
.
format
(
comment_id
))
.
first
.
click
()
EmptyPromise
(
EmptyPromise
(
lambda
:
(
lambda
:
(
not
self
.
is_comment_editor_visible
(
comment_id
)
and
not
self
.
is_comment_editor_visible
(
comment_id
)
and
...
@@ -162,3 +162,72 @@ class DiscussionSingleThreadPage(CoursePage):
...
@@ -162,3 +162,72 @@ class DiscussionSingleThreadPage(CoursePage):
),
),
"Comment edit was canceled"
"Comment edit was canceled"
)
.
fulfill
()
)
.
fulfill
()
class
DiscussionTabSingleThreadPage
(
CoursePage
):
def
__init__
(
self
,
browser
,
course_id
,
thread_id
):
super
(
DiscussionTabSingleThreadPage
,
self
)
.
__init__
(
browser
,
course_id
)
self
.
thread_page
=
DiscussionThreadPage
(
browser
,
"body.discussion .discussion-article[data-id='{thread_id}']"
.
format
(
thread_id
=
thread_id
)
)
self
.
url_path
=
"discussion/forum/dummy/threads/"
+
thread_id
def
is_browser_on_page
(
self
):
return
self
.
thread_page
.
is_browser_on_page
()
def
__getattr__
(
self
,
name
):
return
getattr
(
self
.
thread_page
,
name
)
class
InlineDiscussionPage
(
PageObject
):
url
=
None
def
__init__
(
self
,
browser
,
discussion_id
):
super
(
InlineDiscussionPage
,
self
)
.
__init__
(
browser
)
self
.
_discussion_selector
=
(
"body.courseware .discussion-module[data-discussion-id='{discussion_id}'] "
.
format
(
discussion_id
=
discussion_id
)
)
def
_find_within
(
self
,
selector
):
"""
Returns a query corresponding to the given CSS selector within the scope
of this discussion page
"""
return
self
.
q
(
css
=
self
.
_discussion_selector
+
" "
+
selector
)
def
is_browser_on_page
(
self
):
return
self
.
q
(
css
=
self
.
_discussion_selector
)
.
present
def
is_discussion_expanded
(
self
):
return
self
.
_find_within
(
".discussion"
)
.
present
def
expand_discussion
(
self
):
"""Click the link to expand the discussion"""
self
.
_find_within
(
".discussion-show"
)
.
first
.
click
()
EmptyPromise
(
self
.
is_discussion_expanded
,
"Discussion expanded"
)
.
fulfill
()
def
get_num_displayed_threads
(
self
):
return
len
(
self
.
_find_within
(
".discussion-thread"
))
class
InlineDiscussionThreadPage
(
DiscussionThreadPage
):
def
__init__
(
self
,
browser
,
thread_id
):
super
(
InlineDiscussionThreadPage
,
self
)
.
__init__
(
browser
,
"body.courseware .discussion-module #thread_{thread_id}"
.
format
(
thread_id
=
thread_id
)
)
def
expand
(
self
):
"""Clicks the link to expand the thread"""
self
.
_find_within
(
".expand-post"
)
.
first
.
click
()
EmptyPromise
(
lambda
:
bool
(
self
.
get_response_total_text
()),
"Thread expanded"
)
.
fulfill
()
common/test/acceptance/tests/test_discussion.py
View file @
16847d85
This diff is collapsed.
Click to expand it.
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