""" Tests for discussion pages """ from uuid import uuid4 import pytest from common.test.acceptance.fixtures.course import CourseFixture # lint-amnesty, pylint: disable=unused-import from common.test.acceptance.fixtures.discussion import ( Comment, Response, SingleThreadViewFixture, Thread, ) from common.test.acceptance.pages.common.auto_auth import AutoAuthPage from common.test.acceptance.pages.lms.discussion import ( DiscussionTabHomePage, DiscussionTabSingleThreadPage, ) from common.test.acceptance.tests.discussion.helpers import BaseDiscussionMixin, BaseDiscussionTestCase from common.test.acceptance.tests.helpers import UniqueCourseTest from openedx.core.lib.tests import attr THREAD_CONTENT_WITH_LATEX = """Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt # lint-amnesty, pylint: disable=line-too-long ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit sse cillum dolore eu fugiat nulla pariatur. \n\n----------\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit sse cillum dolore eu fugiat nulla pariatur. (b).\n\n **(a)** $H_1(e^{j\\omega}) = \\sum_{n=-\\infty}^{\\infty}h_1[n]e^{-j\\omega n} = \\sum_{n=-\\infty} ^{\\infty}h[n]e^{-j\\omega n}+\\delta_2e^{-j\\omega n_0}$ $= H(e^{j\\omega})+\\delta_2e^{-j\\omega n_0}=A_e (e^{j\\omega}) e^{-j\\omega n_0} +\\delta_2e^{-j\\omega n_0}=e^{-j\\omega n_0} (A_e(e^{j\\omega})+\\delta_2) $H_3(e^{j\\omega})=A_e(e^{j\\omega})+\\delta_2$. Dummy $A_e(e^{j\\omega})$ dummy post $. $A_e(e^{j\\omega}) \\ge -\\delta_2$, it follows that $H_3(e^{j\\omega})$ is real and $H_3(e^{j\\omega})\\ge 0$.\n\n**(b)** Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit sse cillum dolore eu fugiat nulla pariatur.\n\n **Case 1:** If $re^{j\\theta}$ is a Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit sse cillum dolore eu fugiat nulla pariatur. \n\n**Case 3:** Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit sse cillum dolore eu fugiat nulla pariatur. Lorem $H_3(e^{j\\omega}) = P(cos\\omega)(cos\\omega - cos\\theta)^k$, Lorem Lorem Lorem Lorem Lorem Lorem $P(cos\\omega)$ has no $(cos\\omega - cos\\theta)$ factor. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit sse cillum dolore eu fugiat nulla pariatur. $P(cos\\theta) \\neq 0$. Since $P(cos\\omega)$ this is a dummy data post $\\omega$, dummy $\\delta > 0$ such that for all $\\omega$ dummy $|\\omega - \\theta| < \\delta$, $P(cos\\omega)$ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit sse cillum dolore Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit sse cillum dolore eu fugiat nulla pariatur. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit sse cillum dolore eu fugiat nulla pariatur. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit sse cillum dolore eu fugiat nulla pariatur. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit sse cillum dolore eu fugiat nulla pariatur. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit sse cillum dolore eu fugiat nulla pariatur. """ @attr(shard=2) class DiscussionHomePageTest(BaseDiscussionTestCase): """ Tests for the discussion home page. """ SEARCHED_USERNAME = "gizmo" def setUp(self): super().setUp() AutoAuthPage(self.browser, course_id=self.course_id).visit() self.page = DiscussionTabHomePage(self.browser, self.course_id) self.page.visit() @attr('a11y') def test_page_accessibility(self): self.page.a11y_audit.config.set_rules({ "ignore": [ 'section', # TODO: AC-491 'aria-required-children', # TODO: AC-534 'aria-valid-attr', # TODO: LEARNER-6611 & LEARNER-6865 'region' # TODO: AC-932 ] }) self.page.a11y_audit.check_for_accessibility_errors() class DiscussionTabMultipleThreadTest(BaseDiscussionTestCase, BaseDiscussionMixin): """ Tests for the discussion page with multiple threads """ def setUp(self): super().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() @attr('a11y') def test_page_accessibility(self): self.thread_page_1.a11y_audit.config.set_rules({ "ignore": [ 'section', # TODO: AC-491 'aria-required-children', # TODO: AC-534 'aria-valid-attr', # TODO: LEARNER-6611 & LEARNER-6865 'region', # TODO: AC-932 ] }) self.thread_page_1.a11y_audit.check_for_accessibility_errors() self.thread_page_2.a11y_audit.config.set_rules({ "ignore": [ 'section', # TODO: AC-491 'aria-required-children', # TODO: AC-534 'region' # TODO: AC-932 ] }) self.thread_page_2.a11y_audit.check_for_accessibility_errors() class DiscussionOpenClosedThreadTest(BaseDiscussionTestCase): """ Tests for checking the display of attributes on open and closed threads """ def setUp(self): super().setUp() self.thread_id = f"test_thread_{uuid4().hex}" def setup_user(self, roles=[]): # lint-amnesty, pylint: disable=dangerous-default-value roles_str = ','.join(roles) self.user_id = AutoAuthPage(self.browser, course_id=self.course_id, roles=roles_str).visit().get_user_id() # lint-amnesty, pylint: disable=attribute-defined-outside-init def setup_view(self, **thread_kwargs): # lint-amnesty, pylint: disable=missing-function-docstring thread_kwargs.update({'commentable_id': self.discussion_id}) view = SingleThreadViewFixture( Thread(id=self.thread_id, **thread_kwargs) ) view.addResponse(Response(id="response1")) view.push() def setup_openclosed_thread_page(self, closed=False): # lint-amnesty, pylint: disable=missing-function-docstring self.setup_user(roles=['Moderator']) if closed: self.setup_view(closed=True) else: self.setup_view() page = self.create_single_thread_page(self.thread_id) page.visit() page.close_open_thread() return page @attr('a11y') def test_page_accessibility(self): page = self.setup_openclosed_thread_page() page.a11y_audit.config.set_rules({ 'ignore': [ 'section', # TODO: AC-491 'aria-required-children', # TODO: AC-534 'color-contrast', # Commented out for now because they reproducibly fail on Jenkins but not locally 'aria-valid-attr', # TODO: LEARNER-6611 & LEARNER-6865 'region', # TODO: AC-932 ] }) page.a11y_audit.check_for_accessibility_errors() page = self.setup_openclosed_thread_page(True) page.a11y_audit.config.set_rules({ 'ignore': [ 'section', # TODO: AC-491 'aria-required-children', # TODO: AC-534 'color-contrast', # Commented out for now because they reproducibly fail on Jenkins but not locally 'aria-valid-attr', # TODO: LEARNER-6611 & LEARNER-6865 'region', # TODO: AC-932 ] }) page.a11y_audit.check_for_accessibility_errors() class DiscussionResponseEditTest(BaseDiscussionTestCase): """ Tests for editing responses displayed beneath thread in the single thread view. """ def setup_user(self, roles=[]): # lint-amnesty, pylint: disable=dangerous-default-value roles_str = ','.join(roles) self.user_id = AutoAuthPage(self.browser, course_id=self.course_id, roles=roles_str).visit().get_user_id() # lint-amnesty, pylint: disable=attribute-defined-outside-init def setup_view(self): # lint-amnesty, pylint: disable=missing-function-docstring view = SingleThreadViewFixture(Thread(id="response_edit_test_thread", commentable_id=self.discussion_id)) view.addResponse( Response(id="response_other_author", user_id="other", thread_id="response_edit_test_thread"), ) view.addResponse( Response(id="response_self_author", user_id=self.user_id, thread_id="response_edit_test_thread"), ) view.push() @attr('a11y') def test_page_accessibility(self): self.setup_user() self.setup_view() page = self.create_single_thread_page("response_edit_test_thread") page.a11y_audit.config.set_rules({ 'ignore': [ 'section', # TODO: AC-491 'aria-required-children', # TODO: AC-534 'aria-valid-attr', # TODO: LEARNER-6611 & LEARNER-6865 'region', # TODO: AC-932 ] }) page.visit() page.a11y_audit.check_for_accessibility_errors() class DiscussionCommentEditTest(BaseDiscussionTestCase): """ Tests for editing comments displayed beneath responses in the single thread view. """ def setup_user(self, roles=[]): # lint-amnesty, pylint: disable=dangerous-default-value roles_str = ','.join(roles) self.user_id = AutoAuthPage(self.browser, course_id=self.course_id, roles=roles_str).visit().get_user_id() # lint-amnesty, pylint: disable=attribute-defined-outside-init def setup_view(self): # lint-amnesty, pylint: disable=missing-function-docstring view = SingleThreadViewFixture(Thread(id="comment_edit_test_thread", commentable_id=self.discussion_id)) view.addResponse( Response(id="response1"), [Comment(id="comment_other_author", user_id="other"), Comment(id="comment_self_author", user_id=self.user_id)]) # lint-amnesty, pylint: disable=line-too-long view.push() @attr('a11y') def test_page_accessibility(self): self.setup_user() self.setup_view() page = self.create_single_thread_page("comment_edit_test_thread") page.visit() page.a11y_audit.config.set_rules({ 'ignore': [ 'section', # TODO: AC-491 'aria-required-children', # TODO: AC-534 'aria-valid-attr', # TODO: LEARNER-6611 & LEARNER-6865 'region', # TODO: AC-932 ] }) page.a11y_audit.check_for_accessibility_errors() @attr('a11y') @pytest.mark.skip(reason='This test is too flaky to run at all. TNL-6215') def test_inline_a11y(self): """ Tests Inline Discussion for accessibility issues. """ self.setup_multiple_threads(thread_count=3) # First test the a11y of the expanded list of threads self.discussion_page.expand_discussion() self.discussion_page.a11y_audit.config.set_rules({ 'ignore': [ 'section' ] }) self.discussion_page.a11y_audit.check_for_accessibility_errors() # Now show the first thread and test the a11y again self.discussion_page.show_thread(self.thread_ids[0]) self.discussion_page.a11y_audit.check_for_accessibility_errors() # Finally show the new post form and test its a11y self.discussion_page.click_new_post_button() self.discussion_page.a11y_audit.check_for_accessibility_errors() class DiscussionSearchAlertTest(UniqueCourseTest): """ Tests for spawning and dismissing alerts related to user search actions and their results. """ SEARCHED_USERNAME = "gizmo" def setUp(self): super().setUp() CourseFixture(**self.course_info).install() # first auto auth call sets up a user that we will search for in some tests self.searched_user_id = AutoAuthPage( self.browser, username=self.SEARCHED_USERNAME, course_id=self.course_id ).visit().get_user_id() # this auto auth call creates the actual session user AutoAuthPage(self.browser, course_id=self.course_id).visit() self.page = DiscussionTabHomePage(self.browser, self.course_id) self.page.visit() @attr('a11y') def test_page_accessibility(self): self.page.a11y_audit.config.set_rules({ 'ignore': [ 'section', # TODO: AC-491 'aria-required-children', # TODO: AC-534 'aria-valid-attr', # TODO: LEARNER-6611 & LEARNER-6865 'region', # TODO: AC-932 ] }) self.page.a11y_audit.check_for_accessibility_errors()