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') no_results = GroupLocator(By.CSS_SELECTOR, '.search-results-section .text-muted')
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 QuickfilesPage(BaseQuickfilesPage, GuidBasePage): """Main page for a user's quickfiles. Take's a user's guid, but defaults to USER_ONE's if a guid isn't given.""" base_url = settings.OSF_HOME + '/{guid}/quickfiles/' user = osf_api.current_user() def __init__(self, driver, verify=False, guid=user.id): super().__init__(driver, verify, guid) identity = Locator(By.ID, 'quickfiles-dropzone') loading_indicator = Locator(By.CSS_SELECTOR, '.ball-scale') upload_button = Locator(By.CSS_SELECTOR, 'button[data-analytics-name="Upload"]') share_button = Locator(By.CSS_SELECTOR, '[data-test-share-dialog-button]') download_button = Locator(By.CSS_SELECTOR, '[data-test-download-button]') download_as_zip_button = Locator(By.CSS_SELECTOR, '[data-test-download-zip-button]') view_button = Locator(By.CSS_SELECTOR, '[data-test-view-button]') help_button = Locator(By.CSS_SELECTOR, '[data-test-info-button]') filter_button = Locator(By.CSS_SELECTOR, '[data-test-filter-button]') rename_button = Locator(By.CSS_SELECTOR, '[data-test-rename-file-button]') delete_button = Locator(By.CSS_SELECTOR, '[data-test-delete-file-button]') move_button = Locator(By.CSS_SELECTOR, '[data-test-move-button]') filter_input = Locator(By.CSS_SELECTOR, '[data-test-filter-input]') filter_close_button = Locator(By.CSS_SELECTOR, '[data-test-close-filter]') generic_modal = Locator(By.CSS_SELECTOR, '.modal-title') help_modal_close_button = Locator(By.CSS_SELECTOR, '[data-test-close-current-modal]') share_popover = Locator(By.CSS_SELECTOR, '[data-test-file-share-copyable-text]') move_create_new_project_button = Locator( By.CSS_SELECTOR, '[data-test-ps-new-project-button]') move_existing_project_button = Locator( By.CSS_SELECTOR, '[data-test-ps-existing-project-button]') move_modal_close_button = Locator( By.CSS_SELECTOR, '[data-test-move-to-project-modal-close-button]') confirm_delete_button = Locator(By.CSS_SELECTOR, '[data-test-delete-file-confirm-button]') flash_message = Locator(By.CSS_SELECTOR, '.flash-message') rename_input = Locator(By.CSS_SELECTOR, '[data-test-rename-field="rename"]') rename_save_button = Locator(By.CSS_SELECTOR, '[data-test-save-rename]') rename_close_button = Locator(By.CSS_SELECTOR, '[data-test-close-rename]') # Group Locators files = GroupLocator(By.CSS_SELECTOR, '._file-browser-item_1v8xgw') file_titles = GroupLocator(By.CSS_SELECTOR, '[data-test-file-item-link]') # Components create_project_modal = ComponentLocator(EmberCreateProjectModal) project_created_modal = ComponentLocator(EmberProjectCreatedModal)
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 ProjectList(BaseElement): search_input = Locator(By.ID, 'searchQuery', settings.LONG_TIMEOUT) top_project_link = Locator(By.CSS_SELECTOR, 'div.quick-search-table > div:nth-child(3) > a:nth-child(1)') sort_title_asc_button = Locator(By.CSS_SELECTOR, 'div.quick-search-table > div.row.node-col-headers.m-t-md > div.col-sm-3.col-md-6 > div > button:nth-child(1)') sort_title_dsc_button = Locator(By.CSS_SELECTOR, 'div.quick-search-table > div.row.node-col-headers.m-t-md > div.col-sm-3.col-md-6 > div > button:nth-child(2)') sort_date_asc_button = Locator(By.CSS_SELECTOR, 'div.quick-search-table > div.row.node-col-headers.m-t-md > div:nth-child(3) > div > span > button:nth-child(1)') sort_date_dsc_button = Locator(By.CSS_SELECTOR, 'div.quick-search-table > div.row.node-col-headers.m-t-md > div:nth-child(3) > div > span > button:nth-child(2)') # Group Locators project_list_projects = GroupLocator(By.CSS_SELECTOR, 'div.quick-search-table > div:nth-child(3) > a') def get_nth_project_link(self, n=0): base_selector = 'div.quick-search-table > div:nth-child(3) > a:nth-child' try: selector = '{}({})'.format(base_selector, n) element = self.driver.find_element(By.CSS_SELECTOR, selector) guid = element.get_attribute('href').strip('/') return guid except: raise ValueError('Unable to find a project at position {}'.format(n)) def get_list_length(self): sleep(0.4) # Need sleep to let quicksearch do its thing return len(self.project_list_projects)
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 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 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 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)
class QuickfilesPage(BaseQuickfilesPage, GuidBasePage): """Main page for a user's quickfiles. Take's a user's guid, but defaults to USER_ONE's if a guid isn't given. """ base_url = settings.OSF_HOME + '/{guid}/quickfiles/' user = osf_api.current_user() def __init__(self, driver, verify=False, guid=user.id): super().__init__(driver, verify, guid) # TODO: Add download buttons back in when you have a way to distingish them identity = Locator(By.CSS_SELECTOR, '#quickfiles-dropzone') loading_indicator = Locator(By.CSS_SELECTOR, '.ball-scale') upload_button = Locator(By.CSS_SELECTOR, '.dz-upload-button') share_button = Locator(By.CSS_SELECTOR, '#shareButton') view_button = Locator(By.CSS_SELECTOR, '.btn .fa-file-o') help_button = Locator(By.CSS_SELECTOR, '.btn .fa-info') filter_button = Locator(By.CSS_SELECTOR, '.btn .fa-search') rename_button = Locator(By.CSS_SELECTOR, '.btn .fa-pencil') delete_button = Locator(By.CSS_SELECTOR, '.btn .fa-trash') move_button = Locator(By.CSS_SELECTOR, '.btn .fa-level-up') # Group Locators files = GroupLocator(By.CSS_SELECTOR, '._file-browser-item_1v8xgw') file_titles = GroupLocator(By.CSS_SELECTOR, '._file-browser-item_1v8xgw a')
class UserProfilePage(GuidBasePage): user = osf_api.current_user() def __init__(self, driver, verify=False, guid=user.id): super().__init__(driver, verify, guid) #TODO: Reconsider using a component here (and using component locators correctly) identity = Locator(By.CLASS_NAME, 'profile-fullname', settings.LONG_TIMEOUT) no_public_projects_text = Locator(By.CSS_SELECTOR, '#publicProjects .help-block') no_public_components_text = Locator(By.CSS_SELECTOR, '#publicComponents .help-block') edit_profile_link = Locator(By.CSS_SELECTOR, '#edit-profile-settings') #TODO: Seperate out by component if it becomes necessary loading_indicator = Locator(By.CSS_SELECTOR, '.ball-pulse') # Group Locators public_projects = GroupLocator(By.CSS_SELECTOR, '#publicProjects .list-group-item') public_components = GroupLocator(By.CSS_SELECTOR, '#publicComponents .list-group-item') quickfiles = GroupLocator(By.CSS_SELECTOR, '#quickFiles .list-group-item')
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]')
class ForksPage(GuidBasePage): base_url = settings.OSF_HOME + '/{guid}/forks/' identity = Locator(By.CSS_SELECTOR, '._Forks_1xlord') new_fork_button = Locator(By.CSS_SELECTOR, '._Forks__new-fork_1xlord .btn-success') create_fork_modal_button = Locator(By.CSS_SELECTOR, '.modal-footer .btn-info') cancel_modal_button = Locator(By.CSS_SELECTOR, '.modal-footer .btn-default') info_toast = Locator(By.CSS_SELECTOR, '.toast-info') fork_link = Locator(By.CSS_SELECTOR, 'a[data-analytics-name="Title"]') fork_authors = Locator(By.CSS_SELECTOR, 'div[class="_NodeCard__authors_1i3kzz"]') placeholder_text = Locator(By.CSS_SELECTOR, 'div[class="_Forks__placeholder_1xlord"]') # Group Locators listed_forks = GroupLocator(By.CSS_SELECTOR, '.list-group-item')
class LegacyDashboardPage(BaseDashboardPage): waffle_override = {'ember_home_page': DashboardPage} identity = Locator(By.CSS_SELECTOR, '#osfHome > div.prereg-banner', settings.LONG_TIMEOUT) create_project_button = Locator(By.CSS_SELECTOR, 'button.btn-success:nth-child(1)', settings.LONG_TIMEOUT) view_meetings_button = Locator(By.XPATH, '//a[text()="View meetings"]') view_preprints_button = Locator(By.XPATH, '//a[text()="View preprints"]') new_and_noteworthy = Locator(By.CSS_SELECTOR, '#osfHome > div.newAndNoteworthy > div > div:nth-child(2) > div > div > div:nth-child(1) > div:nth-child(1) > div > h4', settings.LONG_TIMEOUT) first_popular_project_entry = Locator(By.CLASS_NAME, 'public-projects-item', settings.LONG_TIMEOUT) popular_projects = Locator(By.CSS_SELECTOR, '#osfHome > div.newAndNoteworthy > div > div:nth-child(2) > div > div > div:nth-child(1) > div:nth-child(2) > div > h4', settings.LONG_TIMEOUT) institutions_carousel_left_arrow = Locator(By.CSS_SELECTOR, '.left.carousel-control') institutions_carousel_right_arrow = Locator(By.CSS_SELECTOR, '.right.carousel-control') # Group Locators institution_carousel_logos = GroupLocator(By.CSS_SELECTOR, '.carousel-inner .img-circle') # Components create_project_modal = ComponentLocator(components.CreateProjectModal) project_created_modal = ComponentLocator(components.ProjectCreatedModal) project_list = ComponentLocator(components.ProjectList)
class InstitutionalLoginPage(BasePage): url = settings.OSF_HOME + '/login?campaign=institution' identity = Locator(By.CSS_SELECTOR, '#institutionSelect') institution_dropdown = Locator(By.ID, 'institutionSelect') sign_in_button = Locator(By.ID, 'institutionSubmit') osf_home_link = Locator(By.CSS_SELECTOR, '.navbar-link') sign_up_button = Locator(By.ID, 'osfRegister') cant_find_institution_link = Locator(By.LINK_TEXT, "I can't find my institution") need_help_link = Locator(By.LINK_TEXT, 'Need help signing in?') sign_in_with_osf_link = Locator(By.LINK_TEXT, 'Sign in with your OSF account') cos_footer_link = Locator(By.LINK_TEXT, 'Center for Open Science') terms_of_use_footer_link = Locator(By.LINK_TEXT, 'Terms of Use') privacy_policy_footer_link = Locator(By.LINK_TEXT, 'Privacy Policy') status_footer_link = Locator(By.LINK_TEXT, 'Status') dropdown_options = GroupLocator(By.CSS_SELECTOR, '#institutionSelect option')
class LogWidget(BaseElement): loading_indicator = Locator(By.CSS_SELECTOR, '#logFeed .ball-scale') # Group Locators log_items = GroupLocator(By.CSS_SELECTOR, '#logFeed .db-activity-item')
class InstitutionalLoginPage(BasePage): url = settings.OSF_HOME + '/login?campaign=institution' identity = Locator(By.CSS_SELECTOR, '#institution-form-select') dropdown_options = GroupLocator(By.CSS_SELECTOR, '#institution-form-select option')