pages/desktop/developers/submit_addon.py (804 lines of code) (raw):
import os
import time
from pathlib import Path
from pypom import Page
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from pages.desktop.developers.manage_versions import ManageVersions
class SubmitAddon(Page):
"""A class holding all the components used for addon submissions in DevHub"""
_my_addons_page_logo_locator = (By.CSS_SELECTOR, ".site-titles")
_submission_form_header_locator = (By.CSS_SELECTOR, ".is_addon")
_addon_distribution_header_locator = (
By.CSS_SELECTOR,
".addon-submission-process h3",
)
_developer_notification_box_locator = (By.CSS_SELECTOR, ".notification-box")
_distribution_page_explainer_locator = (
By.CSS_SELECTOR,
".addon-submission-process p:nth-of-type(1)",
)
_distribution_agreement_checkbox_locator = (By.ID, "id_distribution_agreement")
_distribution_agreement_link_locator = (
By.CSS_SELECTOR,
".addon-submission-process li:nth-of-type(1) a",
)
_review_policies_checkbox_locator = (By.ID, "id_review_policy")
_review_policies_link_locator = (
By.CSS_SELECTOR,
".addon-submission-process li:nth-of-type(2) a",
)
_user_consent_text_locator = (
By.CSS_SELECTOR,
".addon-submission-process p:nth-of-type(2)",
)
_recaptcha_locator = (By.ID, "id_recaptcha")
_recaptcha_checkbox_locator = (By.ID, "recaptcha-anchor")
_recaptcha_checkbox_is_selected_locator = (
By.CSS_SELECTOR,
'span[aria-checked="true"]',
)
_accept_agreement_button = (By.ID, "accept-agreement")
_cancel_agreement_button = (By.CSS_SELECTOR, ".submit-buttons a")
_dev_accounts_info_link_locator = (By.CSS_SELECTOR, ".addon-submission-process p a")
_listed_option_locator = (By.CSS_SELECTOR, 'input[value="listed"]')
_listed_option_helptext_locator = (
By.CSS_SELECTOR,
"label[for='id_channel_0'] span[class='helptext']",
)
_unlisted_option_locator = (By.CSS_SELECTOR, 'input[value="unlisted"]')
_unlisted_option_helptext_locator = (
By.CSS_SELECTOR,
"label[for='id_channel_1'] span[class='helptext']",
)
_distribution_and_signing_helptext_locator = (
By.CSS_SELECTOR,
".addon-submit-distribute p:nth-of-type(3)",
)
_addon_policies_helptext_locator = (
By.CSS_SELECTOR,
".addon-submit-distribute p:nth-of-type(4)",
)
_change_distribution_link_locator = (By.CSS_SELECTOR, ".addon-submit-distribute a")
_continue_button_locator = (By.CSS_SELECTOR, ".addon-submission-field button")
_file_upload_process_helptext_locator = (By.CSS_SELECTOR, ".new-addon-file p")
_upload_file_button_locator = (By.CSS_SELECTOR, "#upload-addon")
_accepted_file_types_locator = (By.CLASS_NAME, "upload-details")
_compatibility_helptext_locator = (By.CSS_SELECTOR, ".compatible-apps label")
_compatibility_error_message_locator = (By.CSS_SELECTOR, ".errorlist li")
_firefox_compat_checkbox_locator = (By.CSS_SELECTOR, ".app.firefox input")
_android_compat_checkbox_locator = (By.CSS_SELECTOR, ".app.android input")
_android_compat_pop_up = (By.ID, "modal-confirm-android-compatibility")
_android_compat_yes_button = (By.CSS_SELECTOR, "#modal-confirm-android-compatibility > form > div > button")
_create_theme_subheader_locator = (
By.CSS_SELECTOR,
".addon-create-theme-section h3",
)
_create_theme_button_locator = (By.ID, "wizardlink")
_submit_file_button_locator = (By.ID, "submit-upload-file-finish")
_addon_validation_success_locator = (By.CSS_SELECTOR, "#upload-status-bar.bar-success")
_validation_fail_bar_locator = (By.CLASS_NAME, "bar-fail")
_validation_support_link_locator = (By.CSS_SELECTOR, "#upload-status-results a")
_validation_failed_message_locator = (
By.CSS_SELECTOR,
"#upload-status-results strong",
)
_validation_warning_message_locator = (By.CSS_SELECTOR, ".submission-warning p")
_validation_summary_link_locator = (By.CSS_SELECTOR, ".submission-warning a")
_validation_fail_reason_locator = (By.CSS_SELECTOR, "#upload_errors li")
_validation_status_text_locator = (By.ID, "upload-status-text")
_validation_success_message_locator = (By.ID, "upload-status-results")
_failed_validation_message_locator = (By.CSS_SELECTOR, "#upload-status-results > strong:nth-child(2)")
@property
def my_addons_page_logo(self):
self.wait.until(
EC.visibility_of_element_located(self._my_addons_page_logo_locator)
)
return self.find_element(*self._my_addons_page_logo_locator)
@property
def submission_form_header(self):
self.wait.until(
EC.visibility_of_element_located(self._submission_form_header_locator)
)
return self.find_element(*self._submission_form_header_locator)
@property
def submission_form_subheader(self):
self.wait.until(
EC.visibility_of_element_located(self._addon_distribution_header_locator)
)
return self.find_element(*self._addon_distribution_header_locator)
@property
def developer_notification_box(self):
self.wait.until(
EC.visibility_of_element_located(self._developer_notification_box_locator)
)
return self.find_element(*self._developer_notification_box_locator)
@property
def distribution_page_explainer(self):
self.wait.until(
EC.visibility_of_element_located(self._distribution_page_explainer_locator)
)
return self.find_element(*self._distribution_page_explainer_locator).text
@property
def distribution_agreement_checkbox(self):
self.wait.until(
EC.visibility_of_element_located(
self._distribution_agreement_checkbox_locator
)
)
return self.find_element(*self._distribution_agreement_checkbox_locator)
@property
def distribution_agreement_article_link(self):
self.wait.until(
EC.visibility_of_element_located(self._distribution_agreement_link_locator)
)
return self.find_element(*self._distribution_agreement_link_locator)
@property
def review_policies_checkbox(self):
self.wait.until(
EC.visibility_of_element_located(self._review_policies_checkbox_locator)
)
return self.find_element(*self._review_policies_checkbox_locator)
@property
def review_policies_article_link(self):
self.wait.until(
EC.visibility_of_element_located(self._review_policies_link_locator)
)
return self.find_element(*self._review_policies_link_locator)
def click_extension_workshop_article_link(self, link, text):
"""Clicks on the Distribution agreement and the Policies links
which open an Extension Workshop article page in a new tab"""
link.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)
self.wait.until(
EC.text_to_be_present_in_element((By.CSS_SELECTOR, ".page-hero h1"), text)
)
self.driver.close()
# return to the main tab
self.driver.switch_to.window(self.driver.window_handles[0])
@property
def user_consent_text(self):
self.wait.until(
EC.visibility_of_element_located(self._user_consent_text_locator)
)
return self.find_element(*self._user_consent_text_locator).text
@property
def recaptcha(self):
self.wait.until(EC.visibility_of_element_located(self._recaptcha_locator))
return self.find_element(*self._recaptcha_locator)
def click_recaptcha_checkbox(self):
"""reCAPTCHA is stored in an iframe; switch to the iframe and click on the checkbox"""
el = self.find_element(By.CSS_SELECTOR, 'iframe[title="reCAPTCHA"]')
self.driver.switch_to.frame(el)
self.find_element(*self._recaptcha_checkbox_locator).click()
@property
def accept_agreement(self):
self.wait.until(EC.visibility_of_element_located(self._accept_agreement_button))
return self.find_element(*self._accept_agreement_button)
@property
def cancel_agreement(self):
self.wait.until(EC.visibility_of_element_located(self._cancel_agreement_button))
return self.find_element(*self._cancel_agreement_button)
def click_dev_accounts_info_link(self):
"""click on the Developer account info link and check that the
correct Extension Workshop article is opened"""
self.find_element(*self._dev_accounts_info_link_locator).click()
self.wait.until(
EC.text_to_be_present_in_element(
(By.CSS_SELECTOR, ".page-hero h1"), "Developer accounts"
)
)
@property
def listed_option_helptext(self):
self.wait.until(
EC.visibility_of_element_located(self._listed_option_helptext_locator)
)
return self.find_element(*self._listed_option_helptext_locator).text
@property
def unlisted_option_helptext(self):
self.wait.until(
EC.visibility_of_element_located(self._unlisted_option_helptext_locator)
)
return self.find_element(*self._unlisted_option_helptext_locator)
@property
def update_url_link(self):
return self.unlisted_option_helptext.find_element(By.CSS_SELECTOR, "a")
@property
def listed_option_radiobutton(self):
self.wait.until(EC.visibility_of_element_located(self._listed_option_locator))
return self.find_element(*self._listed_option_locator)
def select_listed_option(self):
self.wait.until(EC.element_to_be_clickable(self._listed_option_locator))
self.find_element(*self._listed_option_locator).click()
def select_unlisted_option(self):
self.wait.until(EC.element_to_be_clickable(self._unlisted_option_locator))
self.find_element(*self._unlisted_option_locator).click()
@property
def distribution_and_signing_helptext(self):
self.wait.until(
EC.visibility_of_element_located(
self._distribution_and_signing_helptext_locator
)
)
return self.find_element(*self._distribution_and_signing_helptext_locator)
@property
def distribution_and_signing_link(self):
return self.distribution_and_signing_helptext.find_element(By.CSS_SELECTOR, "a")
@property
def addon_policies_helptext(self):
self.wait.until(
EC.visibility_of_element_located(self._addon_policies_helptext_locator)
)
return self.find_element(*self._addon_policies_helptext_locator)
@property
def addon_policies_link(self):
return self.addon_policies_helptext.find_element(By.CSS_SELECTOR, "a")
def change_version_distribution(self):
"""Changes the distribution (listed/unlisted) when submitting a new version"""
self.find_element(*self._change_distribution_link_locator).click()
self.wait.until(EC.visibility_of_element_located(self._listed_option_locator))
def click_continue(self):
self.find_element(*self._continue_button_locator).click()
@property
def file_upload_helptext(self):
self.wait.until(
EC.visibility_of_element_located(self._file_upload_process_helptext_locator)
)
return self.find_elements(*self._file_upload_process_helptext_locator)
def upload_addon(self, addon):
"""Selects an addon from the 'sample-addons' folder and uploads it"""
button = self.find_element(*self._upload_file_button_locator)
archive = Path(f"{os.getcwd()}/sample-addons/{addon}")
button.send_keys(str(archive))
@property
def accepted_file_types(self):
self.wait.until(
EC.visibility_of_element_located(self._accepted_file_types_locator)
)
return self.find_element(*self._accepted_file_types_locator).text
@property
def compatibility_helptext(self):
self.wait.until(
EC.visibility_of_element_located(self._compatibility_helptext_locator)
)
return self.find_elements(*self._compatibility_helptext_locator)[0].text
@property
def compatibility_error_message(self):
self.wait.until(
EC.visibility_of_element_located(self._compatibility_error_message_locator)
)
return self.find_element(*self._compatibility_error_message_locator).text
@property
def firefox_compat_checkbox(self):
return self.find_element(*self._firefox_compat_checkbox_locator)
@property
def android_compat_checkbox(self):
self.wait.until(
EC.visibility_of_element_located(self._android_compat_checkbox_locator)
)
return self.find_element(*self._android_compat_checkbox_locator)
@property
def android_compat_pop_up(self):
self.wait.until(
EC.visibility_of_element_located(self._android_compat_pop_up)
)
return self.find_element(*self._android_compat_pop_up)
@property
def android_compat_yes_button(self):
self.wait.until(
EC.visibility_of_element_located(self._android_compat_yes_button)
)
return self.find_element(*self._android_compat_yes_button)
@property
def create_theme_subheader(self):
self.wait.until(
EC.visibility_of_element_located(self._create_theme_subheader_locator)
)
return self.find_element(*self._create_theme_subheader_locator).text
def click_create_theme_button(self):
self.find_element(*self._create_theme_button_locator).click()
return ThemeWizard(self.driver, self.base_url).wait_for_page_to_load()
def is_validation_successful(self):
"""Wait for addon validation to complete; if not successful, the test will fail"""
self.wait.until(
EC.visibility_of_element_located(self._addon_validation_success_locator)
)
@property
def failed_validation_bar(self):
self.wait.until(
EC.visibility_of_element_located(self._validation_fail_bar_locator)
)
return self.find_element(*self._validation_fail_bar_locator)
@property
def validation_status_title(self):
self.wait.until(
EC.visibility_of_element_located(self._validation_status_text_locator)
)
return self.find_element(*self._validation_status_text_locator).text
def click_validation_support_link(self):
self.find_element(*self._validation_support_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)
self.wait.until(EC.url_contains("/mozilla/addons-linter/"))
self.driver.close()
# return to the main tab
self.driver.switch_to.window(self.driver.window_handles[0])
def is_validation_failed(self):
self.wait.until(
EC.visibility_of_element_located(self._validation_fail_bar_locator)
)
@property
def validation_failed_message(self):
self.wait.until(
EC.visibility_of_element_located(self._validation_failed_message_locator)
)
return self.find_element(*self._validation_failed_message_locator).text
@property
def validation_failed_reason(self):
self.wait.until(
EC.visibility_of_element_located(self._validation_fail_reason_locator)
)
return self.find_elements(*self._validation_fail_reason_locator)
@property
def validation_warning_message(self):
self.wait.until(
EC.visibility_of_element_located(self._validation_warning_message_locator)
)
return self.find_element(*self._validation_warning_message_locator).text
def click_validation_summary(self):
self.find_element(*self._validation_summary_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)
self.wait.until(EC.visibility_of_element_located((By.CLASS_NAME, "results")))
return ValidationResults(self.driver, self.base_url)
@property
def success_validation_message(self):
self.wait.until(
EC.visibility_of_element_located(self._validation_success_message_locator)
)
return self.find_element(*self._validation_success_message_locator)
def click_continue_upload_button(self):
self.find_element(*self._submit_file_button_locator).click()
return UploadSource(self.driver, self.base_url)
def submit_button_disabled(self):
self.find_element(*self._submit_file_button_locator).get_attribute("disabled")
@property
def failed_validation_message(self):
return self.find_element(*self._failed_validation_message_locator)
class ValidationResults(Page):
_validation_results_header_locator = (
By.CSS_SELECTOR,
"div[class='section'] header h2",
)
_validation_summary_shelf_locator = (By.CLASS_NAME, "tiers")
_validation_general_results_locator = (By.ID, "suite-results-tier-1")
_validation_security_results_locator = (By.ID, "suite-results-tier-2")
_validation_extension_results_locator = (By.ID, "suite-results-tier-3")
_validation_localization_results_locator = (By.ID, "suite-results-tier-4")
_validation_compatibility_results_locator = (By.ID, "suite-results-tier-5")
@property
def validation_results_header(self):
self.wait.until(
EC.visibility_of_element_located(self._validation_results_header_locator)
)
return self.find_element(*self._validation_results_header_locator).text
@property
def validation_summary_shelf(self):
self.wait.until(
EC.visibility_of_element_located(self._validation_results_header_locator)
)
return self.find_element(*self._validation_summary_shelf_locator)
@property
def validation_general_results(self):
self.wait.until(
EC.visibility_of_element_located(self._validation_general_results_locator)
)
return self.find_element(*self._validation_general_results_locator)
@property
def validation_security_results(self):
self.wait.until(
EC.visibility_of_element_located(self._validation_security_results_locator)
)
return self.find_element(*self._validation_security_results_locator)
@property
def validation_extension_results(self):
self.wait.until(
EC.visibility_of_element_located(self._validation_extension_results_locator)
)
return self.find_element(*self._validation_extension_results_locator)
@property
def validation_localization_results(self):
self.wait.until(
EC.visibility_of_element_located(
self._validation_localization_results_locator
)
)
return self.find_element(*self._validation_localization_results_locator)
@property
def validation_compatibility_results(self):
self.wait.until(
EC.visibility_of_element_located(
self._validation_compatibility_results_locator
)
)
return self.find_element(*self._validation_compatibility_results_locator)
class UploadSource(Page):
_submit_source_code_page_header_locator = (
By.CSS_SELECTOR,
".addon-submission-process h3",
)
_yes_submit_source_radio_button_locator = (By.ID, "id_has_source_0")
_no_submit_source_radio_button_locator = (By.ID, "id_has_source_1")
_choose_source_file_button_locator = (By.ID, "id_source")
_continue_button_locator = (
By.CSS_SELECTOR,
".submission-buttons button:nth-child(1)",
)
_upload_source_error_message_locator = (By.CSS_SELECTOR, ".errorlist li")
_cancel_and_disable_version_locator = (
By.CSS_SELECTOR,
".confirm-submission-cancel",
)
_cancel_and_disable_explainer_text_locator = (
By.CSS_SELECTOR,
"#modal-confirm-submission-cancel p",
)
_cancel_version_confirm_button_locator = (
By.CSS_SELECTOR,
".modal-confirm-submission-cancel .delete-button",
)
_yes_cancel_and_disable_version = (By.CSS_SELECTOR, "button.delete-button:nth-child(1)")
_do_not_cancel_version_link_locator = (By.CSS_SELECTOR, "#modal-confirm-submission-cancel > form > div > a")
_release_notes_field_locator = (By.ID, "trans-release_notes")
_notes_to_reviewer_locator = (By.ID, "id_approval_notes")
_version_submitted_text_locator = (By.CLASS_NAME, ".addon-submission-process h3")
@property
def submit_source_page_header(self):
self.wait.until(
EC.visibility_of_element_located(
self._submit_source_code_page_header_locator
)
)
return self.find_element(*self._submit_source_code_page_header_locator).text
def select_yes_to_submit_source(self):
self.wait.until(
EC.visibility_of_element_located(
self._yes_submit_source_radio_button_locator
)
)
self.find_element(*self._yes_submit_source_radio_button_locator).click()
def select_no_to_omit_source(self):
self.find_element(*self._no_submit_source_radio_button_locator).click()
def choose_source(self, file):
button = self.find_element(*self._choose_source_file_button_locator)
archive = Path(f"{os.getcwd()}/sample-addons/{file}")
button.send_keys(str(archive))
def continue_unlisted_submission(self):
self.find_element(*self._continue_button_locator).click()
return SubmissionConfirmationPage(
self.driver, self.base_url
).wait_for_page_to_load()
def continue_listed_submission(self):
self.find_element(*self._continue_button_locator).click()
return ListedAddonSubmissionForm(
self.driver, self.base_url
).wait_for_page_to_load()
@property
def source_upload_fail_message(self):
self.wait.until(
EC.visibility_of_element_located(self._upload_source_error_message_locator)
)
return self.find_element(*self._upload_source_error_message_locator).text
def click_cancel_and_disable_version(self):
self.find_element(*self._cancel_and_disable_version_locator).click()
@property
def cancel_and_disable_explainer_text(self):
self.wait.until(
EC.visibility_of_element_located(
self._cancel_and_disable_explainer_text_locator
)
)
return self.find_element(*self._cancel_and_disable_explainer_text_locator).text
def click_do_not_cancel_version(self):
return self.find_element(*self._do_not_cancel_version_link_locator).click()
def confirm_cancel_and_disable_version(self):
self.find_element(*self._yes_cancel_and_disable_version).click()
return ManageVersions(self.driver, self.base_url).wait_for_page_to_load()
def release_notes_field(self):
self.wait.until(
EC.visibility_of_element_located(
self._release_notes_field_locator
)
)
return self.find_element(*self._release_notes_field_locator)
def notes_to_reviewers_field(self):
self.wait.until(
EC.visibility_of_element_located(
self._notes_to_reviewer_locator
)
)
return self.find_element(*self._notes_to_reviewer_locator)
def version_submitted_text(self):
self.wait.until(
EC.visibility_of_element_located(
self._version_submitted_text_locator
)
)
return self.find_element(*self._version_submitted_text_locator).text
class ListedAddonSubmissionForm(Page):
_addon_name_field_locator = (By.CSS_SELECTOR, "#trans-name input:nth-child(1)")
_edit_addon_slug_link_locator = (By.ID, "edit_slug")
_edit_addon_slug_field_locator = (By.ID, "id_slug")
_addon_summary_field_locator = (By.ID, "id_summary_0")
_addon_detail_fields_info_text_locator = (By.CSS_SELECTOR, ".edit-addon-details")
_summary_character_count_locator = (
By.CSS_SELECTOR,
".char-count[data-for-startswith='id_summary_'] > b",
)
_addon_description_field_locator = (By.ID, "id_description_0")
_is_experimental_checkbox_locator = (By.ID, "id_is_experimental")
_requires_payment_checkbox_locator = (By.ID, "id_requires_payment")
_categories_section_locator = (By.ID, "addon-categories-edit")
_categories_locator = (
By.CSS_SELECTOR,
".addon-app-cats:nth-of-type(1) > ul input",
)
# _android_categories_locator = (
# By.CSS_SELECTOR,
# ".addon-app-cats:nth-of-type(2) > ul input",
# )
_email_input_field_locator = (By.ID, "id_support_email_0")
_support_site_input_field_locator = (By.ID, "id_support_url_0")
_license_options_locator = (By.CLASS_NAME, "license")
_license_details_link_locator = (By.CSS_SELECTOR, ".xx.extra")
_custom_license_name_locator = (By.ID, "id_license-name")
_custom_license_text_locator = (By.ID, "id_license-text")
_privacy_policy_checkbox_locator = (By.ID, "id_has_priv")
_privacy_policy_textarea_locator = (By.ID, "id_privacy_policy_0")
_reviewer_notes_textarea_locator = (By.ID, "id_approval_notes")
_submit_addon_button_locator = (
By.CSS_SELECTOR,
".submission-buttons button:nth-child(1)",
)
_cancel_addon_submission_button_locator = (
By.CSS_SELECTOR,
".submission-buttons button:nth-child(2)",
)
# _theme_categories_locator = (By.CSS_SELECTOR, '#addon-categories-edit > ul input') - temporary not available
_theme_categories_locator = (By.CSS_SELECTOR, ".addon-app-cats")
_theme_category_abstract_locator = (By.CSS_SELECTOR, "#id_categories > div:nth-child(1) > label")
_theme_licence_sharing_rights_locator = (
By.CSS_SELECTOR,
"#cc-chooser ul:nth-of-type(1) input",
)
_theme_license_commercial_use_locator = (
By.CSS_SELECTOR,
"#cc-chooser ul:nth-of-type(2) input",
)
_theme_license_creation_rights_locator = (
By.CSS_SELECTOR,
"#cc-chooser ul:nth-of-type(3) input",
)
_selected_theme_license_locator = (By.CSS_SELECTOR, "#cc-license")
_open_theme_licenses_list_locator = (By.CLASS_NAME, "select-license")
_theme_licenses_list_locator = (By.CSS_SELECTOR, "#id_license-builtin input")
def wait_for_page_to_load(self):
self.wait.until(
EC.visibility_of_element_located(self._addon_summary_field_locator)
)
return self
def set_addon_name(self, value):
self.find_element(*self._addon_name_field_locator).send_keys(value)
def clear_addon_name(self):
self.find_element(*self._addon_name_field_locator).clear()
@property
def theme_category_abstract(self):
return self.find_element(*self._theme_category_abstract_locator)
@property
def addon_name_field(self):
self.wait.until(
EC.visibility_of_element_located(self._addon_name_field_locator)
)
return self.find_element(*self._addon_name_field_locator)
def edit_addon_slug(self, value):
self.find_element(*self._edit_addon_slug_link_locator).click()
edit_field = WebDriverWait(self.driver, 10).until(
EC.visibility_of_element_located(self._edit_addon_slug_field_locator)
)
edit_field.send_keys(value)
def set_addon_summary(self, value):
self.find_element(*self._addon_summary_field_locator).send_keys(value)
def addon_detail_fields_info_text(self):
self.find_elements(*self._addon_detail_fields_info_text_locator)
@property
def summary_character_count(self):
self.wait.until(
EC.visibility_of_element_located(self._summary_character_count_locator)
)
return self.find_element(*self._summary_character_count_locator).text
def set_addon_description(self, value):
self.find_element(*self._addon_description_field_locator).send_keys(value)
@property
def is_experimental(self):
self.wait.until(
EC.visibility_of_element_located(self._is_experimental_checkbox_locator)
)
return self.find_element(*self._is_experimental_checkbox_locator)
@property
def requires_payment(self):
self.wait.until(
EC.visibility_of_element_located(self._requires_payment_checkbox_locator)
)
return self.find_element(*self._requires_payment_checkbox_locator)
@property
def categories_section(self):
self.wait.until(
EC.visibility_of_element_located(self._categories_section_locator)
)
return self.find_element(*self._categories_section_locator)
def select_categories(self, count):
self.find_elements(*self._categories_locator)[count].click()
# def select_android_categories(self, count):
# self.find_elements(*self._android_categories_locator)[count].click()
def select_theme_categories(self, count):
self.find_elements(*self._theme_categories_locator)[count].click()
def email_input_field(self, value):
self.find_element(*self._email_input_field_locator).send_keys(value)
def support_site_input_field(self, value):
self.find_element(*self._support_site_input_field_locator).send_keys(value)
@property
def select_license_options(self):
self.wait.until(EC.visibility_of_element_located(self._license_options_locator))
return self.find_elements(*self._license_options_locator)
def license_option_names(self, count, value):
return self.select_license_options[count].get_attribute(value)
def license_details_link(self):
self.wait.until(
EC.visibility_of_element_located(self._license_details_link_locator)
)
self.find_element(*self._license_details_link_locator).click()
def set_custom_license_name(self, value):
self.wait.until(
EC.visibility_of_element_located(self._custom_license_name_locator)
)
self.find_element(*self._custom_license_name_locator).send_keys(value)
def set_custom_license_text(self, value):
self.wait.until(
EC.visibility_of_element_located(self._custom_license_text_locator)
)
self.find_element(*self._custom_license_text_locator).send_keys(value)
def select_theme_licence_sharing_rights(self, count):
self.wait.until(
EC.visibility_of_element_located(self._theme_licence_sharing_rights_locator)
)
self.find_elements(*self._theme_licence_sharing_rights_locator)[count].click()
def select_theme_license_commercial_use(self, count):
self.wait.until(
EC.visibility_of_element_located(self._theme_license_commercial_use_locator)
)
self.find_elements(*self._theme_license_commercial_use_locator)[count].click()
def select_theme_license_creation_rights(self, count):
self.find_elements(*self._theme_license_creation_rights_locator)[count].click()
@property
def generated_theme_license(self):
self.wait.until(
EC.visibility_of_element_located(self._selected_theme_license_locator)
)
return self.find_element(*self._selected_theme_license_locator)
def open_theme_licenses_list(self):
self.wait.until(
EC.visibility_of_element_located(self._open_theme_licenses_list_locator)
)
self.find_element(*self._open_theme_licenses_list_locator).click()
def select_theme_license_from_list(self):
self.wait.until(
EC.visibility_of_element_located(self._theme_licenses_list_locator)
)
self.find_elements(*self._theme_licenses_list_locator)
def set_privacy_policy(self, value):
self.wait.until(
EC.element_to_be_clickable(self._privacy_policy_checkbox_locator)
)
self.find_element(*self._privacy_policy_checkbox_locator).click()
self.find_element(*self._privacy_policy_textarea_locator).send_keys(value)
def set_reviewer_notes(self, value):
self.find_element(*self._reviewer_notes_textarea_locator).send_keys(value)
def submit_addon(self):
self.find_element(*self._submit_addon_button_locator).click()
return SubmissionConfirmationPage(
self.driver, self.base_url
).wait_for_page_to_load()
def cancel_submission(self):
self.find_element(*self._cancel_addon_submission_button_locator).click()
from pages.desktop.developers.edit_addon import EditAddon
return EditAddon(self.driver, self.base_url).wait_for_page_to_load()
class ThemeWizard(Page):
_wizard_header_locator = (By.CSS_SELECTOR, ".addon-submission-process > h3")
_theme_name_input_field = (By.ID, "theme-name")
_upload_theme_image_button_locator = (By.ID, "header-img")
_uploaded_image_preview_locator = (By.CLASS_NAME, "preview.loaded")
_change_image_button_locator = (By.CLASS_NAME, "reset")
_browser_preview_locator = (By.ID, "preview-svg-root")
_browser_preview_header_image_locator = (By.ID, "svg-header-img")
_submit_theme_button_locator = (By.CLASS_NAME, "button.upload")
_cancel_submission_button_locator = (
By.CSS_SELECTOR,
".submission-buttons .delete-button",
)
def wait_for_page_to_load(self):
self.wait.until(EC.visibility_of_element_located((By.ID, "theme-header")))
return self
@property
def wizard_header(self):
self.wait.until(EC.visibility_of_element_located(self._wizard_header_locator))
return self.find_element(*self._wizard_header_locator).text
def set_theme_name(self, value):
self.find_element(*self._theme_name_input_field).send_keys(value)
def upload_theme_header(self, img):
button = self.find_element(*self._upload_theme_image_button_locator)
header_img = Path(f"{os.getcwd()}/img/{img}")
button.send_keys(str(header_img))
@property
def uploaded_image_preview(self):
self.wait.until(
EC.visibility_of_element_located(self._uploaded_image_preview_locator)
)
return self.find_element(*self._uploaded_image_preview_locator)
@property
def uploaded_image_source(self):
"""Fetch the source of the uploaded theme image"""
return self.uploaded_image_preview.get_attribute("src")
@property
def browser_preview(self):
self.wait.until(EC.visibility_of_element_located(self._browser_preview_locator))
return self.find_element(*self._browser_preview_locator)
@property
def browser_preview_image(self):
"""Fetch the source of tha generated theme preview image"""
return self.find_element(
*self._browser_preview_header_image_locator
).get_attribute("href")
def submit_theme(self):
self.find_element(*self._submit_theme_button_locator).click()
time.sleep(5)
return ListedAddonSubmissionForm(
self.driver, self.base_url
).wait_for_page_to_load()
def cancel_submission(self):
self.find_element(*self._cancel_submission_button_locator).click()
return SubmitAddon(self.driver, self.base_url).wait_for_page_to_load()
class SubmissionConfirmationPage(Page):
_confirmation_page_header_locator = (
By.CSS_SELECTOR,
".addon-submission-process h3",
)
_confirmation_messages_locator = (By.CSS_SELECTOR, ".addon-submission-process p")
_manage_listing_button_locator = (By.LINK_TEXT, "Go to My Submissions")
_edit_version_button_locator = (
By.CSS_SELECTOR,
".addon-submission-process p:nth-child(6) > a",
)
_edit_listing_button_locator = (By.LINK_TEXT, "Manage Listing")
_theme_preview_locator = (By.CSS_SELECTOR, ".addon-submission-process img")
def wait_for_page_to_load(self):
self.wait.until(
EC.visibility_of_element_located(self._confirmation_page_header_locator)
)
return self
@property
def submission_confirmation_messages(self):
self.wait.until(
EC.visibility_of_element_located(self._confirmation_messages_locator)
)
return self.find_elements(*self._confirmation_messages_locator)
def click_manage_listing_button(self):
self.wait.until(EC.element_to_be_clickable(self._manage_listing_button_locator))
self.find_element(*self._manage_listing_button_locator).click()
from pages.desktop.developers.addons_manage import ManageAddons
return ManageAddons(self.driver, self.base_url).wait_for_page_to_load()
def click_edit_version_button(self):
self.wait.until(EC.element_to_be_clickable(self._edit_version_button_locator))
self.find_element(*self._edit_version_button_locator).click()
return ManageVersions(self.driver, self.base_url)
def click_edit_listing_button(self):
self.wait.until(EC.element_to_be_clickable(self._edit_listing_button_locator))
self.find_element(*self._edit_listing_button_locator).click()
from pages.desktop.developers.edit_addon import EditAddon
return EditAddon(self.driver, self.base_url).wait_for_page_to_load()
@property
def generated_theme_preview(self):
return self.find_element(*self._theme_preview_locator)