From 6e6aa036e7edae9bb0f033a3e73302d8f9c8670e Mon Sep 17 00:00:00 2001 From: Awais Jibran Date: Fri, 24 Apr 2015 22:44:15 +0500 Subject: [PATCH] Switching between discussion threads take focus to bottom of the page. TNL-1530 --- common/djangoapps/terrain/stubs/comments.py | 4 +- .../views/discussion_thread_view.coffee | 2 +- common/test/acceptance/fixtures/discussion.py | 10 ++++ .../test/acceptance/pages/lms/discussion.py | 36 ++++++++++++ .../tests/discussion/test_discussion.py | 57 ++++++++++++++++++- 5 files changed, 106 insertions(+), 3 deletions(-) diff --git a/common/djangoapps/terrain/stubs/comments.py b/common/djangoapps/terrain/stubs/comments.py index b2a072fb37..660117954d 100644 --- a/common/djangoapps/terrain/stubs/comments.py +++ b/common/djangoapps/terrain/stubs/comments.py @@ -100,7 +100,9 @@ class StubCommentsServiceHandler(StubHttpRequestHandler): self.send_response(404, content="404 Not Found") def do_threads(self): - self.send_json_response({"collection": [], "page": 1, "num_pages": 1}) + threads = self.server.config.get('threads', {}) + threads_data = [val for key, val in threads.items()] + self.send_json_response({"collection": threads_data, "page": 1, "num_pages": 1}) def do_search_threads(self): self.send_json_response(self.server.config.get('search_result', {})) diff --git a/common/static/coffee/src/discussion/views/discussion_thread_view.coffee b/common/static/coffee/src/discussion/views/discussion_thread_view.coffee index 7b315571c3..69d45e1acc 100644 --- a/common/static/coffee/src/discussion/views/discussion_thread_view.coffee +++ b/common/static/coffee/src/discussion/views/discussion_thread_view.coffee @@ -125,7 +125,7 @@ if Backbone? resp_limit: responseLimit if responseLimit $elem: elem $loading: elem - takeFocus: true + takeFocus: false complete: => @responsesRequest = null success: (data, textStatus, xhr) => diff --git a/common/test/acceptance/fixtures/discussion.py b/common/test/acceptance/fixtures/discussion.py index 71cc2899c0..cec8aa6003 100644 --- a/common/test/acceptance/fixtures/discussion.py +++ b/common/test/acceptance/fixtures/discussion.py @@ -119,6 +119,16 @@ class SingleThreadViewFixture(DiscussionContentFixture): } +class MultipleThreadFixture(DiscussionContentFixture): + + def __init__(self, threads): + self.threads = threads + + def get_config_data(self): + threads_list = {thread['id']: thread for thread in self.threads} + return {"threads": json.dumps(threads_list), "comments": '{}'} + + class UserProfileViewFixture(DiscussionContentFixture): def __init__(self, threads): diff --git a/common/test/acceptance/pages/lms/discussion.py b/common/test/acceptance/pages/lms/discussion.py index 2b2f17d9a8..6bcfb85433 100644 --- a/common/test/acceptance/pages/lms/discussion.py +++ b/common/test/acceptance/pages/lms/discussion.py @@ -341,6 +341,42 @@ class DiscussionTabSingleThreadPage(CoursePage): with self.thread_page._secondary_action_menu_open(".forum-thread-main-wrapper"): self._find_within(".forum-thread-main-wrapper .action-close").first.click() + @wait_for_js + def is_window_on_top(self): + """ + Check if window's scroll is at top + """ + return self.browser.execute_script("return $('html, body').offset().top") == 0 + + def _thread_is_rendered_successfully(self, thread_id): + return self.q(css=".discussion-article[data-id='{}']".format(thread_id)).visible + + def click_and_open_thread(self, thread_id): + """ + Click specific thread on the list. + """ + thread_selector = "li[data-id='{}']".format(thread_id) + self.q(css=thread_selector).first.click() + EmptyPromise( + lambda: self._thread_is_rendered_successfully(thread_id), + "Thread has been rendered" + ).fulfill() + + def check_threads_rendered_successfully(self, thread_count): + """ + Count the number of threads available on page. + """ + return len(self.q(css=".forum-nav-thread").results) == thread_count + + def check_window_is_on_top(self): + """ + Check window is on top of the page + """ + EmptyPromise( + self.is_window_on_top, + "Window is on top" + ).fulfill() + class InlineDiscussionPage(PageObject): url = None diff --git a/common/test/acceptance/tests/discussion/test_discussion.py b/common/test/acceptance/tests/discussion/test_discussion.py index 597df3ad3f..e5d8ef45a1 100644 --- a/common/test/acceptance/tests/discussion/test_discussion.py +++ b/common/test/acceptance/tests/discussion/test_discussion.py @@ -30,7 +30,7 @@ from ...fixtures.discussion import ( Response, Comment, SearchResult, -) + MultipleThreadFixture) from .helpers import BaseDiscussionMixin @@ -256,6 +256,61 @@ class DiscussionTabSingleThreadTest(BaseDiscussionTestCase, DiscussionResponsePa self.assertFalse(self.thread_page.is_show_comments_visible(response_id)) +@attr('shard_1') +class DiscussionTabMultipleThreadTest(BaseDiscussionTestCase): + """ + Tests for the discussion page with multiple threads + """ + def setUp(self): + super(DiscussionTabMultipleThreadTest, self).setUp() + AutoAuthPage(self.browser, course_id=self.course_id).visit() + self.thread_count = 2 + self.thread_ids = [] + self.setup_multiple_threads(thread_count=self.thread_count) + + self.thread_page_1 = DiscussionTabSingleThreadPage( + self.browser, + self.course_id, + self.discussion_id, + self.thread_ids[0] + ) + self.thread_page_2 = DiscussionTabSingleThreadPage( + self.browser, + self.course_id, + self.discussion_id, + self.thread_ids[1] + ) + self.thread_page_1.visit() + + def setup_multiple_threads(self, thread_count): + threads = [] + 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), + ) + self.thread_ids.append(thread_id) + view = MultipleThreadFixture(threads) + view.push() + + def test_page_scroll_on_thread_change_view(self): + """ + Check switching between threads changes the page to scroll to bottom + """ + # verify threads are rendered on the page + self.assertTrue( + self.thread_page_1.check_threads_rendered_successfully(thread_count=self.thread_count) + ) + + # From the thread_page_1 open & verify next thread + self.thread_page_1.click_and_open_thread(thread_id=self.thread_ids[1]) + self.assertTrue(self.thread_page_2.is_browser_on_page()) + + # Verify that window is on top of page. + self.thread_page_2.check_window_is_on_top() + + @attr('shard_1') class DiscussionOpenClosedThreadTest(BaseDiscussionTestCase): """