import time
import pytest
import requests

from pypom import Region

from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select
from selenium.webdriver.support import expected_conditions as EC

from pages.desktop.base import Base
from pages.desktop.developers.addons_manage import ManageAddons
from pages.desktop.developers.edit_addon import EditAddon
from pages.desktop.developers.submit_addon import SubmitAddon


class DevHubHome(Base):
    """AMO Developer Hub homepage"""

    URL_TEMPLATE = "developers/"

    _logo_locator = (By.CLASS_NAME, "DevHub-Navigation-Logo")
    _ext_workshop_link_locator = (By.LINK_TEXT, "Extension Workshop")
    _documentation_link_locator = (By.LINK_TEXT, "Documentation")
    _support_link_locator = (By.LINK_TEXT, "Support")
    _blog_link_locator = (By.LINK_TEXT, "Blog")
    _fxa_login_button_locator = (By.CLASS_NAME, "DevHub-Navigation-Register")
    _page_overview_title_locator = (By.CSS_SELECTOR, ".DevHub-Overview h1")
    _page_overview_summary_locator = (By.CSS_SELECTOR, ".DevHub-Overview p")
    _learn_how_button_locator = (By.CSS_SELECTOR, ".DevHub-Overview a")
    _page_content_title_locator = (
        By.CSS_SELECTOR,
        ".DevHub-content-header--submit-or-manage",
    )
    _page_content_summary_locator = (
        By.CSS_SELECTOR,
        ".DevHub-content-copy p:nth-child(3)",
    )
    _page_content_login_link_locator = (
        By.CSS_SELECTOR,
        ".DevHub-content-copy:nth-child(1) > a",
    )
    _page_content_featured_image_locator = (
        By.CSS_SELECTOR,
        ".DevHub-content-image--submit-or-manage",
    )
    _get_involved_title_locator = (
        By.CSS_SELECTOR,
        ".DevHub-content-container--get-involved h3",
    )
    _get_involved_summary_locator = (
        By.CSS_SELECTOR,
        ".DevHub-content-container--get-involved p",
    )
    _add_ons_contribute_title_locator = (
        By.CSS_SELECTOR,
        ".mw-page-title-main"
    )
    _dev_community_link_locator = (
        By.CSS_SELECTOR,
        ".DevHub-content-container--get-involved a",
    )
    _get_involved_image_locator = (By.CLASS_NAME, "DevHub-content-image--get-involved")
    _footer_language_picker_locator = (By.ID, "language")
    _footer_products_section_locator = (By.CSS_SELECTOR, ".Footer-products-links")
    _footer_links_locator = (By.CSS_SELECTOR, ".Footer-links li a")

    # elements visible only to logged in users
    _sign_out_link_locator = (
        By.CSS_SELECTOR,
        ".DevHub-Navigation-SignOut a:nth-child(1)",
    )
    _user_logged_in_avatar_locator = (
        By.CSS_SELECTOR,
        ".DevHub-Navigation-SignOut a:nth-child(2)",
    )
    _my_addons_header_link_locator = (By.LINK_TEXT, "My Add-ons")
    _user_profile_picture_locator = (
        By.CSS_SELECTOR,
        ".DevHub-Navigation-SignOut a img",
    )
    _logged_in_hero_banner_header_locator = (
        By.CSS_SELECTOR,
        ".DevHub-callout-box--banner h2",
    )
    _logged_in_hero_banner_text_locator = (
        By.CSS_SELECTOR,
        ".DevHub-callout-box--banner p",
    )
    _logged_in_hero_banner_link_locator = (
        By.CSS_SELECTOR,
        ".DevHub-callout-box--banner a",
    )
    _my_addons_section_header_locator = (By.CSS_SELECTOR, ".DevHub-MyAddons h2")
    _my_addons_section_paragraph_locator = (By.CSS_SELECTOR, ".DevHub-MyAddons-copy")
    _my_addons_section_list_locator = (By.CSS_SELECTOR, ".DevHub-MyAddons-item")
    _see_all_addons_link_locator = (
        By.CSS_SELECTOR,
        ".DevHub-MyAddons-item-buttons-all",
    )
    _submit_addon_button_locator = (
        By.CSS_SELECTOR,
        ".DevHub-MyAddons .Button:nth-of-type(1)",
    )
    _submit_theme_button_locator = (
        By.CSS_SELECTOR,
        ".DevHub-MyAddons .Button:nth-of-type(2)",
    )

    def wait_for_page_to_load(self):
        self.wait.until(lambda _: self.find_element(*self._logo_locator).is_displayed())
        return self

    @property
    def page_logo(self):
        self.wait_for_element_to_be_displayed(self._logo_locator)
        return self.find_element(*self._logo_locator)

    def extension_workshop_is_loaded(self):
        # There are a few Devhub links that redirect to the Extension Workshop(EW) page.
        # The following method can be used by tests which verify that EW has loaded.
        self.wait.until(
            EC.visibility_of_element_located((By.CSS_SELECTOR, ".banner.intro h1"))
        )

    @property
    def extension_workshop(self):
        self.wait_for_element_to_be_displayed(self._ext_workshop_link_locator)
        return self.find_element(*self._ext_workshop_link_locator)

    def click_documentation(self):
        self.wait_for_element_to_be_clickable(self._documentation_link_locator)
        self.find_element(*self._documentation_link_locator).click()
        self.wait.until(
            EC.text_to_be_present_in_element(
                (By.CSS_SELECTOR, ".main-content h1"), "Browser extensions"
            ),
            message=f'Expected "Browser Extensions" in the page title but got'
            f' "{self.find_element(By.CSS_SELECTOR, ".main-content h1").text}".',
        )

    def click_support(self):
        self.wait_for_element_to_be_clickable(self._blog_link_locator)
        self.find_element(*self._support_link_locator).click()

    def click_blog(self):
        self.wait_for_element_to_be_clickable(self._blog_link_locator)
        self.find_element(*self._blog_link_locator).click()
        self.wait.until(EC.visibility_of_element_located((By.ID, "site-title")))

    @property
    def header_login_button(self):
        self.wait_for_element_to_be_displayed(self._fxa_login_button_locator)
        return self.find_element(*self._fxa_login_button_locator)

    def click_header_login_button(self):
        self.wait_for_element_to_be_clickable(self._fxa_login_button_locator)
        self.find_element(*self._fxa_login_button_locator).click()
        from pages.desktop.frontend.login import Login

        return Login(self.driver, self.base_url)

    @property
    def sign_out_link(self):
        self.wait_for_element_to_be_displayed(self._sign_out_link_locator)
        return self.find_element(*self._sign_out_link_locator)

    def click_sign_out(self):
        self.sign_out_link.click()

    @property
    def user_avatar(self):
        self.wait_for_element_to_be_displayed(self._user_logged_in_avatar_locator)
        return self.find_element(*self._user_logged_in_avatar_locator)

    def devhub_login(self, user):
        fxa = self.click_header_login_button()
        # wait for the FxA login page to load
        self.wait.until(
            EC.visibility_of_element_located((By.NAME, "email")),
            message=f"FxA email input field was not displayed in {self.driver.current_url}",
        )
        fxa.account(user)
        # assess that the user has been logged in
        self.wait.until(
            lambda _: self.sign_out_link.is_displayed(),
            message=f"Log in flow was not successful. URL at fail time was {self.driver.current_url}",
        )

    @property
    def devhub_overview_title(self):
        self.wait_for_element_to_be_displayed(self._page_overview_title_locator)
        return self.find_element(*self._page_overview_title_locator).text

    @property
    def devhub_overview_summary(self):
        self.wait_for_element_to_be_displayed(self._page_overview_summary_locator)
        return self.find_element(*self._page_overview_summary_locator).text

    def click_overview_learn_how_button(self):
        self.wait_for_element_to_be_clickable(self._learn_how_button_locator)
        self.find_element(*self._learn_how_button_locator).click()

    @property
    def devhub_content_title(self):
        self.wait_for_element_to_be_displayed(self._page_content_title_locator)
        return self.find_element(*self._page_content_title_locator).text

    @property
    def devhub_content_summary(self):
        self.wait_for_element_to_be_displayed(self._page_content_summary_locator)
        return self.find_element(*self._page_content_summary_locator).text

    @property
    def devhub_content_image(self):
        self.wait_for_element_to_be_displayed(self._page_content_featured_image_locator)
        return self.find_element(*self._page_content_featured_image_locator)

    @property
    def devhub_get_involved_title(self):
        self.wait_for_element_to_be_displayed(self._get_involved_title_locator)
        return self.find_element(*self._get_involved_title_locator).text

    @property
    def devhub_get_involved_summary(self):
        self.wait_for_element_to_be_displayed(self._get_involved_summary_locator)
        return self.find_element(*self._get_involved_summary_locator).text

    @property
    def devhub_get_involved_link(self):
        self.wait_for_element_to_be_displayed(self._dev_community_link_locator)
        return self.find_element(*self._dev_community_link_locator)

    @property
    def devhub_get_involved_image(self):
        self.wait_for_element_to_be_displayed(self._get_involved_image_locator)
        return self.find_element(*self._get_involved_image_locator)

    @property
    def devhub_addon_contribute_title(self):
        self.wait_for_element_to_be_displayed(self._add_ons_contribute_title_locator)
        return self.find_element(*self._add_ons_contribute_title_locator)

    def click_content_login_link(self):
        self.wait_for_element_to_be_clickable(self._page_content_login_link_locator)
        self.find_element(*self._page_content_login_link_locator).click()

    @property
    def user_profile_icon(self):
        # get the 'alt' attribute to determine if img is uploaded by the user and is not the default avatar
        self.wait_for_element_to_be_displayed(self._user_profile_picture_locator)
        return self.find_element(*self._user_profile_picture_locator).get_attribute(
            "alt"
        )

    def click_user_profile_picture(self):
        icon = self.wait.until(
            EC.element_to_be_clickable(self._user_profile_picture_locator)
        )
        icon.click()
        from pages.desktop.frontend.users import User

        return User(self.driver, self.base_url)

    def click_my_addons_header_link(self):
        self.wait_for_element_to_be_clickable(self._my_addons_header_link_locator)
        self.find_element(*self._my_addons_header_link_locator).click()
        return ManageAddons(self.driver, self.base_url)

    @property
    def logged_in_hero_banner_header(self):
        self.wait_for_element_to_be_displayed(
            self._logged_in_hero_banner_header_locator
        )
        return self.find_element(*self._logged_in_hero_banner_header_locator).text

    @property
    def my_addons_section_header(self):
        self.wait_for_element_to_be_displayed(self._my_addons_section_header_locator)
        return self.find_element(*self._my_addons_section_header_locator)

    @property
    def my_addons_section_paragraph(self):
        self.wait_for_element_to_be_displayed(self._my_addons_section_paragraph_locator)
        return self.find_element(*self._my_addons_section_paragraph_locator)

    @property
    def logged_in_hero_banner_text(self):
        self.wait_for_element_to_be_displayed(self._logged_in_hero_banner_text_locator)
        return self.find_element(*self._logged_in_hero_banner_text_locator).text

    def click_logged_in_hero_banner_extension_workshop_link(self):
        self.wait_for_element_to_be_clickable(self._logged_in_hero_banner_link_locator)
        self.find_element(*self._logged_in_hero_banner_link_locator).click()

    def click_see_all_addons_link(self):
        self.wait_for_element_to_be_clickable(self._submit_addon_button_locator)
        self.find_element(*self._see_all_addons_link_locator).click()
        return ManageAddons(self.driver, self.base_url)

    def click_submit_addon_button(self):
        self.wait_for_element_to_be_clickable(self._submit_addon_button_locator)
        self.find_element(*self._submit_addon_button_locator).click()
        return SubmitAddon(self.driver, self.base_url)

    def click_submit_theme_button(self):
        self.find_element(*self._submit_theme_button_locator).click()
        return SubmitAddon(self.driver, self.base_url)

    @property
    def my_addons_list(self):
        items = self.find_elements(*self._my_addons_section_list_locator)
        return [self.MyAddonsList(self, el) for el in items]

    @property
    def connect(self):
        return ConnectFooter(self)

    @property
    def resources(self):
        return ResourcesFooter(self)

    def footer_language_picker(self, value):
        select = Select(self.find_element(*self._footer_language_picker_locator))
        select.select_by_visible_text(value)

    @property
    def products_links(self):
        self.wait_for_element_to_be_displayed(self._footer_products_section_locator)
        element = self.find_element(*self._footer_products_section_locator)
        return element.find_elements(*self._footer_links_locator)

    class MyAddonsList(Region):
        _my_addon_icon_locator = (By.CSS_SELECTOR, ".DevHub-MyAddons-item-icon")
        _my_addon_name_locator = (By.CSS_SELECTOR, ".DevHub-MyAddons-item-name")
        _my_addon_edit_link_locator = (By.CSS_SELECTOR, ".DevHub-MyAddons-item-edit")
        _my_addon_version_number_locator = (
            By.CSS_SELECTOR,
            ".DevHub-MyAddons-item-versions",
        )
        _my_addon_version_status_locator = (
            By.CSS_SELECTOR,
            ".DevHub-MyAddons-VersionStatus",
        )
        _my_addon_rating_text_locator = (By.CSS_SELECTOR, ".addon-rating strong")
        _my_addon_rating_stars_locator = (By.CSS_SELECTOR, ".stars")
        _my_addon_last_modified_date_locator = (
            By.CSS_SELECTOR,
            ".DevHub-MyAddons-item-modified span:nth-of-type(2)",
        )

        @property
        def my_addon_icon(self):
            self.wait.until(
                EC.visibility_of_element_located(self._my_addon_icon_locator)
            )
            return self.find_element(*self._my_addon_icon_locator)

        @property
        def my_addon_name(self):
            self.wait.until(
                EC.visibility_of_element_located(self._my_addon_name_locator)
            )
            return self.find_element(*self._my_addon_name_locator)

        def click_my_addon_edit_link(self):
            self.find_element(*self._my_addon_edit_link_locator).click()
            return EditAddon(self.driver, self.page.base_url)

        @property
        def my_addon_version_number(self):
            self.wait.until(
                EC.visibility_of_element_located(self._my_addon_version_number_locator)
            )
            return self.find_element(*self._my_addon_version_number_locator)

        @property
        def my_addon_version_status(self):
            self.wait.until(
                EC.visibility_of_element_located(self._my_addon_version_status_locator)
            )
            return self.find_element(*self._my_addon_version_status_locator)

        @property
        def my_addon_rating_text(self):
            self.wait.until(
                EC.visibility_of_element_located(self._my_addon_rating_text_locator)
            )
            return self.find_element(*self._my_addon_rating_text_locator)

        @property
        def my_addon_rating_stars(self):
            self.wait.until(
                EC.visibility_of_element_located(self._my_addon_rating_stars_locator)
            )
            return self.find_element(*self._my_addon_rating_stars_locator)

        @property
        def my_addon_last_modified_date(self):
            self.wait.until(
                EC.visibility_of_element_located(
                    self._my_addon_last_modified_date_locator
                )
            )
            return self.find_element(*self._my_addon_last_modified_date_locator)

        @property
        def my_addon_modified_date_text(self):
            """Get the date string from the Last Update date section and format it"""
            site_date = self.my_addon_last_modified_date.text
            month = site_date.split()[0]
            # get only the first three letters in the month to have a uniform date structure
            final_date = site_date.replace(month, month[0:3])
            return final_date

        def is_listed_addon(self):
            """Checks the add-on listing visibility in DevHub homepage
            by looking at its status in the Edit add-on page"""
            status = self.click_my_addon_edit_link()
            try:
                # DevHub homepage will display only the Approved or Awaiting Review statuses, so we check these first
                if (
                    "Approved" in status.listed_addon_status
                    or "Awaiting Review" in status.listed_addon_status
                ):
                    return True
                else:
                    # addon is either in Incomplete or Disabled status,
                    # so we won't see the status in DevHub homepage for such cases
                    return False
            except NoSuchElementException:
                # if the add-on is unlisted, there is no status displayed, so the 'listed_addon_status'
                # element is not present in the Edit Addon page, resulting in a 'NoSuchElementException'
                return False
            finally:
                # we execute this regardless of the status in order to go back and select
                # the next available addon in the Devhub Homepage, My Addons list
                self.driver.back()


class ConnectFooter(Region):
    _connect_footer_title_locator = (
        By.CSS_SELECTOR,
        ".DevHub-content-header--Connect h2",
    )
    _twitter_column_title_locator = (
        By.CSS_SELECTOR,
        ".Devhub-content-copy--Connect div:nth-child(1) h4:nth-child(1)",
    )
    _twitter_links_locator = (
        By.CSS_SELECTOR,
        ".DevHub-content-copy--Connect-twitter-list a",
    )
    _more_column_title_locator = (
        By.CSS_SELECTOR,
        ".Devhub-content-copy--Connect div:nth-child(2) h4:nth-child(1)",
    )
    _more_contact_links_locator = (
        By.CSS_SELECTOR,
        ".DevHub-Connect-section:nth-child(2) > ul a",
    )
    _newsletter_header_locator = (
        By.CSS_SELECTOR,
        ".Devhub-content-copy--Connect div:nth-child(3) h4",
    )
    _newsletter_info_text_locator = (
        By.CSS_SELECTOR,
        ".Devhub-content-copy--Connect div:nth-child(3) p",
    )
    _newsletter_email_input_field_locator = (By.ID, "email")
    _newsletter_sign_up_button_locator = (By.CSS_SELECTOR, ".btn-success")
    _newsletter_privacy_checkbox_locator = (By.ID, "privacy")
    _newsletter_privacy_notice_link_locator = (By.CSS_SELECTOR, ".form_group-agree a")
    _newsletter_sign_up_confirmation_header_locator = (
        By.CSS_SELECTOR,
        ".newsletter_thanks h2",
    )
    _newsletter_sign_up_confirmation_message_locator = (
        By.CSS_SELECTOR,
        ".newsletter_thanks p",
    )

    @property
    def connect_footer_title(self):
        self.wait.until(
            EC.visibility_of_element_located(self._connect_footer_title_locator)
        )
        return self.find_element(*self._connect_footer_title_locator).text

    @property
    def connect_twitter_title(self):
        self.wait.until(
            EC.visibility_of_element_located(self._twitter_column_title_locator)
        )
        return self.find_element(*self._twitter_column_title_locator).text

    @property
    def twitter_links(self):
        self.wait.until(EC.visibility_of_element_located(self._twitter_links_locator))
        return self.find_elements(*self._twitter_links_locator)

    @property
    def connect_more_title(self):
        self.wait.until(
            EC.visibility_of_element_located(self._more_column_title_locator)
        )
        return self.find_element(*self._more_column_title_locator).text

    @property
    def more_connect_links(self):
        self.wait.until(
            EC.visibility_of_element_located(self._more_contact_links_locator)
        )
        return self.find_elements(*self._more_contact_links_locator)

    @property
    def newsletter_section_header(self):
        self.wait.until(
            EC.visibility_of_element_located(self._newsletter_header_locator)
        )
        return self.find_element(*self._newsletter_header_locator).text

    @property
    def newsletter_info_text(self):
        self.wait.until(
            EC.visibility_of_element_located(self._newsletter_info_text_locator)
        )
        return self.find_element(*self._newsletter_info_text_locator).text

    def newsletter_email_input_field(self, email):
        self.wait.until(
            EC.element_to_be_clickable(self._newsletter_email_input_field_locator)
        )
        self.find_element(*self._newsletter_email_input_field_locator).send_keys(email)

    @property
    def newsletter_sign_up(self):
        self.wait.until(
            EC.visibility_of_element_located(self._newsletter_sign_up_button_locator)
        )
        return self.find_element(*self._newsletter_sign_up_button_locator)

    def click_privacy_checkbox(self):
        self.wait.until(
            EC.element_to_be_clickable(self._newsletter_privacy_checkbox_locator)
        )
        self.find_element(*self._newsletter_privacy_checkbox_locator).click()

    def click_newsletter_privacy_notice_link(self):
        self.find_element(*self._newsletter_privacy_notice_link_locator).click()
        self.wait.until(
            EC.number_of_windows_to_be(2),
            message=f"Number of windows was {len(self.driver.window_handles)}, expected 2",
        )
        new_tab = self.driver.window_handles[1]
        self.driver.switch_to.window(new_tab)

    @property
    def newsletter_signup_confirmation_header(self):
        self.wait.until(
            EC.visibility_of_element_located(
                self._newsletter_sign_up_confirmation_header_locator
            )
        )
        return self.find_element(
            *self._newsletter_sign_up_confirmation_header_locator
        ).text

    @property
    def newsletter_signup_confirmation_message(self):
        self.wait.until(
            EC.visibility_of_element_located(
                self._newsletter_sign_up_confirmation_message_locator
            )
        )
        return self.find_element(
            *self._newsletter_sign_up_confirmation_message_locator
        ).text

    def check_newsletter_signup_email(self, email):
        retry = 0
        while retry < 10:
            # verify that a response is available and get the email subject
            request = requests.get(f"https://restmail.net/mail/{email}", timeout=10)
            response = request.json()
            if response:
                confirmation = [key["subject"] for key in response]
                return confirmation
            elif not response:
                print("Confirmation email not received yet")
                # fail if we retired 10 times and there was no email received
                if retry == 9:
                    pytest.fail("Newsletter confirmation email was not sent")
                # pause between subsequent requests to give more time to the email to be sent
                time.sleep(2)
                retry += 1
        return self


class ResourcesFooter(Region):
    _documentation_section_header_locator = (
        By.CSS_SELECTOR,
        ".DevHub-Footer-sections:nth-of-type(1) .DevHub-Footer-section:nth-of-type(1) h4",
    )
    _documentation_section_locator = (
        By.CSS_SELECTOR,
        ".DevHub-Footer-sections:nth-of-type(1) .DevHub-Footer-section:nth-of-type(1)",
    )
    _tools_section_header_locator = (
        By.CSS_SELECTOR,
        ".DevHub-Footer-sections:nth-of-type(1) .DevHub-Footer-section:nth-of-type(2) h4",
    )
    _tools_section_locator = (
        By.CSS_SELECTOR,
        ".DevHub-Footer-sections:nth-of-type(1) .DevHub-Footer-section:nth-of-type(2)",
    )
    _promote_section_header_locator = (
        By.CSS_SELECTOR,
        ".DevHub-Footer-sections:nth-of-type(1) .DevHub-Footer-section:nth-of-type(3) h4",
    )
    _promote_section_locator = (
        By.CSS_SELECTOR,
        ".DevHub-Footer-sections:nth-of-type(1) .DevHub-Footer-section:nth-of-type(3)",
    )
    _resources_footer_section_links = (By.CSS_SELECTOR, ".DevHub-Footer-sections li a")
    _addon_review_section_header_locator = (
        By.CSS_SELECTOR,
        ".DevHub-Footer-sections:nth-of-type(2) .DevHub-Footer-section:nth-of-type(1) h4",
    )
    _addon_review_info_text_locator = (
        By.CSS_SELECTOR,
        ".DevHub-Footer-sections:nth-of-type(2) .DevHub-Footer-section:nth-of-type(1) p",
    )
    _addon_review_link_locator = (
        By.CSS_SELECTOR,
        ".DevHub-Footer-sections:nth-of-type(2) .DevHub-Footer-section:nth-of-type(1) a",
    )
    _write_code_section_header_locator = (
        By.CSS_SELECTOR,
        ".DevHub-Footer-sections:nth-of-type(2) .DevHub-Footer-section:nth-of-type(2) h4",
    )
    _write_code_info_text_locator = (
        By.CSS_SELECTOR,
        ".DevHub-Footer-sections:nth-of-type(2) .DevHub-Footer-section:nth-of-type(2) p",
    )
    _write_code_link_locator = (
        By.CSS_SELECTOR,
        ".DevHub-Footer-sections:nth-of-type(2) .DevHub-Footer-section:nth-of-type(2) a",
    )
    _participate_section_header_locator = (
        By.CSS_SELECTOR,
        ".DevHub-Footer-sections:nth-of-type(2) .DevHub-Footer-section:nth-of-type(2) h4",
    )
    _participate_info_text_locator = (
        By.CSS_SELECTOR,
        ".DevHub-Footer-sections:nth-of-type(2) .DevHub-Footer-section:nth-of-type(2) p",
    )
    _participate_link_locator = (
        By.CSS_SELECTOR,
        ".DevHub-Footer-sections:nth-of-type(2) .DevHub-Footer-section:nth-of-type(2) a",
    )

    @property
    def documentation_section_header(self):
        self.wait.until(
            EC.visibility_of_element_located(self._documentation_section_header_locator)
        )
        return self.find_element(*self._documentation_section_header_locator).text

    @property
    def documentation_section_links(self):
        self.wait.until(
            EC.visibility_of_element_located(self._documentation_section_locator)
        )
        el = self.find_element(*self._documentation_section_locator)
        return el.find_elements(*self._resources_footer_section_links)

    @property
    def tools_section_header(self):
        self.wait.until(
            EC.visibility_of_element_located(self._tools_section_header_locator)
        )
        return self.find_element(*self._tools_section_header_locator).text

    @property
    def tools_section_links(self):
        self.wait.until(EC.visibility_of_element_located(self._tools_section_locator))
        el = self.find_element(*self._tools_section_locator)
        return el.find_elements(*self._resources_footer_section_links)

    @property
    def promote_section_header(self):
        self.wait.until(
            EC.visibility_of_element_located(self._promote_section_header_locator)
        )
        return self.find_element(*self._promote_section_header_locator).text

    @property
    def promote_section_links(self):
        self.wait.until(EC.visibility_of_element_located(self._promote_section_locator))
        el = self.find_element(*self._promote_section_locator)
        return el.find_elements(*self._resources_footer_section_links)

    @property
    def review_addons_section_header(self):
        self.wait.until(
            EC.visibility_of_element_located(self._addon_review_section_header_locator)
        )
        return self.find_element(*self._addon_review_section_header_locator).text

    @property
    def review_addons_section_info_text(self):
        self.wait.until(
            EC.visibility_of_element_located(self._addon_review_info_text_locator)
        )
        return self.find_element(*self._addon_review_info_text_locator).text

    def click_join_addon_review_link(self):
        self.find_element(*self._addon_review_link_locator).click()

    @property
    def write_code_section_header(self):
        self.wait.until(
            EC.visibility_of_element_located(self._write_code_section_header_locator)
        )
        return self.find_element(*self._write_code_section_header_locator).text

    @property
    def write_code_section_info_text(self):
        self.wait.until(
            EC.visibility_of_element_located(self._write_code_info_text_locator)
        )
        return self.find_element(*self._write_code_info_text_locator).text

    def click_write_code_section_link(self):
        self.find_element(*self._write_code_link_locator).click()

    @property
    def participate_section_header(self):
        self.wait.until(
            EC.visibility_of_element_located(self._participate_section_header_locator)
        )
        return self.find_element(*self._participate_section_header_locator).text

    @property
    def participate_section_info_text(self):
        self.wait.until(
            EC.visibility_of_element_located(self._participate_info_text_locator)
        )
        return self.find_element(*self._participate_info_text_locator).text

    def click_participate_section_link(self):
        self.wait.until(EC.element_to_be_clickable(self._participate_link_locator))
        self.find_element(*self._participate_link_locator).click()
