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
95af1843
Commit
95af1843
authored
Nov 23, 2016
by
Andy Armstrong
Committed by
Brian Jacobel
Dec 12, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix inline discussion Bok Choy tests
parent
82d05c6e
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
149 additions
and
131 deletions
+149
-131
common/test/acceptance/fixtures/discussion.py
+1
-0
common/test/acceptance/pages/lms/discussion.py
+71
-64
common/test/acceptance/tests/discussion/helpers.py
+16
-0
common/test/acceptance/tests/discussion/test_cohorts.py
+2
-2
common/test/acceptance/tests/discussion/test_discussion.py
+49
-57
common/test/acceptance/tests/lms/test_teams.py
+10
-8
No files found.
common/test/acceptance/fixtures/discussion.py
View file @
95af1843
...
...
@@ -51,6 +51,7 @@ class Thread(ContentFactory):
group_id
=
None
pinned
=
False
read
=
False
context
=
"course"
class
Comment
(
ContentFactory
):
...
...
common/test/acceptance/pages/lms/discussion.py
View file @
95af1843
...
...
@@ -15,6 +15,54 @@ class DiscussionPageMixin(object):
def
is_ajax_finished
(
self
):
return
self
.
browser
.
execute_script
(
"return jQuery.active"
)
==
0
def
find_visible_element
(
self
,
selector
):
"""
Finds a single visible element with the specified selector.
"""
full_selector
=
selector
if
self
.
root_selector
:
full_selector
=
self
.
root_selector
+
" "
+
full_selector
elements
=
self
.
q
(
css
=
full_selector
)
return
next
((
element
for
element
in
elements
if
element
.
is_displayed
()),
None
)
@property
def
new_post_button
(
self
):
"""
Returns the new post button if visible, else it returns None.
"""
return
self
.
find_visible_element
(
".new-post-btn"
)
@property
def
new_post_form
(
self
):
"""
Returns the new post form if visible, else it returns None.
"""
return
self
.
find_visible_element
(
".forum-new-post-form"
)
def
click_new_post_button
(
self
):
"""
Clicks the 'New Post' button.
"""
self
.
wait_for
(
lambda
:
self
.
new_post_button
,
description
=
"Waiting for new post button"
)
self
.
new_post_button
.
click
()
self
.
wait_for
(
lambda
:
self
.
new_post_form
,
description
=
"Waiting for new post form"
)
def
click_cancel_new_post
(
self
):
"""
Clicks the 'Cancel' button from the new post form.
"""
self
.
click_element
(
".cancel"
)
self
.
wait_for
(
lambda
:
not
self
.
new_post_form
,
"Waiting for new post form to close"
)
class
DiscussionThreadPage
(
PageObject
,
DiscussionPageMixin
):
url
=
None
...
...
@@ -470,12 +518,15 @@ class DiscussionTabSingleThreadPage(CoursePage):
return
len
(
self
.
q
(
css
=
".forum-nav-thread"
)
.
results
)
==
thread_count
class
InlineDiscussionPage
(
PageObject
):
class
InlineDiscussionPage
(
PageObject
,
DiscussionPageMixin
):
"""
Acceptance tests for inline discussions.
"""
url
=
None
def
__init__
(
self
,
browser
,
discussion_id
):
super
(
InlineDiscussionPage
,
self
)
.
__init__
(
browser
)
self
.
_discussion
_selector
=
(
self
.
root
_selector
=
(
".discussion-module[data-discussion-id='{discussion_id}'] "
.
format
(
discussion_id
=
discussion_id
)
...
...
@@ -486,11 +537,11 @@ class InlineDiscussionPage(PageObject):
Returns a query corresponding to the given CSS selector within the scope
of this discussion page
"""
return
self
.
q
(
css
=
self
.
_discussion
_selector
+
" "
+
selector
)
return
self
.
q
(
css
=
self
.
root
_selector
+
" "
+
selector
)
def
is_browser_on_page
(
self
):
self
.
wait_for_ajax
()
return
self
.
q
(
css
=
self
.
_discussion
_selector
)
.
present
return
self
.
q
(
css
=
self
.
root
_selector
)
.
present
def
is_discussion_expanded
(
self
):
return
self
.
_find_within
(
".discussion"
)
.
present
...
...
@@ -506,58 +557,41 @@ class InlineDiscussionPage(PageObject):
def
get_num_displayed_threads
(
self
):
return
len
(
self
.
_find_within
(
".forum-nav-thread"
))
def
has_thread
(
self
,
thread_id
):
"""Returns true if this page is showing the thread with the specified id."""
return
self
.
_find_within
(
'.discussion-thread#thread_{}'
.
format
(
thread_id
))
.
present
def
element_exists
(
self
,
selector
):
return
self
.
q
(
css
=
self
.
_discussion_selector
+
" "
+
selector
)
.
present
def
is_new_post_opened
(
self
):
return
self
.
_find_within
(
".new-post-article"
)
.
visible
return
self
.
q
(
css
=
self
.
root_selector
+
" "
+
selector
)
.
present
def
click_element
(
self
,
selector
):
self
.
wait_for_element_presence
(
"{discussion} {selector}"
.
format
(
discussion
=
self
.
_discussion
_selector
,
selector
=
selector
),
"{discussion} {selector}"
.
format
(
discussion
=
self
.
root
_selector
,
selector
=
selector
),
"{selector} is visible"
.
format
(
selector
=
selector
)
)
self
.
_find_within
(
selector
)
.
click
()
def
click_cancel_new_post
(
self
):
self
.
click_element
(
".cancel"
)
EmptyPromise
(
lambda
:
not
self
.
is_new_post_opened
(),
"New post closed"
)
.
fulfill
()
def
click_new_post_button
(
self
):
self
.
click_element
(
".new-post-btn"
)
EmptyPromise
(
self
.
is_new_post_opened
,
"New post opened"
)
.
fulfill
()
@wait_for_js
def
_is_element_visible
(
self
,
selector
):
query
=
self
.
_find_within
(
selector
)
return
query
.
present
and
query
.
visible
def
show_thread
(
self
,
thread_id
):
"""
Clicks the link for the specified thread to show the detailed view.
"""
thread_selector
=
".forum-nav-thread[data-id='{thread_id}'] .forum-nav-thread-link"
.
format
(
thread_id
=
thread_id
)
self
.
_find_within
(
thread_selector
)
.
first
.
click
()
self
.
thread_page
=
InlineDiscussionThreadPage
(
self
.
browser
,
thread_id
)
# pylint: disable=attribute-defined-outside-init
self
.
thread_page
.
wait_for_page
()
class
InlineDiscussionThreadPage
(
DiscussionThreadPage
):
"""
Page object to manipulate an individual thread view in an inline discussion.
"""
def
__init__
(
self
,
browser
,
thread_id
):
super
(
InlineDiscussionThreadPage
,
self
)
.
__init__
(
browser
,
"
body.courseware .discussion-module #thread_{thread_id}
"
.
format
(
thread_id
=
thread_id
)
"
.discussion-module .discussion-article[data-id='{thread_id}']
"
.
format
(
thread_id
=
thread_id
)
)
def
expand
(
self
):
"""Clicks the link to expand the thread"""
self
.
_find_within
(
".forum-thread-expand"
)
.
first
.
click
()
EmptyPromise
(
lambda
:
bool
(
self
.
get_response_total_text
()),
"Thread expanded"
)
.
fulfill
()
def
is_thread_anonymous
(
self
):
return
not
self
.
q
(
css
=
".posted-details > .username"
)
.
present
...
...
@@ -682,6 +716,7 @@ class DiscussionTabHomePage(CoursePage, DiscussionPageMixin):
def
__init__
(
self
,
browser
,
course_id
):
super
(
DiscussionTabHomePage
,
self
)
.
__init__
(
browser
,
course_id
)
self
.
url_path
=
"discussion/forum/"
self
.
root_selector
=
None
def
is_browser_on_page
(
self
):
return
self
.
q
(
css
=
".discussion-body section.home-header"
)
.
present
...
...
@@ -733,18 +768,6 @@ class DiscussionTabHomePage(CoursePage, DiscussionPageMixin):
"waiting for dismissed alerts to disappear"
)
.
fulfill
()
def
click_new_post_button
(
self
):
"""
Clicks the 'New Post' button.
"""
self
.
new_post_button
.
click
()
EmptyPromise
(
lambda
:
(
self
.
new_post_form
),
"New post action succeeded"
)
.
fulfill
()
def
click_element
(
self
,
selector
):
"""
Clicks the element specified by selector
...
...
@@ -752,22 +775,6 @@ class DiscussionTabHomePage(CoursePage, DiscussionPageMixin):
element
=
self
.
q
(
css
=
selector
)
return
element
.
click
()
@property
def
new_post_button
(
self
):
"""
Returns the new post button.
"""
elements
=
self
.
q
(
css
=
".new-post-btn"
)
return
elements
.
first
if
elements
.
visible
and
len
(
elements
)
==
1
else
None
@property
def
new_post_form
(
self
):
"""
Returns the new post form.
"""
elements
=
self
.
q
(
css
=
".forum-new-post-form"
)
return
elements
[
0
]
if
elements
.
visible
and
len
(
elements
)
==
1
else
None
def
set_new_post_editor_value
(
self
,
new_body
):
"""
Set the Discussions new post editor (wmd) with the content in new_body
...
...
common/test/acceptance/tests/discussion/helpers.py
View file @
95af1843
...
...
@@ -37,6 +37,22 @@ class BaseDiscussionMixin(object):
self
.
setup_thread_page
(
thread_id
)
return
thread_id
def
setup_multiple_threads
(
self
,
thread_count
,
**
thread_kwargs
):
"""
Set up multiple threads on the page by passing 'thread_count'.
"""
self
.
thread_ids
=
[]
# pylint: disable=attribute-defined-outside-init
threads
=
[]
# pylint: disable=attribute-defined-outside-init
for
i
in
range
(
thread_count
):
thread_id
=
"test_thread_{}_{}"
.
format
(
i
,
uuid4
()
.
hex
)
thread_body
=
"Dummy long text body."
*
50
threads
.
append
(
Thread
(
id
=
thread_id
,
commentable_id
=
self
.
discussion_id
,
body
=
thread_body
,
**
thread_kwargs
),
)
self
.
thread_ids
.
append
(
thread_id
)
thread_fixture
=
MultipleThreadFixture
(
threads
)
thread_fixture
.
push
()
class
CohortTestMixin
(
object
):
"""
...
...
common/test/acceptance/tests/discussion/test_cohorts.py
View file @
95af1843
...
...
@@ -129,8 +129,8 @@ class InlineDiscussionTest(UniqueCourseTest):
discussion_page
=
InlineDiscussionPage
(
self
.
browser
,
self
.
discussion_id
)
discussion_page
.
expand_discussion
()
self
.
assertEqual
(
discussion_page
.
get_num_displayed_threads
(),
1
)
self
.
thread_page
=
InlineDiscussionThreadPage
(
self
.
browser
,
thread_id
)
# pylint: disable=attribute-defined-outside-init
self
.
thread_page
.
expand
()
discussion_page
.
show_thread
(
thread_id
)
self
.
thread_page
=
discussion_page
.
thread_page
# pylint: disable=attribute-defined-outside-init
def
refresh_thread_page
(
self
,
thread_id
):
self
.
browser
.
refresh
()
...
...
common/test/acceptance/tests/discussion/test_discussion.py
View file @
95af1843
...
...
@@ -1031,41 +1031,8 @@ class InlineDiscussionTest(UniqueCourseTest, DiscussionResponsePaginationTestMix
def
setup_thread_page
(
self
,
thread_id
):
self
.
discussion_page
.
expand_discussion
()
self
.
assertEqual
(
self
.
discussion_page
.
get_num_displayed_threads
(),
1
)
self
.
thread_page
=
InlineDiscussionThreadPage
(
self
.
browser
,
thread_id
)
# pylint: disable=attribute-defined-outside-init
self
.
thread_page
.
expand
()
def
setup_multiple_inline_threads
(
self
,
thread_count
):
"""
Set up multiple treads on the page by passing 'thread_count'
"""
threads
=
[]
for
i
in
range
(
thread_count
):
thread_id
=
"test_thread_{}_{}"
.
format
(
i
,
uuid4
()
.
hex
)
threads
.
append
(
Thread
(
id
=
thread_id
,
commentable_id
=
self
.
discussion_id
),
)
self
.
thread_ids
.
append
(
thread_id
)
thread_fixture
=
MultipleThreadFixture
(
threads
)
thread_fixture
.
add_response
(
Response
(
id
=
"response1"
),
[
Comment
(
id
=
"comment1"
,
user_id
=
"other"
),
Comment
(
id
=
"comment2"
,
user_id
=
self
.
user_id
)],
threads
[
0
]
)
thread_fixture
.
push
()
def
test_page_while_expanding_inline_discussion
(
self
):
"""
Tests for the Inline Discussion page with multiple treads. Page should not focus 'thread-wrapper'
after loading responses.
"""
self
.
setup_multiple_inline_threads
(
thread_count
=
3
)
self
.
discussion_page
.
expand_discussion
()
thread_page
=
InlineDiscussionThreadPage
(
self
.
browser
,
self
.
thread_ids
[
0
])
thread_page
.
expand
()
# Check if 'thread-wrapper' is focused after expanding thread
self
.
assertFalse
(
thread_page
.
check_if_selector_is_focused
(
selector
=
'.thread-wrapper'
))
self
.
discussion_page
.
show_thread
(
thread_id
)
self
.
thread_page
=
self
.
discussion_page
.
thread_page
# pylint: disable=attribute-defined-outside-init
@attr
(
'a11y'
)
def
test_inline_a11y
(
self
):
...
...
@@ -1097,7 +1064,7 @@ class InlineDiscussionTest(UniqueCourseTest, DiscussionResponsePaginationTestMix
thread
=
Thread
(
id
=
uuid4
()
.
hex
,
anonymous_to_peers
=
True
,
commentable_id
=
self
.
discussion_id
)
thread_fixture
=
SingleThreadViewFixture
(
thread
)
thread_fixture
.
push
()
self
.
setup_thread_page
(
thread
.
get
(
"id"
))
self
.
setup_thread_page
(
thread
.
get
(
"id"
))
# pylint: disable=no-member
self
.
assertEqual
(
self
.
thread_page
.
is_thread_anonymous
(),
not
is_staff
)
def
test_anonymous_to_peers_threads_as_staff
(
self
):
...
...
@@ -1130,41 +1097,66 @@ class InlineDiscussionTest(UniqueCourseTest, DiscussionResponsePaginationTestMix
Response
(
id
=
"response1"
),
[
Comment
(
id
=
"comment1"
,
user_id
=
"other"
),
Comment
(
id
=
"comment2"
,
user_id
=
self
.
user_id
)])
thread_fixture
.
push
()
self
.
setup_thread_page
(
thread
.
get
(
"id"
))
self
.
setup_thread_page
(
thread
.
get
(
"id"
))
# pylint: disable=no-member
self
.
assertFalse
(
self
.
thread_page
.
has_add_response_button
())
self
.
assertFalse
(
self
.
thread_page
.
is_element_visible
(
"action-more"
))
def
test_dual_discussion_xblock
(
self
):
"""
Scenario: Two discussion xblocks in one unit shouldn't override their actions
Given that I'm on courseware page where there are two inline discussion
When I click on one discussion xblock new post button
Then it should add new post form of that xblock in DOM
And I should be shown new post form of that xblock
And I shouldn't be shown second discussion xblock new post form
And I click on second discussion xblock new post button
Then it should add new post form of second xblock in DOM
And I should be shown second discussion new post form
And I shouldn't be shown first discussion xblock new post form
And I have two new post form in the DOM
When I click back on first xblock new post button
And I should be shown new post form of that xblock
And I shouldn't be shown second discussion xblock new post form
Given that I'm on a courseware page where there are two inline discussion
When I click on the first discussion block's new post button
Then I should be shown only the new post form for the first block
When I click on the second discussion block's new post button
Then I should be shown both new post forms
When I cancel the first form
Then I should be shown only the new post form for the second block
When I cancel the second form
And I click on the first discussion block's new post button
Then I should be shown only the new post form for the first block
When I cancel the first form
Then I should be shown none of the forms
"""
self
.
discussion_page
.
wait_for_page
()
self
.
additional_discussion_page
.
wait_for_page
()
# Expand the first discussion, click to add a post
self
.
discussion_page
.
expand_discussion
()
self
.
discussion_page
.
click_new_post_button
()
with
self
.
discussion_page
.
handle_alert
():
self
.
discussion_page
.
click_cancel_new_post
()
# Verify that only the first discussion's form is shown
self
.
assertIsNotNone
(
self
.
discussion_page
.
new_post_form
)
self
.
assertIsNone
(
self
.
additional_discussion_page
.
new_post_form
)
# Expand the second discussion, click to add a post
self
.
additional_discussion_page
.
expand_discussion
()
self
.
additional_discussion_page
.
click_new_post_button
()
self
.
assertFalse
(
self
.
discussion_page
.
_is_element_visible
(
".new-post-article"
))
with
self
.
additional_discussion_page
.
handle_alert
():
self
.
additional_discussion_page
.
click_cancel_new_post
()
self
.
discussion_page
.
expand_discussion
()
# Verify that both discussion's forms are shown
self
.
assertIsNotNone
(
self
.
discussion_page
.
new_post_form
)
self
.
assertIsNotNone
(
self
.
additional_discussion_page
.
new_post_form
)
# Cancel the first form
self
.
discussion_page
.
click_cancel_new_post
()
# Verify that only the second discussion's form is shown
self
.
assertIsNone
(
self
.
discussion_page
.
new_post_form
)
self
.
assertIsNotNone
(
self
.
additional_discussion_page
.
new_post_form
)
# Cancel the second form and click to show the first one
self
.
additional_discussion_page
.
click_cancel_new_post
()
self
.
discussion_page
.
click_new_post_button
()
self
.
assertFalse
(
self
.
additional_discussion_page
.
_is_element_visible
(
".new-post-article"
))
# Verify that only the first discussion's form is shown
self
.
assertIsNotNone
(
self
.
discussion_page
.
new_post_form
)
self
.
assertIsNone
(
self
.
additional_discussion_page
.
new_post_form
)
# Cancel the first form
self
.
discussion_page
.
click_cancel_new_post
()
# Verify that neither discussion's forms are shwon
self
.
assertIsNone
(
self
.
discussion_page
.
new_post_form
)
self
.
assertIsNone
(
self
.
additional_discussion_page
.
new_post_form
)
@attr
(
shard
=
2
)
...
...
common/test/acceptance/tests/lms/test_teams.py
View file @
95af1843
...
...
@@ -1689,7 +1689,8 @@ class TeamPageTest(TeamsTabBase):
thread
=
Thread
(
id
=
"test_thread_{}"
.
format
(
uuid4
()
.
hex
),
commentable_id
=
self
.
teams
[
0
][
'discussion_topic_id'
],
body
=
"Dummy text body."
body
=
"Dummy text body."
,
context
=
"standalone"
,
)
thread_fixture
=
MultipleThreadFixture
([
thread
])
thread_fixture
.
push
()
...
...
@@ -1718,14 +1719,15 @@ class TeamPageTest(TeamsTabBase):
thread
=
self
.
setup_thread
()
self
.
team_page
.
visit
()
self
.
assertEqual
(
self
.
team_page
.
discussion_id
,
self
.
teams
[
0
][
'discussion_topic_id'
])
discussion
=
self
.
team_page
.
discussion_page
discussion
.
wait_for_page
()
self
.
assertTrue
(
discussion
.
is_discussion_expanded
())
self
.
assertEqual
(
discussion
.
get_num_displayed_threads
(),
1
)
self
.
assertTrue
(
discussion
.
has_thread
(
thread
[
'id'
]))
discussion_page
=
self
.
team_page
.
discussion_page
discussion_page
.
wait_for_page
()
self
.
assertTrue
(
discussion_page
.
is_discussion_expanded
())
self
.
assertEqual
(
discussion_page
.
get_num_displayed_threads
(),
1
)
discussion_page
.
show_thread
(
thread
[
'id'
])
thread_page
=
discussion_page
.
thread_page
assertion
=
self
.
assertTrue
if
should_have_permission
else
self
.
assertFalse
assertion
(
discussion
.
q
(
css
=
'.post-header-actions'
)
.
present
)
assertion
(
discussion
.
q
(
css
=
'.add-response'
)
.
present
)
assertion
(
thread_page
.
q
(
css
=
'.post-header-actions'
)
.
present
)
assertion
(
thread_page
.
q
(
css
=
'.add-response'
)
.
present
)
def
test_discussion_on_my_team_page
(
self
):
"""
...
...
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