Migrate to PyPOM and remove implicit waits (#387)
This commit is contained in:
Родитель
7d2061f284
Коммит
022ee6cf2d
|
@ -1,10 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
from selenium.webdriver.common.by import By
|
||||
|
||||
from pages.base import Base
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from pypom import Page
|
||||
from selenium.webdriver.common.by import By
|
||||
|
||||
from pages.page import Page
|
||||
from selenium.webdriver.support import expected_conditions as expected
|
||||
|
||||
|
||||
class Auth0(Page):
|
||||
|
@ -14,8 +14,8 @@ class Auth0(Page):
|
|||
_send_email_button_locator = (By.CSS_SELECTOR, '.auth0-lock-passwordless-submit')
|
||||
|
||||
def request_login_link(self, username):
|
||||
self.wait_for_element_visible(*self._login_with_email_button_locator)
|
||||
self.selenium.find_element(*self._login_with_email_button_locator).click()
|
||||
self.wait_for_element_visible(*self._email_input_locator)
|
||||
self.selenium.find_element(*self._email_input_locator).send_keys(username)
|
||||
self.selenium.find_element(*self._send_email_button_locator).click()
|
||||
self.wait.until(expected.visibility_of_element_located(
|
||||
self._login_with_email_button_locator)).click()
|
||||
self.wait.until(expected.visibility_of_element_located(
|
||||
self._email_input_locator)).send_keys(username)
|
||||
self.find_element(*self._send_email_button_locator).click()
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from pypom import Page
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.common.keys import Keys
|
||||
from selenium.webdriver.support import expected_conditions as expected
|
||||
from selenium.webdriver.support.select import Select
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
|
||||
from pages.auth0 import Auth0
|
||||
from pages.page import Page
|
||||
from tests import conftest
|
||||
|
||||
|
||||
class Base(Page):
|
||||
URL_TEMPLATE = '/{locale}'
|
||||
|
||||
_logout_locator = (By.ID, 'nav-logout')
|
||||
|
||||
|
@ -24,18 +23,21 @@ class Base(Page):
|
|||
# Not logged in
|
||||
_sign_in_button_locator = (By.ID, 'nav-login')
|
||||
|
||||
def __init__(self, selenium, base_url, locale='en-US', **url_kwargs):
|
||||
super(Base, self).__init__(selenium, base_url, locale=locale, **url_kwargs)
|
||||
|
||||
@property
|
||||
def page_title(self):
|
||||
WebDriverWait(self.selenium, self.timeout).until(lambda s: self.selenium.title)
|
||||
self.wait.until(lambda s: self.selenium.title)
|
||||
return self.selenium.title
|
||||
|
||||
@property
|
||||
def is_pending_approval_visible(self):
|
||||
return self.is_element_visible(*self._pending_approval_locator)
|
||||
return self.is_element_displayed(*self._pending_approval_locator)
|
||||
|
||||
@property
|
||||
def was_account_created_successfully(self):
|
||||
return self.is_element_visible(*self._account_created_successfully_locator)
|
||||
return self.is_element_displayed(*self._account_created_successfully_locator)
|
||||
|
||||
# Not logged in
|
||||
|
||||
|
@ -48,36 +50,28 @@ class Base(Page):
|
|||
return self.is_element_present(*self._logout_locator)
|
||||
|
||||
def click_sign_in_button(self):
|
||||
self.selenium.find_element(*self._sign_in_button_locator).click()
|
||||
self.find_element(*self._sign_in_button_locator).click()
|
||||
|
||||
def login(self, email):
|
||||
self.click_sign_in_button()
|
||||
auth0 = Auth0(self.base_url, self.selenium)
|
||||
auth0 = Auth0(self.selenium, self.base_url)
|
||||
auth0.request_login_link(email)
|
||||
login_link = conftest.login_link(email)
|
||||
self.selenium.get(login_link)
|
||||
WebDriverWait(self.selenium, self.timeout).until(lambda s: self.is_user_loggedin)
|
||||
self.wait.until(lambda s: self.is_user_loggedin)
|
||||
|
||||
def create_new_user(self, email):
|
||||
self.login(email)
|
||||
from pages.register import Register
|
||||
return Register(self.base_url, self.selenium)
|
||||
return Register(self.selenium, self.base_url).wait_for_page_to_load()
|
||||
|
||||
@property
|
||||
def header(self):
|
||||
return self.Header(self.base_url, self.selenium)
|
||||
return self.Header(self.selenium, self.base_url)
|
||||
|
||||
@property
|
||||
def footer(self):
|
||||
return self.Footer(self.base_url, self.selenium)
|
||||
|
||||
def open_user_profile(self, username):
|
||||
self.get_relative_path(u'/u/%s' % username)
|
||||
from pages.profile import Profile
|
||||
return Profile(self.base_url, self.selenium)
|
||||
|
||||
def logout_using_url(self):
|
||||
self.get_relative_path(u'/logout')
|
||||
return self.Footer(self.selenium, self.base_url)
|
||||
|
||||
class Header(Page):
|
||||
|
||||
|
@ -99,18 +93,19 @@ class Base(Page):
|
|||
|
||||
def search_for(self, search_term, loggedin=False):
|
||||
if loggedin:
|
||||
search_field = self.selenium.find_element(*self._search_box_loggedin_locator)
|
||||
search_field = self.find_element(*self._search_box_loggedin_locator)
|
||||
else:
|
||||
search_field = self.selenium.find_element(*self._search_box_locator)
|
||||
search_field = self.find_element(*self._search_box_locator)
|
||||
search_field.send_keys(search_term)
|
||||
search_field.send_keys(Keys.RETURN)
|
||||
from pages.search import Search
|
||||
return Search(self.base_url, self.selenium)
|
||||
return Search(self.selenium, self.base_url).wait_for_page_to_load()
|
||||
|
||||
def click_options(self):
|
||||
self.wait_for_element_present(*self._profile_menu_locator)
|
||||
self.selenium.find_element(*self._profile_menu_locator).click()
|
||||
WebDriverWait(self.selenium, self.timeout).until(lambda s: self.selenium.find_element(*self._dropdown_menu_locator))
|
||||
self.wait.until(expected.visibility_of_element_located(
|
||||
self._profile_menu_locator)).click()
|
||||
self.wait.until(expected.visibility_of_element_located(
|
||||
self._dropdown_menu_locator))
|
||||
|
||||
@property
|
||||
def is_logout_menu_item_present(self):
|
||||
|
@ -123,26 +118,26 @@ class Base(Page):
|
|||
# menu items
|
||||
def click_view_profile_menu_item(self):
|
||||
self.click_options()
|
||||
self.selenium.find_element(*self._view_profile_menu_item_locator).click()
|
||||
self.find_element(*self._view_profile_menu_item_locator).click()
|
||||
from pages.profile import Profile
|
||||
return Profile(self.base_url, self.selenium)
|
||||
return Profile(self.selenium, self.base_url).wait_for_page_to_load()
|
||||
|
||||
def click_invite_menu_item(self):
|
||||
self.click_options()
|
||||
self.selenium.find_element(*self._invite_menu_item_locator).click()
|
||||
self.find_element(*self._invite_menu_item_locator).click()
|
||||
from pages.invite import Invite
|
||||
return Invite(self.base_url, self.selenium)
|
||||
return Invite(self.selenium, self.base_url)
|
||||
|
||||
def click_settings_menu_item(self):
|
||||
self.click_options()
|
||||
self.selenium.find_element(*self._settings_menu_item_locator).click()
|
||||
self.find_element(*self._settings_menu_item_locator).click()
|
||||
from pages.settings import Settings
|
||||
return Settings(self.base_url, self.selenium)
|
||||
return Settings(self.selenium, self.base_url)
|
||||
|
||||
def click_logout_menu_item(self):
|
||||
self.click_options()
|
||||
self.selenium.find_element(*self._logout_menu_item_locator).click()
|
||||
WebDriverWait(self.selenium, self.timeout).until(lambda s: not self.is_logout_menu_item_present)
|
||||
self.find_element(*self._logout_menu_item_locator).click()
|
||||
self.wait.until(lambda s: not self.is_logout_menu_item_present)
|
||||
|
||||
class Footer(Page):
|
||||
|
||||
|
@ -151,11 +146,11 @@ class Base(Page):
|
|||
_language_selection_ok_button = (By.CSS_SELECTOR, '#language-switcher button')
|
||||
|
||||
def click_about_link(self):
|
||||
self.selenium.find_element(*self._about_mozillians_link_locator).click()
|
||||
self.find_element(*self._about_mozillians_link_locator).click()
|
||||
from pages.about import About
|
||||
return About(self.base_url, self.selenium)
|
||||
return About(self.selenium, self.base_url)
|
||||
|
||||
def select_language(self, lang_code):
|
||||
element = self.selenium.find_element(*self._language_selector_locator)
|
||||
element = self.find_element(*self._language_selector_locator)
|
||||
select = Select(element)
|
||||
select.select_by_value(lang_code)
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
from selenium.webdriver.common.by import By
|
||||
|
||||
from pages.base import Base
|
||||
|
@ -18,7 +15,7 @@ class ConfirmProfileDelete(Base):
|
|||
|
||||
@property
|
||||
def is_confirm_text_present(self):
|
||||
return self.is_element_visible(*self._confirm_profile_delete_text_locator)
|
||||
return self.is_element_displayed(*self._confirm_profile_delete_text_locator)
|
||||
|
||||
@property
|
||||
def is_delete_button_present(self):
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support import expected_conditions as expected
|
||||
|
||||
from pages.base import Base
|
||||
|
||||
|
@ -17,12 +15,11 @@ class CreateGroupPage(Base):
|
|||
_create_group_submit_button = (By.CSS_SELECTOR, 'form.add-group .btn-primary')
|
||||
|
||||
def create_group_name(self, group_name):
|
||||
self.wait_for_element_visible(*self._create_group_name)
|
||||
element = self.selenium.find_element(*self._create_group_name)
|
||||
element.send_keys(group_name)
|
||||
self.wait.until(expected.visibility_of_element_located(
|
||||
self._create_group_name)).send_keys(group_name)
|
||||
|
||||
def click_create_group_submit(self):
|
||||
self.wait_for_element_visible(*self._create_group_form)
|
||||
self.selenium.find_element(*self._create_group_submit_button).click()
|
||||
self.wait.until(expected.visibility_of_element_located(self._create_group_form))
|
||||
self.find_element(*self._create_group_submit_button).click()
|
||||
from pages.edit_group import EditGroupPage
|
||||
return EditGroupPage(self.base_url, self.selenium)
|
||||
return EditGroupPage(self.selenium, self.base_url)
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from pypom import Region
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support.wait import WebDriverWait
|
||||
from selenium.webdriver.support import expected_conditions as expected
|
||||
|
||||
from pages.base import Base
|
||||
from pages.page import PageRegion
|
||||
|
||||
|
||||
class EditGroupPage(Base):
|
||||
|
@ -17,138 +17,130 @@ class EditGroupPage(Base):
|
|||
_invitations_button_locator = (By.ID, 'invitations-tab')
|
||||
_invitations_tab_locator = (By.ID, 'invitations')
|
||||
|
||||
def __init__(self, base_url, selenium):
|
||||
super(EditGroupPage, self).__init__(base_url, selenium)
|
||||
WebDriverWait(self.selenium, self.timeout).until(
|
||||
lambda s: self.is_element_visible(*self._description_button_locator))
|
||||
def wait_for_page_to_load(self):
|
||||
self.wait.until(lambda s: self.is_element_displayed(*self._description_button_locator))
|
||||
return self
|
||||
|
||||
@property
|
||||
def description(self):
|
||||
self.selenium.find_element(*self._description_button_locator).click()
|
||||
return self.DescriptionTab(self.base_url, self.selenium,
|
||||
self.selenium.find_element(*self._description_tab_locator))
|
||||
self.find_element(*self._description_button_locator).click()
|
||||
return self.DescriptionTab(self, self.find_element(*self._description_tab_locator))
|
||||
|
||||
@property
|
||||
def access(self):
|
||||
self.selenium.find_element(*self._access_button_locator).click()
|
||||
return self.AccessTab(self.base_url, self.selenium,
|
||||
self.selenium.find_element(*self._access_tab_locator))
|
||||
self.find_element(*self._access_button_locator).click()
|
||||
return self.AccessTab(self, self.find_element(*self._access_tab_locator))
|
||||
|
||||
@property
|
||||
def invitations(self):
|
||||
self.wait_for_element_visible(*self._invitations_button_locator)
|
||||
self.selenium.find_element(*self._invitations_button_locator).click()
|
||||
return self.InvitationsTab(self.base_url, self.selenium,
|
||||
self.selenium.find_element(*self._invitations_tab_locator))
|
||||
self.wait.until(expected.visibility_of_element_located(
|
||||
self._invitations_button_locator)).click()
|
||||
return self.InvitationsTab(self, self.find_element(*self._invitations_tab_locator))
|
||||
|
||||
class DescriptionTab(PageRegion):
|
||||
class DescriptionTab(Region):
|
||||
_description_form_locator = (By.ID, 'description-form')
|
||||
_delete_panel_locator = (By.CSS_SELECTOR, '.panel-danger')
|
||||
|
||||
@property
|
||||
def description_info(self):
|
||||
return self.DescriptionForm(self.base_url, self.selenium,
|
||||
self._root_element.find_element(*self._description_form_locator))
|
||||
return self.DescriptionForm(self.page, self.find_element(*self._description_form_locator))
|
||||
|
||||
@property
|
||||
def delete_group(self):
|
||||
return self.DeletePanel(self.base_url, self.selenium,
|
||||
self._root_element.find_element(*self._delete_panel_locator))
|
||||
return self.DeletePanel(self.page, self.find_element(*self._delete_panel_locator))
|
||||
|
||||
class DescriptionForm(PageRegion):
|
||||
class DescriptionForm(Region):
|
||||
_description_locator = (By.ID, 'id_description')
|
||||
_irc_channel_locator = (By.ID, 'id_irc_channel')
|
||||
_update_locator = (By.ID, 'form-submit-description')
|
||||
|
||||
def set_description(self, description_text):
|
||||
element = self._root_element.find_element(*self._description_locator)
|
||||
element = self.find_element(*self._description_locator)
|
||||
element.clear()
|
||||
element.send_keys(description_text)
|
||||
|
||||
def set_irc_channel(self, irc_channel):
|
||||
element = self._root_element.find_element(*self._irc_channel_locator)
|
||||
element = self.find_element(*self._irc_channel_locator)
|
||||
element.clear()
|
||||
element.send_keys(irc_channel)
|
||||
|
||||
def click_update(self):
|
||||
self._root_element.find_element(*self._update_locator).click()
|
||||
self.wait_for_element_not_present(*self._update_locator)
|
||||
self.wait_for_element_present(*self._update_locator)
|
||||
el = self.find_element(*self._update_locator)
|
||||
el.click()
|
||||
self.wait.until(expected.staleness_of(el))
|
||||
self.wait.until(expected.presence_of_element_located(
|
||||
self._update_locator))
|
||||
|
||||
class DeletePanel(PageRegion):
|
||||
class DeletePanel(Region):
|
||||
_delete_acknowledgement_locator = (By.ID, 'delete-checkbox')
|
||||
_delete_group_button_locator = (By.ID, 'delete-group')
|
||||
|
||||
def check_acknowledgement(self):
|
||||
self._root_element.find_element(*self._delete_acknowledgement_locator).click()
|
||||
self.find_element(*self._delete_acknowledgement_locator).click()
|
||||
|
||||
@property
|
||||
def is_delete_button_enabled(self):
|
||||
return 'disabled' not in self._root_element.find_element(*self._delete_group_button_locator).get_attribute('class')
|
||||
return 'disabled' not in self.find_element(*self._delete_group_button_locator).get_attribute('class')
|
||||
|
||||
def click_delete_group(self):
|
||||
self._root_element.find_element(*self._delete_group_button_locator).click()
|
||||
self.find_element(*self._delete_group_button_locator).click()
|
||||
from pages.groups_page import GroupsPage
|
||||
return GroupsPage(self.base_url, self.selenium)
|
||||
return GroupsPage(self.page.selenium, self.page.base_url)
|
||||
|
||||
class AccessTab(PageRegion):
|
||||
class AccessTab(Region):
|
||||
_group_type_form_locator = (By.ID, 'grouptype-form')
|
||||
|
||||
@property
|
||||
def group_type(self):
|
||||
return self.GroupTypeForm(self.base_url, self.selenium,
|
||||
self._root_element.find_element(*self._group_type_form_locator))
|
||||
return self.GroupTypeForm(self.page, self.find_element(*self._group_type_form_locator))
|
||||
|
||||
class GroupTypeForm(PageRegion):
|
||||
class GroupTypeForm(Region):
|
||||
_reviewed_type_locator = (By.ID, 'id_accepting_new_members_1')
|
||||
_new_member_criteria_locator = (By.ID, 'id_new_member_criteria_fieldset')
|
||||
|
||||
def set_reviewed_group_type(self):
|
||||
self._root_element.find_element(*self._reviewed_type_locator).click()
|
||||
self.find_element(*self._reviewed_type_locator).click()
|
||||
|
||||
@property
|
||||
def is_member_criteria_visible(self):
|
||||
return self._root_element.find_element(*self._new_member_criteria_locator).is_displayed()
|
||||
return self.find_element(*self._new_member_criteria_locator).is_displayed()
|
||||
|
||||
class InvitationsTab(PageRegion):
|
||||
class InvitationsTab(Region):
|
||||
_invite_form_locator = (By.ID, 'invite-form')
|
||||
_invitations_list_form_locator = (By.ID, 'invitations-form')
|
||||
|
||||
@property
|
||||
def invitations_list(self):
|
||||
return self.InvitationsForm(self.base_url, self.selenium,
|
||||
self._root_element.find_element(*self._invitations_list_form_locator))
|
||||
return self.InvitationsForm(self.page, self.find_element(*self._invitations_list_form_locator))
|
||||
|
||||
@property
|
||||
def invite(self):
|
||||
return self.InviteForm(self.base_url, self.selenium,
|
||||
self._root_element.find_element(*self._invite_form_locator))
|
||||
return self.InviteForm(self.page, self.find_element(*self._invite_form_locator))
|
||||
|
||||
class InvitationsForm(PageRegion):
|
||||
class InvitationsForm(Region):
|
||||
_invitatation_list_locator = (By.CSS_SELECTOR, '.invitee')
|
||||
|
||||
@property
|
||||
def search_invitation_list(self):
|
||||
return [self.SearchResult(self.base_url, self.selenium, el) for el in
|
||||
self.selenium.find_elements(*self._invitatation_list_locator)]
|
||||
return [self.SearchResult(self.page, el) for el in
|
||||
self.find_elements(*self._invitatation_list_locator)]
|
||||
|
||||
class SearchResult(PageRegion):
|
||||
class SearchResult(Region):
|
||||
_name_locator = (By.CSS_SELECTOR, '.invitee a:nth-child(2)')
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._root_element.find_element(*self._name_locator).text
|
||||
return self.find_element(*self._name_locator).text
|
||||
|
||||
class InviteForm(PageRegion):
|
||||
class InviteForm(Region):
|
||||
_invite_search_locator = (By.CSS_SELECTOR, '.select2-search__field')
|
||||
_invite_locator = (By.ID, 'form-submit-invite')
|
||||
|
||||
def invite_new_member(self, mozillian):
|
||||
search = self._root_element.find_element(*self._invite_search_locator)
|
||||
search = self.find_element(*self._invite_search_locator)
|
||||
search.send_keys(mozillian)
|
||||
self.wait_for_element_visible(By.XPATH, '//li[contains(text(), "{0}")]'.format(mozillian))
|
||||
result = self._root_element.find_element(By.XPATH, '//li[contains(text(), "{0}")]'.format(mozillian))
|
||||
result.click()
|
||||
self.wait.until(expected.visibility_of_element_located((
|
||||
By.XPATH, '//li[contains(text(), "{0}")]'.format(mozillian)))).click()
|
||||
|
||||
def click_invite(self):
|
||||
self._root_element.find_element(*self._invite_locator).click()
|
||||
self.find_element(*self._invite_locator).click()
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
import random
|
||||
|
||||
from selenium.webdriver.common.by import By
|
||||
|
@ -42,92 +39,92 @@ class EditProfile(Base):
|
|||
_services_mozilla_reps_locator = (By.ID, 'services-mozilla-reps')
|
||||
|
||||
def click_update_button(self):
|
||||
self.selenium.find_element(*self._update_button_locator).click()
|
||||
return Profile(self.base_url, self.selenium)
|
||||
self.find_element(*self._update_button_locator).click()
|
||||
return Profile(self.selenium, self.base_url)
|
||||
|
||||
def click_cancel_button(self):
|
||||
self.selenium.find_element(*self._cancel_button_locator).click()
|
||||
self.find_element(*self._cancel_button_locator).click()
|
||||
|
||||
def click_find_group_link(self):
|
||||
self.selenium.find_element(*self._find_group_page).click()
|
||||
return GroupsPage(self.base_url, self.selenium)
|
||||
self.find_element(*self._find_group_page).click()
|
||||
return GroupsPage(self.selenium, self.base_url)
|
||||
|
||||
def set_full_name(self, full_name):
|
||||
element = self.selenium.find_element(*self._full_name_field_locator)
|
||||
element = self.find_element(*self._full_name_field_locator)
|
||||
element.clear()
|
||||
element.send_keys(full_name)
|
||||
|
||||
def set_website(self, website):
|
||||
element = self.selenium.find_element(*self._website_field_locator)
|
||||
element = self.find_element(*self._website_field_locator)
|
||||
element.clear()
|
||||
element.send_keys(website)
|
||||
|
||||
def set_bio(self, biography):
|
||||
element = self.selenium.find_element(*self._bio_field_locator)
|
||||
element = self.find_element(*self._bio_field_locator)
|
||||
element.clear()
|
||||
element.send_keys(biography)
|
||||
|
||||
def add_skill(self, skill_name):
|
||||
element = self.selenium.find_element(*self._skills_field_locator)
|
||||
element = self.find_element(*self._skills_field_locator)
|
||||
element.send_keys(skill_name)
|
||||
element.send_keys(Keys.RETURN)
|
||||
|
||||
@property
|
||||
def vouched_by(self):
|
||||
return self.selenium.find_element(*self._voucher_name_locator).text
|
||||
return self.find_element(*self._voucher_name_locator).text
|
||||
|
||||
@property
|
||||
def username(self):
|
||||
return self.selenium.find_element(*self._username_field_locator).text
|
||||
return self.find_element(*self._username_field_locator).text
|
||||
|
||||
def click_delete_profile_button(self):
|
||||
self.selenium.find_element(*self._acknowledge_deletion_checkbox_locator).click()
|
||||
self.selenium.find_element(*self._delete_profile_button_locator).click()
|
||||
self.find_element(*self._acknowledge_deletion_checkbox_locator).click()
|
||||
self.find_element(*self._delete_profile_button_locator).click()
|
||||
from pages.confirm_profile_delete import ConfirmProfileDelete
|
||||
return ConfirmProfileDelete(self.base_url, self.selenium)
|
||||
return ConfirmProfileDelete(self.selenium, self.base_url)
|
||||
|
||||
def select_month(self, option_month):
|
||||
element = self.selenium.find_element(*self._select_month_locator)
|
||||
element = self.find_element(*self._select_month_locator)
|
||||
select = Select(element)
|
||||
select.select_by_value(option_month)
|
||||
|
||||
def select_year(self, option_year):
|
||||
element = self.selenium.find_element(*self._select_year_locator)
|
||||
element = self.find_element(*self._select_year_locator)
|
||||
select = Select(element)
|
||||
select.select_by_value(option_year)
|
||||
|
||||
@property
|
||||
def month(self):
|
||||
return self.selenium.find_element(*self._selected_month_locator).text
|
||||
return self.find_element(*self._selected_month_locator).text
|
||||
|
||||
@property
|
||||
def year(self):
|
||||
return self.selenium.find_element(*self._selected_year_locator).text
|
||||
return self.find_element(*self._selected_year_locator).text
|
||||
|
||||
@property
|
||||
def months_values(self):
|
||||
return [month.get_attribute('value') for month in self.selenium.find_elements(*self._month_locator)]
|
||||
return [month.get_attribute('value') for month in self.find_elements(*self._month_locator)]
|
||||
|
||||
def select_random_month(self):
|
||||
return self.select_month(random.choice(self.months_values[1:]))
|
||||
|
||||
@property
|
||||
def years_values(self):
|
||||
return [year.get_attribute('value') for year in self.selenium.find_elements(*self._year_locator)]
|
||||
return [year.get_attribute('value') for year in self.find_elements(*self._year_locator)]
|
||||
|
||||
@property
|
||||
def groups(self):
|
||||
groups = self.selenium.find_elements(*self._groups_locator)
|
||||
groups = self.find_elements(*self._groups_locator)
|
||||
return [groups[i].text for i in range(0, len(groups))]
|
||||
|
||||
@property
|
||||
def skills(self):
|
||||
skills = self.selenium.find_elements(*self._skills_locator)
|
||||
skills = self.find_elements(*self._skills_locator)
|
||||
return [skills[i].text for i in range(0, len(skills))]
|
||||
|
||||
@property
|
||||
def delete_skill_buttons(self):
|
||||
return self.selenium.find_elements(*self._delete_skill_buttons_locator)
|
||||
return self.find_elements(*self._delete_skill_buttons_locator)
|
||||
|
||||
def select_random_year(self):
|
||||
return self.select_year(random.choice(self.years_values[1:]))
|
||||
|
@ -137,7 +134,7 @@ class EditProfile(Base):
|
|||
urls = []
|
||||
|
||||
for element in locs:
|
||||
url = self.selenium.find_element(*element).get_attribute('href')
|
||||
url = self.find_element(*element).get_attribute('href')
|
||||
urls.append(url)
|
||||
|
||||
return urls
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support import expected_conditions as expected
|
||||
|
||||
from pages.base import Base
|
||||
|
||||
|
@ -16,16 +14,20 @@ class GroupInfoPage(Base):
|
|||
_description_locator = (By.CSS_SELECTOR, '.group-description')
|
||||
_irc_channel_locator = (By.ID, 'group-irc')
|
||||
|
||||
def wait_for_page_to_load(self):
|
||||
self.wait.until(lambda _: self.find_element(By.CSS_SELECTOR, 'html.js body#group-show'))
|
||||
return self
|
||||
|
||||
def delete_group(self):
|
||||
self.wait_for_element_visible(*self._delete_group_button)
|
||||
self.selenium.find_element(*self._delete_group_button).click()
|
||||
self.wait.until(expected.visibility_of_element_located(
|
||||
self._delete_group_button)).click()
|
||||
from pages.groups_page import GroupsPage
|
||||
return GroupsPage(self.base_url, self.selenium)
|
||||
return GroupsPage(self.selenium, self.base_url)
|
||||
|
||||
@property
|
||||
def description(self):
|
||||
return self.selenium.find_element(*self._description_locator).text
|
||||
return self.find_element(*self._description_locator).text
|
||||
|
||||
@property
|
||||
def irc_channel(self):
|
||||
return self.selenium.find_element(*self._irc_channel_locator).text
|
||||
return self.find_element(*self._irc_channel_locator).text
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support import expected_conditions as expected
|
||||
|
||||
from pages.base import Base
|
||||
from pages.create_group_page import CreateGroupPage
|
||||
|
@ -17,11 +15,12 @@ class GroupsPage(Base):
|
|||
_alert_message_locator = (By.CSS_SELECTOR, '.alert-info')
|
||||
|
||||
def click_create_group_main_button(self):
|
||||
self.selenium.find_element(*self._create_group_main_button).click()
|
||||
return CreateGroupPage(self.base_url, self.selenium)
|
||||
self.find_element(*self._create_group_main_button).click()
|
||||
return CreateGroupPage(self.selenium, self.base_url)
|
||||
|
||||
def wait_for_alert_message(self):
|
||||
self.wait_for_element_visible(*self._alert_message_locator)
|
||||
self.wait.until(expected.visibility_of_element_located(
|
||||
self._alert_message_locator))
|
||||
|
||||
def is_group_deletion_alert_present(self):
|
||||
return self.is_element_visible(*self._alert_message_locator)
|
||||
return self.is_element_displayed(*self._alert_message_locator)
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
|
||||
from pages.base import Base
|
||||
|
||||
|
@ -15,28 +12,18 @@ class Home(Base):
|
|||
_groups_link_locator = (By.CSS_SELECTOR, 'section.groups > a')
|
||||
_functional_areas_link_locator = (By.CSS_SELECTOR, 'section.functional-areas > a')
|
||||
|
||||
def __init__(self, base_url, selenium, open_url=True):
|
||||
Base.__init__(self, base_url, selenium)
|
||||
if open_url:
|
||||
self.selenium.get(self.base_url)
|
||||
|
||||
@property
|
||||
def is_groups_link_visible(self):
|
||||
return self.is_element_visible(*self._groups_link_locator)
|
||||
return self.is_element_displayed(*self._groups_link_locator)
|
||||
|
||||
@property
|
||||
def is_functional_areas_link_visible(self):
|
||||
return self.is_element_visible(*self._functional_areas_link_locator)
|
||||
|
||||
def go_to_localized_settings_page(self, non_US):
|
||||
self.get_relative_path("/" + non_US + "/user/edit/")
|
||||
from pages.settings import Settings
|
||||
return Settings(self.base_url, self.selenium)
|
||||
return self.is_element_displayed(*self._functional_areas_link_locator)
|
||||
|
||||
def wait_for_user_login(self):
|
||||
# waits to see if user gets logged back in
|
||||
# if not then all ok
|
||||
try:
|
||||
WebDriverWait(self.selenium, self.timeout).until(lambda s: self.is_user_loggedin)
|
||||
self.wait.until(lambda s: self.is_user_loggedin)
|
||||
except Exception:
|
||||
pass
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
from selenium.webdriver.common.by import By
|
||||
|
||||
from pages.base import Base
|
||||
|
@ -19,13 +16,13 @@ class Invite(Base):
|
|||
|
||||
@property
|
||||
def error_text_message(self):
|
||||
return self.selenium.find_element(*self._error_text_locator).text
|
||||
return self.find_element(*self._error_text_locator).text
|
||||
|
||||
def invite(self, email, reason=''):
|
||||
email_field = self.selenium.find_element(*self._recipient_field_locator)
|
||||
email_field = self.find_element(*self._recipient_field_locator)
|
||||
email_field.send_keys(email)
|
||||
reason_field = self.selenium.find_element(*self._vouch_reason_field_locator)
|
||||
reason_field = self.find_element(*self._vouch_reason_field_locator)
|
||||
reason_field.send_keys(reason)
|
||||
self.selenium.find_element(*self._send_invite_button_locator).click()
|
||||
self.find_element(*self._send_invite_button_locator).click()
|
||||
from pages.invite_success import InviteSuccess
|
||||
return InviteSuccess(self.base_url, self.selenium)
|
||||
return InviteSuccess(self.selenium, self.base_url)
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
from selenium.webdriver.common.by import By
|
||||
|
||||
from pages.base import Base
|
||||
|
@ -16,4 +13,4 @@ class InviteSuccess(Base):
|
|||
|
||||
@property
|
||||
def success_message(self):
|
||||
return self.selenium.find_element(*self._success_message_locator).text
|
||||
return self.find_element(*self._success_message_locator).text
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from random import randrange
|
||||
|
||||
from pypom import Region
|
||||
from selenium.webdriver.common.by import By
|
||||
|
||||
from pages.base import Base
|
||||
from pages.page import PageRegion
|
||||
|
||||
|
||||
class LocationSearchResults(Base):
|
||||
|
@ -19,26 +17,25 @@ class LocationSearchResults(Base):
|
|||
|
||||
@property
|
||||
def title(self):
|
||||
return self.selenium.find_element(*self._results_title_locator).text
|
||||
return self.find_element(*self._results_title_locator).text
|
||||
|
||||
@property
|
||||
def results_count(self):
|
||||
return len(self.selenium.find_elements(*self._result_item_locator))
|
||||
return len(self.find_elements(*self._result_item_locator))
|
||||
|
||||
@property
|
||||
def search_results(self):
|
||||
return [self.SearchResult(self.base_url, self.selenium, el) for el in
|
||||
self.selenium.find_elements(*self._result_item_locator)]
|
||||
return [self.SearchResult(self, el) for el in self.find_elements(*self._result_item_locator)]
|
||||
|
||||
def get_random_profile(self):
|
||||
random_index = randrange(self.results_count)
|
||||
return self.search_results[random_index].open_profile_page()
|
||||
|
||||
class SearchResult(PageRegion):
|
||||
class SearchResult(Region):
|
||||
|
||||
_profile_page_link_locator = (By.CSS_SELECTOR, 'img')
|
||||
|
||||
def open_profile_page(self):
|
||||
self._root_element.find_element(*self._profile_page_link_locator).click()
|
||||
self.find_element(*self._profile_page_link_locator).click()
|
||||
from pages.profile import Profile
|
||||
return Profile(self.base_url, self.selenium)
|
||||
return Profile(self.page.selenium, self.page.base_url)
|
||||
|
|
102
pages/page.py
102
pages/page.py
|
@ -1,102 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import time
|
||||
|
||||
from selenium.common.exceptions import (ElementNotVisibleException,
|
||||
NoSuchElementException,
|
||||
TimeoutException)
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
|
||||
|
||||
class Page(object):
|
||||
|
||||
def __init__(self, base_url, selenium):
|
||||
self.base_url = base_url
|
||||
self.selenium = selenium
|
||||
self.timeout = 60
|
||||
|
||||
@property
|
||||
def is_the_current_page(self):
|
||||
if self._page_title:
|
||||
WebDriverWait(self.selenium, self.timeout).until(lambda s: s.title)
|
||||
|
||||
assert self._page_title == self.selenium.title
|
||||
return True
|
||||
|
||||
def scroll_to_element(self, element):
|
||||
self.selenium.execute_script("return arguments[0].scrollIntoView();", element)
|
||||
|
||||
def get_url_current_page(self):
|
||||
WebDriverWait(self.selenium, self.timeout).until(lambda s: s.title)
|
||||
return self.selenium.current_url
|
||||
|
||||
def is_element_present(self, *locator):
|
||||
self.selenium.implicitly_wait(0)
|
||||
try:
|
||||
self.selenium.find_element(*locator)
|
||||
return True
|
||||
except NoSuchElementException:
|
||||
return False
|
||||
finally:
|
||||
# set back to where you once belonged
|
||||
self.selenium.implicitly_wait(10)
|
||||
|
||||
def wait_for_element_visible(self, *locator):
|
||||
count = 0
|
||||
while not self.is_element_visible(*locator):
|
||||
time.sleep(1)
|
||||
count += 1
|
||||
if count == self.timeout:
|
||||
raise Exception(':'.join(locator) + " is not visible")
|
||||
|
||||
def wait_for_element_not_visible(self, *locator):
|
||||
count = 0
|
||||
while self.is_element_visible(*locator):
|
||||
time.sleep(1)
|
||||
count += 1
|
||||
if count == self.timeout:
|
||||
raise Exception(':'.join(locator) + " is still visible")
|
||||
|
||||
def wait_for_element_present(self, *locator):
|
||||
"""Wait for an element to become present."""
|
||||
self.selenium.implicitly_wait(0)
|
||||
try:
|
||||
WebDriverWait(self.selenium, self.timeout).until(
|
||||
lambda s: s.find_element(*locator))
|
||||
finally:
|
||||
# set back to where you once belonged
|
||||
self.selenium.implicitly_wait(10)
|
||||
|
||||
def wait_for_element_not_present(self, *locator):
|
||||
"""Wait for an element to become not present."""
|
||||
self.selenium.implicitly_wait(0)
|
||||
try:
|
||||
WebDriverWait(self.selenium, self.timeout).until(
|
||||
lambda s: len(s.find_elements(*locator)) < 1)
|
||||
return True
|
||||
except TimeoutException:
|
||||
return False
|
||||
finally:
|
||||
# set back to where you once belonged
|
||||
self.selenium.implicitly_wait(10)
|
||||
|
||||
def is_element_visible(self, *locator):
|
||||
try:
|
||||
return self.selenium.find_element(*locator).is_displayed()
|
||||
except (NoSuchElementException, ElementNotVisibleException):
|
||||
return False
|
||||
|
||||
def return_to_previous_page(self):
|
||||
self.selenium.back()
|
||||
|
||||
def get_relative_path(self, url):
|
||||
self.selenium.get(u'%s%s' % (self.base_url, url))
|
||||
|
||||
|
||||
class PageRegion(Page):
|
||||
|
||||
def __init__(self, base_url, selenium, root_element):
|
||||
Page.__init__(self, base_url, selenium)
|
||||
self._root_element = root_element
|
|
@ -1,18 +1,15 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support.select import Select
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
|
||||
from pages.base import Base
|
||||
|
||||
|
||||
class Profile(Base):
|
||||
URL_TEMPLATE = '/{locale}/u/{username}'
|
||||
|
||||
_profile_photo_locator = (By.CSS_SELECTOR, '#profile-stats > div.profile-photo img')
|
||||
_name_locator = (By.CSS_SELECTOR, 'h1.p-name')
|
||||
|
@ -31,86 +28,85 @@ class Profile(Base):
|
|||
_profile_message_locator = (By.CSS_SELECTOR, '.alert')
|
||||
_view_as_locator = (By.ID, 'view-privacy-mode')
|
||||
|
||||
def __init__(self, base_url, selenium):
|
||||
Base.__init__(self, base_url, selenium)
|
||||
WebDriverWait(self.selenium, self.timeout).until(
|
||||
lambda s: self.is_element_visible(*self._profile_photo_locator))
|
||||
def wait_for_page_to_load(self):
|
||||
self.wait.until(lambda _: self.find_element(By.CSS_SELECTOR, 'html.js body#profile'))
|
||||
return self
|
||||
|
||||
def view_profile_as(self, view_as):
|
||||
element = self.selenium.find_element(*self._view_as_locator)
|
||||
element = self.find_element(*self._view_as_locator)
|
||||
select = Select(element)
|
||||
select.select_by_visible_text(view_as)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self.selenium.find_element(*self._name_locator).text
|
||||
return self.find_element(*self._name_locator).text
|
||||
|
||||
@property
|
||||
def biography(self):
|
||||
return self.selenium.find_element(*self._biography_locator).text
|
||||
return self.find_element(*self._biography_locator).text
|
||||
|
||||
@property
|
||||
def email(self):
|
||||
return self.selenium.find_element(*self._email_locator).text
|
||||
return self.find_element(*self._email_locator).text
|
||||
|
||||
@property
|
||||
def irc_nickname(self):
|
||||
return self.selenium.find_element(*self._irc_nickname_locator).text
|
||||
return self.find_element(*self._irc_nickname_locator).text
|
||||
|
||||
@property
|
||||
def website(self):
|
||||
return self.selenium.find_element(*self._website_locator).text
|
||||
return self.find_element(*self._website_locator).text
|
||||
|
||||
@property
|
||||
def vouched_by(self):
|
||||
return self.selenium.find_element(*self._vouched_by_locator).text
|
||||
return self.find_element(*self._vouched_by_locator).text
|
||||
|
||||
@property
|
||||
def skills(self):
|
||||
return self.selenium.find_element(*self._skills_locator).text.split('\n')[1]
|
||||
return self.find_element(*self._skills_locator).text.split('\n')[1]
|
||||
|
||||
@property
|
||||
def groups(self):
|
||||
return self.selenium.find_element(*self._groups_locator).text.split('\n')[1]
|
||||
return self.find_element(*self._groups_locator).text.split('\n')[1]
|
||||
|
||||
@property
|
||||
def location(self):
|
||||
return self.selenium.find_element(*self._location_locator).text
|
||||
return self.find_element(*self._location_locator).text
|
||||
|
||||
@property
|
||||
def city(self):
|
||||
return self.selenium.find_element(*self._city_locator).text
|
||||
return self.find_element(*self._city_locator).text
|
||||
|
||||
@property
|
||||
def region(self):
|
||||
return self.selenium.find_element(*self._region_locator).text
|
||||
return self.find_element(*self._region_locator).text
|
||||
|
||||
@property
|
||||
def country(self):
|
||||
return self.selenium.find_element(*self._country_locator).text
|
||||
return self.find_element(*self._country_locator).text
|
||||
|
||||
def click_profile_city_filter(self):
|
||||
self.selenium.find_element(*self._city_locator).click()
|
||||
self.find_element(*self._city_locator).click()
|
||||
from location_search_results import LocationSearchResults
|
||||
return LocationSearchResults(self.base_url, self.selenium)
|
||||
return LocationSearchResults(self.selenium, self.base_url)
|
||||
|
||||
def click_profile_region_filter(self,):
|
||||
self.selenium.find_element(*self._region_locator).click()
|
||||
self.find_element(*self._region_locator).click()
|
||||
from location_search_results import LocationSearchResults
|
||||
return LocationSearchResults(self.base_url, self.selenium)
|
||||
return LocationSearchResults(self.selenium, self.base_url)
|
||||
|
||||
def click_profile_country_filter(self):
|
||||
self.selenium.find_element(*self._country_locator).click()
|
||||
self.find_element(*self._country_locator).click()
|
||||
from location_search_results import LocationSearchResults
|
||||
return LocationSearchResults(self.base_url, self.selenium)
|
||||
return LocationSearchResults(self.selenium, self.base_url)
|
||||
|
||||
@property
|
||||
def languages(self):
|
||||
return self.selenium.find_element(*self._languages_locator).text.split('\n')[1]
|
||||
return self.find_element(*self._languages_locator).text.split('\n')[1]
|
||||
|
||||
@property
|
||||
def profile_message(self):
|
||||
return self.selenium.find_element(*self._profile_message_locator).text
|
||||
return self.find_element(*self._profile_message_locator).text
|
||||
|
||||
@property
|
||||
def is_groups_present(self):
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
from selenium.webdriver.support import expected_conditions as expected
|
||||
|
||||
from pages.base import Base
|
||||
|
||||
|
@ -32,62 +29,65 @@ class Register(Base):
|
|||
_city_results_list_locator = (By.CSS_SELECTOR, '#select2-id_city-results > li.select2-results__option--highlighted')
|
||||
_first_city_search_result_locator = (By.CSS_SELECTOR, '#select2-id_city-results > li.select2-results__option--highlighted:first-child')
|
||||
|
||||
def wait_for_page_to_load(self):
|
||||
self.wait.until(lambda _: self.find_element(By.CSS_SELECTOR, 'html.js body#edit-profile'))
|
||||
return self
|
||||
|
||||
@property
|
||||
def error_message(self):
|
||||
return self.selenium.find_element(*self._error_locator).text
|
||||
return self.find_element(*self._error_locator).text
|
||||
|
||||
def set_full_name(self, full_name):
|
||||
element = self.selenium.find_element(*self._full_name_field_locator)
|
||||
element = self.find_element(*self._full_name_field_locator)
|
||||
element.send_keys(full_name)
|
||||
|
||||
@property
|
||||
def privacy_error_message(self):
|
||||
return self.selenium.find_element(*self._privacy_error_message_locator).text
|
||||
return self.find_element(*self._privacy_error_message_locator).text
|
||||
|
||||
def select_country(self, country):
|
||||
self.selenium.find_element(*self._country_countainer_locator).click()
|
||||
self.selenium.find_element(*self._input_locator).send_keys(country)
|
||||
self.wait_for_element_present(*self._first_country_search_result_locator)
|
||||
countries_list = self.selenium.find_elements(*self._country_results_list_locator)
|
||||
self.find_element(*self._country_countainer_locator).click()
|
||||
self.find_element(*self._input_locator).send_keys(country)
|
||||
self.wait.until(expected.presence_of_element_located(
|
||||
self._first_country_search_result_locator))
|
||||
countries_list = self.find_elements(*self._country_results_list_locator)
|
||||
country_item = next(item for item in countries_list if country == item.text)
|
||||
country_item.click()
|
||||
|
||||
def select_region(self, region):
|
||||
self.selenium.find_element(*self._region_container_locator).click()
|
||||
self.selenium.find_element(*self._input_locator).send_keys(region)
|
||||
self.wait_for_element_present(*self._first_region_search_result_locator)
|
||||
regions_list = self.selenium.find_elements(*self._region_results_list_locator)
|
||||
self.find_element(*self._region_container_locator).click()
|
||||
self.find_element(*self._input_locator).send_keys(region)
|
||||
self.wait.until(expected.presence_of_element_located(
|
||||
self._first_region_search_result_locator))
|
||||
regions_list = self.find_elements(*self._region_results_list_locator)
|
||||
region_item = next(item for item in regions_list if region in item.text)
|
||||
region_item.click()
|
||||
|
||||
def select_city(self, city):
|
||||
self.selenium.find_element(*self._city_container_locator).click()
|
||||
self.selenium.find_element(*self._input_locator).send_keys(city)
|
||||
self.wait_for_element_present(*self._first_city_search_result_locator)
|
||||
cities_list = self.selenium.find_elements(*self._city_results_list_locator)
|
||||
self.find_element(*self._city_container_locator).click()
|
||||
self.find_element(*self._input_locator).send_keys(city)
|
||||
self.wait.until(expected.presence_of_element_located(
|
||||
self._first_city_search_result_locator))
|
||||
cities_list = self.find_elements(*self._city_results_list_locator)
|
||||
city_item = next(item for item in cities_list if city in item.text)
|
||||
city_item.click()
|
||||
|
||||
def check_privacy(self):
|
||||
self.selenium.find_element(*self._privacy_locator).click()
|
||||
self.find_element(*self._privacy_locator).click()
|
||||
|
||||
def check_recaptcha(self):
|
||||
recaptcha_iframe_locator = (By.CSS_SELECTOR, '.g-recaptcha iframe')
|
||||
recaptcha_iframe = self.selenium.find_element(*recaptcha_iframe_locator)
|
||||
recaptcha_iframe = self.find_element(*recaptcha_iframe_locator)
|
||||
self.selenium.switch_to_frame(recaptcha_iframe)
|
||||
|
||||
recaptcha_checkbox = self.selenium.find_element(*self._recaptcha_checkbox_locator)
|
||||
self.scroll_to_element(recaptcha_checkbox)
|
||||
recaptcha_checkbox.click()
|
||||
WebDriverWait(self.selenium, self.timeout).until(
|
||||
lambda s: self.selenium.find_element(*self._recaptcha_checkbox_checked)
|
||||
)
|
||||
self.wait.until(expected.visibility_of_element_located(
|
||||
self._recaptcha_checkbox_locator)).click()
|
||||
self.wait.until(lambda s: self.find_element(*self._recaptcha_checkbox_checked))
|
||||
self.selenium.switch_to_default_content()
|
||||
|
||||
def click_create_profile_button(self, leavepage=True):
|
||||
self.selenium.find_element(*self._create_profile_button_locator).click()
|
||||
self.find_element(*self._create_profile_button_locator).click()
|
||||
if not leavepage:
|
||||
return self
|
||||
else:
|
||||
from pages.profile import Profile
|
||||
return Profile(self.base_url, self.selenium)
|
||||
return Profile(self.selenium, self.base_url)
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
from pypom import Region
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support import expected_conditions as expected
|
||||
|
||||
from pages.base import Base
|
||||
from pages.page import PageRegion
|
||||
|
||||
|
||||
class Search(Base):
|
||||
|
@ -24,61 +22,60 @@ class Search(Base):
|
|||
_last_page_number_locator = (By.CSS_SELECTOR, '#pagination-form select option:last-child')
|
||||
_group_name_locator = (By.CSS_SELECTOR, '.group-name')
|
||||
|
||||
def wait_for_page_to_load(self):
|
||||
self.wait.until(lambda _: self.find_element(By.CSS_SELECTOR, 'html.js body#search'))
|
||||
return self
|
||||
|
||||
@property
|
||||
def results_count(self):
|
||||
return len(self.selenium.find_elements(*self._result_locator))
|
||||
return len(self.find_elements(*self._result_locator))
|
||||
|
||||
@property
|
||||
def number_of_pages(self):
|
||||
element = self.selenium.find_element(*self._last_page_number_locator)
|
||||
element = self.find_element(*self._last_page_number_locator)
|
||||
return element.get_attribute('text')
|
||||
|
||||
@property
|
||||
def no_results_message_head(self):
|
||||
return self.selenium.find_element(*self._no_results_locator_head).text
|
||||
return self.find_element(*self._no_results_locator_head).text
|
||||
|
||||
@property
|
||||
def no_results_message_body(self):
|
||||
return self.selenium.find_element(*self._no_results_locator_body).text
|
||||
return self.find_element(*self._no_results_locator_body).text
|
||||
|
||||
@property
|
||||
def advanced_options_shown(self):
|
||||
return self.is_element_visible(*self._advanced_options_locator)
|
||||
return self.is_element_displayed(*self._advanced_options_locator)
|
||||
|
||||
def toggle_advanced_options(self):
|
||||
self.selenium.find_element(*self._advanced_options_button_locator).click()
|
||||
self.find_element(*self._advanced_options_button_locator).click()
|
||||
|
||||
def check_non_vouched_only(self):
|
||||
self.selenium.find_element(*self._non_vouched_only_checkbox_locator).click()
|
||||
self.find_element(*self._non_vouched_only_checkbox_locator).click()
|
||||
|
||||
def check_with_photos_only(self):
|
||||
self.selenium.find_element(*self._with_photos_only_checkbox_locator).click()
|
||||
self.find_element(*self._with_photos_only_checkbox_locator).click()
|
||||
|
||||
@property
|
||||
def search_results(self):
|
||||
return [self.SearchResult(self.base_url, self.selenium, el) for el in
|
||||
self.selenium.find_elements(*self._result_locator)]
|
||||
return [self.SearchResult(self, el) for el in self.find_elements(*self._result_locator)]
|
||||
|
||||
def open_group(self, name):
|
||||
self.wait_for_element_visible(*self._search_button_locator)
|
||||
groups_names = self.selenium.find_elements(*self._group_name_locator)
|
||||
for group in groups_names:
|
||||
if group.get_attribute('title') == name:
|
||||
group.click()
|
||||
self.wait.until(expected.visibility_of_element_located(
|
||||
(By.CSS_SELECTOR, '.group-name[title="{}"]'.format(name)))).click()
|
||||
from pages.group_info_page import GroupInfoPage
|
||||
group_info_page = GroupInfoPage(self.base_url, self.selenium)
|
||||
return group_info_page
|
||||
return GroupInfoPage(self.selenium, self.base_url).wait_for_page_to_load()
|
||||
|
||||
class SearchResult(PageRegion):
|
||||
class SearchResult(Region):
|
||||
|
||||
_profile_page_link_locator = (By.CSS_SELECTOR, 'li a')
|
||||
_name_locator = (By.CSS_SELECTOR, '.result .details h2')
|
||||
|
||||
def open_profile_page(self):
|
||||
self._root_element.find_element(*self._profile_page_link_locator).click()
|
||||
self.find_element(*self._profile_page_link_locator).click()
|
||||
from pages.profile import Profile
|
||||
return Profile(self.base_url, self.selenium)
|
||||
return Profile(self.page.selenium, self.page.base_url).wait_for_page_to_load()
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._root_element.find_element(*self._name_locator).text
|
||||
return self.find_element(*self._name_locator).text
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import random
|
||||
|
||||
from pypom import Region
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.common.keys import Keys
|
||||
from selenium.webdriver.support import expected_conditions as expected
|
||||
from selenium.webdriver.support.select import Select
|
||||
|
||||
from pages.base import Base
|
||||
from pages.groups_page import GroupsPage
|
||||
from pages.page import PageRegion
|
||||
|
||||
|
||||
class Settings(Base):
|
||||
URL_TEMPLATE = '{locale}/user/edit'
|
||||
|
||||
_profile_tab_locator = (By.ID, 'profile')
|
||||
_profile_button_locator = (By.CSS_SELECTOR, '#profile-tab > a')
|
||||
|
||||
|
@ -33,34 +34,29 @@ class Settings(Base):
|
|||
|
||||
@property
|
||||
def profile(self):
|
||||
self.wait_for_element_present(*self._profile_button_locator)
|
||||
self.selenium.find_element(*self._profile_button_locator).click()
|
||||
return self.ProfileTab(self.base_url, self.selenium,
|
||||
self.selenium.find_element(*self._profile_tab_locator))
|
||||
self.wait.until(expected.presence_of_element_located(
|
||||
self._profile_button_locator)).click()
|
||||
return self.ProfileTab(self, self.find_element(*self._profile_tab_locator))
|
||||
|
||||
@property
|
||||
def you_and_mozilla(self):
|
||||
self.selenium.find_element(*self._you_and_mozilla_button_locator).click()
|
||||
return self.YouAndMozilla(self.base_url, self.selenium,
|
||||
self.selenium.find_element(*self._you_and_mozilla_tab_locator))
|
||||
self.find_element(*self._you_and_mozilla_button_locator).click()
|
||||
return self.YouAndMozilla(self, self.find_element(*self._you_and_mozilla_tab_locator))
|
||||
|
||||
@property
|
||||
def groups(self):
|
||||
self.selenium.find_element(*self._groups_button_locator).click()
|
||||
return self.Groups(self.base_url, self.selenium,
|
||||
self.selenium.find_element(*self._groups_tab_locator))
|
||||
self.find_element(*self._groups_button_locator).click()
|
||||
return self.Groups(self, self.find_element(*self._groups_tab_locator))
|
||||
|
||||
@property
|
||||
def external_accounts(self):
|
||||
self.selenium.find_element(*self._external_accounts_button_locator).click()
|
||||
return self.ExternalAccountsTab(self.base_url, self.selenium,
|
||||
self.selenium.find_element(*self._external_accounts_tab_locator))
|
||||
self.find_element(*self._external_accounts_button_locator).click()
|
||||
return self.ExternalAccountsTab(self, self.find_element(*self._external_accounts_tab_locator))
|
||||
|
||||
@property
|
||||
def developer(self):
|
||||
self.selenium.find_element(*self._developer_button_locator).click()
|
||||
return self.DeveloperTab(self.base_url, self.selenium,
|
||||
self.selenium.find_element(*self._developer_tab_locator))
|
||||
self.find_element(*self._developer_button_locator).click()
|
||||
return self.DeveloperTab(self, self.find_element(*self._developer_tab_locator))
|
||||
|
||||
def create_group(self, group_name):
|
||||
groups = self.groups.click_find_group_link()
|
||||
|
@ -69,66 +65,64 @@ class Settings(Base):
|
|||
group = create_group.click_create_group_submit()
|
||||
return group
|
||||
|
||||
class ProfileTab(PageRegion):
|
||||
class ProfileTab(Region):
|
||||
_basic_info_form_locator = (By.CSS_SELECTOR, 'form.edit-profile:nth-child(1)')
|
||||
_skills_form_locator = (By.CSS_SELECTOR, 'form.edit-profile:nth-child(3)')
|
||||
_delete_account_form_locator = (By.CSS_SELECTOR, 'div.panel-danger')
|
||||
|
||||
@property
|
||||
def basic_information(self):
|
||||
return self.EditProfileForm(self.base_url, self.selenium,
|
||||
self._root_element.find_element(*self._basic_info_form_locator))
|
||||
return self.EditProfileForm(self.page, self.find_element(*self._basic_info_form_locator))
|
||||
|
||||
@property
|
||||
def skills(self):
|
||||
skill_form = self.SkillsForm(self.base_url, self.selenium,
|
||||
self._root_element.find_element(*self._skills_form_locator))
|
||||
return skill_form
|
||||
return self.SkillsForm(self.page, self.find_element(*self._skills_form_locator))
|
||||
|
||||
@property
|
||||
def delete_account(self):
|
||||
return self.DeleteAccount(self.base_url, self.selenium,
|
||||
self._root_element.find_element(*self._delete_account_form_locator))
|
||||
return self.DeleteAccount(self.page, self.find_element(*self._delete_account_form_locator))
|
||||
|
||||
class EditProfileForm (PageRegion):
|
||||
class EditProfileForm (Region):
|
||||
|
||||
_full_name_field_locator = (By.ID, 'id_full_name')
|
||||
_bio_field_locator = (By.ID, 'id_bio')
|
||||
_update_locator = (By.ID, 'form-submit-basic')
|
||||
|
||||
def set_full_name(self, full_name):
|
||||
element = self._root_element.find_element(*self._full_name_field_locator)
|
||||
element = self.find_element(*self._full_name_field_locator)
|
||||
element.clear()
|
||||
element.send_keys(full_name)
|
||||
|
||||
def set_bio(self, biography):
|
||||
element = self._root_element.find_element(*self._bio_field_locator)
|
||||
element = self.find_element(*self._bio_field_locator)
|
||||
element.clear()
|
||||
element.send_keys(biography)
|
||||
|
||||
def click_update(self):
|
||||
self._root_element.find_element(*self._update_locator).click()
|
||||
self.wait_for_element_not_present(*self._update_locator)
|
||||
self.wait_for_element_present(*self._update_locator)
|
||||
el = self.find_element(*self._update_locator)
|
||||
el.click()
|
||||
self.wait.until(expected.staleness_of(el))
|
||||
self.wait.until(expected.presence_of_element_located(
|
||||
self._update_locator))
|
||||
|
||||
class DeleteAccount(PageRegion):
|
||||
class DeleteAccount(Region):
|
||||
|
||||
_delete_acknowledgement_locator = (By.CSS_SELECTOR, '#delete-checkbox')
|
||||
_delete_profile_button_locator = (By.ID, 'delete-profile')
|
||||
|
||||
def check_acknowledgement(self):
|
||||
self._root_element.find_element(*self._delete_acknowledgement_locator).click()
|
||||
self.find_element(*self._delete_acknowledgement_locator).click()
|
||||
|
||||
@property
|
||||
def is_delete_button_enabled(self):
|
||||
return 'disabled' not in self._root_element.find_element(*self._delete_profile_button_locator).get_attribute('class')
|
||||
return 'disabled' not in self.find_element(*self._delete_profile_button_locator).get_attribute('class')
|
||||
|
||||
def click_delete_profile(self):
|
||||
self._root_element.find_element(*self._delete_profile_button_locator).click()
|
||||
self.find_element(*self._delete_profile_button_locator).click()
|
||||
from pages.confirm_profile_delete import ConfirmProfileDelete
|
||||
return ConfirmProfileDelete(self.base_url, self.selenium)
|
||||
return ConfirmProfileDelete(self.page.selenium, self.page.base_url)
|
||||
|
||||
class SkillsForm(PageRegion):
|
||||
class SkillsForm(Region):
|
||||
_skills_locator = (By.CSS_SELECTOR, '#skills .select2-selection__choice')
|
||||
_skills_field_locator = (By.CSS_SELECTOR, '#skills input')
|
||||
_delete_skill_buttons_locator = (By.CSS_SELECTOR, '#skills .select2-selection__choice__remove')
|
||||
|
@ -138,36 +132,36 @@ class Settings(Base):
|
|||
@property
|
||||
def skills(self):
|
||||
# Return skills list with leading `x` button stripped
|
||||
skills = self._root_element.find_elements(*self._skills_locator)
|
||||
skills = self.find_elements(*self._skills_locator)
|
||||
return [skills[i].text[1:] for i in range(0, len(skills))]
|
||||
|
||||
def add_skill(self, skill_name):
|
||||
element = self._root_element.find_element(*self._skills_field_locator)
|
||||
element = self.find_element(*self._skills_field_locator)
|
||||
element.send_keys(skill_name)
|
||||
self.wait_for_element_present(*self._skills_first_result_locator)
|
||||
self.wait.until(expected.presence_of_element_located(
|
||||
self._skills_first_result_locator))
|
||||
element.send_keys(Keys.RETURN)
|
||||
|
||||
@property
|
||||
def delete_skill_buttons(self):
|
||||
return self._root_element.find_elements(*self._delete_skill_buttons_locator)
|
||||
return self.find_elements(*self._delete_skill_buttons_locator)
|
||||
|
||||
def delete_skill(self, skill):
|
||||
skill_index = self.skills.index(skill)
|
||||
self.delete_skill_buttons[skill_index].click()
|
||||
|
||||
def click_update(self):
|
||||
self._root_element.find_element(*self._update_locator).click()
|
||||
self.find_element(*self._update_locator).click()
|
||||
|
||||
class YouAndMozilla(PageRegion):
|
||||
class YouAndMozilla(Region):
|
||||
|
||||
_contributions_form_locator = (By.CSS_SELECTOR, 'form.edit-profile:nth-child(1)')
|
||||
|
||||
@property
|
||||
def contributions(self):
|
||||
return self.Contributions(self.base_url, self.selenium,
|
||||
self._root_element.find_element(*self._contributions_form_locator))
|
||||
return self.Contributions(self.page, self.find_element(*self._contributions_form_locator))
|
||||
|
||||
class Contributions(PageRegion):
|
||||
class Contributions(Region):
|
||||
|
||||
_select_month_locator = (By.ID, 'id_date_mozillian_month')
|
||||
_select_year_locator = (By.ID, 'id_date_mozillian_year')
|
||||
|
@ -178,34 +172,34 @@ class Settings(Base):
|
|||
_update_locator = (By.ID, 'form-submit-contribution')
|
||||
|
||||
def select_month(self, option_month):
|
||||
element = self._root_element.find_element(*self._select_month_locator)
|
||||
element = self.find_element(*self._select_month_locator)
|
||||
select = Select(element)
|
||||
select.select_by_value(option_month)
|
||||
|
||||
def select_year(self, option_year):
|
||||
element = self._root_element.find_element(*self._select_year_locator)
|
||||
element = self.find_element(*self._select_year_locator)
|
||||
select = Select(element)
|
||||
select.select_by_value(option_year)
|
||||
|
||||
@property
|
||||
def month(self):
|
||||
# Return selected month text
|
||||
return self._root_element.find_element(*self._selected_month_locator).text
|
||||
return self.find_element(*self._selected_month_locator).text
|
||||
|
||||
@property
|
||||
def year(self):
|
||||
# Return selected year text
|
||||
return self._root_element.find_element(*self._selected_year_locator).text
|
||||
return self.find_element(*self._selected_year_locator).text
|
||||
|
||||
@property
|
||||
def months_values(self):
|
||||
# Return all month values
|
||||
return [month.get_attribute('value') for month in self._root_element.find_elements(*self._month_locator)]
|
||||
return [month.get_attribute('value') for month in self.find_elements(*self._month_locator)]
|
||||
|
||||
@property
|
||||
def years_values(self):
|
||||
# Return all year values
|
||||
return [year.get_attribute('value') for year in self._root_element.find_elements(*self._year_locator)]
|
||||
return [year.get_attribute('value') for year in self.find_elements(*self._year_locator)]
|
||||
|
||||
def select_random_month(self):
|
||||
return self.select_month(random.choice(self.months_values[1:]))
|
||||
|
@ -214,73 +208,76 @@ class Settings(Base):
|
|||
return self.select_year(random.choice(self.years_values[1:]))
|
||||
|
||||
def click_update(self):
|
||||
self._root_element.find_element(*self._update_locator).click()
|
||||
self.wait_for_element_not_present(*self._update_locator)
|
||||
self.wait_for_element_present(*self._update_locator)
|
||||
el = self.find_element(*self._update_locator)
|
||||
el.click()
|
||||
self.wait.until(expected.staleness_of(el))
|
||||
self.wait.until(expected.presence_of_element_located(
|
||||
self._update_locator))
|
||||
|
||||
class Groups(PageRegion):
|
||||
class Groups(Region):
|
||||
|
||||
_find_group_page = (By.PARTIAL_LINK_TEXT, 'find the group')
|
||||
|
||||
@property
|
||||
def is_find_group_link_visible(self):
|
||||
return self.is_element_visible(*self._find_group_page)
|
||||
return self.is_element_displayed(*self._find_group_page)
|
||||
|
||||
def click_find_group_link(self):
|
||||
self.selenium.find_element(*self._find_group_page).click()
|
||||
return GroupsPage(self.base_url, self.selenium)
|
||||
self.find_element(*self._find_group_page).click()
|
||||
return GroupsPage(self.page.selenium, self.page.base_url)
|
||||
|
||||
class ExternalAccountsTab(PageRegion):
|
||||
class ExternalAccountsTab(Region):
|
||||
|
||||
_external_accounts_form_locator = (By.CSS_SELECTOR, '#extaccounts > form > div:nth-child(2)')
|
||||
_irc_form_locator = (By.CSS_SELECTOR, '#extaccounts > form > div:nth-child(3)')
|
||||
|
||||
@property
|
||||
def external_accounts_form(self):
|
||||
return self.ExternalAccounts(self.base_url, self.selenium,
|
||||
self._root_element.find_element(*self._external_accounts_form_locator))
|
||||
return self.ExternalAccounts(self.page, self.find_element(*self._external_accounts_form_locator))
|
||||
|
||||
@property
|
||||
def irc_form(self):
|
||||
return self.Irc(self.base_url, self.selenium, self._root_element.find_element(*self._irc_form_locator))
|
||||
return self.Irc(self.page, self.find_element(*self._irc_form_locator))
|
||||
|
||||
class ExternalAccounts(PageRegion):
|
||||
class ExternalAccounts(Region):
|
||||
_add_account_locator = (By.ID, 'accounts-addfield')
|
||||
_account_row_locator = (By.CSS_SELECTOR, 'div.externalaccount-fieldrow')
|
||||
|
||||
@property
|
||||
def is_displayed(self):
|
||||
return self._root_element.is_displayed()
|
||||
return self.root.is_displayed()
|
||||
|
||||
def count_external_accounts(self):
|
||||
return len(self._root_element.find_elements(*self._account_row_locator))
|
||||
return len(self.find_elements(*self._account_row_locator))
|
||||
|
||||
def click_add_account(self):
|
||||
self._root_element.find_element(*self._add_account_locator).click()
|
||||
self.find_element(*self._add_account_locator).click()
|
||||
|
||||
class Irc(PageRegion):
|
||||
class Irc(Region):
|
||||
_irc_nickname_locator = (By.ID, 'id_ircname')
|
||||
_update_locator = (By.ID, 'form-submit-irc')
|
||||
|
||||
@property
|
||||
def nickname(self):
|
||||
return self._root_element.find_element(*self._irc_nickname_locator).get_attribute('value')
|
||||
return self.find_element(*self._irc_nickname_locator).get_attribute('value')
|
||||
|
||||
@property
|
||||
def is_displayed(self):
|
||||
return self._root_element.is_displayed()
|
||||
return self.root.is_displayed()
|
||||
|
||||
def update_nickname(self, new_nickname):
|
||||
element = self._root_element.find_element(*self._irc_nickname_locator)
|
||||
element = self.find_element(*self._irc_nickname_locator)
|
||||
element.clear()
|
||||
element.send_keys(new_nickname)
|
||||
|
||||
def click_update(self):
|
||||
self._root_element.find_element(*self._update_locator).click()
|
||||
self.wait_for_element_not_present(*self._update_locator)
|
||||
self.wait_for_element_present(*self._update_locator)
|
||||
el = self.find_element(*self._update_locator)
|
||||
el.click()
|
||||
self.wait.until(expected.staleness_of(el))
|
||||
self.wait.until(expected.presence_of_element_located(
|
||||
self._update_locator))
|
||||
|
||||
class DeveloperTab(PageRegion):
|
||||
class DeveloperTab(Region):
|
||||
|
||||
_services_bugzilla_locator = (By.ID, 'services-bugzilla-url')
|
||||
_services_mozilla_reps_locator = (By.ID, 'services-mozilla-reps')
|
||||
|
@ -290,7 +287,7 @@ class Settings(Base):
|
|||
urls = []
|
||||
|
||||
for element in locs:
|
||||
url = self._root_element.find_element(*element).get_attribute('href')
|
||||
url = self.find_element(*element).get_attribute('href')
|
||||
urls.append(url)
|
||||
|
||||
return urls
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
BeautifulSoup==3.2.1
|
||||
mozlog==3.5
|
||||
PyPOM==1.2.0
|
||||
pytest==3.2.5
|
||||
pytest-metadata==1.5.0
|
||||
pytest-selenium==1.11.2
|
||||
|
|
|
@ -24,13 +24,6 @@ def capabilities(request, capabilities):
|
|||
return capabilities
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def selenium(selenium):
|
||||
selenium.implicitly_wait(10)
|
||||
selenium.maximize_window()
|
||||
return selenium
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def new_email():
|
||||
return 'mozillians_{0}@restmail.net'.format(uuid.uuid1())
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
@ -14,7 +12,7 @@ class TestAboutPage:
|
|||
|
||||
@pytest.mark.nondestructive
|
||||
def test_about_page(self, base_url, selenium):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
about_mozillians_page = home_page.footer.click_about_link()
|
||||
assert about_mozillians_page.is_privacy_section_present
|
||||
assert about_mozillians_page.is_get_involved_section_present
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
@ -15,7 +13,7 @@ class TestAccount:
|
|||
@pytest.mark.credentials
|
||||
@pytest.mark.nondestructive
|
||||
def test_login_logout(self, base_url, selenium, vouched_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(vouched_user['email'])
|
||||
assert home_page.header.is_logout_menu_item_present
|
||||
home_page.header.click_logout_menu_item()
|
||||
|
@ -24,10 +22,10 @@ class TestAccount:
|
|||
@pytest.mark.credentials
|
||||
@pytest.mark.nondestructive
|
||||
def test_logout_verify_bid(self, base_url, selenium, vouched_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(vouched_user['email'])
|
||||
assert home_page.header.is_logout_menu_item_present
|
||||
home_page.logout_using_url()
|
||||
selenium.get(base_url + '/logout')
|
||||
|
||||
home_page.wait_for_user_login()
|
||||
assert home_page.is_sign_in_button_present
|
||||
|
|
|
@ -14,7 +14,7 @@ class TestGroup:
|
|||
|
||||
@pytest.mark.credentials
|
||||
def test_group_description_edit(self, base_url, selenium, vouched_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(vouched_user['email'])
|
||||
|
||||
# Create a new group
|
||||
|
@ -41,7 +41,7 @@ class TestGroup:
|
|||
|
||||
@pytest.mark.credentials
|
||||
def test_group_deletion_confirmation(self, base_url, selenium, vouched_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(vouched_user['email'])
|
||||
|
||||
# Create a new group
|
||||
|
@ -59,7 +59,7 @@ class TestGroup:
|
|||
|
||||
@pytest.mark.credentials
|
||||
def test_group_type_change(self, base_url, selenium, vouched_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(vouched_user['email'])
|
||||
|
||||
# Create a new group
|
||||
|
@ -75,7 +75,7 @@ class TestGroup:
|
|||
|
||||
@pytest.mark.credentials
|
||||
def test_group_invitations(self, base_url, selenium, vouched_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(vouched_user['email'])
|
||||
|
||||
# Create a new group
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
@ -13,7 +11,7 @@ class TestInvite:
|
|||
|
||||
@pytest.mark.credentials
|
||||
def test_inviting_an_invalid_email_address(self, base_url, selenium, vouched_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(vouched_user['email'])
|
||||
invite_page = home_page.header.click_invite_menu_item()
|
||||
invite_page.invite("invalidmail")
|
||||
|
@ -21,7 +19,7 @@ class TestInvite:
|
|||
|
||||
@pytest.mark.credentials
|
||||
def test_invite(self, base_url, selenium, vouched_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(vouched_user['email'])
|
||||
invite_page = home_page.header.click_invite_menu_item()
|
||||
email_address = "user@example.com"
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
@ -11,6 +9,8 @@ from selenium.webdriver.common.by import By
|
|||
|
||||
from pages.home_page import Home
|
||||
from pages.link_crawler import LinkCrawler
|
||||
from pages.profile import Profile
|
||||
from pages.settings import Settings
|
||||
|
||||
|
||||
class TestProfile:
|
||||
|
@ -18,7 +18,7 @@ class TestProfile:
|
|||
@pytest.mark.credentials
|
||||
@pytest.mark.nondestructive
|
||||
def test_profile_deletion_confirmation(self, base_url, selenium, vouched_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(vouched_user['email'])
|
||||
settings = home_page.header.click_settings_menu_item()
|
||||
|
||||
|
@ -37,7 +37,7 @@ class TestProfile:
|
|||
|
||||
@pytest.mark.credentials
|
||||
def test_edit_profile_information(self, base_url, selenium, vouched_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(vouched_user['email'])
|
||||
settings = home_page.header.click_settings_menu_item()
|
||||
current_time = str(time.time()).split('.')[0]
|
||||
|
@ -61,7 +61,7 @@ class TestProfile:
|
|||
|
||||
@pytest.mark.credentials
|
||||
def test_skill_addition(self, base_url, selenium, vouched_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(vouched_user['email'])
|
||||
|
||||
settings = home_page.header.click_settings_menu_item()
|
||||
|
@ -77,7 +77,7 @@ class TestProfile:
|
|||
|
||||
@pytest.mark.credentials
|
||||
def test_skill_deletion(self, base_url, selenium, vouched_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(vouched_user['email'])
|
||||
|
||||
settings = home_page.header.click_settings_menu_item()
|
||||
|
@ -99,10 +99,10 @@ class TestProfile:
|
|||
@pytest.mark.credentials
|
||||
@pytest.mark.nondestructive
|
||||
def test_that_filter_by_city_works(self, base_url, selenium, vouched_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(vouched_user['email'])
|
||||
|
||||
profile_page = home_page.open_user_profile(u'Mozillians.User')
|
||||
profile_page = home_page.header.click_view_profile_menu_item()
|
||||
city = profile_page.city
|
||||
country = profile_page.country
|
||||
|
||||
|
@ -118,10 +118,10 @@ class TestProfile:
|
|||
@pytest.mark.credentials
|
||||
@pytest.mark.nondestructive
|
||||
def test_that_filter_by_region_works(self, base_url, selenium, vouched_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(vouched_user['email'])
|
||||
|
||||
profile_page = home_page.open_user_profile(u'Mozillians.User')
|
||||
profile_page = home_page.header.click_view_profile_menu_item()
|
||||
region = profile_page.region
|
||||
country = profile_page.country
|
||||
search_results_page = profile_page.click_profile_region_filter()
|
||||
|
@ -136,10 +136,10 @@ class TestProfile:
|
|||
@pytest.mark.credentials
|
||||
@pytest.mark.nondestructive
|
||||
def test_that_filter_by_country_works(self, base_url, selenium, vouched_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(vouched_user['email'])
|
||||
|
||||
profile_page = home_page.open_user_profile(u'Mozillians.User')
|
||||
profile_page = home_page.header.click_view_profile_menu_item()
|
||||
country = profile_page.country
|
||||
search_results_page = profile_page.click_profile_country_filter()
|
||||
expected_results_title = u'Mozillians in %s' % country
|
||||
|
@ -152,9 +152,9 @@ class TestProfile:
|
|||
|
||||
@pytest.mark.credentials
|
||||
def test_that_non_us_user_can_set_get_involved_date(self, base_url, selenium, vouched_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(vouched_user['email'])
|
||||
settings = home_page.go_to_localized_settings_page("es")
|
||||
settings = Settings(selenium, base_url, locale='es').open()
|
||||
contributions = settings.you_and_mozilla.contributions
|
||||
selected_date = contributions.month + contributions.year
|
||||
contributions.select_random_month()
|
||||
|
@ -164,7 +164,7 @@ class TestProfile:
|
|||
profile_page = home_page.header.click_view_profile_menu_item()
|
||||
|
||||
assert "Tu perfil" == profile_page.profile_message
|
||||
settings = home_page.go_to_localized_settings_page("es")
|
||||
settings = home_page.header.click_settings_menu_item()
|
||||
contributions = settings.you_and_mozilla.contributions
|
||||
assert selected_date != contributions.month + contributions.year
|
||||
|
||||
|
@ -172,7 +172,7 @@ class TestProfile:
|
|||
def test_that_user_can_create_and_delete_group(self, base_url, selenium, vouched_user):
|
||||
group_name = (time.strftime('%x-%X'))
|
||||
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(vouched_user['email'])
|
||||
settings = home_page.header.click_settings_menu_item()
|
||||
groups = settings.groups.click_find_group_link()
|
||||
|
@ -198,7 +198,7 @@ class TestProfile:
|
|||
# User has certain fields preset to values to run the test properly
|
||||
# groups - private
|
||||
# belongs to at least one group
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(private_user['email'])
|
||||
|
||||
profile_page = home_page.header.click_view_profile_menu_item()
|
||||
|
@ -208,14 +208,13 @@ class TestProfile:
|
|||
@pytest.mark.credentials
|
||||
@pytest.mark.nondestructive
|
||||
def test_private_groups_field_when_not_logged_in(self, base_url, selenium, private_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
profile_page = home_page.open_user_profile(private_user['name'])
|
||||
assert not profile_page.is_groups_present
|
||||
page = Profile(selenium, base_url, username=private_user['name']).open()
|
||||
assert not page.is_groups_present
|
||||
|
||||
@pytest.mark.credentials
|
||||
@pytest.mark.nondestructive
|
||||
def test_that_links_in_the_services_page_return_200_code(self, base_url, selenium, vouched_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(vouched_user['email'])
|
||||
|
||||
settings = home_page.header.click_settings_menu_item()
|
||||
|
@ -236,7 +235,7 @@ class TestProfile:
|
|||
@pytest.mark.credentials
|
||||
@pytest.mark.nondestructive
|
||||
def test_that_user_can_view_external_accounts(self, base_url, selenium, vouched_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(vouched_user['email'])
|
||||
settings = home_page.header.click_settings_menu_item()
|
||||
|
||||
|
@ -245,7 +244,7 @@ class TestProfile:
|
|||
|
||||
@pytest.mark.credentials
|
||||
def test_that_user_can_add_external_account(self, base_url, selenium, vouched_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(vouched_user['email'])
|
||||
settings = home_page.header.click_settings_menu_item()
|
||||
|
||||
|
@ -257,7 +256,7 @@ class TestProfile:
|
|||
|
||||
@pytest.mark.credentials
|
||||
def test_that_user_can_modify_external_accounts_irc_nickname(self, base_url, selenium, vouched_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(vouched_user['email'])
|
||||
settings = home_page.header.click_settings_menu_item()
|
||||
|
||||
|
@ -281,7 +280,7 @@ class TestProfile:
|
|||
@pytest.mark.credentials
|
||||
@pytest.mark.nondestructive
|
||||
def test_new_user_cannot_see_groups_or_functional_areas(self, base_url, selenium, unvouched_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(unvouched_user['email'])
|
||||
|
||||
assert not home_page.header.is_groups_menu_item_present
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
@ -10,7 +8,7 @@ from pages.home_page import Home
|
|||
class TestRegister:
|
||||
|
||||
def test_profile_creation(self, base_url, selenium, new_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
profile = home_page.create_new_user(new_user['email'])
|
||||
|
||||
# Click recaptcha box
|
||||
|
@ -37,7 +35,7 @@ class TestRegister:
|
|||
assert 'Mountain View, California, United States' == profile_page.location
|
||||
|
||||
def test_creating_profile_without_checking_privacy_policy_checkbox(self, base_url, selenium, new_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
profile = home_page.create_new_user(new_user['email'])
|
||||
|
||||
profile.set_full_name("User that doesn't like policy")
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
@ -18,7 +16,7 @@ class TestSearch:
|
|||
@pytest.mark.credentials
|
||||
@pytest.mark.nondestructive
|
||||
def test_that_search_returns_results_for_email_substring(self, base_url, selenium, vouched_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(vouched_user['email'])
|
||||
search_page = home_page.header.search_for(u'@mozilla.com', loggedin=True)
|
||||
assert search_page.results_count > 0
|
||||
|
@ -27,7 +25,7 @@ class TestSearch:
|
|||
@pytest.mark.nondestructive
|
||||
def test_that_search_returns_results_for_first_name(self, base_url, selenium, vouched_user):
|
||||
query = u'Matt'
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(vouched_user['email'])
|
||||
search_page = home_page.header.search_for(query, loggedin=True)
|
||||
assert search_page.results_count > 0
|
||||
|
@ -39,7 +37,7 @@ class TestSearch:
|
|||
@pytest.mark.credentials
|
||||
@pytest.mark.nondestructive
|
||||
def test_that_search_returns_results_for_irc_nickname(self, base_url, selenium, vouched_user):
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(vouched_user['email'])
|
||||
search_page = home_page.header.search_for(u'mbrandt', loggedin=True)
|
||||
assert search_page.results_count > 0
|
||||
|
@ -50,7 +48,7 @@ class TestSearch:
|
|||
@pytest.mark.nondestructive
|
||||
def test_search_for_not_existing_mozillian_when_logged_in(self, base_url, selenium, vouched_user):
|
||||
query = u'Qwerty'
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
home_page.login(vouched_user['email'])
|
||||
search_page = home_page.header.search_for(query, loggedin=True)
|
||||
assert 0 == search_page.results_count
|
||||
|
@ -58,7 +56,7 @@ class TestSearch:
|
|||
@pytest.mark.nondestructive
|
||||
def test_search_for_not_existing_mozillian_when_not_logged_in(self, base_url, selenium):
|
||||
query = u'Qwerty'
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
search_page = home_page.header.search_for(query)
|
||||
assert 0 == search_page.results_count
|
||||
|
||||
|
@ -67,6 +65,6 @@ class TestSearch:
|
|||
# Searching for empty string redirects to the Search page
|
||||
# with publicly available profiles
|
||||
query = u''
|
||||
home_page = Home(base_url, selenium)
|
||||
home_page = Home(selenium, base_url).open()
|
||||
search_page = home_page.header.search_for(query)
|
||||
assert search_page.results_count == 0
|
||||
|
|
Загрузка…
Ссылка в новой задаче