Beispiel #1
0
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)
Beispiel #7
0
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)