class _BasicMetadataEntry(PageObject): attribute = id = TextLabelWebElement('th') value = TextLabelWebElement('td') remove = ButtonWebItem('.oneicon-close') def __str__(self): return 'metadata basic entry'
class _Chunk(PageObject): start = TextLabelWebElement('.file-size .start') end = TextLabelWebElement('.file-size .end') _canvas = WebElement('canvas') _file_chunks = WebElement('.file-chunks') def __str__(self): return 'file blocks for {}'.format(self.parent) @property def size(self): end, unit = self.end.split() return int(end) - int(self.start), unit @property def chunks(self): file_size, _ = self.size chunks = self.driver.execute_script(_canvas_fill, self._canvas) if chunks is not False: return [(chunk[0]*file_size, chunk[1]*file_size) for chunk in chunks] else: raise RuntimeError('{} is not filled correctly: some columns ' 'are not filled with one color'.format(self)) def is_never_synchronized(self): return 'never-synchronized' in self._file_chunks.get_attribute('class')
class _SpaceRecord(PageObject, ExpandableMixin): name = id = TextLabelWebElement('.space-header.truncate', parent_name='given space record') size = TextLabelWebElement('.space-header-size') providers_count = TextLabelWebElement('.providers-count') settings = WebItem('.settings-tool .settings-dropdown', cls=_SettingsDropdown) providers = WebItemsSequence('ul.tertiary-list li.sidebar-space-provide', cls=_ProviderRecord) _toggle = ToggleWebElement('.secondary-item-container .clickable') _add_storage_btn = ButtonWebElement('ul.tertiary-list li.get-support') _set_home_btn = ButtonWebElement('.secondary-item-element.star-toggle ' '.oneicon-home-outline') _home_space_icon = WebElement('.oneicon-space-home') _home_icon = WebElement( '.secondary-item-element.star-toggle .oneicon-home') def __str__(self): return 'space record named: "{}" in {}'.format(self.name, self.parent) def is_home(self): try: _ = self._home_icon and self._home_space_icon except RuntimeError: return False else: return True def add_storage(self): self._click_on_btn('add_storage') def set_as_home(self): if not self.is_home(): self._click_on_btn('set_home')
class _SpaceRecord(PageObject): name = id = TextLabelWebElement('.one-label.truncate', parent_name='provider popup') size = TextLabelWebElement('.space-header-size') _space_icon = IconWebElement('.oneicon') def __str__(self): return '"{}" space record in {}'.format(self.name, self.parent) def is_home(self): return 'default' in self._space_icon.get_attribute('class')
class OZPanel(PageObject, ExpandableMixin): name = TextLabelWebElement('a.main-accordion-toggle', parent_name='oz panel') _toggle = ToggleWebElement('a.main-accordion-toggle') def __str__(self): return '{} panel in {}'.format(self.name, self.parent)
class AddStorage(PageObject): _header = WebElement('.modal-header') _space_name = WebElement('.modal-header .special-name') @property def title(self): header = self.driver.execute_script( '$(arguments[0]).clone().children().remove().end().text()', self._header ) return (header + ' ' + self._space_name).lower() token = command = TextLabelWebElement('textarea.token-input') _copy_btn = ButtonWebElement('.copy-btn') _gen_token_btn = ButtonWithTextWebElement('a.clickable', text='generate another token') def generate_another_token(self): self._click_on_btn('gen_token') def copy(self): self._click_on_btn('copy') def __str__(self): return 'Add storage modal for "{}"'.format(self.title)
class FileDistributionModal(Modal): file_name = TextLabelWebElement('.modal-row strong') providers = WebItemsSequence('table.file-blocks-table tbody tr', cls=_FileDistributionRecord) def __str__(self): return 'File distribution modal for "{}"'.format(self.file_name)
class _ProviderPopup(PageObject): hostname = InputWebElement('input.provider-host-text') name = id = TextLabelWebElement('.title-label', parent_name='given provider popup') spaces = WebItemsSequence('ul li.provider-place-drop-space', cls=_SpaceRecord) _cp_hostname_btn = ButtonWebElement('.provider-host-copy-btn') _go_to_files_btn = ButtonWebElement('.drop-body .btn-go-to-files, ' '.drop-body button') _popup = WebElement('.provider-place-drop') def __str__(self): return '"{}" provider popup on {}'.format(self.name, self.parent) def is_working(self): return 'working' in self.web_elem.get_attribute('class') def is_displayed(self): try: _ = self._popup except RuntimeError: return False else: return True def copy_hostname(self): self._click_on_btn('cp_hostname') def go_to_your_files(self): self._click_on_btn('go_to_files')
class ProgressBar(PageObject): progress_text = TextLabelWebElement('.progress-text') _progress_container = WebElement('.progress-bar') @property def progress_bar(self): style = self._progress_container.get_attribute('style') return re.search(r'width:\s*(\d+?%)', style).group(1)
class PermissionType(PageObject): name = id = TextLabelWebElement('.option-label') def set(self): self.web_elem.click() def __str__(self): return 'permission type option {} in {}'.format(self.name, self.parent)
class _FileDistributionRecord(PageObject): name = id = TextLabelWebElement('.provider-name', parent_name='given provider') distribution = WebItem('.chunks', cls=_Chunk) def __str__(self): return 'provider record for "{item}" in ' \ '{parent}'.format(item=self.name, parent=self.parent)
class MigrationRecord(PageObject): name = id = TextLabelWebElement('.item-label') def select(self): self.web_elem.click() def __str__(self): return 'provider record in migration menu in {}'.format(self.parent)
class TransferRecord(PageObject): name = TextLabelWebElement('td:first-of-type') username = TextLabelWebElement('td:nth-of-type(2)') destination = TextLabelWebElement('td:nth-of-type(3)') status_icon = IconWebElement('.cell-status') type_icon = IconWebElement('.cell-type') icon = IconWebElement('.transfer-file-icon') def __init__(self, driver, web_elem, parent, **kwargs): super(TransferRecord, self).__init__(driver, web_elem, parent, **kwargs) status_class = self.status_icon.get_attribute('class').split() type_class = self.type_icon.get_attribute('class').split() self.status = [x for x in status_class if x in TransferStatusList][0] self.type = [x for x in type_class if x in TransferTypeList][0] def get_chart(self): if not 'expanded-row' in self.web_elem.get_attribute('class'): raise RuntimeError( "Transfer record for file {} is not expanded".format( self.name)) return TransferChart( self.driver, self.web_elem.find_element_by_xpath(' .//following-sibling::tr'), self.web_elem) def is_expanded(self): return "expanded-row" in self.web_elem.get_attribute('class') def expand(self): if not self.is_expanded(): self.web_elem.click() def collapse(self): if self.is_expanded(): self.web_elem.click() def is_file(self): return "oneicon-file" in self.icon.get_attribute('class') def is_directory(self): return "oneicon-folder" in self.icon.get_attribute("class") def __str__(self): return 'Transfer row {} in {}'.format(self.name, self.parent)
class _ProviderRecord(PageObject, ExpandableMixin): name = id = TextLabelWebElement('.provider-header.truncate', parent_name='given provider record') spaces_count = TextLabelWebElement('.spaces-count') spaces = WebItemsSequence('ul.tertiary-list li.sidebar-provider-space', cls=_SpaceRecord) _provider_icon = IconWebElement('.provider-icon .oneicon') _toggle = ToggleWebElement('.spaces-count') _click_area = WebElement('.secondary-item-container') _set_home_btn = ButtonWebElement('.secondary-item-element.star-toggle ' '.oneicon-home-outline') _home_icon = WebElement('.secondary-item-element.star-toggle ' '.oneicon-home') def __str__(self): return 'provider record named: "{}" in {}'.format( self.name, self.parent) def is_home(self): home1 = 'provider-home' in self._provider_icon.get_attribute('class') try: _ = self._home_icon except RuntimeError: return False else: return True and home1 def set_as_home(self): if not self.is_home(): self._click_on_btn('set_home') def unset_from_home(self): if self.is_home(): click_on_web_elem( self.driver, self._home_icon, 'cannot click on home icon for {item} in ' '{parent}'.format(item=self, parent=self.parent)) def is_working(self): return 'color-provider-online' \ in self._provider_icon.get_attribute('class') def is_not_working(self): return 'color-provider-offline' \ in self._provider_icon.get_attribute('class')
class DataDistributionModal(Modal): file_name = TextLabelWebElement('.modal-row strong') providers = WebItemsSequence('table.file-blocks-table tbody tr', cls=_DataDistributionRecord) migrate = WebItemsSequence('.migrate-popover li.migrate-item', cls=MigrationRecord) def __str__(self): return 'Data distribution modal for "{}"'.format(self.file_name)
class _SpaceRecord(PageObject): name = id = TextLabelWebElement('.item-label', parent_name='given space record') _icon = IconWebElement('.item-icon .one-icon') def __str__(self): return '{name} in {parent}'.format(name=self.name, parent=self.parent) def is_home(self): return 'oneicon-space-home' in self._icon.get_attribute('class')
class UserAliasPanel(OZPanel): alias = TextLabelWebElement('.alias-text') edit_box = WebItem('.alias-accordion-toggle.clickable', cls=EditBox) _rename_btn = ButtonWebElement('.oneicon-rename') def edit(self): with suppress(NoSuchElementException): err_msg = 'clicking on rename btn in {} disabled'.format(self) click_on_web_elem(self.driver, self._rename_btn, err_msg)
class TransferChart(PageObject): minute = ButtonWithTextWebElement('button.btn-default', text='Minute') hour = ButtonWithTextWebElement('button.btn-default', text='Hour') active = TextLabelWebElement('button.btn-default.active') # We take only last point in the chart _speed = WebElement( '.transfers-transfer-chart .ct-series line:last-of-type') def get_speed(self): return self._speed.get_attribute('ct:value').split(',')[1]
class SpaceSelector(PageObject, ExpandableMixin): selected_space_name = TextLabelWebElement('.item-label') spaces = WebItemsSequence('ul.dropdown-menu-list li', cls=_SpaceRecord) _icon = IconWebElement('.item-icon .one-icon') _toggle = ToggleWebElement('a.dropdown-toggle') def __str__(self): return 'space selector in {}'.format(self.parent) def is_selected_space_home(self): return 'oneicon-space-home' in self._icon.get_attribute('class')
class _ProviderRecord(PageObject): name = id = TextLabelWebElement('.one-label.truncate', parent_name='given provider record') _unsupport_space_btn = ButtonWebElement('.clickable .oneicon-leave-space') _click_area = WebElement('.clickable') def __str__(self): return 'provider record named: "{}" in {}'.format( self.name, self.parent) def unsupport_space(self): self._click_on_btn('unsupport_space')
class FileRow(PageObject): name = TextLabelWebElement('.file-label', parent_name='given file row') size = TextLabelWebElement('.file-list-col-size') modification_date = TextLabelWebElement('.file-list-col-modification') _icon = IconWebElement('.file-icon .one-icon') _metadata_tool = IconWebElement('.file-tool-metadata') _share_tool = IconWebElement('.file-tool-share') def __str__(self): return '{item} in {parent}'.format(item=self.name, parent=str(self.parent)) def is_selected(self): return 'active' in self.web_elem.get_attribute('class') def is_file(self): return 'file' in self._icon.get_attribute('class') def is_directory(self): return 'folder' in self._icon.get_attribute('class') def is_shared(self): return 'share' in self._icon.get_attribute('class') def is_tool_visible(self, name): tool = getattr(self, '_{tool}_tool'.format(tool=name)) return '25p' in tool.get_attribute('class') def click_on_tool(self, name): tool = getattr(self, '_{tool}_tool'.format(tool=name)) tool_icon = tool.find_element_by_css_selector('.oneicon') click_on_web_elem(self.driver, tool_icon, lambda: 'cannot click on "{}" in ' '{}'.format(name, self)) def double_click(self): ActionChains(self.driver).double_click(self.web_elem).perform()
class DirectoryTree(PageObject, ExpandableMixin): name = TextLabelWebElement('.item-label') _toggle = ToggleWebElement('.item-icon .one-icon') _header = HeaderWebElement('.secondary-sidebar-item.dir-item') _click_area = WebElement('.secondary-sidebar-item.dir-item ' '.item-click-area') _header_label = HeaderWebElement('.secondary-sidebar-item.dir-item ' '.truncate-secondary-sidebar-item') def __init__(self, *args, **kwargs): self._children = kwargs.pop('children') super(DirectoryTree, self).__init__(*args, **kwargs) def __str__(self): return 'DirectoryTree({path}) in {parent}'.format(path=self.pwd(), parent=self.parent) def __iter__(self): css_sel = 'ul.data-files-tree-list li:not(.clickable)' return (DirectoryTree(self.driver, dir_tree, self, children=dir_tree) for dir_tree in self._children.find_elements_by_css_selector(css_sel)) def __getitem__(self, name): for directory in self: if directory.name == name: return directory else: raise RuntimeError('no subdirectory named "{name}" found ' 'in {path}'.format(name=name, path=self)) def is_expanded(self): return True if 'open' in self._toggle.get_attribute('class') else False def is_active(self): return 'active' in self._header.get_attribute('class') def pwd(self): if not isinstance(self.parent, DirectoryTree): return '/' else: return '{path}{dir}/'.format(path=self.parent.pwd(), dir=self.name) @property def displayed_name_width(self): return self.driver.execute_script("return $(arguments[0]).width();", self._header_label)
class FileUploader(PageObject): heading = TextLabelWebElement('.panel-heading') _progress = WebElement('.resumable-progress') _rows = ItemListWebElement('ul.resumable-list li') @property def progress(self): return ProgressBar(self.driver, self._progress, self) def is_visible(self): return 'visible' in self.web_elem.get_attribute('class') def __str__(self): return 'file uploader in {}'.format(self.parent) def __iter__(self): return (FileUploadRow(self.driver, item, self) for item in self._rows) def __getitem__(self, selector): if isinstance(selector, int): items_count = self.items_count if selector >= items_count: raise RuntimeError('requested index {index} out of bound ' '{limit}'.format(index=selector, limit=items_count)) else: return FileRow(self.driver, nth(self._rows, selector), self) elif isinstance(selector, (str, unicode)): for item in self: if item.name == selector: return item else: raise RuntimeError('unable to find "{name}" in ' '{item}'.format(name=selector, item=self)) @property def items_count(self): return len(self._rows) def scroll_to_bottom(self): self.driver.execute_script('arguments[0].scrollIntoView();', self._rows[-1])
class _GroupRecord(PageObject, ExpandableMixin): name = id = TextLabelWebElement('.secondary-header', parent_name='given group record') def __str__(self): return 'group record named: "{}" in {}'.format(self.name, self.parent)
class _Message(PageObject): title = TextLabelWebElement('.panel-heading') msg = TextLabelWebElement('.panel-body') def __str__(self): return 'Message modal on {}'.format(self.parent)
class FileBrowser(PageObject): empty_dir_msg = TextLabelWebElement('.empty-model-container') _empty_dir_icon = IconWebElement('.empty-dir-image') _files = ItemListWebElement('tbody tr.file-row') _files_with_metadata = ItemListWebElement('tbody tr.first-level') _bottom = WebElement('.file-row-load-more') def __str__(self): return 'file browser in {}'.format(self.parent) def __iter__(self): return (FileRow(self.driver, item, self) for item in self._files) def __getitem__(self, selector): if isinstance(selector, int): items_count = self.files_count if selector >= items_count: raise RuntimeError('requested index {index} out of bound ' '{limit}'.format(index=selector, limit=items_count)) else: return FileRow(self.driver, nth(self._files, selector), self) elif isinstance(selector, (str, unicode)): for item in self: if item.name == selector: return item else: raise RuntimeError('unable to find "{name}" in ' '{item}'.format(name=selector, item=self)) @property def files_count(self): return len(self._files) def is_empty(self): try: self._empty_dir_icon except RuntimeError: return False else: return True def get_metadata_for(self, name): for item1, item2 in iter_ahead(self._files_with_metadata): if 'file-row' in item1.get_attribute('class'): if 'file-row' not in item2.get_attribute('class'): if FileRow(self.driver, item1, self).name == name: return MetadataRow(self.driver, item2, self) else: raise RuntimeError('no metadata row for "{name}" in {item} ' 'found'.format(name=name, item=self)) def scroll_to_bottom(self): self.driver.execute_script('arguments[0].scrollIntoView();', self._bottom) @contextmanager def select_files(self): from platform import system as get_system ctrl_or_cmd_key = \ Keys.COMMAND if get_system() == 'Darwin' else Keys.LEFT_CONTROL action = ActionChains(self.driver) action.shift_down = lambda: action.key_down(Keys.LEFT_SHIFT) action.shift_up = lambda: action.key_up(Keys.LEFT_SHIFT) action.ctrl_or_cmd_down = lambda: action.key_down(ctrl_or_cmd_key) action.ctrl_or_cmd_up = lambda: action.key_up(ctrl_or_cmd_key) action.select = lambda item: action.click(item.web_elem) yield action action.perform()
class _MetadataEditPanel(PageObject): text_area = InputWebElement('textarea') status = TextLabelWebElement('.parse-status-panel') def __str__(self): return 'metadata edit panel in {}'.format(self.parent)
class TransferRecordHistory(TransferRecord): transferred = TextLabelWebElement('td:nth-of-type(6)') total_files = TextLabelWebElement('td:nth-of-type(7)')
class TabHeader(PageObject): name = TextLabelWebElement('.nav-link') def click(self): self.web_elem.click()
class TransferRecordActive(TransferRecord): transferred = TextLabelWebElement('td:nth-of-type(5)') total_files = TextLabelWebElement('td:nth-of-type(6)')