def export_objs_to_csv(self, path_to_export_dir): """Click to 'Export Objects' button to export objects, wait for export, download as CSV and return path to the downloaded file. """ export_items_before_count = len(self.get_export_items()) self.export_objs_btn.click() def exported_item(): """Return the export item that was just created.""" difference = len(self.get_export_items()) - export_items_before_count if difference == 1: return self.get_export_items()[-1] return None export_item = test_utils.wait_for(exported_item) selenium_utils.set_chrome_download_location( self._driver, path_to_export_dir) downloads_before = os.listdir(path_to_export_dir) export_item.download_csv() def path_to_downloaded_file(): """Path to a file that has appeared.""" difference = set(os.listdir(path_to_export_dir)) - set(downloads_before) if len(difference) == 1: filename = list(difference)[0] return os.path.join(path_to_export_dir, filename) return None return test_utils.wait_for(path_to_downloaded_file)
def export_objs_to_csv(self, path_to_export_dir): """Click to 'Export Objects' button to export objects, wait for export, download as CSV and return path to the downloaded file. """ export_items_before_count = len(self.get_export_items()) self.export_objs_btn.click() def exported_item(): """Return the export item that was just created.""" difference = len( self.get_export_items()) - export_items_before_count if difference == 1: return self.get_export_items()[-1] return None export_item = test_utils.wait_for(exported_item) selenium_utils.set_chrome_download_location(self._driver, path_to_export_dir) downloads_before = os.listdir(path_to_export_dir) export_item.download_csv() def path_to_downloaded_file(): """Path to a file that has appeared.""" difference = set( os.listdir(path_to_export_dir)) - set(downloads_before) if len(difference) == 1: filename = list(difference)[0] return os.path.join(path_to_export_dir, filename) return None return test_utils.wait_for(path_to_downloaded_file)
def get_snapshoted_obj(self, origin_obj, paren_obj): """Get and return snapshoted object according to 'origin_obj' and 'paren_obj'. """ def get_response(): """Get response from query.""" return self.client.create_object( type=self.endpoint, object_name=objects.get_obj_type(objects.SNAPSHOTS), filters=query.Query.expression_get_snapshoted_obj( obj_type=origin_obj.type, obj_id=origin_obj.id, parent_type=paren_obj.type, parent_id=paren_obj.id)) def get_response_values(): """Get values fom responese.""" return json.loads(get_response().text, encoding="utf-8")[0]["Snapshot"]["values"] test_utils.wait_for(get_response_values, constants.ux.MAX_USER_WAIT_SECONDS * 2) snapshoted_obj_dict = (BaseRestService.get_items_from_resp( get_response()).get("values")[0]) return Representation.repr_dict_to_obj(snapshoted_obj_dict)
def wait_to_be_init(self): """Waits for page to be fully initialized.""" rows = self.task_group_rows() def is_assignee_set(): """Assignee column is one of the last places to be init on the page.""" return rows[-1].text_for_header("Assignee") != "" if rows: test_utils.wait_for(is_assignee_set)
def start(self): """Starts this cycle task.""" def workflow_state(): """Returns workflow cycle state.""" # pylint: disable=protected-access return self._parent_row._parent_row.state initial_workflow_state = workflow_state() self._root.hover() self._root.button(text="Start").click() test_utils.wait_for(lambda: workflow_state() != initial_workflow_state)
def _wait_loading(self): """Wait for elements to load.""" def results_present(): """Return if results are present.""" if self._root.element(class_name="tree-no-results-message").present: return True if list(self._tree_item_rows()): return True return False test_utils.wait_for(results_present)
def soft_assert_cannot_add_comment(soft_assert, obj): """Performs soft assert that comment input field is not displayed when 'Add Comment' button is clicked.""" info_page = factory.get_cls_webui_service(objects.get_plural( obj.type))().open_info_page_of_obj(obj) info_page.comments_panel.click_add_button() # wait until new tab contains info page url _, new_tab = browsers.get_browser().windows() test_utils.wait_for(lambda: new_tab.url.endswith(url.Widget.INFO)) soft_assert.expect(not info_page.comments_panel.comment_input.exists, "There should be no input field in comments panel.")
def complete_assessment(self, obj): """Navigate to info page of object according to URL of object then find and click 'Complete' button then return info page of object in new state""" info_widget = self.open_info_page_of_obj(obj) initial_state = info_widget.status() info_widget.click_complete() def wait_for_status_to_change(): """Waits for status to become completed.""" return self.info_widget_cls(self._driver).status() != initial_state test_utils.wait_for(wait_for_status_to_change) ui_utils.wait_for_spinner_to_disappear()
def soft_assert_role_cannot_be_edited(soft_assert, obj, role): """Performs soft assert that click on role's pencil icon doesn't open an input field.""" info_widget = factory.get_cls_webui_service( objects.get_plural(obj.type))().open_info_page_of_obj(obj) role_field_element = getattr(info_widget, role) role_field_element.inline_edit.open() # wait until new tab contains info page url _, new_tab = browsers.get_browser().windows() test_utils.wait_for(lambda: new_tab.url.endswith(url.Widget.INFO)) soft_assert.expect(not role_field_element.add_person_text_field.exists, "There should be no input field.")
def add_user(url_origin): """If two processes log in as a new user at the same time, the second login may fail because of a race condition in dev code (user_generator.py). We workaround this issue by creating a user not in parallel as this issue is considered not worth to fix by developers. """ from lib.entities import entities_factory import json from lib.service.rest.template_provider import TemplateProvider from lib.service.rest import session_pool environment.app_url = url_origin environment.app_url = urlparse.urljoin(environment.app_url, "/") session = requests.Session() test_utils.wait_for( lambda: session.get(environment.app_url).status_code == OK_CODE, constants.timeouts.TWO_MIN_USER_WAIT * 4) test_utils.wait_for(lambda: session.get(url_module.Urls().gae_login( users.FAKE_SUPER_USER)).status_code == OK_CODE) test_utils.wait_for( lambda: session.get(url_module.Urls().login).status_code == OK_CODE) person_dict = entities_factory.PeopleFactory().create( is_add_rest_attrs=True, **{}).__dict__ url = environment.app_url + "api/people" body = json.dumps([ TemplateProvider.generate_template_as_dict(json_tmpl_name='person', **person_dict) ]).encode("string-escape") test_utils.wait_for(lambda: session.post( url=url, data=body, headers=session_pool.BASIC_HEADERS).status_code == OK_CODE)
def add_user(url_origin): """If two processes log in as a new user at the same time, the second login may fail because of a race condition in dev code (user_generator.py). We workaround this issue by creating a user not in parallel as this issue is considered not worth to fix by developers. """ environment.app_url = url_origin environment.app_url = urlparse.urljoin(environment.app_url, "/") session = requests.Session() test_utils.wait_for(lambda: session.get(url_module.Urls().gae_login( users.FAKE_SUPER_USER)).status_code == OK_CODE) test_utils.wait_for( lambda: session.get(url_module.Urls().login).status_code == OK_CODE)
def get_items_from_resp(resp, timeout=constants.ux.MAX_USER_WAIT_SECONDS): """Check response (waiting object of requests library) from server and get items {key: value} from it.""" def get_items_from_resp(): """Get items from response.""" def get_extra_items(resp_dict): """Get extra items {key: value} that used in entities.""" extra = {} if resp_dict.get("selfLink"): extra.update({"href": resp_dict.get("selfLink")}) if resp_dict.get("viewLink"): extra.update( {"url": environment.app_url + resp_dict.get("viewLink")[1:]}) return extra if isinstance(resp, requests.models.Response): try: resp_text = json.loads(resp.text, encoding="utf-8") except UnicodeDecodeError as unicode_err: raise requests.exceptions.ContentDecodingError( messages.ExceptionsMessages.err_server_req_resp.format( resp.request.body, resp.status_code + unicode_err, resp.text)) resp_status_code = resp.status_code req_method = resp.request.method is_query_resp = False # check response from server if resp_status_code == client.RestClient.STATUS_CODES["OK"]: # 'POST' request methods if req_method == "POST" and isinstance(resp_text, list): # REST API: [[201, {resp}]] to {resp} if len(resp_text[0]) == 2 and resp_text[0][0] == 201: resp_text = resp_text[0][1] # QUERY API: [[{resp}]] to {resp} elif len(resp_text[0]) == 1 and resp_text[0] != 201: is_query_resp = True resp_text = resp_text[0] # 'PUT' request methods if req_method == "PUT": pass # {resp} == {key: {value}} if isinstance(resp_text, dict) and len(resp_text) == 1: # {key: {value}} to {value} resp_text = resp_text.itervalues().next() resp_text = resp_text["values"][0] if is_query_resp else resp_text try: return dict(resp_text.items() + get_extra_items(resp_text).items()) except AttributeError: raise requests.exceptions.RequestException( messages.ExceptionsMessages.err_server_req_resp.format( resp.request.body, resp.status_code, resp.text)) else: resp_code, resp_message = resp_text[0] raise requests.exceptions.ContentDecodingError( messages.ExceptionsMessages.err_server_req_resp.format( resp.request.body, resp_code, resp_message)) else: raise requests.exceptions.RequestException( messages.ExceptionsMessages.err_server_resp.format(resp)) return test_utils.wait_for(get_items_from_resp, timeout)
def get_items_from_resp(resp, timeout=constants.ux.MAX_USER_WAIT_SECONDS): """Check response (waiting object of requests library) from server and get items {key: value} from it.""" def get_items_from_resp(): """Get items from response.""" def get_extra_items(resp_dict): """Get extra items {key: value} that used in entities.""" extra = {} if resp_dict.get("selfLink"): extra.update({"href": resp_dict.get("selfLink")}) if resp_dict.get("viewLink"): extra.update({ "url": environment.app_url + resp_dict.get("viewLink")[1:] }) return extra if isinstance(resp, requests.models.Response): try: resp_text = json.loads(resp.text, encoding="utf-8") except UnicodeDecodeError as unicode_err: raise requests.exceptions.ContentDecodingError( messages.ExceptionsMessages.err_server_req_resp.format( resp.request.body, resp.status_code + unicode_err, resp.text)) resp_status_code = resp.status_code req_method = resp.request.method is_query_resp = False # check response from server if resp_status_code == client.RestClient.STATUS_CODES["OK"]: # 'POST' request methods if req_method == "POST" and isinstance(resp_text, list): # REST API: [[201, {resp}]] to {resp} if len(resp_text[0]) == 2 and resp_text[0][0] == 201: resp_text = resp_text[0][1] # QUERY API: [[{resp}]] to {resp} elif len(resp_text[0]) == 1 and resp_text[0] != 201: is_query_resp = True resp_text = resp_text[0] # 'PUT' request methods if req_method == "PUT": pass # {resp} == {key: {value}} if isinstance(resp_text, dict) and len(resp_text) == 1: # {key: {value}} to {value} resp_text = resp_text.itervalues().next() return (dict(resp_text.items() + ({}.items() if is_query_resp else get_extra_items(resp_text).items()))) else: resp_code, resp_message = resp_text[0] raise requests.exceptions.ContentDecodingError( messages.ExceptionsMessages.err_server_req_resp.format( resp.request.body, resp_code, resp_message)) else: raise requests.exceptions.RequestException( messages.ExceptionsMessages.err_server_resp.format(resp)) return test_utils.wait_for(get_items_from_resp, timeout)
def wait_loading_after_actions(self): """Wait loading elements of Tree View after made some action with object(s) under Tree View. """ from lib.utils.test_utils import wait_for selenium_utils.wait_until_not_present( self._driver, self._locators.ITEM_LOADING_CSS) selenium_utils.get_when_invisible( self._driver, self._locators.TREE_SPINNER_CSS) if "MAPPER_TREE_SPINNER_NO_RESULT" in self._locators.__dict__: def is_result_ready(): """Check if the results on mapper is ready.""" is_results_ready = False if not selenium_utils.is_element_enabled( selenium_utils.get_when_visible( self._driver, constants.locator.CommonModalUnifiedMapper.BUTTON_SEARCH) ): return is_results_ready if ( selenium_utils.is_element_exist( self._driver, self._locators.MAPPER_TREE_SPINNER_NO_RESULT) or selenium_utils.is_element_exist( self._driver, self._locators.MAPPER_TREE_SPINNER_ITEMS) ): return is_results_ready if ( selenium_utils.is_element_exist( self._driver, self.locator_no_results_message) or selenium_utils.get_when_all_visible( self._driver, (By.CSS_SELECTOR, self._locators.ITEMS)) ): is_results_ready = True return is_results_ready return is_results_ready wait_for(is_result_ready) selenium_utils.wait_for_doc_is_ready(self._driver) selenium_utils.wait_for_js_to_load(self._driver)
def wait_loading_after_actions(self): """Wait loading elements of Tree View after made some action with object(s) under Tree View. """ from lib.utils.test_utils import wait_for selenium_utils.wait_until_not_present(self._driver, self._locators.ITEM_LOADING_CSS) selenium_utils.get_when_invisible(self._driver, self._locators.TREE_SPINNER_CSS) if "MAPPER_TREE_SPINNER_NO_RESULT" in self._locators.__dict__: def is_result_ready(): """Check if the results on mapper is ready.""" is_results_ready = False if not selenium_utils.is_element_enabled( selenium_utils.get_when_visible( self._driver, constants.locator. CommonModalUnifiedMapper.BUTTON_SEARCH)): return is_results_ready if (selenium_utils.is_element_exist( self._driver, self._locators.MAPPER_TREE_SPINNER_NO_RESULT) or selenium_utils.is_element_exist( self._driver, self._locators.MAPPER_TREE_SPINNER_ITEMS)): return is_results_ready if (selenium_utils.is_element_exist( self._driver, self.locator_no_results_message) or selenium_utils.get_when_all_visible( self._driver, (By.CSS_SELECTOR, self._locators.ITEMS))): is_results_ready = True return is_results_ready return is_results_ready wait_for(is_result_ready) selenium_utils.wait_for_doc_is_ready(self._driver) selenium_utils.wait_for_js_to_load(self._driver)
def get_proposal_creation_date(self, obj, proposal): """Get proposal creation date.""" prop_value = string_utils.escape_html( proposal.changes[0]["proposed_value"]) def needed_proposal(): """Get proposal with needed proposal value.""" return [prop for prop in self.get_obj_proposals(obj) if prop_value in prop["content"]["fields"]["description"]] actual_proposal = test_utils.wait_for( needed_proposal, constants.ux.MAX_USER_WAIT_SECONDS) return parser.parse(actual_proposal[0]["created_at"]).replace( tzinfo=tz.tzutc())
def download_obj_to_csv(self, path_to_export_dir): """Download as CSV and return path to the downloaded file.""" export_item = self.get_export_items()[-1] selenium_utils.set_chrome_download_location( self._driver, path_to_export_dir) downloads_before = os.listdir(path_to_export_dir) export_item.download_csv() def path_to_downloaded_file(): """Path to a file that has appeared.""" difference = set(os.listdir(path_to_export_dir)) - set(downloads_before) if len(difference) == 1: filename = list(difference)[0] if not filename.endswith("crdownload"): # file is not fully downloaded return os.path.join(path_to_export_dir, filename) return None return test_utils.wait_for(path_to_downloaded_file)
def download_obj_to_csv(self, path_to_export_dir): """Download as CSV and return path to the downloaded file.""" export_item = self.get_export_items()[-1] selenium_utils.set_chrome_download_location(self._driver, path_to_export_dir) downloads_before = os.listdir(path_to_export_dir) export_item.download_csv() def path_to_downloaded_file(): """Path to a file that has appeared.""" difference = set( os.listdir(path_to_export_dir)) - set(downloads_before) if len(difference) == 1: filename = list(difference)[0] return os.path.join(path_to_export_dir, filename) return None return test_utils.wait_for(path_to_downloaded_file)
def download_export_file(self, path_to_export_dir): """Click to 'Export Objects' button to confirm export objects according to selected before export format (Google Sheet or CSV) and return path to the downloaded file. """ downloads_before = os.listdir(path_to_export_dir) selenium_utils.set_chrome_download_location( self._driver, path_to_export_dir) self.export_objs_btn.click() selenium_utils.get_when_invisible( self.export_page, locator.Common.SPINNER_CSS) selenium_utils.wait_for_js_to_load(self._driver) def path_to_downloaded_file(): """Path to a file that has appeared.""" difference = set(os.listdir(path_to_export_dir)) - set(downloads_before) if len(difference) == 1: filename = list(difference)[0] return os.path.join(path_to_export_dir, filename) return test_utils.wait_for(path_to_downloaded_file)
def select_user(root, email): """Selects user in person autocomplete list.""" def autocomplete_row(): """Returns a row with an email.""" # Iterating through elements may raise exception if elements are removed # during iteration # (https://github.com/watir/watir/issues/769) try: rows = list(root.elements(class_name="ui-menu-item")) # Only user is shown in some cases # In others user and "Create" is shown if len(rows) in (1, 2): row = rows[0] if email in row.text: return row except nerodia.exception.UnknownObjectException: pass return False row = test_utils.wait_for(autocomplete_row) row.click()