diff --git a/common/test/acceptance/pages/studio/index.py b/common/test/acceptance/pages/studio/index.py index 210de24358..a7eac88493 100644 --- a/common/test/acceptance/pages/studio/index.py +++ b/common/test/acceptance/pages/studio/index.py @@ -7,6 +7,7 @@ from selenium.webdriver import ActionChains from common.test.acceptance.pages.studio import BASE_URL from common.test.acceptance.pages.studio.login import LoginPage from common.test.acceptance.pages.studio.signup import SignupPage +from common.test.acceptance.pages.studio.utils import HelpMixin class HeaderMixin(object): @@ -40,7 +41,7 @@ class IndexPage(PageObject, HeaderMixin): return self.q(css='.wrapper-text-welcome').visible -class DashboardPage(PageObject): +class DashboardPage(PageObject, HelpMixin): """ Studio Dashboard page with courses. The user must be logged in to access this page. diff --git a/common/test/acceptance/pages/studio/library.py b/common/test/acceptance/pages/studio/library.py index 1113fb7f5c..73562aba76 100644 --- a/common/test/acceptance/pages/studio/library.py +++ b/common/test/acceptance/pages/studio/library.py @@ -10,13 +10,13 @@ from common.test.acceptance.pages.studio.container import XBlockWrapper from common.test.acceptance.pages.studio.users import UsersPageMixin from common.test.acceptance.pages.studio.pagination import PaginatedMixin from selenium.webdriver.common.keys import Keys - +from common.test.acceptance.pages.studio.utils import HelpMixin from common.test.acceptance.pages.common.utils import confirm_prompt, wait_for_notification from common.test.acceptance.pages.studio import BASE_URL -class LibraryPage(PageObject): +class LibraryPage(PageObject, HelpMixin): """ Base page for Library pages. Defaults URL to the edit page. """ diff --git a/common/test/acceptance/pages/studio/login.py b/common/test/acceptance/pages/studio/login.py index 335f3c700b..8d99aee051 100644 --- a/common/test/acceptance/pages/studio/login.py +++ b/common/test/acceptance/pages/studio/login.py @@ -6,6 +6,7 @@ from bok_choy.promise import EmptyPromise from common.test.acceptance.pages.studio import BASE_URL from common.test.acceptance.pages.studio.course_page import CoursePage +from common.test.acceptance.pages.studio.utils import HelpMixin class LoginMixin(object): @@ -34,7 +35,7 @@ class LoginMixin(object): ).fulfill() -class LoginPage(PageObject, LoginMixin): +class LoginPage(PageObject, LoginMixin, HelpMixin): """ Login page for Studio. """ diff --git a/common/test/acceptance/pages/studio/signup.py b/common/test/acceptance/pages/studio/signup.py index 02748c79f6..d3bbac1b94 100644 --- a/common/test/acceptance/pages/studio/signup.py +++ b/common/test/acceptance/pages/studio/signup.py @@ -4,11 +4,11 @@ Signup page for studio from bok_choy.page_object import PageObject from common.test.acceptance.pages.studio import BASE_URL -from common.test.acceptance.pages.studio.utils import set_input_value +from common.test.acceptance.pages.studio.utils import set_input_value, HelpMixin from common.test.acceptance.pages.common.utils import click_css -class SignupPage(PageObject): +class SignupPage(PageObject, HelpMixin): """ Signup page for Studio. """ diff --git a/common/test/acceptance/pages/studio/users.py b/common/test/acceptance/pages/studio/users.py index 7102641145..0f1e5f4359 100644 --- a/common/test/acceptance/pages/studio/users.py +++ b/common/test/acceptance/pages/studio/users.py @@ -6,6 +6,7 @@ from bok_choy.page_object import PageObject from common.test.acceptance.tests.helpers import disable_animations from common.test.acceptance.pages.studio.course_page import CoursePage from common.test.acceptance.pages.studio import BASE_URL +from common.test.acceptance.pages.studio.utils import HelpMixin def wait_for_ajax_or_reload(browser): @@ -147,7 +148,7 @@ class UsersPageMixin(PageObject): disable_animations(self) -class LibraryUsersPage(UsersPageMixin): +class LibraryUsersPage(UsersPageMixin, HelpMixin): """ Library Team page in Studio """ diff --git a/common/test/acceptance/pages/studio/utils.py b/common/test/acceptance/pages/studio/utils.py index f58ef20935..b83b74daf2 100644 --- a/common/test/acceptance/pages/studio/utils.py +++ b/common/test/acceptance/pages/studio/utils.py @@ -9,6 +9,12 @@ from bok_choy.promise import EmptyPromise from common.test.acceptance.pages.common.utils import click_css, wait_for_notification +NAV_HELP_NOT_SIGNED_IN_CSS = '.nav-item.nav-not-signedin-help a' +NAV_HELP_CSS = '.nav-item.nav-account-help a' +SIDE_BAR_HELP_AS_LIST_ITEM = '.bit li.action-item a' +SIDE_BAR_HELP_CSS = '.bit.external-help a' + + @js_defined('window.jQuery') def press_the_notification_button(page, name): # Because the notification uses a CSS transition, @@ -148,6 +154,7 @@ def type_in_codemirror(page, index, text, find_prefix="$"): CodeMirror.signal(cm, "focus", cm); cm.setValue(arguments[0]); CodeMirror.signal(cm, "blur", cm);""".format(index=index, find_prefix=find_prefix) + page.browser.execute_script(script, str(text)) @@ -250,3 +257,52 @@ def click_studio_help(page): def studio_help_links(page): """Return the list of Studio help links in the page footer.""" return page.q(css='.support .list-actions a').results + + +class HelpMixin(object): + """ + Mixin for testing Help links. + """ + def get_nav_help_element_and_click_help(self, signed_in=True): + """ + Click on the help, and also get the DOM help element. + + It operates on the help elements in the navigation bar. + + Arguments: + signed_in (bool): Indicates whether user is signed in or not. + + Returns: + WebElement: Help DOM element in the navigation bar. + """ + + element_css = None + if signed_in: + element_css = NAV_HELP_CSS + else: + element_css = NAV_HELP_NOT_SIGNED_IN_CSS + + self.q(css=element_css).click() + return self.q(css=element_css).results[0] + + def get_side_bar_help_element_and_click_help(self, as_list_item=False): + """ + Click on the help, and also get the DOM help element. + + It operates on the help elements in the side bar. + + Arguments: + as_list_item (bool): Indicates whether help element is + enclosed in a 'li' DOM element. + + Returns: + WebElement: Help DOM element in the side bar. + """ + element_css = None + if as_list_item: + element_css = SIDE_BAR_HELP_AS_LIST_ITEM + else: + element_css = SIDE_BAR_HELP_CSS + + self.q(css=element_css).click() + return self.q(css=element_css).results[0] diff --git a/common/test/acceptance/tests/helpers.py b/common/test/acceptance/tests/helpers.py index 04c6787c35..f2e352ad67 100644 --- a/common/test/acceptance/tests/helpers.py +++ b/common/test/acceptance/tests/helpers.py @@ -379,6 +379,48 @@ def auto_auth(browser, username, email, staff, course_id): AutoAuthPage(browser, username=username, email=email, course_id=course_id, staff=staff).visit() +def get_url_with_changed_domain(url): + """ + Replaces .org with .io in the url + + Arguments: + url (str): The url to perform replace operation on. + + Returns: + str: The updated url + """ + return url.replace('.org/', '.io/') + + +def assert_link(test, expected_link, actual_link): + """ + Assert that 'href' and text inside help DOM element are correct. + + Arguments: + test: Test on which links are being tested. + expected_link (dict): The expected link attributes. + actual_link (dict): The actual link attribute on page. + """ + test.assertEqual(expected_link['href'], actual_link.get_attribute('href')) + test.assertEqual(expected_link['text'], actual_link.text) + + +def assert_opened_help_link_is_correct(test, url): + """ + Asserts that url of browser when help link is clicked is correct. + Arguments: + test (WebAppTest): test calling this method. + url (str): url to verify. + """ + test.browser.switch_to_window(test.browser.window_handles[-1]) + # Assert that url in the browser is the same. + # Please note that .org domain in href attribute of help anchor DOM element + # is changed into .io domain. This is because browser is redirected from .org + # domain to .io domain. + test.assertEqual(get_url_with_changed_domain(url), test.browser.current_url) + test.assertNotIn('Maze Found', test.browser.title) + + class EventsTestMixin(TestCase): """ Helpers and setup for running tests that evaluate events emitted @@ -772,6 +814,57 @@ def create_user_partition_json(partition_id, name, description, groups, scheme=" ).to_json() +def assert_nav_help_link(test, page, href, signed_in=True): + """ + Asserts that help link in navigation bar is correct. + + It first checks the url inside anchor DOM element and + then clicks to ensure that help opens correctly. + + Arguments: + test (WebAppTest): Test object + page (PageObject): Page object to perform tests on. + href (str): The help link which we expect to see when it is opened. + signed_in (bool): Specifies whether user is logged in or not. (It effects the css) + """ + expected_link = { + 'href': href, + 'text': 'Help' + } + # Get actual anchor help element from the page. + actual_link = page.get_nav_help_element_and_click_help(signed_in) + # Assert that 'href' and text are the same as expected. + assert_link(test, expected_link, actual_link) + # Assert that opened link is correct + assert_opened_help_link_is_correct(test, href) + + +def assert_side_bar_help_link(test, page, href, help_text, as_list_item=False): + """ + Asserts that help link in side bar is correct. + + It first checks the url inside anchor DOM element and + then clicks to ensure that help opens correctly. + + Arguments: + test (WebAppTest): Test object + page (PageObject): Page object to perform tests on. + href (str): The help link which we expect to see when it is opened. + as_list_item (bool): Specifies whether help element is in one of the + 'li' inside a sidebar list DOM element. + """ + expected_link = { + 'href': href, + 'text': help_text + } + # Get actual anchor help element from the page. + actual_link = page.get_side_bar_help_element_and_click_help(as_list_item) + # Assert that 'href' and text are the same as expected. + assert_link(test, expected_link, actual_link) + # Assert that opened link is correct + assert_opened_help_link_is_correct(test, href) + + class TestWithSearchIndexMixin(object): """ Mixin encapsulating search index creation """ TEST_INDEX_FILENAME = "test_root/index_file.dat" diff --git a/common/test/acceptance/tests/studio/test_studio_help.py b/common/test/acceptance/tests/studio/test_studio_help.py index 8cf7bb62da..8f3e79e163 100644 --- a/common/test/acceptance/tests/studio/test_studio_help.py +++ b/common/test/acceptance/tests/studio/test_studio_help.py @@ -3,10 +3,22 @@ Test the Studio help links. """ from flaky import flaky +from bok_choy.web_app_test import WebAppTest from common.test.acceptance.tests.studio.base_studio_test import StudioCourseTest from common.test.acceptance.pages.studio.index import DashboardPage from common.test.acceptance.pages.studio.utils import click_studio_help, studio_help_links +from common.test.acceptance.pages.studio.index import IndexPage, HomePage +from common.test.acceptance.tests.studio.base_studio_test import StudioLibraryTest +from common.test.acceptance.pages.studio.utils import click_css +from common.test.acceptance.pages.studio.library import LibraryPage +from common.test.acceptance.pages.studio.users import LibraryUsersPage +from common.test.acceptance.tests.helpers import ( + assert_nav_help_link, + assert_side_bar_help_link +) +from common.test.acceptance.pages.studio.import_export import ExportLibraryPage, ImportLibraryPage +from common.test.acceptance.pages.studio.auto_auth import AutoAuthPage class StudioHelpTest(StudioCourseTest): @@ -47,3 +59,445 @@ class StudioHelpTest(StudioCourseTest): expected['sr_text'], actual.find_element_by_xpath('following-sibling::span').text ) + + +class SignInHelpTest(WebAppTest): + """ + Tests help links on 'Sign In' page + """ + def setUp(self): + super(SignInHelpTest, self).setUp() + self.index_page = IndexPage(self.browser) + self.index_page.visit() + + def test_sign_in_nav_help(self): + """ + Scenario: Help link in navigation bar is working on 'Sign In' page. + Given that I am on the 'Sign In" page. + And I want help about the sign in + And I click the 'Help' in the navigation bar + Then Help link should open. + And help url should end with 'getting_started/get_started.html' + """ + sign_in_page = self.index_page.click_sign_in() + # The href we want to see in anchor help element. + href = 'http://edx.readthedocs.org/projects/edx-partner-course-staff/' \ + 'en/latest/getting_started/get_started.html' + + # Assert that help link is correct. + assert_nav_help_link( + test=self, + page=sign_in_page, + href=href, + signed_in=False + ) + + +class SignUpHelpTest(WebAppTest): + """ + Tests help links on 'Sign Up' page. + """ + def setUp(self): + super(SignUpHelpTest, self).setUp() + self.index_page = IndexPage(self.browser) + self.index_page.visit() + + def test_sign_up_nav_help(self): + """ + Scenario: Help link in navigation bar is working on 'Sign Up' page. + Given that I am on the 'Sign Up" page. + And I want help about the sign up + And I click the 'Help' in the navigation bar + Then Help link should open. + And help url should end with 'getting_started/get_started.html' + """ + sign_up_page = self.index_page.click_sign_up() + # The href we want to see in anchor help element. + href = 'http://edx.readthedocs.org/projects/edx-partner-course-staff/' \ + 'en/latest/getting_started/get_started.html' + + # Assert that help link is correct. + assert_nav_help_link( + test=self, + page=sign_up_page, + href=href, + signed_in=False + ) + + +class HomeHelpTest(StudioCourseTest): + """ + Tests help links on 'Home'(Courses tab) page. + """ + def setUp(self): # pylint: disable=arguments-differ + super(HomeHelpTest, self).setUp() + self.home_page = HomePage(self.browser) + self.home_page.visit() + + def test_course_home_nav_help(self): + """ + Scenario: Help link in navigation bar is working on 'Home'(Courses tab) page. + Given that I am on the 'Home'(Courses tab) page. + And I want help about the courses + And I click the 'Help' in the navigation bar + Then Help link should open. + And help url should end with 'getting_started/get_started.html' + """ + # The href we want to see in anchor help element. + href = 'http://edx.readthedocs.org/projects/edx-partner-course-staff/' \ + 'en/latest/getting_started/get_started.html' + + # Assert that help link is correct. + assert_nav_help_link( + test=self, + page=self.home_page, + href=href + ) + + def test_course_home_side_bar_help(self): + """ + Scenario: Help link in sidebar links is working on 'Home'(Courses tab) page. + Given that I am on the 'Home'(Courses tab) page. + And I want help about the courses + And I click the 'Getting Started with edX Studio' in the sidebar links + Then Help link should open. + And help url should end with 'getting_started/get_started.html' + """ + # The href we want to see in anchor help element. + href = 'http://edx.readthedocs.org/projects/edx-partner-course-staff/' \ + 'en/latest/getting_started/get_started.html' + + # Assert that help link is correct. + assert_side_bar_help_link( + test=self, + page=self.home_page, + href=href, + help_text='Getting Started with edX Studio', + as_list_item=True + ) + + +class NewCourseHelpTest(WebAppTest): + """ + Test help links while creating a new course. + """ + def setUp(self): + super(NewCourseHelpTest, self).setUp() + self.auth_page = AutoAuthPage(self.browser, staff=True) + self.dashboard_page = DashboardPage(self.browser) + self.auth_page.visit() + self.dashboard_page.visit() + self.assertTrue(self.dashboard_page.new_course_button.present) + self.dashboard_page.click_new_course_button() + + def test_course_create_nav_help(self): + """ + Scenario: Help link in navigation bar is working on 'Create a New Course' page in the dashboard. + Given that I am on the 'Create a New Course' page in the dashboard. + And I want help about the process + And I click the 'Help' in the navigation bar + Then Help link should open. + And help url should end with 'getting_started/get_started.html' + """ + # The href we want to see in anchor help element. + href = 'http://edx.readthedocs.org/projects/edx-partner-course-staff' \ + '/en/latest/getting_started/get_started.html' + + # Assert that help link is correct. + assert_nav_help_link( + test=self, + page=self.dashboard_page, + href=href + ) + + def test_course_create_side_bar_help(self): + """ + Scenario: Help link in sidebar links is working on 'Create a New Course' page in the dashboard. + Given that I am on the 'Create a New Course' page in the dashboard. + And I want help about the process + And I click the 'Getting Started with edX Studio' in the sidebar links + Then Help link should open. + And help url should end with 'getting_started/get_started.html' + """ + # The href we want to see in anchor help element. + href = 'http://edx.readthedocs.org/projects/edx-partner-course-staff/' \ + 'en/latest/getting_started/get_started.html' + + # Assert that help link is correct. + assert_side_bar_help_link( + test=self, + page=self.dashboard_page, + href=href, + help_text='Getting Started with edX Studio', + as_list_item=True + ) + + +class NewLibraryHelpTest(WebAppTest): + """ + Test help links while creating a new library + """ + def setUp(self): + super(NewLibraryHelpTest, self).setUp() + self.auth_page = AutoAuthPage(self.browser, staff=True) + self.dashboard_page = DashboardPage(self.browser) + self.auth_page.visit() + self.dashboard_page.visit() + self.assertTrue(self.dashboard_page.has_new_library_button) + self.dashboard_page.click_new_library() + + def test_library_create_nav_help(self): + """ + Scenario: Help link in navigation bar is working on 'Create a New Library' page in the dashboard. + Given that I am on the 'Create a New Library' page in the dashboard. + And I want help about the process + And I click the 'Help' in the navigation bar + Then Help link should open. + And help url should end with 'getting_started/get_started.html' + """ + # The href we want to see in anchor help element. + href = 'http://edx.readthedocs.org/projects/edx-partner-course-staff/' \ + 'en/latest/getting_started/get_started.html' + + # Assert that help link is correct. + assert_nav_help_link( + test=self, + page=self.dashboard_page, + href=href + ) + + def test_library_create_side_bar_help(self): + """ + Scenario: Help link in sidebar links is working on 'Create a New Library' page in the dashboard. + Given that I am on the 'Create a New Library' page in the dashboard. + And I want help about the process + And I click the 'Getting Started with edX Studio' in the sidebar links + Then Help link should open. + And help url should end with 'getting_started/get_started.html' + """ + # The href we want to see in anchor help element. + href = 'http://edx.readthedocs.org/projects/edx-partner-course-staff/' \ + 'en/latest/getting_started/get_started.html' + + # Assert that help link is correct. + assert_side_bar_help_link( + test=self, + page=self.dashboard_page, + href=href, + help_text='Getting Started with edX Studio', + as_list_item=True + ) + + +class LibraryTabHelpTest(WebAppTest): + """ + Test help links on the library tab present at dashboard. + """ + def setUp(self): + super(LibraryTabHelpTest, self).setUp() + self.auth_page = AutoAuthPage(self.browser, staff=True) + self.dashboard_page = DashboardPage(self.browser) + self.auth_page.visit() + self.dashboard_page.visit() + + def test_library_tab_nav_help(self): + """ + Scenario: Help link in navigation bar is working on 'Home'(Courses tab) page. + Given that I am on the 'Home'(Courses tab) page. + And I want help about the process + And I click the 'Help' in the navigation bar + Then Help link should open. + And help url should end with 'getting_started/get_started.html' + """ + self.assertTrue(self.dashboard_page.has_new_library_button) + click_css(self.dashboard_page, '#course-index-tabs .libraries-tab', 0, False) + # The href we want to see in anchor help element. + href = 'http://edx.readthedocs.org/projects/edx-partner-course-staff/' \ + 'en/latest/getting_started/get_started.html' + + # Assert that help link is correct. + assert_nav_help_link( + test=self, + page=self.dashboard_page, + href=href + ) + + +class LibraryHelpTest(StudioLibraryTest): + """ + Test help links on a Library page. + """ + def setUp(self): + super(LibraryHelpTest, self).setUp() + self.library_page = LibraryPage(self.browser, self.library_key) + self.library_user_page = LibraryUsersPage(self.browser, self.library_key) + + def test_library_content_nav_help(self): + """ + Scenario: Help link in navigation bar is working on content + library page(click a library on the Library list page). + Given that I am on the content library page(click a library on the Library list page). + And I want help about the process + And I click the 'Help' in the navigation bar + Then Help link should open. + And help url should end with 'course/components/libraries.html' + """ + self.library_page.visit() + # The href we want to see in anchor help element. + href = 'http://edx.readthedocs.org/projects/edx-partner-course-staff/' \ + 'en/latest/course_components/libraries.html' + + # Assert that help link is correct. + assert_nav_help_link( + test=self, + page=self.library_page, + href=href + ) + + def test_library_content_side_bar_help(self): + """ + Scenario: Help link in sidebar links is working on + content library page(click a library on the Library list page). + Given that I am on the content library page(click a library on the Library list page). + And I want help about the process + And I click the 'Learn more about content libraries' in the sidebar links + Then Help link should open. + And help url should end with 'course/components/libraries.html' + """ + self.library_page.visit() + # The href we want to see in anchor help element. + href = 'http://edx.readthedocs.org/projects/edx-partner-course-staff/' \ + 'en/latest/course_components/libraries.html' + + # Assert that help link is correct. + assert_side_bar_help_link( + test=self, + page=self.library_page, + href=href, + help_text='Learn more about content libraries' + ) + + def test_library_user_access_setting_nav_help(self): + """ + Scenario: Help link in navigation bar is working on 'User Access' + settings page of library. + Given that I am on the 'User Access' settings page of library. + And I want help about the process + And I click the 'Help' in the navigation bar + Then Help link should open. + And help url should end with + 'creating_content/libraries.html#give-other-users-access-to-your-library' + """ + self.library_user_page.visit() + # The href we want to see in anchor help element. + href = 'http://edx.readthedocs.org/projects/edx-partner-course-staff/en/' \ + 'latest/course_components/libraries.html#give-other-users-access-to-your-library' + + # Assert that help link is correct. + assert_nav_help_link( + test=self, + page=self.library_user_page, + href=href + ) + + +class LibraryImportHelpTest(StudioLibraryTest): + """ + Test help links on a Library import and export pages. + """ + def setUp(self): + super(LibraryImportHelpTest, self).setUp() + self.library_import_page = ImportLibraryPage(self.browser, self.library_key) + self.library_import_page.visit() + + def test_library_import_nav_help(self): + """ + Scenario: Help link in navigation bar is working on Library import page. + Given that I am on the Library import page. + And I want help about the process + And I click the 'Help' in the navigation bar + Then Help link should open. + And help url should end with 'creating_content/libraries.html#import-a-library' + """ + # The href we want to see in anchor help element. + href = 'http://edx.readthedocs.org/projects/edx-partner-course-staff/en/' \ + 'latest/course_components/libraries.html#import-a-library' + + # Assert that help link is correct. + assert_nav_help_link( + test=self, + page=self.library_import_page, + href=href + ) + + def test_library_import_side_bar_help(self): + """ + Scenario: Help link in sidebar links is working on Library import page. + Given that I am on the Library import page. + And I want help about the process + And I click the 'Learn more about importing a library' in the sidebar links + Then Help link should open. + And help url should end with 'creating_content/libraries.html#import-a-library' + """ + # The href we want to see in anchor help element. + href = 'http://edx.readthedocs.org/projects/edx-partner-course-staff/en/' \ + 'latest/course_components/libraries.html#import-a-library' + + # Assert that help link is correct. + assert_side_bar_help_link( + test=self, + page=self.library_import_page, + href=href, + help_text='Learn more about importing a library' + ) + + +class LibraryExportHelpTest(StudioLibraryTest): + """ + Test help links on a Library export pages. + """ + def setUp(self): + super(LibraryExportHelpTest, self).setUp() + self.library_export_page = ExportLibraryPage(self.browser, self.library_key) + self.library_export_page.visit() + + def test_library_export_nav_help(self): + """ + Scenario: Help link in navigation bar is working on Library export page. + Given that I am on the Library export page. + And I want help about the process + And I click the 'Help' in the navigation bar + Then Help link should open. + And help url should end with 'creating_content/libraries.html#export-a-library' + """ + # The href we want to see in anchor help element. + href = 'http://edx.readthedocs.org/projects/edx-partner-course-staff/en/' \ + 'latest/course_components/libraries.html#export-a-library' + + # Assert that help link is correct. + assert_nav_help_link( + test=self, + page=self.library_export_page, + href=href + ) + + def test_library_export_side_bar_help(self): + """ + Scenario: Help link in sidebar links is working on Library export page. + Given that I am on the Library export page. + And I want help about the process + And I click the 'Learn more about exporting a library' in the sidebar links + Then Help link should open. + And help url should end with 'creating_content/libraries.html#export-a-library' + """ + # The href we want to see in anchor help element. + href = 'http://edx.readthedocs.org/projects/edx-partner-course-staff/en/' \ + 'latest/course_components/libraries.html#export-a-library' + + # Assert that help link is correct. + assert_side_bar_help_link( + test=self, + page=self.library_export_page, + href=href, + help_text='Learn more about exporting a library' + )