class RegistriesDiscoverPage(BaseRegistriesPage): url = settings.OSF_HOME + '/registries/discover' identity = Locator( By.CSS_SELECTOR, 'div[data-analytics-scope="Registries Discover page"]' ) search_box = Locator(By.ID, 'search') loading_indicator = Locator(By.CSS_SELECTOR, '.ball-scale', settings.LONG_TIMEOUT) osf_filter = Locator( By.CSS_SELECTOR, '[data-test-source-filter-id$="OSF Registries"]' ) # Group Locators search_results = GroupLocator( By.CSS_SELECTOR, '._RegistriesSearchResult__Title_1wvii8' ) def get_first_non_withdrawn_registration(self): for result in self.search_results: try: result.find_element_by_class_name('label-default') except NoSuchElementException: return result.find_element_by_css_selector( '[data-test-result-title-id]' )
class RegistriesLandingPage(BaseRegistriesPage): url = settings.OSF_HOME + '/registries' identity = Locator( By.CSS_SELECTOR, '._RegistriesHeader_3zbd8x', settings.LONG_TIMEOUT ) search_box = Locator(By.ID, 'search')
class COSDonatePage(BasePage): url = 'https://cos.io/about/support-cos/' identity = Locator(By.CSS_SELECTOR, 'div[class="slide-wrapper-background"]', settings.LONG_TIMEOUT) page_heading = Locator(By.CSS_SELECTOR, 'div[class="banner-element"]')
class AnalyticsPage(GuidBasePage): base_url = settings.OSF_HOME + '/{guid}/analytics/' identity = Locator(By.CSS_SELECTOR, '._Counts_1mhar6') private_project_message = Locator(By.CSS_SELECTOR, '._PrivateProject_1mhar6') disabled_chart = Locator(By.CSS_SELECTOR, '._Chart_1hff7g _Blurred_1hff7g')
class ProjectCreatedModal(BaseElement): go_to_project_href_link = Locator(By.XPATH, '//a[text()="Go to new project"]', settings.LONG_TIMEOUT) keep_working_here_button = Locator(By.CSS_SELECTOR, 'button[data-dismiss="modal"]', settings.TIMEOUT)
class PreprintDiscoverPage(BasePreprintPage): url_addition = 'discover' identity = Locator(By.ID, 'share-logo') loading_indicator = Locator(By.CSS_SELECTOR, '.ball-scale') # Group Locators search_results = GroupLocator(By.CSS_SELECTOR, '.search-result h4 > a')
class PreprintDetailPage(GuidBasePage, BasePreprintPage): url_base = urljoin(settings.OSF_HOME, '{guid}') identity = Locator(By.ID, 'preprintTitle', settings.LONG_TIMEOUT) title = Locator(By.ID, 'preprintTitle', settings.LONG_TIMEOUT) supplemental_link = Locator( By.CSS_SELECTOR, 'h6[class="detail-header-info"] > div:last-child > a:last-child')
class PreprintLandingPage(BasePreprintPage): identity = Locator(By.CSS_SELECTOR, '.ember-application .preprint-header', settings.LONG_TIMEOUT) add_preprint_button = Locator(By.CLASS_NAME, 'preprint-submit-button', settings.LONG_TIMEOUT) search_button = Locator(By.CSS_SELECTOR, '.preprint-search .btn-default') submit_navbar = Locator(By.CSS_SELECTOR, '.branded-nav > :nth-child(2)') submit_button = Locator(By.CSS_SELECTOR, '.btn.btn-success')
class FileWidget(BaseElement): loading_indicator = Locator(By.CSS_SELECTOR, '#treeGrid .ball-scale', settings.VERY_LONG_TIMEOUT) file_expander = Locator(By.CSS_SELECTOR, '.fa-plus') filter_button = Locator(By.CSS_SELECTOR, '.fangorn-toolbar-icon .fa-search') filter_input = Locator(By.CSS_SELECTOR, '#folderRow .form-control') # Group Locators component_and_file_titles = GroupLocator(By.CSS_SELECTOR, '.td-title')
class SearchPage(OSFBasePage): url = settings.OSF_HOME + '/search/' identity = Locator(By.ID, 'searchPageFullBar') search_bar = Locator(By.ID, 'searchPageFullBar') loading_indicator = Locator(By.CSS_SELECTOR, '.ball-scale') # Group Locators search_results = GroupLocator(By.CSS_SELECTOR, '.search-result')
class ProfileInformationPage(BaseUserSettingsPage): url = settings.OSF_HOME + '/settings/' identity = Locator(By.CSS_SELECTOR, 'div[id="profileSettings"]') middle_name_input = Locator( By.CSS_SELECTOR, '#names > div > form > div:nth-child(5) > input') save_button = Locator( By.CSS_SELECTOR, '#names > div > form > div.p-t-lg.p-b-lg > button.btn.btn-success') update_success = Locator(By.CSS_SELECTOR, '.text-success')
class CASAuthorizationPage(BasePage): url = settings.CAS_DOMAIN + '/oauth2/authorize' identity = Locator(By.CLASS_NAME, 'login-section') navbar_brand = Locator(By.CLASS_NAME, 'cas-brand-text') status_message = Locator( By.CSS_SELECTOR, '#content > div > section > section.card-message > h2') allow_button = Locator(By.ID, 'allow') deny_button = Locator(By.ID, 'deny')
class FilesPage(GuidBasePage): base_url = settings.OSF_HOME + '/{guid}/files/' identity = Locator(By.CSS_SELECTOR, '#treeGrid') session = osf_api.get_default_session() fangorn_rows = GroupLocator(By.CSS_SELECTOR, '#tb-tbody .fg-file-links') fangorn_addons = GroupLocator(By.CSS_SELECTOR, "div[data-level='2']") file_action_buttons = GroupLocator(By.CSS_SELECTOR, '#folderRow .fangorn-toolbar-icon') delete_modal = Locator(By.CSS_SELECTOR, 'span.btn:nth-child(1)')
class CreateProjectModal(BaseElement): modal = Locator(By.ID, 'addProjectFromHome') create_project_button = Locator(By.CSS_SELECTOR, '#addProject button.btn.btn-success') cancel_button = Locator( By.CSS_SELECTOR, '#addProjectFromHome > div > div > div.modal-footer > button.btn.btn-default', ) title_input = Locator(By.CSS_SELECTOR, '.form-control') select_all_link = Locator(By.XPATH, '//a[text()="Select all"]') remove_all_link = Locator(By.XPATH, '//a[text()="Remove all"]') more_arrow = Locator( By.CSS_SELECTOR, '#addProjectFromHome > div > div > div.modal-body > div > div.text-muted.pointer', ) description_input = Locator( By.CSS_SELECTOR, '#addProjectFromHome > div > div > div.modal-body > div > div:nth-child(4) > input', ) template_dropdown = Locator(By.ID, 'select2-chosen-2') def institution_selected(self, institution): try: logo = self.modal.find_element(By.NAME, institution) return '0.25' not in logo.value_of_css_property('opacity') except Exception: raise ValueError( 'Institution logo for {} not present in modal'.format( institution))
class LoginPage(BasePage): url = settings.OSF_HOME + '/login' identity = Locator(By.CSS_SELECTOR, '#cas', settings.LONG_TIMEOUT) username_input = Locator(By.ID, 'username') password_input = Locator(By.ID, 'password') submit_button = Locator(By.NAME, 'submit') remember_me_checkbox = Locator(By.ID, 'rememberMe') institutional_login_button = Locator(By.ID, 'alt-login-inst') orcid_login_button = Locator(By.ID, 'alt-login-orcid') if 'localhost:5000' in settings.OSF_HOME: submit_button = Locator(By.ID, 'submit') identity = Locator(By.ID, 'login') def error_handling(self): if '/login' not in self.driver.current_url: raise LoginError('Already logged in') def submit_login(self, user, password): self.username_input.send_keys(user) if ('localhost:5000' not in settings.OSF_HOME): self.password_input.send_keys(password) if self.remember_me_checkbox.is_selected(): self.remember_me_checkbox.click() self.submit_button.click()
class InstitutionBrandedPage(OSFBasePage): identity = Locator( By.CSS_SELECTOR, '#fileBrowser > div.db-header.row > div.db-buttonRow.col-xs-12.col-sm-4.col-lg-3 > div > input', ) empty_collection_indicator = Locator(By.CLASS_NAME, 'db-non-load-template') # Group Locators project_list = GroupLocator(By.CSS_SELECTOR, '#tb-tbody > div > div > div.tb-row')
class MyProjectsPage(OSFBasePage): url = settings.OSF_HOME + '/myprojects/' identity = Locator(By.CSS_SELECTOR, '.col-xs-8 > h3:nth-child(1)', settings.LONG_TIMEOUT) create_project_button = Locator(By.CSS_SELECTOR, '[data-target="#addProject"]') create_collection_button = Locator(By.CSS_SELECTOR, '[data-target="#addColl"]') first_project = Locator( By.CSS_SELECTOR, 'div[class="tb-tbody-inner"] > div:first-child > div:nth-child(1)', ) first_project_hyperlink = Locator( By.CSS_SELECTOR, 'div[data-rindex="0"] > div:first-child >' ' span:last-child > a:first-child', ) first_custom_collection = Locator(By.CSS_SELECTOR, 'li[data-index="4"] span', settings.QUICK_TIMEOUT) first_collection_settings_button = Locator(By.CSS_SELECTOR, '.fa-ellipsis-v', settings.QUICK_TIMEOUT) first_collection_remove_button = Locator(By.CSS_SELECTOR, '[data-target="#removeColl"]', settings.QUICK_TIMEOUT) # Components create_collection_modal = ComponentLocator(CreateCollectionModal) delete_collection_modal = ComponentLocator(DeleteCollectionModal) create_project_modal = ComponentLocator(CreateProjectModal) project_created_modal = ComponentLocator(ProjectCreatedModal)
class InstitutionsLandingPage(OSFBasePage): url = settings.OSF_HOME + '/institutions/' # TODO fix insitution typo identity = Locator(By.CSS_SELECTOR, 'div[data-test-insitutions-header]', settings.VERY_LONG_TIMEOUT) search_bar = Locator(By.CSS_SELECTOR, '.ember-text-field') # Group Locators institution_list = GroupLocator(By.CSS_SELECTOR, 'span[data-test-institution-name]') navbar = ComponentLocator(InstitutionsNavbar)
def click_recaptcha(self): self.driver.switch_to.frame(self.driver.find_element_by_tag_name('iframe')) # only click the captcha checkbox if it isn't already checked if ( Locator(By.ID, 'recaptcha-anchor') .get_element(self.driver, 'recaptcha-anchor') .get_attribute('aria-checked') == 'false' ): Locator(By.CSS_SELECTOR, '.recaptcha-checkbox-border').get_element( self.driver, 'capcha' ).click() self.driver.switch_to.default_content() sleep(2)
class GenericCASPage(BasePage): url = settings.CAS_DOMAIN identity = Locator(By.CLASS_NAME, 'login-error-card') navbar_brand = Locator(By.CLASS_NAME, 'cas-brand-text') auto_redirect_message = Locator( By.CSS_SELECTOR, '#content > div > section > section.text-without-mdi.text-center.text-bold.text-large.margin-large-vertical.title', ) status_message = Locator( By.CSS_SELECTOR, '#content > div > section > section.card-message > h2') error_detail = Locator( By.CSS_SELECTOR, '#content > div > section > section.card-message > pre')
class EmberRegisterPage(OSFBasePage): url = settings.OSF_HOME + '/register' identity = Locator(By.CSS_SELECTOR, '._sign-up-container_19kgff') # Components sign_up_form = ComponentLocator(SignUpForm)
class RegisterPage(OSFBasePage): waffle_override = {'ember_auth_register': EmberRegisterPage} url = settings.OSF_HOME + '/register' identity = Locator(By.CSS_SELECTOR, '#signUpScope')
class DeveloperAppsPage(BaseUserSettingsPage): waffle_override = {'ember_user_settings_apps_page': EmberDeveloperAppsPage} url = settings.OSF_HOME + '/settings/applications/' identity = Locator(By.CSS_SELECTOR, 'div[data-analytics-scope="Developer apps"')
class LandingPage(OSFBasePage): identity = Locator(By.CSS_SELECTOR, '._heroHeader_1qc5dv', settings.LONG_TIMEOUT) # Components navbar = ComponentLocator(EmberNavbar) sign_up_form = ComponentLocator(SignUpForm)
class BaseUserSettingsPage(OSFBasePage): url = settings.OSF_HOME + '/settings/' identity = Locator(By.ID, 'profileSettings') # Components side_navigation = ComponentLocator(SettingsSideNavigation)
class RegistriesDiscoverPage(BaseRegistriesPage): url = settings.OSF_HOME + '/registries/discover' identity = Locator(By.CSS_SELECTOR, '[data-test-share-logo]') loading_indicator = Locator(By.CSS_SELECTOR, '.ball-scale') # Group Locators search_results = GroupLocator(By.CSS_SELECTOR, '._RegistriesSearchResult__Title_1wvii8') def get_first_non_withdrawn_registration(self): for result in self.search_results: try: result.find_element_by_class_name('label-default') except NoSuchElementException: return result.find_element_by_css_selector( '[data-test-result-title-id]')
def click_recaptcha(self): self.driver.switch_to.frame( self.driver.find_element_by_tag_name('iframe')) Locator(By.CSS_SELECTOR, '.recaptcha-checkbox-checkmark').get_element( self.driver, 'capcha').click() self.driver.switch_to.default_content() #TODO: Replace with an expected condition that checks if aria-checked="true" sleep(2)
class EmberProjectList(BaseElement): search_input = Locator(By.CSS_SELECTOR, '._quick-search-input_1b28t4 > input') top_project_link = Locator(By.CLASS_NAME, '_DashboardItem_17nn6d') sort_title_asc_button = Locator(By.CSS_SELECTOR, '._quick-search-col_1b28t4 ._SortButton_1ifm79 [title~="ascending"]') sort_title_dsc_button = Locator(By.CSS_SELECTOR, '._quick-search-col_1b28t4 ._SortButton_1ifm79 [title~="descending"]') sort_date_asc_button = Locator(By.CSS_SELECTOR, '.col-md-3 ._quick-search-col_1b28t4 ._SortButton_1ifm79 [title~="ascending"]') sort_date_dsc_button = Locator(By.CSS_SELECTOR, '.col-md-3 ._quick-search-col_1b28t4 ._SortButton_1ifm79 [title~="descending"]') loading_dashboard_item = Locator(By.CLASS_NAME, '_loading-dashboard-item_1b28t4', settings.QUICK_TIMEOUT) # Group Locators project_list_projects = GroupLocator(By.CSS_SELECTOR, '._quick-search-table_1b28t4 a') def get_nth_project_link(self, n=0): if self.loading_dashboard_item.here_then_gone(): try: element = self.project_list_projects[n - 1] return element.get_attribute('href') except IndexError: raise ValueError('Unable to find a project at position {}'.format(n)) raise ValueError('Dashboard page is still loading.') def get_list_length(self): if self.loading_dashboard_item.here_then_gone(): return len(self.project_list_projects) raise ValueError('Dashboard page is still loading.')
class DashboardPage(BaseDashboardPage): url = settings.OSF_HOME + '/dashboard/' identity = Locator( By.CSS_SELECTOR, '._institutions-panel_1b28t4', settings.LONG_TIMEOUT ) create_project_button = Locator( By.CSS_SELECTOR, '[data-test-create-project-modal-button]', settings.LONG_TIMEOUT, ) view_meetings_button = Locator(By.XPATH, '//a[text()="View meetings"]') view_preprints_button = Locator(By.XPATH, '//a[text()="View preprints"]') first_noteworthy_project = Locator( By.CSS_SELECTOR, '[data-test-noteworthy-project]', settings.LONG_TIMEOUT ) institutions_carousel_left_arrow = Locator( By.CSS_SELECTOR, '.carousel-control.left' ) institutions_carousel_right_arrow = Locator( By.CSS_SELECTOR, '.carousel-control.right' ) # Group Locators institution_carousel_logos = GroupLocator(By.CSS_SELECTOR, '.carousel-inner img') # Components navbar = ComponentLocator(EmberNavbar) create_project_modal = ComponentLocator(components.EmberCreateProjectModal) project_created_modal = ComponentLocator(components.EmberProjectCreatedModal) project_list = ComponentLocator(components.EmberProjectList, settings.LONG_TIMEOUT)
class SignUpForm(BaseElement): name_input = Locator(By.NAME, 'fullName') email_one_input = Locator(By.NAME, 'email1') email_two_input = Locator(By.NAME, 'email2') password_input = Locator(By.NAME, 'password') terms_of_service_checkbox = Locator(By.NAME, 'acceptedTermsOfService') sign_up_button = Locator(By.CSS_SELECTOR, '[data-test-sign-up-button]') registration_success = Locator( By.CSS_SELECTOR, '.ext-success', settings.LONG_TIMEOUT ) def click_recaptcha(self): self.driver.switch_to.frame(self.driver.find_element_by_tag_name('iframe')) # only click the captcha checkbox if it isn't already checked if ( Locator(By.ID, 'recaptcha-anchor') .get_element(self.driver, 'recaptcha-anchor') .get_attribute('aria-checked') == 'false' ): Locator(By.CSS_SELECTOR, '.recaptcha-checkbox-border').get_element( self.driver, 'capcha' ).click() self.driver.switch_to.default_content() sleep(2)