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):
"/api/v1/threads$"
:
self
.
do_threads
,
"/api/v1/threads/(?P<thread_id>
\\
w+)$"
:
self
.
do_thread
,
"/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
for
pattern
in
pattern_handlers
:
...
...
@@ -63,6 +64,17 @@ class StubCommentsServiceHandler(StubHttpRequestHandler):
comment
=
self
.
server
.
config
[
'comments'
][
comment_id
]
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
):
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
.course_page
import
CoursePage
class
DiscussionSingleThreadPage
(
CoursePage
):
def
__init__
(
self
,
browser
,
course_id
,
thread_id
):
super
(
DiscussionSingleThreadPage
,
self
)
.
__init__
(
browser
,
course_id
)
self
.
thread_id
=
thread_id
class
DiscussionThreadPage
(
PageObject
):
url
=
None
def
is_browser_on_page
(
self
):
return
self
.
q
(
css
=
"body.discussion .discussion-article[data-id='{thread_id}']"
.
format
(
thread_id
=
self
.
thread_id
)
)
.
present
def
__init__
(
self
,
browser
,
thread_selector
):
super
(
DiscussionThreadPage
,
self
)
.
__init__
(
browser
)
self
.
thread_selector
=
thread_selector
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
@unguarded
def
url_path
(
self
):
return
"discussion/forum/dummy/threads/"
+
self
.
thread_id
def
is_browser_on_page
(
self
):
return
self
.
q
(
css
=
self
.
thread_selector
)
.
present
def
_get_element_text
(
self
,
selector
):
"""
Returns the text of the first element matching the given selector, or
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
def
_is_element_visible
(
self
,
selector
):
query
=
self
.
_find_within
(
selector
)
return
query
.
present
and
query
.
visible
def
get_response_total_text
(
self
):
"""Returns the response count text, or None if not present"""
return
self
.
_get_element_text
(
".response-count"
)
def
get_num_displayed_responses
(
self
):
"""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
):
"""Returns the shown response count text, or None if not present"""
...
...
@@ -45,7 +51,7 @@ class DiscussionSingleThreadPage(CoursePage):
def
load_more_responses
(
self
):
"""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
():
return
self
.
browser
.
execute_script
(
"return jQuery.active"
)
==
0
...
...
@@ -64,25 +70,19 @@ class DiscussionSingleThreadPage(CoursePage):
Clicks the add response button and ensures that the response text
field receives focus
"""
self
.
q
(
css
=
".add-response-btn"
)
.
first
.
click
()
self
.
_find_within
(
".add-response-btn"
)
.
first
.
click
()
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"
)
.
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
):
"""Returns true if the response editor is present, false otherwise"""
return
self
.
_is_element_visible
(
".response_{} .edit-post-body"
.
format
(
response_id
))
def
start_response_edit
(
self
,
response_id
):
"""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
(
lambda
:
self
.
is_response_editor_visible
(
response_id
),
"Response edit started"
...
...
@@ -105,7 +105,7 @@ class DiscussionSingleThreadPage(CoursePage):
def
delete_comment
(
self
,
comment_id
):
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
(
lambda
:
not
self
.
is_comment_visible
(
comment_id
),
"Deleted comment was removed"
...
...
@@ -120,12 +120,12 @@ class DiscussionSingleThreadPage(CoursePage):
return
self
.
_is_element_visible
(
".edit-comment-body[data-id='{}']"
.
format
(
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
):
"""Click the edit button for the comment, loading the editing view"""
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
(
lambda
:
(
self
.
is_comment_editor_visible
(
comment_id
)
and
...
...
@@ -137,11 +137,11 @@ class DiscussionSingleThreadPage(CoursePage):
def
set_comment_editor_value
(
self
,
comment_id
,
new_body
):
"""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
):
"""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
(
lambda
:
(
not
self
.
is_comment_editor_visible
(
comment_id
)
and
...
...
@@ -153,7 +153,7 @@ class DiscussionSingleThreadPage(CoursePage):
def
cancel_comment_edit
(
self
,
comment_id
,
original_body
):
"""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
(
lambda
:
(
not
self
.
is_comment_editor_visible
(
comment_id
)
and
...
...
@@ -162,3 +162,72 @@ class DiscussionSingleThreadPage(CoursePage):
),
"Comment edit was canceled"
)
.
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