class MyCustomizedLibraryKeywords(LibraryComponent): def __init__(self, ctx): LibraryComponent.__init__(self, ctx) self.elementkeys = ElementKeywords(ctx) self.waiting_management = WaitingKeywords(ctx) def get_all_product_in_tab(self, locator): return self.find_element(locator).find_elements_by_tag_name("li") def click(self, element): self.elementkeys.js_click(element) @keyword def click_on_product_item(self, locator, product_name, product_price): """ :locator: Locator of the tab container :product_name: Displayed name of product "product_price: Displayed price of product" """ items = self.get_all_product_in_tab(locator) for i in items: if self.get_product_name(i) == product_name: if self.get_product_price(i) == product_price: self.click(self.get_product_clickable_item(i)) return message = "Item %s - %s not found in %s!" % (product_name, product_price, locator) raise AssertionError(message) def get_product_url(self, element): return self._get_child_element_by_property(element).get_attribute( "href").strip() def get_product_clickable_item(self, element): return self._get_child_element_by_property(element, "url") def get_product_name(self, element): return self._get_child_element_by_property( element, "name").get_attribute("textContent").strip() def get_product_price(self, element): return self._get_child_element_by_property( element, "price").get_attribute("textContent").strip().replace("$", "") def _get_child_element_by_property(self, locator, property): return self.find_element(locator).find_element_by_xpath( ".//*[@itemprop='" + property + "']") @keyword def get_alert_div(self): return self.driver.find_element_by_xpath( "//*[@id='center_column']//*[@class='alert alert-danger']" ) #get the first element @keyword def is_alert_visible(self): try: self.get_alert_div() return True except: return False @keyword def wait_until_alert_displayed(self, timeout=None, error=None): self.waiting_management._wait_until( lambda: self.is_alert_visible() == True, "Alert was not appeared in <TIMEOUT>", timeout, error) @keyword def get_login_alert_messages(self): alert = self.get_alert_div() return [ li.get_attribute("textContent").strip() for li in alert.find_elements_by_tag_name("li") ] @keyword def is_error_message(self, error_message): messages = self.get_login_alert_messages() if error_message in messages: pass else: raise AssertionError( "Message '{}' is not found".format(error_message))
class GoBearCoreKeywords(LibraryComponent): def __init__(self, ctx): LibraryComponent.__init__(self, ctx) self.elementKeys = ElementKeywords(ctx) self.waiting_management = WaitingKeywords(ctx) def get_element(self, locator, tag=None): _locator = GBUtilies.extract_locator(locator) if GB_ATTRIBUTE_NAME in _locator[0].lower(): return self.elementKeys.find_element_by_attribute( GB_ATTRIBUTE_NAME, _locator[1]) if 'href' in _locator[0].lower(): return self.elementKeys.find_element_by_href(_locator[1]) else: return ExtWebElement(self.elementKeys.find_element(locator, tag)) def get_elements(self, locator, tag=None): _locator = GBUtilies.extract_locator(locator) if GB_ATTRIBUTE_NAME in _locator[0].lower(): return self.elementKeys.find_elements_by_attribute( GB_ATTRIBUTE_NAME, _locator[1]) else: return [ ExtWebElement(e) for e in self.elementKeys.find_elements(locator, tag) ] @keyword def count_elements_found(self, locator): return len(self.get_elements(locator)) @keyword def number_of_found_elements_should_be(self, locator, num, message=None): count = self.count_elements_found(locator) if count != int(num): if not message: message = "%s of element '%s' found instead of %s" % ( count, locator, num) raise AssertionError(message) @keyword def number_of_found_elements_should_at_least(self, locator, num, message=None): count = self.count_elements_found(locator) if count < int(num): if not message: message = "Only %s of element '%s' found instead of %s" % ( count, locator, num) raise AssertionError(message) @keyword def select_element(self, locator): self.get_element(locator).click() @keyword def select_gb_element(self, locator): self.find_element(locator).click() def is_loading(self, locator=GB_LOADING_LOCATOR): try: return self.get_element(locator).is_displayed() except: return False @keyword def wait_until_loaded(self, timeout=None, error=None): # time.sleep(5) self.waiting_management._wait_until( lambda: self.is_loading() == False, "Web is loading too long '<TIMEOUT>'", timeout, error) def is_element_visible(self, locator): try: e = self.get_element(locator) print(e) return True except: return False @keyword def wait_until_element_is_visible(self, locator, timeout=None, error=None): self.waiting_management._wait_until( lambda: self.is_element_visible(locator) == True, "Element %s is not visible <TIMEOUT>" % locator, timeout, error) @keyword def tab_should_be_active(self, locator): if not self.get_element(locator).is_contain_class('active'): raise AssertionError("Tab %s is not active" % locator) @keyword def select_button_dropdown(self, locator, value): self.wait_until_element_is_visible(locator) control = self.get_element(locator) # show dropdown list control.get_elements_by_tag('button')[0].click() # options are in 'li' tags self.wait_until_dropdown_menu_visible(control, 'li') control.select_element_by_tag('li', value) def is_dropdown_menu_visible(self, element, tag): """ Check if the dropdown menu of BG Dropdown Button is visible and contains given TAGs :param element: :param tag: tag of child elements """ try: element.get_element_by_class(BG_DROPDOWN_MENU_OPEN) return len(element.get_children_by_tag(tag)) > 0 except: return False def wait_until_dropdown_menu_visible(self, control, tag=None, timeout=None, error=None): self.waiting_management._wait_until( lambda: self.is_dropdown_menu_visible(control, tag) == True, "No dropdown menu is visible <TIMEOUT>", timeout, error) @keyword def text_should_be_equal(self, locator, expected_string): actual_string = self.get_element(locator).get_textContent() if actual_string != expected_string: message = "'%s' not equal '%s'" % (expected_string, actual_string) raise AssertionError(message) pass ################## DETAILS OPTIONS #################### def get_detail_options(self, locator): sort_section = self.get_element(locator) return sort_section.find_elements_by_tag_name('label') @keyword def select_detail_option(self, locator, option): for f in self.get_detail_options(locator): if f.get_textContent().lower() == option.lower(): f.click() return message = "Detail option '%s' not found in '%s'" % (option, locator) raise AssertionError(message) ################## SORT OPTIONS #################### def get_sort_options(self, locator): sort_section = self.get_element(locator) return sort_section.get_elements_by_attribute(GB_ATTRIBUTE_NAME, GB_SORT_OPTION) @keyword def select_sort_option(self, locator, option): for f in self.get_sort_options(locator): if f.get_textContent().lower() == option.lower(): f.click() return message = "Sort option '%s' not found in '%s'" % (option, locator) raise AssertionError(message) ################## FILTER OPTIONS #################### def get_filter_options(self, locator): filter_section = self.get_element(locator) return filter_section.get_elements_by_attribute( GB_ATTRIBUTE_NAME, GB_FILTER_OPTION) @keyword def select_filter_option(self, locator, option): for f in self.get_filter_options(locator): if f.get_textContent().lower() == option.lower(): f.click() return message = "Filter option '%s' not found in '%s'" % (option, locator) raise AssertionError(message) #################### SLIDER ########################## @keyword def set_min_slider(self, locator, name_slider, value): slider = GBSlider(self.get_slider(locator, name_slider)) slider.set_min_value(value) @keyword def set_max_slider(self, locator, name_slider, value): slider = GBSlider(self.get_slider(locator, name_slider)) slider.set_max_value(value) def get_slider(self, locator, name_slider): slider_group = GBSliderGroup(self.get_element(locator)) return slider_group.get_slider_by_label(name_slider) #################### DATE PICKER ########################## @keyword def set_date(self, locator, value): """ Set date values for date picker Support input value in format: dd-mm-yyy or dd/mm/yyy or dd.mm.yyy Where 'mm' is month in WORD (ex: April) :param locator: :param value: """ dates = GBUtilies.split(value, ['/', ' ', '.', '-']) day = dates[0] month = dates[1] year = dates[2] # popup date picker self.get_element(locator).click() self.wait_until_data_picker_popup() # get date picker date_picker = self.get_date_picker_popup() # check if date picker is Days mode if self.is_date_picker_days(): _position = 0 # get date picker values datepicker_switch_value = self.get_date_picker_switch_values() current_month = datepicker_switch_value['month'] or None current_year = datepicker_switch_value['year'] or None # TODO: Add case for Decays, Centuries if current_year != year: self.select_datepicker_year_at(date_picker, day, month, year, _position) elif current_month != month: self.select_datepicker_month_at(date_picker, day, month, year, _position) else: # current_month == month and current_year == year self.select_datepicker_day_at(date_picker, day, month, year, _position) # TODO: Add more cases when Date Picker is at Month screen when popup # if self.is_date_picker_months(): # _position = 1 # get month popup # current_date_picker = date_picker.get_element_by_class(GB_DATE_PICKER_MONTHS_CLASS) # TODO: Add more cases when Date Picker is at Year screen when popup # if self.is_date_picker_years(): # _position = 2 # get years popup # current_date_picker = date_picker.get_element_by_class(GB_DATE_PICKER_YEARS_CLASS) def select_datepicker_year_at(self, datepicker, day, month, year, position=2): """ Select year value for DatePicker when standing at Year's popup :param datepicker: :param day: number from 1 - 31 :param month: month in names (Jan or January to Dec or December). Notes: Not support number at this version :param year: year in format yyyy :param position: integer number | is where datepicker at 0: for days, 1: for month, 2: for year """ if position == 0: # at Day => click twice on switch self.click_date_picker_switch(2) if position == 1: # at Month => click once on switch self.click_date_picker_switch(1) self.select_datepicker_value(datepicker, GB_DATE_PICKER_YEARS_CLASS, year) self.select_datepicker_value(datepicker, GB_DATE_PICKER_MONTHS_CLASS, month) self.select_datepicker_value(datepicker, GB_DATE_PICKER_DAYS_CLASS, day) def select_datepicker_month_at(self, date_picker, day, month, year, position=1): if position == 0: # at Day => click once on switch self.click_date_picker_switch(1) if position == 2: # at Year => select Year self.select_datepicker_value(year) self.select_datepicker_value(date_picker, GB_DATE_PICKER_MONTHS_CLASS, month) self.select_datepicker_value(date_picker, GB_DATE_PICKER_DAYS_CLASS, day) def select_datepicker_day_at(self, datepicker, day, month, year, position=0): if position == 1: # at Month => select Month self.select_datepicker_value(datepicker, GB_DATE_PICKER_MONTHS_CLASS, month) if position == 2: # at Year, select Year then Month self.select_datepicker_value(datepicker, GB_DATE_PICKER_YEARS_CLASS, year) self.select_datepicker_value(datepicker, GB_DATE_PICKER_MONTHS_CLASS, month) self.select_datepicker_value(datepicker, GB_DATE_PICKER_DAYS_CLASS, day) def select_datepicker_value(self, datepicker, picker_class, value): tmp = value current_date_picker = datepicker.get_element_by_class(picker_class) if picker_class == GB_DATE_PICKER_DAYS_CLASS: values = current_date_picker.get_children_by_tag("td") else: values = current_date_picker.get_children_by_tag("span") if picker_class == GB_DATE_PICKER_MONTHS_CLASS: value = GBUtilies.month_lname_to_sname(value) available_values = [ v for v in values if not v.is_contain_class('disabled') ] for v in available_values: if v.get_textContent() == value: v.click() return message = "Cannot select value %s" % tmp raise AssertionError(message) def click_date_picker_switch(self, times=1): for i in range(0, times): self.get_date_picker_switch().click() time.sleep(0.25) def get_date_picker_switch(self): if self.is_date_picker_days(): picker_class = GB_DATE_PICKER_DAYS_CLASS elif self.is_date_picker_months(): picker_class = GB_DATE_PICKER_MONTHS_CLASS else: picker_class = GB_DATE_PICKER_YEARS_CLASS current_picker = self.elementKeys.find_element_by_class(picker_class) return current_picker.get_element_by_class(GB_DATE_PICKER_SWITCH_CLASS) def get_date_picker_switch_values(self): datepicker_switch = self.get_date_picker_switch() _raw = datepicker_switch.get_textContent() if ' ' in _raw: values = _raw.split(' ') return {'month': values[0], 'year': values[1]} elif '-' in _raw: values = _raw.split('-') return {'start': values[0], 'end': values[1]} else: return {'year': _raw} def is_date_picker_days(self): try: return self.elementKeys.find_element_by_class( GB_DATE_PICKER_DAYS_CLASS).is_displayed() except: return False def is_date_picker_months(self): try: return self.elementKeys.find_element_by_class( GB_DATE_PICKER_MONTHS_CLASS).is_displayed() except: return False def is_date_picker_years(self): try: return self.elementKeys.find_element_by_class( GB_DATE_PICKER_YEARS_CLASS).is_displayed() except: return False def get_date_picker_popup(self): return self.elementKeys.find_element_by_class( GB_DATE_PICKER_MENU_CLASS) def is_date_picker_popup(self): return self.elementKeys.is_any_element_contain_class( GB_DATE_PICKER_MENU_CLASS) def wait_until_data_picker_popup(self, timeout=None, error=None): self.waiting_management._wait_until( lambda: self.is_date_picker_popup() == True, "No date picker is popup <TIMEOUT>", timeout, error)
class PCNKeywords(LibraryComponent): def __init__(self, ctx): LibraryComponent.__init__(self, ctx) self.elementkeywords_management = ElementKeywords(ctx) self.waiting_management = WaitingKeywords(ctx) self.tablekeywords_management = TableKeywords(ctx) @keyword def compare_element_text_content(self, locator, value): element = self.find_element(locator) if element.get_textContent() == value: print("Content of text field" + locator + " is " + value) return element.get_textContent() else: return False @keyword def compare_element_value(self, locator, value): element = self.find_element(locator) if element.get_attribute('value') == value: return else: print(value) print(element.get_attribute('value')) mess = 'Current value is %s ' % element.get_attribute('value') raise AssertionError(mess) @keyword def split_text_to_list(self, text, character): return str(text).replace(" ", "").split(str(character)) @keyword def get_multiple_params(*multiple_params): return list(multiple_params) @keyword def element_value_should_be(self, locator, expected_value): ''' This function will replace for "Element Text Should Be" on edge browsers because text of some element contains space character so we cannot use "Element Text Should Be" function :param locator: element locator will be compared :param expected_value: value will be compared with text of element :return: True if element text is same with expected value ''' element = self.find_element(locator) if element: if element.text.strip() == expected_value.strip(): return True else: mess = 'Current value is %s ' % element.text raise AssertionError(mess) else: message = "%s not found" % locator raise AssertionError(message) @keyword def set_selectbox_value(self, locator, value): select_box = self.find_element(locator) options = select_box.find_elements_by_tag_name("option") for option in options: if option.get_textContent() == value: option.click() return message = "%s not found" % value raise AssertionError(message) @keyword def set_option(self, option_locator): options = self.find_element(option_locator) if None != options: options.click() return message = "Locator: %s not found" % option_locator raise AssertionError(message) @keyword def get_number_in_text(self, text): data = [] for i in text: if i.isdigit(): data.append(int(i)) return data mess = "%s is not contain number" % text raise AssertionError(mess) @keyword def get_data_in_text(self, text): ''' This function only use for: text :param text: "Text: data" :return: list[data] ''' data = [] temp = str(text).split(": ") data.append(temp[1]) return data @keyword def get_element_text_in_list(self, locator, value): elements = self.find_element(locator).find_elements_by_tag_name("li") for element in range(0, len(elements)): if elements[element].text == value: return elements[element].text mess = "%s not found value: " % value raise AssertionError(mess) @keyword def split_store_number(self, list): list_store = [] for index in range(0, len(list)): a = list[index][1:5] list_store.append(a) return list_store @keyword def create_directory_by_path(self, path): if os.path.isdir(path): shutil.rmtree(path) os.makedirs(path) else: os.makedirs(path) return path @keyword def get_obj_attr_by_value(self, obj, value): null = None data = obj[0].get(value) return data def get_all_object_by_key_name(self, object, key_name): # get value by key in json file null = None list_data = [] for obj in range(0, len(object)): value = object[obj].get(key_name) list_data.append(value) return list_data @keyword def generate_name(self): min_char = 8 max_char = 12 allchar = string.ascii_letters + string.digits name = "".join( choice(allchar) for x in range(randint(min_char, max_char))) return name @keyword def remove_directory_by_path(self, path): if not os.path.isdir(path): mess = "Directory in '%s' not exists." % path raise AssertionError(mess) else: shutil.rmtree(path) return path @keyword def get_random_subnet(self, number_random, path): with open(path) as resultsFile: readFile = csv.reader(resultsFile) list_all_subnet = [] for row in readFile: list_all_subnet.append(row[0]) list_random_subnet = [] for x in range(0, int(number_random)): subnet = choice(list_all_subnet) list_random_subnet.append(subnet) return list_random_subnet @keyword def get_rows_by_column_name(self, path, column_name): # this functions just apply to csv,excel...file with open(path) as f: reader = csv.reader(f) columns = next(reader) list_column = [] for column in columns: list_column.append(column) for i in range(0, len(list_column)): if list_column[i] == column_name: index = i list_all_data = [] for row in reader: list_all_data.append(row[index]) return list_all_data @keyword def compare_two_lists(self, list_1, list_2): if len(list_1) == 0 or len(list_2) == 0: mess = "List is empty" raise AssertionError(mess) for item in list_1: if item in list_2: continue else: mess = "Compare failed, that lists to diffirence!" raise AssertionError(mess) message = "Compare successfully!" print(message) @keyword def compare_exact_list(self, list_1, list_2): ''' Documentation: Sort two lists > compare that :param list_1: :param list_2: :return: ''' print(list_1) print(list_2) temp_1 = self.sort_list_data(list_1) temp_2 = self.sort_list_data(list_2) if len(temp_1) == 0 or len(temp_2) == 0: mess = "Length of list must be > 0" raise AssertionError(mess) elif len(temp_1) != len(temp_2): mess = "Length of 2 lists is difference!" raise AssertionError(mess) else: for i in range(0, len(temp_1)): if temp_1[i].strip() == temp_2[i].strip(): continue else: mess = "Elements in the 2 lists are not the same, compare failed!" raise AssertionError(mess) print("Compare successfully!") return @keyword def compare_list(self, list_1, list_2): print(list_1) print(list_2) temp_1 = self.sort_list_data(list_1) temp_2 = self.sort_list_data(list_2) if len(temp_1) != len(temp_2): mess = "Length of 2 lists is difference!" raise AssertionError(mess) else: for i in range(0, len(temp_1)): if temp_1[i] == temp_2[i]: continue else: mess = "Elements in the 2 lists are not the same, compare failed!" raise AssertionError(mess) print("Compare successfully!") return @keyword def get_file_in_directory(self, path): dirs = os.listdir(path) file = dirs[0] return file @keyword def wait_until_file_is_downloaded(self, path, setTime=None): ''' :param path: folder directory will be contains download file :param setTime: timeout of function. Out that time, function will be break. unit: /seconds :return: check file is downloaded succeed or failed ''' if setTime == None: timeout = time.time() + 30 else: timeout = time.time() + int(setTime) dirs = os.listdir(path) if len(dirs) == 1: for i in dirs: a = i.split(".") if a[len(a) - 1] == 'csv': print(dirs[0]) return True else: while a[len(a) - 1] != 'csv': dirs = os.listdir(path) if time.time() > timeout: mess = "Download is break down!" raise AssertionError(mess) return for i in dirs: a = i.split(".") if a[len(a) - 1] == 'csv': print(dirs[0]) return True else: continue while len(dirs) != 1: dirs = os.listdir(path) if time.time() > timeout: mess = "Too long to respond, download failed!" raise AssertionError(mess) return if len(dirs) == 1: for i in dirs: a = i.split(".") if a[len(a) - 1] == 'csv': print(dirs[0]) return True else: while a[len(a) - 1] != 'csv': dirs = os.listdir(path) if time.time() > timeout: mess = "Download is break down!" raise AssertionError(mess) return for i in dirs: a = i.split(".") if a[len(a) - 1] == 'csv': print(dirs[0]) return True else: continue @keyword def get_all_data_in_table_by_selectbox(self, locator, table_locator, column_name): ''' :param locator: this is selectbox locator. Every table will be have next,prev,up button and select box used to paging :param table_locator: table locator :param column_name: get data of this column :return: list contains all data on this table include data is paging ''' list_data = [] list_all_data = [] list_length = self.elementkeywords_management.get_length_selectbox( locator) for i in range(0, list_length): index = i + 1 self.set_selectbox_value(locator, str(index)) temp = self.tablekeywords_management.get_all_rows_by_column( table_locator, column_name, is_index=False) list_data.append(temp) for i in list_data: for value in i: list_all_data.append(value) return list_all_data @keyword def get_all_data_in_table_by_button(self, locator, table_locator, column_name): ''' :param locator: this is button next locator. Every table will be have next,prev,up button and select box used to paging :param table_locator: table locator :param column_name: get data of this column :return: list contains all data on this table include data is paging ''' list_data = [] list_all_data = [] elements = self.find_element(locator) data = self.tablekeywords_management.get_all_rows_by_column( table_locator, column_name, is_index=False) list_data.append(data) while True: if elements.is_enabled() == True: self.tablekeywords_management.click_element(locator) temp = self.tablekeywords_management.get_all_rows_by_column( table_locator, column_name, is_index=False) list_data.append(temp) continue else: break for i in list_data: for value in i: list_all_data.append(value) return list_all_data @keyword def get_all_data_in_table(self, locator, table_locator, column_name): ''' :param locator: this is selectbox locator. Every table will be have next,prev,up button and select box used to paging :param table_locator: table locator :param column_name: get data of this column :return: list contains all data on this table include data is paging ''' list_data = [] list_all_data = [] data = self.tablekeywords_management.get_all_rows_by_column( table_locator, column_name, is_index=False) list_data.append(data) for i in list_data: for value in i: list_all_data.append(value) return list_all_data @keyword def convert_two_list_object_to_list(self, list_1, list_2): list_data = [] for item in list_1: for data in item: list_data.append(data) return list_data @keyword def get_header_in_file(self, path): with open(path, 'rt') as f: reader = csv.reader(f) columns = next(reader) if len(columns) == 0: mess = "List is empty" raise AssertionError(mess) header = [] for col in columns: header.append(col) return header @keyword def get_data_by_row(self, path, position=None): with open(path, 'rt') as f: print(path) reader = csv.reader(f) columns = next(reader) header = [] for col in columns: header.append(col) row_data = [] list_data = [] for i in reader: list_data.append(i) if len(list_data) == 0: mess = "List is empty" raise AssertionError(mess) if position == None: for row in list_data: for data in row: row_data.append(data) return row_data else: row_data.append(list_data[position]) data = [] for row in row_data: for i in row: data.append(i) return data @keyword def export_element_locator(self, locator, count): list_data = [] if count == 0: mess = "Array will be return empty!!!" raise AssertionError(mess) for i in range(0, int(count)): temp = locator.replace("']", str(i) + "']") list_data.append(temp) return list_data @keyword def check_value_in_list(self, list_value, value): if len(list_value) == 0: mess = "List is empty!" raise AssertionError(mess) elif value == None: mess = "Value cannot be 'None'!" raise AssertionError(mess) for i in list_value: if value == i: return True else: mess = "Value haven't exist in that list" raise AssertionError(mess) # @keyword # def wait_load_status(self, locator, timeout=None, error=None): # element = self.find_element(locator) # while True: # text = element.text # if text != "On Going" and text != "None" and text != "": # return # print(text) # # # self.waiting_management._wait_until( # # lambda: element.text != "On Going" and element.text != "None" and element.text != "", # # "Element '%s' still in loading over <TIMEOUT>." % locator, # # timeout, # # error # # ) # return @keyword def wait_load_status(self, locator, setTime=None): if setTime == None: timeout = time.time() + 0 else: timeout = time.time() + int(setTime) element = self.find_element(locator) while True: text = element.text if time.time() > timeout: mess = "Request timeout" raise AssertionError(mess) if text != "On Going" and text != "None" and text != "": return text @keyword def wait_until_element_text_is_exactly(self, locator, value, timeout=100, error=None): element = self.find_element(locator) self.waiting_management._wait_until( lambda: element.text == value, ("The text of element '%s' should have been '%s' " "but it was '%s'." % (locator, value, element.text)), timeout, error) print(element.text) return element.text @keyword def wait_until_element_value_is_exactly(self, locator, value, timeout=100, error=None): element = self.find_element(locator) self.waiting_management._wait_until( lambda: element.get_attribute('value') == value, ("The text of element '%s' should have been '%s' " "but it was '%s'." % (locator, value, element.text)), timeout, error) print(element.text) return element.text @keyword def get_table_data_by_keyword(self, locator, keyword): c = "\n" rows = self.tablekeywords_management.get_table_rows(locator) data = [] for i in range(0, len(rows)): if keyword in rows[i].text: temp = rows[i].text.replace(c, " ") data.append(temp) return data @keyword def get_table_data_by_status(self, locator, status): c = "\n" rows = self.tablekeywords_management.get_table_rows(locator) data = [] for i in range(0, len(rows)): if status in rows[i].text: temp = rows[i].text.split(c) for item in temp: data.append(item) return data @keyword def get_table_data_by_status_of_column(self, locator, column, status, is_index=False): c = "\n" rows = self.tablekeywords_management.get_table_rows(locator) if not is_index: column = self.tablekeywords_management.get_column_index( locator, column) data = [] for row in rows: cells = self.tablekeywords_management.get_cells_in_table_row(row) if cells[column].text == status: temp = rows[row].text.split(c) for item in temp: data.append(item) return data @keyword def remove_space_of_text(self, text): return str(text).strip() @keyword def sort_list_data(self, list_data): ''' convert all elements in list to string(follow alphabet) :param list_data: list data contains all elements :return: list has been sort successfully ''' data = [] for i in list_data: data.append(str(i)) return sorted(data) @keyword def reserve_list(self, *list): if len(list) == 0: mess = "Length is 0" raise AssertionError(mess) data = [] for i in list: data.append(i) return data.reverse() @keyword def export_dhcp_range(self, ip_start, dhcp_range, status): ''' :param ip_start: start range. ex: 241.56.0.6 :param dhcp_range: size of dhcp range. ex: 4 :param status: status of dhcp range. ex: DHCP, DHCP Range, DHCP Scope.... :return: ["241.56.0.6", "DHCP", "241.56.0.7", "DHCP", "241.56.0.8", "DHCP", "241.56.0.9", "DHCP"] ''' temp = ip_start.split(".") data = [] for i in temp: a = int(temp[len(temp) - 1]) prefix = temp[0] + "." + temp[1] + "." + temp[2] + "." for i in range(0, int(dhcp_range)): data.append(prefix + str(a + i)) data.append(status) return data @keyword def generate_dhcp_range(self, first, last, status): ip_list = list(iter_iprange(str(first), str(last))) temp = [] data = [] for i in ip_list: temp.append(str(i)) for i in temp: data.append(i) data.append(str(status)) return data @keyword def generate_mac_address(self, numbers_of_mac_addr): temp = [] mac_addr = [] for i in range(0, numbers_of_mac_addr): temp.append(RandMac("00:00:00:00:00:00", True)) for i in temp: mac_addr.append(i.mac) return mac_addr @keyword def load_selectbox_value_by_next_button(self, selectbox_locator, next_button_locator, value): select_box = self.find_element(selectbox_locator) options = select_box.find_elements_by_tag_name("option") while True: for i in options: if i.text != value: self.tablekeywords_management.click_element( next_button_locator) continue else: return mess = "%s not found" % value raise AssertionError(mess) return @keyword def enable_download_in_headless_chrome(self, driver, download_dir): # add missing support for chrome "send_command" to selenium webdriver driver.command_executor._commands["send_command"] = ( "POST", '/session/$sessionId/chromium/send_command') params = { 'cmd': 'Page.setDownloadBehavior', 'params': { 'behavior': 'allow', 'downloadPath': download_dir } } command_result = driver.execute("send_command", params)
class ElementKeywords(LibraryComponent): def __init__(self, ctx): LibraryComponent.__init__(self, ctx) self.element_management = SeleniumElementKeywords(ctx) self.formelement_management = FormElementKeywords(ctx) self.waiting_management = WaitingKeywords(ctx) @keyword def clear_textfield_value(self, locator): text = self.element_management.get_value(locator) i = 0 while i < len(text): i += 1 self.element_management.press_key(locator, Keys.BACK_SPACE) self.element_management.press_key(locator, Keys.DELETE) @keyword def scroll_to_element(self, locator): self.waiting_management.wait_until_element_is_visible(locator) self.driver.execute_script("arguments[0].scrollIntoView();", self.find_element(locator)) @keyword def scroll_to_top(self, webelement): js = "arguments[0].scrollTo(0,-2*arguments[0].scrollHeight);" self.driver.execute_script(js, webelement) @keyword def scroll_to_bottom(self, webelement): js = "arguments[0].scrollTo(0,2*arguments[0].scrollHeight);" self.driver.execute_script(js, webelement) @keyword def special_click_element(self, locator): try: element = self.find_element(locator) element.remove_hidden_attribute() element.js_click() except: raise AssertionError("Failed to click element") return @keyword def my_click(self, locator): self.find_element(locator).click() @keyword def set_toggle_button_value(self, element_locator, value): element = self.find_element(element_locator) current_status = element.get_attribute('className') if current_status != value: element.js_click() return return "Failed to set toggle button value" @keyword def get_toggle_button_value(self, element_locator): element = self.find_element(element_locator) current_status = element.get_attribute('className') if current_status == "toggle active": return "True" return "False" @keyword def click_hidden_element(self, locator): try: if not self._is_element(locator): if "auto-tag" in locator: element = self.get_element_by_auto_tag(locator) else: element = self.find_element(locator) element.remove_hidden_attribute() element.js_click() except: message = "Failed to click on hidden element %s" % locator raise AssertionError(message) @keyword def input_text(self, locator, text): self.scroll_to_element(locator) # self.clear_textfield_value(locator) self.formelement_management.input_text(locator, text) @keyword def input_password(self, locator, password): self.scroll_to_element(locator) self.formelement_management.input_password(locator, password) @keyword def get_elements_by_attribute(self, attribute): """ Get element that has attribute with value :param attribute: <attribute_name>=<attribute_value> :return: list of found elements """ attribute_name = attribute.split('=')[0] attribute_value = attribute.split('=')[1].replace('"', '') return self.driver.find_elements_by_xpath("//*[@" + attribute_name + "='" + attribute_value + "']") @keyword def get_element_by_attribute(self, attribute): elements = self.get_elements_by_attribute(attribute) return elements[0] if len(elements) > 0 else elements @keyword def get_element_by_auto_tag(self, auto_tag): return self.get_element_by_attribute(auto_tag) @keyword def get_elements_by_auto_tag(self, auto_tag): return self.get_elements_by_attribute(auto_tag) @keyword def get_elements_by_tag(self, locator, tag): try: elements = self.find_elements(locator) if len(elements) == 1: if elements[0].get_property("tagName") == tag.upper(): return elements else: return elements[0].find_elements_by_tag_name(tag) else: return [ e for e in elements if e.get_property("tagName") == tag.upper() ] except: message = "Cannot get element(s) by tag '%s' with locator '%s'" % ( tag, locator) raise AssertionError(message) @keyword def find_element_contains_class(self, class_name): class_list = class_name.split(' ') elements = self.driver.find_elements_by_class_name(class_list[0]) for element in elements: actual_class_list = element.get_attribute("class").split(' ') if Utilities().is_sublist(actual_class_list, class_list[1:]): return element message = "Not found any element has '%s'" % class_name raise AssertionError(message) @keyword def wait_until_element_has_class(self, element, class_name, timeout=5, error=None): """ Wait until element contain class name :param element: element :param class_name: class name to expect element will has :param timeout: timeout in second :param error: error message :return: None """ self.waiting_management._wait_until( lambda: class_name in element.get_attribute("class"), "Element '%s' has no class name '%s' in <TIMEOUT>" % (element, class_name), timeout, error) @keyword def wait_until_element_has_number_child(self, element, class_name, children_num=1, timeout=5, error=None): """ Wait until the element has number of children as expected :param element: parent element :param class_name: class name of child element :param children_num: expected number of children need to wait for :param timeout: timeout in second :param error: error message :return: None """ self.waiting_management._wait_until( lambda: len(element.find_elements_by_class_name(class_name) ) == children_num, "Element '%s' has more than one child '%s' in <TIMEOUT>" % (element, class_name), timeout, error) def _is_element(self, item): return isinstance(item, WebElement) @keyword def get_element_contains_text_in_list(self, elements, text): """ Get the element from the list which has input text :param elements: list of elements :param text: text of finding element :return: the element which has input text """ for element in elements: actual = element.get_textContent() if str(text).strip() == actual: return element message = "Not found %s in list!" % text raise AssertionError(message) @keyword def select_item_in_list(self, elements, value): try: element = self.get_element_contains_text_in_list(elements, value) element.js_click() except: message = "Failed to select item %s in list!" % value raise AssertionError(message) @keyword def get_element_text(self, locator): text = self.find_element(locator) result = text.get_attribute("textContent") return result @keyword def set_special_list_value(self, locator, value): list_value = self.find_element(locator) values = list_value.find_elements_by_tag_name('span') for val in values: if val.get_textContent() == value: val.click() return mess = "Not Found By %s" % value raise AssertionError(mess) @keyword def compare_special_element_text(self, locator, value): element = self.find_element(locator) props = element.get_attribute("textContent") if value == props: return True else: mess = ("The text of element '%s' should have been '%s' " "but it was '%s'." % (locator, value, props)) raise AssertionError(mess) @keyword def is_disabled(self, locator): element = self.find_element(locator) props = element.get_attribute("disabled") if props == 'true': return True mess = "Element still is enabled" raise AssertionError(mess) @keyword def wait_until_element_is_disabled(self, locator, timeout=30, error=None): self.waiting_management._wait_until( lambda: self.is_disabled(locator), "Element '%s' still in enable over <TIMEOUT>." % locator, timeout, error) @keyword def text_field_is_disabled(self, locator): element = self.find_element(locator) props = element.get_attribute("readonly") if props == "true": return True mess = "Text field %s is enabled" % locator raise AssertionError(mess) @keyword def wait_until_text_field_is_disabled(self, locator, timeout=30, error=None): self.waiting_management._wait_until( lambda: self.text_field_is_disabled(locator), "Element '%s' still in enable over <TIMEOUT>." % locator, timeout, error) @keyword def get_length_selectbox(self, locator): element = self.find_element(locator) props = element.find_elements_by_tag_name('option') return len(props)
class TableKeywords(LibraryComponent): def __init__(self, ctx): LibraryComponent.__init__(self, ctx) self.elementkeywords_management = ElementKeywords(ctx) self.waiting_management = WaitingKeywords(ctx) def get_table(self, locator): self.wait_until_table_loaded(locator) # return self.find_element(locator) return self.elementkeywords_management.get_element_by_auto_tag(locator).find_element_by_tag_name("table") @keyword def wait_until_table_loaded(self, locator, timeout=150, error=None): try: self.wait_until_table_loading(locator) except: None self.waiting_management._wait_until( lambda: self.is_table_loaded(locator), "Table '%s' still in loading over <TIMEOUT>." % locator, timeout, error ) def wait_until_table_loading(self, locator, timeout=2, error=None): self.waiting_management._wait_until( lambda: not self.is_table_loaded(locator), "Table '%s' still in loading over <TIMEOUT>." % locator, timeout, error ) def is_table_loaded(self, locator): table_loader = self.get_table_loader(locator) return not table_loader.is_visible() def get_table_loader(self, locator): return self.elementkeywords_management.get_element_by_auto_tag(locator).find_element_by_tag_name("core-loader") def get_table_header(self, locator): return self.get_table(locator).find_element_by_tag_name("thead") def get_table_body(self, locator): return self.get_table(locator).find_element_by_tag_name("tbody") def get_header_columns(self, locator): return self.get_table_header(locator).find_elements_by_tag_name("th") def get_header_texts(self, locator): header_cols = self.get_header_columns(locator) headers = [] for header_col in header_cols: try: headers.append(header_col.get_textContent()) except: headers.append("") return headers @keyword def get_table_rows(self, locator): return self.get_table_body(locator).find_elements_by_tag_name("tr") def get_cells_in_table_row(self, row): return row.find_elements_by_tag_name("td") @keyword def get_column_index(self, locator, column_title): """ Get the index of column in table. :locator: locator of table :column_title: string of column title to get index :return: index of the column """ headers = self.get_header_texts(locator) return headers.index(column_title) @keyword def get_row_by_column_cell(self, locator, column, value, is_index=False): """ Get the row of table :locator: locator of table :column: string of column title or column index that contains value :value: string of cell's value :is_index: True if column is index, False if column is column title :return: row of value identified by column title """ rows = self.get_table_rows(locator) if not is_index: column = self.get_column_index(locator, column) for row in rows: cells = self.get_cells_in_table_row(row) if cells[column].get_textContent() == value: return row message = "Not found the value '%s' in any row!" % value raise AssertionError(message) @keyword def get_all_rows_by_column(self, table_locator, column_name, is_index=False): list_data = [] rows = self.get_table_rows(table_locator) if len(rows) == 0: mess = "Table is empty!" raise AssertionError(mess) if not is_index: column = self.get_column_index(table_locator, column_name) for row in rows: cells = self.get_cells_in_table_row(row)[column].text list_data.append(cells) return list_data @keyword def get_table_length(self, locator): rows = self.get_table_rows(locator) table_length = len(rows) return table_length @keyword def get_table_row(self, locator, value): rows = self.get_table_rows(locator) """ Get a row from table :param locator: table locator :param row_values: list values of row <value1> <value2> e.g. 1/1/1 10 Enable. Or a Dictionary Values list from YAML :return: table row """ for row in range(0, len(rows)): if value == rows[row].text: return value message = "Not found the value '%s' in any row!" % value raise AssertionError(message) @keyword def get_radio_on_row(self, locator, value): """ Get all row of this locator :param locator: table locator :param value: row text contains radio button :return: True if radio button is selected and else """ rows = self.get_table_rows(locator) for row in range(0, len(rows)): if rows[row].text == value: if rows[row].find_element_by_tag_name('td').find_element_by_tag_name('span').find_element_by_tag_name('input').is_selected(): return True else: message = "Value not be selected" % value raise AssertionError(message) return False def _is_text_in_list(self, elements, *text): if len(text) > 1: checking_text = text else: checking_text = text[0] for t in filter(lambda x: x != "" and x is not None, checking_text): try: self.elementkeywords_management.get_element_contains_text_in_list(elements, t) except: message = "Not found the value '%s' in table!" % text raise AssertionError(message) return False return True @keyword def is_table_has_value(self, locator, column, value): """ Check if table contains column's value :param locator: table locator :param column: column title (string) :param value: column value (string) :return: True if value is found other wise False """ try: row = self.get_row_by_column_cell(locator, column, value) return not (row is None) except: return False @keyword def get_row_by_index(self, locator, index): return self.get_table_rows(locator)[index] @keyword def get_status_in_row(self, locator, index, value): rows = self.get_row_by_index(locator, index) fail_status = "Failed" complete_errors_status = "Completed with Errors" on_going_status = "On Going" if value in rows.text: return value elif fail_status in rows.text: return fail_status elif complete_errors_status in rows.text: return complete_errors_status return on_going_status @keyword def click_element(self, locator): return self.find_element(locator).js_click() @keyword def click_on_row(self, locator, column_title, value): self.get_row_by_column_cell(locator, column_title, value).click() @keyword def click_on_row_radio_button(self, locator, column_title, value): row = self.get_row_by_column_cell(locator, column_title, value) self.click_on_radio_button(row) def click_on_radio_button(self, element): self.get_radio_button(element).js_click() def get_radio_button(self, element): return element.find_element_by_tag_name("input") def get_link(self, element): return element.find_element_by_tag_name("a") @keyword def click_on_link(self, element): self.get_link(element).click() @keyword def is_table_has_text(self, locator, text): """ The function help check search result in table :param locator: locator of table :param text: verify text :return: True if text contains in table otherwise False """ self.wait_until_table_loaded(locator) table_data = self.get_table_body(locator) text_content = table_data.get_textContent() if text == text_content[0:12]: return True else: message = "Not found the value '%s' in table!" % text raise AssertionError(message) @keyword def is_table_contains_text(self, locator, text): """ The function help check search result in table :param locator: locator of table :param text: verify text :return: True if text contains in table otherwise False """ self.wait_until_table_loaded(locator) table_data = self.get_table_body(locator) text_content = table_data.get_textContent() if text in text_content: return True else: message = "Not found the value '%s' in table!" % text raise AssertionError(message) @keyword def table_should_be_empty(self, locator): table_data = self.get_table_body(locator) if len(table_data.text) == 0: return True message = "Table still has data" raise AssertionError(message) @keyword def table_should_be_none(self, locator): element = self.find_element(locator).find_elements_by_name("tbody") if len(element) > 0: mess = "Table %s is not empty" % locator raise AssertionError(mess) return @keyword def click_on_link_in_row(self, locator, column, value, is_index=False): """ Click on link in a table row :locator: locator of table :column: string of column title or column index that contains value :value: string of cell's value :is_index: True if column is index, False if column is column title :return: row of value identified by column title """ rows = self.get_table_rows(locator) if not is_index: column = self.get_column_index(locator, column) for row in rows: cells = self.get_cells_in_table_row(row) if cells[column].get_textContent() == value: return row.find_element_by_tag_name("a").js_click() message = "Not found the value '%s' in any row!" % value raise AssertionError(message) @keyword def get_all_data_of_table(self, locator): rows = self.get_table_body(locator).find_elements_by_tag_name("span") data = [] for i in rows: data.append(i.text) return data @keyword def get_text_on_table_without_empty_text(self, locator): rows = self.get_table_body(locator).find_elements_by_tag_name("span") data = [] for i in range(0, len(rows)): if rows[i].text != '': data.append(rows[i].text) return data
class ExtendedSeleniumLibrary(SeleniumLibrary): ROBOT_LIBRARY_SCOPE = 'GLOBAL' def __init__(self): SeleniumLibrary.__init__(self, 30) self.waiting_management = WaitingKeywords(self) @keyword def clear_textfield_value(self, locator): text = self.get_value(locator) i = 0 while i < len(text): i += 1 self.press_key(locator, Keys.BACK_SPACE) self.press_key(locator, Keys.DELETE) @keyword def wait_until_location_is(self, expected, timeout=None, error=None): self.waiting_management._wait_until( lambda: self.get_location() == expected, "Location was not match '%s' in <TIMEOUT>. Actual value was '%s'" % (expected, self.get_location()), timeout, error) @keyword def wait_until_location_is_not(self, expected, timeout=None, error=None): self.waiting_management._wait_until( lambda: self.get_location() != expected, "Location did not change to value different to '%s' in <TIMEOUT>" % (expected, self.get_location()), timeout, error) @keyword def wait_until_location_contains(self, expected, timeout=None, error=None): self.waiting_management._wait_until( lambda: expected in self.get_location(), "Location '%s' did not contain '%s' in <TIMEOUT>" % (self.get_location(), expected), timeout, error) @keyword def location_should_not_be(self, expected): actual = self.get_location() if expected == actual: message = "Location should not be '%s' but it was NOT" % (expected) raise AssertionError(message) @keyword def element_css_property_value_should_be(self, locator, property_name, expected, message=''): element = self._element_find(locator, True, True) actual = element.value_of_css_property(property_name) if expected != actual: if not message: message = "The css value '%s' of element '%s' should have been '%s' but "\ "in fact it was '%s'." % (property_name, locator, expected, actual) raise AssertionError(message) @keyword def element_color_css_property_value_should_be(self, locator, property_name, expected, message=''): if self._is_rgb_color(expected): expected = self._convert_rgb_to_hex(expected) element = self._element_find(locator, True, True) actual = element.value_of_css_property(property_name) if self._is_rgb_color(actual): actual = self._convert_rgb_to_hex(actual) if expected != actual: if not message: message = "The color related css value '%s' of element '%s' should have been '%s' but "\ "in fact it was '%s'." % (property_name, locator, expected, actual) raise AssertionError(message) @keyword def wait_until_element_css_property_value_is(self, locator, property_name, expected, timeout=None, error=None): self.waiting_management._wait_until( lambda: expected == self._element_find( locator, True, True).value_of_css_property(property_name), "The css value '%s' of element '%s' did not match '%s' in <TIMEOUT>. Actual value is '%s'" % (property_name, locator, expected, self._element_find(locator, True, True).value_of_css_property(property_name)), timeout, error) @keyword def wait_until_element_css_property_value_is_not(self, locator, property_name, expected, timeout=None, error=None): self.waiting_management._wait_until( lambda: expected == self._element_find( locator, True, True).value_of_css_property(property_name), "The css value '%s' of element '%s' did not different to '%s' in <TIMEOUT>" % (property_name, locator, expected), timeout, error) @keyword def wait_until_element_color_css_property_value_is(self, locator, property_name, expected, timeout=None, error=None): if self._is_rgb_color(expected): expected = self._convert_rgb_to_hex(expected) def check_css_property_value(): element = self._element_find(locator, True, True) actual = element.value_of_css_property(property_name) if self._is_rgb_color(actual): actual = self._convert_rgb_to_hex(actual) return actual == expected self.waiting_management._wait_until( lambda: check_css_property_value, "The color related css value '%s' of element '%s' did not match '%s' in <TIMEOUT>" % (property_name, locator, expected), timeout, error) @keyword def wait_until_element_color_css_property_value_is_not( self, locator, property_name, expected, timeout=None, error=None): if self._is_rgb_color(expected): expected = self._convert_rgb_to_hex(expected) def check_css_property_value(): element = self._element_find(locator, True, True) actual = element.value_of_css_property(property_name) if self._is_rgb_color(actual): actual = self._convert_rgb_to_hex(actual) return actual == expected self.waiting_management._wait_until( lambda: check_css_property_value, "The color related css value '%s' of element '%s' did not different to '%s' in <TIMEOUT>" % (property_name, locator, expected), timeout, error) @keyword def is_element_present(self, locator, tag=None): return self._is_element_present(locator, tag) @keyword def scroll_to_element(self, locator): self.driver.execute_script("arguments[0].scrollIntoView();", self.find_element(locator)) def _scroll_to_left_of_webElement(self, element): self.driver.execute_script("arguments[0].scrollTo(0,0);", element) def _convert_rgb_to_hex(self, rgb_string): color_tuple = rgb_string.replace("rgb(", "").replace("rgba(", "").replace( ")", "").replace(" ", "") color_tuple = color_tuple.split(",") rgb = (int(color_tuple[0]), int(color_tuple[1]), int(color_tuple[2])) hex_str = rgb_to_hex(rgb) return hex_str def _is_rgb_color(self, color_str): r = r"rgb\((\d+),\s*(\d+),\s*(\d+)\)" r2 = r"rgba\((\d+),\s*(\d+),\s*(\d+),\s*(\d+)\)" return re.match(r, color_str) or re.match(r2, color_str) @keyword def switch_to_frame(self, locator): self.wait_for_data_loaded() frame = self.find_element(locator) self.driver.switch_to_frame(frame)
class BrowserKeywords(LibraryComponent): def __init__(self, ctx): LibraryComponent.__init__(self, ctx) self.waiting_management = WaitingKeywords(ctx) self.browser_management = BrowserManagementKeywords(ctx) @keyword def setup_browser_driver(self, settings): """ Create instance of selenium webdriver base on driver type :settings: dictionary of browser setting. Sample: BROWSER: TYPE: chrome BROWSER_BINARY_PATH: <path_name_of_browser_binary> BROWSER_DRIVER_PATH: <path_name_of_browser_driver> HEADLESS: True WINDOW_SIZE: 1920,1080 BROWSER_ARGUMENTS: no-sandbox arg2=value2 """ # init browsers firefox = AosBrowser('firefox', 'ff', None, '/Webdrivers/firefoxdriver/geckodriver', False, None, None) chrome = AosBrowser('chrome', 'gc', None, '/Webdrivers/chromedriver/chromedriver', False, None, None) ie = AosBrowser('ie', 'ie', None, '/Webdrivers/iedriver/IEDriverServer', False, None, None) _BROWSER_MAP = {'firefox': firefox, 'chrome': chrome, 'ie': ie} browser_type = settings.get(_BROWSER_TYPE_KEY).strip().lower() bin_path = settings.get(_BROWSER_BINARY_PATH_KEY, None) driver_path = settings.get(_BROWSER_DRIVER_PATH_KEY) headless_mode = settings.get(_BROWSER_HEADLESS_MODE, False) window_size = settings.get(_BROWSER_WINDOW_SIZE, None) browser_args = settings.get(_BROWSER_ARGUMENTS_KEY, None) detected_browser = _BROWSER_MAP[browser_type] detected_browser.set_bin_path(bin_path) detected_browser.set_driver_path(driver_path) detected_browser.set_headless(headless_mode) detected_browser.set_window_size(window_size) detected_browser.set_args(browser_args) driver = detected_browser.get_driver() driver.delete_all_cookies() if detected_browser.is_maximum(): driver.maximize_window() return self.browser_management.ctx.register_driver(driver, None) def get_location(self): return self.browser_management.get_location() @keyword def wait_until_location_is(self, expected, timeout=None, error=None): self.waiting_management._wait_until( lambda: self.get_location() == expected, "Location was not match '%s' in <TIMEOUT>. Actual value was '%s'" % (expected, self.get_location()), timeout, error) @keyword def wait_until_location_is_not(self, expected, timeout=None, error=None): self.waiting_management._wait_until( lambda: self.get_location() != expected, "Location did not change to value different to '%s' in <TIMEOUT>. Actual value was '%s'" % (expected, self.get_location()), timeout, error) @keyword def wait_until_location_contains(self, expected, timeout=None, error=None): self.waiting_management._wait_until( lambda: expected in self.get_location(), "Location '%s' did not contain '%s' in <TIMEOUT>" % (self.get_location(), expected), timeout, error) @keyword def location_should_not_be(self, expected): actual = self.get_location() if expected == actual: message = "Location should not be '%s' but it was NOT" % expected raise AssertionError(message) @keyword def element_css_property_value_should_be(self, locator, property_name, expected, message=''): element = self.find_element(locator) actual = element.value_of_css_property(property_name) if expected != actual: if not message: message = "The css value '%s' of element '%s' should have been '%s' but " \ "in fact it was '%s'." % (property_name, locator, expected, actual) raise AssertionError(message) @keyword def element_color_css_property_value_should_be(self, locator, property_name, expected, message=''): if Utilities.is_rgb_color(expected): expected = Utilities.convert_rgb_to_hex(expected) element = self.find_element(locator) actual = element.value_of_css_property(property_name) if Utilities.is_rgb_color(actual): actual = Utilities.convert_rgb_to_hex(actual) if expected.upper() != actual.upper(): if not message: message = "The color related css value '%s' of element '%s' should have been '%s' but " \ "in fact it was '%s'." % (property_name, locator, expected, actual) raise AssertionError(message) @keyword def wait_until_element_css_property_value_is(self, locator, property_name, expected, timeout=None, error=None): self.waiting_management._wait_until( lambda: expected == self.find_element( locator).value_of_css_property(property_name), "The css value '%s' of element '%s' did not match '%s' in <TIMEOUT>. Actual value is '%s'" % (property_name, locator, expected, self.find_element(locator).value_of_css_property(property_name)), timeout, error) @keyword def wait_until_element_css_property_value_is_not(self, locator, property_name, expected, timeout=None, error=None): self.waiting_management._wait_until( lambda: expected == self.find_element( locator).value_of_css_property(property_name), "The css value '%s' of element '%s' did not different to '%s' in <TIMEOUT>" % (property_name, locator, expected), timeout, error) @keyword def wait_until_element_color_css_property_value_is(self, locator, property_name, expected, timeout=None, error=None): if Utilities.is_rgb_color(expected): expected = Utilities.convert_rgb_to_hex(expected) def check_css_property_value(): element = self.find_element(locator) actual = element.value_of_css_property(property_name) if Utilities.is_rgb_color(actual): actual = Utilities.convert_rgb_to_hex(actual) return actual == expected self.waiting_management._wait_until( lambda: check_css_property_value, "The color related css value '%s' of element '%s' did not match '%s' in <TIMEOUT>" % (property_name, locator, expected), timeout, error) @keyword def wait_until_element_color_css_property_value_is_not( self, locator, property_name, expected, timeout=None, error=None): if Utilities.is_rgb_color(expected): expected = Utilities.convert_rgb_to_hex(expected) def check_css_property_value(): element = self.find_element(locator) actual = element.value_of_css_property(property_name) if Utilities.is_rgb_color(actual): actual = Utilities.convert_rgb_to_hex(actual) return actual == expected self.waiting_management._wait_until( lambda: check_css_property_value, "The color related css value '%s' of element '%s' did not different to '%s' in <TIMEOUT>" % (property_name, locator, expected), timeout, error) @keyword def cleanup_download(self): shutil.rmtree(get_download_path(), ignore_errors=True) @keyword def get_single_downloaded_file(self, ext): for root, dirs, files in walk(get_download_path()): for f in files: if f.endswith(ext): return os.path.join(root, f) raise AssertionError("No match downloaded file") @keyword def wait_until_file_downloaded(self, file_name='', ext='', timeout=30, error=None): self.waiting_management._wait_until( lambda: Utilities().is_downloaded_file_has_extension( get_download_path(file_name), ext), "There is no download file in <TIMEOUT>.", timeout, error) def _get_actual_downloaded_file(self, extension, file_name=''): self.wait_until_file_downloaded(file_name, extension) return file_name if file_name else self.get_single_downloaded_file( extension) @keyword def get_downloaded_xlsx_data(self, file_name=''): file_name = self._get_actual_downloaded_file(_XLSX_EXTENSION, file_name) data = [] try: wb = xlrd.open_workbook(file_name) except: raise AssertionError("Failed to open XLSX downloaded file!") ws = wb.sheet_by_index(0) for row in ws.get_rows(): for cell in row: data.append(cell.value) return data @keyword def get_downloaded_csv_data(self, file_name=''): file_name = self._get_actual_downloaded_file(_CSV_EXTENSION, file_name) data = [] try: with open(file_name, encoding='utf-8-sig') as csv_file: reader = csv.reader(csv_file) for row in reader: for item in row: data.append(item.strip()) return data except: raise AssertionError("Failed to open CSV downloaded file!") @keyword def current_remote_ip_address(self): hostname = socket.gethostname() return socket.gethostbyname(hostname) @keyword def current_router_ip_address(self, aos_url): temp = aos_url.replace("http://", "") if temp.find(":") > -1: router_address = temp.split(":")[0] elif temp.find("/") > -1: router_address = temp.split("/")[0] else: router_address = temp return router_address
class BrowserKeywords(LibraryComponent): WINDOWS_FIREFOX_DRIVER_PATH = r'\Drivers\geckodriver.exe' WINDOWS_CHROME_DRIVER_PATH = r'\Drivers\chromedriver.exe' WINDOWS_EDGE_DRIVER_PATH = r'\Drivers\MicrosoftWebDriver.exe' LINUX_FIREFOX_DRIVER_PATH = r'\Drivers\geckodriver' LINUX_CHROME_DRIVER_PATH = r'\Drivers\chromedriver' FIREFOX_DOWNLOAD_LOCATION = r'\Results\Exported\Firefox_exported' CHROME_DOWNLOAD_LOCATION = r'\Results\Exported\Chrome_exported' EDGE_DOWNLOAD_LOCATION = r'\Results\Exported\Edge_exported' EDGE_REG_DOWNLOAD_PATH = r"SOFTWARE\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppContainer\Storage\microsoft.microsoftedge_8wekyb3d8bbwe\MicrosoftEdge\Main" EDGE_REG_DOWNLOAD_POPUP_PATH = r"Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppContainer\Storage\microsoft.microsoftedge_8wekyb3d8bbwe\MicrosoftEdge\Download" EDGE_REG_DOWNLOAD_KEY = r"Default Download Directory" EDGE_REG_DOWNLOAD_POPUP_KEY = "EnableSavePrompt" EDGE_TURN_OFF_DOWNLOAD_POPUP = "0" def __init__(self, ctx): LibraryComponent.__init__(self, ctx) self.waiting_management = WaitingKeywords(ctx) self.browser_management = BrowserManagementKeywords(ctx) @keyword def get_current_os(self): return platform.system() @keyword def format_os_path(self, path): # /: Linux # \: Windows return path.replace('\\', '/') if os.sep == '/' else path.replace( '/', '\\') @keyword def get_current_path_of_project(self): current_path = os.path.dirname(os.path.dirname(__file__)) return os.path.dirname( os.path.dirname(os.path.join("..", current_path))) @keyword def enable_download_in_headless_chrome(self, driver, download_dir): # add missing support for chrome "send_command" to selenium webdriver driver.command_executor._commands["send_command"] = ( "POST", '/session/$sessionId/chromium/send_command') params = { 'cmd': 'Page.setDownloadBehavior', 'params': { 'behavior': 'allow', 'downloadPath': download_dir } } driver.execute("send_command", params) @keyword def open_my_browser(self, setup): curr_path = self.get_current_path_of_project() if setup.get('setup').get('browser').lower() == 'firefox': options = FirefoxOptions() if setup.get('setup').get('headless').lower() == 'true': options.headless = True else: options.headless = False options.set_preference( 'pdfjs.previousHandler.alwaysAskBeforeHandling', False) options.set_preference('browser.download.folderList', 2) options.set_preference( 'browser.download.dir', curr_path + self.format_os_path(self.FIREFOX_DOWNLOAD_LOCATION)) options.set_preference('browser.download.panel.shown', False) options.set_preference( "browser.helperApps.neverAsk.saveToDisk", "application/csv," + "text/csv," + "application/x-msexcel,application/excel," + "application/vnd.openxmlformats-officedocument.wordprocessingml.document," + "application/x-excel,application/vnd.ms-excel" + "application / xml") if self.get_current_os().lower() == 'windows': driver = webdriver.Firefox( capabilities=None, options=options, executable_path=curr_path + self.format_os_path(self.WINDOWS_FIREFOX_DRIVER_PATH)) else: driver = webdriver.Firefox( capabilities=None, options=options, executable_path=curr_path + self.format_os_path(self.LINUX_FIREFOX_DRIVER_PATH)) driver.maximize_window() else: options = ChromeOptions() if setup.get('setup').get('headless').lower() == 'true': options.add_argument("headless") else: options.add_argument("--start-maximized") prefs = { "profile.default_content_settings.popups": 0, "download.default_directory": curr_path + self.format_os_path(self.CHROME_DOWNLOAD_LOCATION), "directory_upgrade": True } options.add_experimental_option("prefs", prefs) if self.get_current_os().lower() == 'windows': driver = webdriver.Chrome( chrome_options=options, executable_path=curr_path + self.format_os_path(self.WINDOWS_CHROME_DRIVER_PATH)) else: driver = webdriver.Chrome( chrome_options=options, executable_path=curr_path + self.format_os_path(self.LINUX_CHROME_DRIVER_PATH)) if setup.get('setup').get('headless') == 'True': self.enable_download_in_headless_chrome( driver, curr_path + self.format_os_path(self.CHROME_DOWNLOAD_LOCATION)) driver.get( setup.get(BuiltIn().get_variable_value("${RESOURCE}")).get('url')) self.debug('Opened browser with session id %s.' % driver.session_id) return self.ctx.register_driver(driver, None) @keyword def setup_browser_driver(self, browser, path=''): """ Create instance of selenium webdriver base on driver type :browser: browser type: chrome | firefox | ie :path: the path of executable driver """ browser = browser.strip().lower() if browser == 'firefox': if path == '': path = self.get_project_path() + self.FIREFOX_DRIVER_PATH driver = Firefox(executable_path=self.format_executable_path(path)) else: if path == '': path = self.get_project_path() + self.CHROME_DRIVER_PATH driver = Chrome(self.format_executable_path(path)) driver.delete_all_cookies() return self.browser_management.ctx.register_driver(driver, None) def format_executable_path(self, path): if ".exe" in path: return path else: return path if os.sep == '/' else path + ".exe" def get_project_path(self): """ Get the root directory of the project """ return os.path.dirname(__file__).replace('\Libs\PCNLibrary\keywords', '') def get_location(self): return self.browser_management.get_location() @keyword def wait_until_location_is(self, expected, timeout=None, error=None): self.waiting_management._wait_until( lambda: self.get_location() == expected, "Location was not match '%s' in <TIMEOUT>. Actual value was '%s'" % (expected, self.get_location()), timeout, error) @keyword def wait_until_location_is_not(self, expected, timeout=None, error=None): self.waiting_management._wait_until( lambda: self.get_location() != expected, "Location did not change to value different to '%s' in <TIMEOUT>" % (expected, self.get_location()), timeout, error) @keyword def wait_until_location_contains(self, expected, timeout=None, error=None): self.waiting_management._wait_until( lambda: expected in self.get_location(), "Location '%s' did not contain '%s' in <TIMEOUT>" % (self.get_location(), expected), timeout, error) @keyword def location_should_not_be(self, expected): actual = self.get_location() if expected == actual: message = "Location should not be '%s' but it was NOT" % expected raise AssertionError(message) @keyword def element_css_property_value_should_be(self, locator, property_name, expected, message=''): element = self.find_element(locator) actual = element.value_of_css_property(property_name) if expected != actual: if not message: message = "The css value '%s' of element '%s' should have been '%s' but "\ "in fact it was '%s'." % (property_name, locator, expected, actual) raise AssertionError(message) @keyword def element_color_css_property_value_should_be(self, locator, property_name, expected, message=''): if self._is_rgb_color(expected): expected = self._convert_rgb_to_hex(expected) element = self.find_element(locator) actual = element.value_of_css_property(property_name) if self._is_rgb_color(actual): actual = self._convert_rgb_to_hex(actual) if expected != actual: if not message: message = "The color related css value '%s' of element '%s' should have been '%s' but "\ "in fact it was '%s'." % (property_name, locator, expected, actual) raise AssertionError(message) @keyword def wait_until_element_css_property_value_is(self, locator, property_name, expected, timeout=None, error=None): self.waiting_management._wait_until( lambda: expected == self.find_element( locator).value_of_css_property(property_name), "The css value '%s' of element '%s' did not match '%s' in <TIMEOUT>. Actual value is '%s'" % (property_name, locator, expected, self.find_element(locator).value_of_css_property(property_name)), timeout, error) @keyword def wait_until_element_css_property_value_is_not(self, locator, property_name, expected, timeout=None, error=None): self.waiting_management._wait_until( lambda: expected == self.find_element( locator).value_of_css_property(property_name), "The css value '%s' of element '%s' did not different to '%s' in <TIMEOUT>" % (property_name, locator, expected), timeout, error)