# FindBy.py文件 做用是將yaml格式中的Type的值轉換爲可被By對象可識別的元組,被FindWebElement調用 # -*- coding:utf-8 -*- # explain :元素定位方式說明,用於返回By類型 import sys from selenium.common.exceptions import NoSuchElementException from selenium.webdriver.common.by import By from com.chanpin.initialize.Start import Primary class FindBy: def __init__(self, Type): """ 用於返回loaction元組的by類型 :param Type: yaml文件的Type值 """ self.__Type = Type # 定義查找元素 def find_by(self) -> By: """ 經過'id', 'name', 'class', 'tag', 'link', 'plink', 'css', 'xpath'查找相應的locationby :rtype locationby : selenium.webdriver.common.by.By :return locationby 對應的location元組的By的值 """ """定位元素""" by = self.__Type locationby = None if by in ['id', 'name', 'class', 'tag', 'link', 'plink', 'css', 'xpath']: try: if by == 'id': locationby = By.ID elif by == 'name': locationby = By.NAME elif by == 'class': locationby = By.CLASS_NAME elif by == 'tag': locationby = By.TAG_NAME elif by == 'link': locationby = By.LINK_TEXT elif by == 'plink': locationby = By.PARTIAL_LINK_TEXT elif by == 'css': locationby = By.CSS_SELECTOR elif by == 'xpath': locationby = By.XPATH else: Primary.Log.error("沒有找到對應元素Type類型,請使用'id', 'name', 'class', 'tag', 'link', 'plink', 'css', 'xpath'") # Log.info('元素定位成功。定位方式:%s,使用的值%s:' % (by, value)) return locationby except NoSuchElementException as e: # print("no suceelement") method = sys._getframe(1).f_code.co_name # 調用該函數的函數名字,若是沒有被調用,則返回<module> path = sys._getframe(1).f_code.co_filename # 調用該函數的文件名字,若是沒有被調用,則返回<module> Primary.Log.error("在執行【" + path + "】文件中的【" + method + "】方法時出現錯誤" + "沒有找到對應的元素" + e.__str__()) else: # print("輸入的元素定位方式錯誤") Primary.Log.error("輸入的元素定位方式錯誤,請使用'id', 'name', 'class', 'tag', 'link', 'plink', 'css', 'xpath'") # --FindWebElemnet.py文件,該文件的做用是將yaml文件中Type值做爲元素定位的方式值,Value做爲元素內容值,兩個方法分別返回WebElement對象和由WebElement對象組成的list列表,被ReadyamlToElement類調用 # -*- coding:utf-8 -*- # explain : WebElement元素定位,給GetelementFromYaml使用 from com.chanpin.initialize.Start import Primary from selenium.common.exceptions import NoSuchElementException from selenium.webdriver.remote import webelement class FindWebElement: def __init__(self, driver, Type, Value): """ :type driver: selenium.webdriver.remote.webdriver.WebDriver 實例化findWebElement :param driver: :param Type: yaml文件的Type值 :param Value: yaml文件的value值 """ self.__driver = driver self.__Type = Type self.__Value = Value # 定義查找元素 def find_element(self, yamlpath, key) -> webelement: """ 經過'id', 'name', 'class', 'tag', 'link', 'plink', 'css', 'xpath'查找相應的元素 :return: WebElemt對應 """ """定位元素""" by = self.__Type value = self.__Value element = None if by in ['id', 'name', 'class', 'tag', 'link', 'plink', 'css', 'xpath']: # noinspection PyBroadException try: if by == 'id': element = self.__driver.find_element_by_id(value) elif by == 'name': element = self.__driver.find_element_by_name(value) elif by == 'class': element = self.__driver.find_element_by_class_name(value) elif by == 'tag': element = self.__driver.find_element_by_tag_name(value) elif by == 'link': element = self.__driver.find_element_by_link_text(value) elif by == 'plink': element = self.__driver.find_element_by_partial_link_text(value) elif by == 'css': element = self.__driver.find_element_by_css_selector(value) elif by == 'xpath': element = self.__driver.find_element_by_xpath(value) else: Primary.Log.error("沒有找到對應元素Type類型,請使用'id', 'name', " "'class', 'tag', 'link', 'plink', 'css', 'xpath'") # Log.info('元素定位成功。定位方式:%s,使用的值%s:' % (by, value)) return element except NoSuchElementException as e: # print("no suceelement") Primary.Log.error("yaml文件爲:" + yamlpath + ";頁面中沒有定位key值爲'" + key + "'對應的元素;" + e.__str__() + ";請確保定位準確。") # self.get_img() # 調用截圖 else: # print("輸入的元素定位方式錯誤") Primary.Log.error("輸入的元素定位方式錯誤,請使用'id', 'name', 'class', " "'tag', 'link', 'plink', 'css', 'xpath'") def find_elements(self, yamlpath, key) -> list: """ 經過'id', 'name', 'class', 'tag', 'link', 'plink', 'css', 'xpath'查找相應的元素 :return: 當list_elements只有1個時直接返回selenium.webdriver.remote.webelement類,不然返回list :rtype list_elements : list of WebElement """ """定位元素""" by = self.__Type value = self.__Value list_elements = None if by in ['id', 'name', 'class', 'tag', 'link', 'plink', 'css', 'xpath']: # noinspection PyBroadException try: if by == 'id': list_elements = self.__driver.find_elements_by_id(value) elif by == 'name': list_elements = self.__driver.find_elements_by_name(value) elif by == 'class': list_elements = self.__driver.find_elements_by_class_name(value) elif by == 'tag': list_elements = self.__driver.find_elements_by_tag_name(value) elif by == 'link': list_elements = self.__driver.find_elements_by_link_text(value) elif by == 'plink': list_elements = self.__driver.find_elements_by_partial_link_text(value) elif by == 'css': list_elements = self.__driver.find_elements_by_css_selector(value) elif by == 'xpath': list_elements = self.__driver.find_elements_by_xpath(value) else: Primary.Log.error("沒有找到對應元素Type類型,請使用'id', 'name', 'class', " "'tag', 'link', 'plink', 'css', 'xpath'") # Log.info('元素定位成功。定位方式:%s,使用的值%s:' % (by, value)) return list_elements except NoSuchElementException as e: # print("no suceelement") Primary.Log.error("yaml文件爲:" + yamlpath + ";頁面中沒有定位key值爲'" + key + "'對應的元素;" + e.__str__() + ";請確保定位準確。") # self.get_img() # 調用截圖 else: # print("輸入的元素定位方式錯誤") Primary.Log.error("輸入的元素定位方式錯誤,請使用'id', 'name', 'class', " "'tag', 'link', 'plink', 'css', 'xpath'") # GetelementFromYaml.py文件,真正被調用其餘模塊的調用的類,經過傳入yaml文件中的key值根據狀況得到真正能使用的WebElement對象,進行元素點擊輸入等操做 # -*- coding:utf-8 -*- # explain : 從yaml文件中讀取返回webelement import yaml from selenium.webdriver.remote.webdriver import WebDriver from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.remote.webelement import WebElement from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException from com.chanpin.utils.FindWebElemet import FindWebElement from com.chanpin.utils.FindBy import FindBy from com.chanpin.initialize.Start import Primary # yaml文件位置 ''' 初始化添加對應的yaml文件位置,而後調用getAllValue方法,調用 getelement方法獲取到對應的webelement 改進方法:保證yaml的文件名和test_case的文件名或者類名一致 ''' class ReadyamlToElement: """ 經過yaml文件獲取相應的元素定位,方法以下: getelement(self, key) : 返回WebElement類元素 getelements(self, key) : 返回list getelementsintnum(self, key, intnum=0) : 返回WebElement類元素 getelementsstringtext(self, key, strtext: str, attributename=None) : 返回WebElement類元素 waitgetelement(self, key) : 返回WebElement類元素 waitgetelements(self, key) : 返回list waitgetelement_clickable(self, key) : 返回WebElement類元素 getlocator(self, key) : 返回tuple """ def __init__(self, driver: WebDriver, yamlpath): """ 實例化readyaml類 :param driver: :param yamlpath: 對應的yaml文件名 """ self.__yamlPath = yamlpath self.__driver = driver def __getAllValue(self): """ 將指定yaml文件轉化爲dic字典,key爲 :return dic字典 """ ''' curPath = os.path.dirname(os.path.realpath(__file__)) # 獲取yaml文件路徑 yamlPath = os.path.join(curPath, "cfgyaml.yaml") print(type(yamlPath)) ''' with open(self.__yamlPath, 'r', encoding='utf-8') as f: cfg = f.read() dic_yaml = yaml.load(cfg, Loader=yaml.FullLoader) # 用load方法轉字典 return dic_yaml ''' 經過key獲取到對應的webelement,改進方法,將其所有遍歷後,生成key:element的字典,從裏面取對應的數據 ''' def getelement(self, key) -> WebElement: """ 經過yaml文件的key獲取到對應的Webelement :param key: yaml文件的key :return: 對應的WebElement對象 :rtype keyelement: selenium.webdriver.remote.webelement """ dic = ReadyamlToElement(self.__driver, self.__yamlPath).__getAllValue() # 接受readyaml().getAllValue()返回的dict if key in dic: list_value = dic.get(key) # list_Type_value = list_value[0].split(":")[1] #獲取type的值 # list_Value_value = list_value[1].split(":")[1] #獲取value的值 list_Type_value = list_value.get("Type") # 獲取type的值 list_Value_value = list_value.get("Value") # 獲取value的值 keyelement = FindWebElement(self.__driver, list_Type_value, list_Value_value).find_element(self.__yamlPath, key) # 用於返回webelement對象 Primary.Log.info(self.__yamlPath + "中獲取到該element,經過該key:" + key) return keyelement else: Primary.Log.error(self.__yamlPath + "中不存在該key:" + key + ":關閉程序") # self.__driver.quit() def getelements(self, key): """ 經過yaml文件的key獲取到對應的Webelement :param key: yaml文件的key :return: 對應的WebElement對象 類型爲WebElement :rtype keyelements: list """ dic = ReadyamlToElement(self.__driver, self.__yamlPath).__getAllValue() # 接受readyaml().getAllValue()返回的dict # print(dic) if key in dic: list_value = dic.get(key) list_Type_value = list_value.get("Type") # 獲取type的值 list_Value_value = list_value.get("Value") # 獲取value的值 keyelementlist = FindWebElement(self.__driver, list_Type_value, list_Value_value).find_elements(self.__yamlPath, key) # 用於返回webelement對象 Primary.Log.info(self.__yamlPath + "中獲取到該element,經過該key:" + key) return keyelementlist else: Primary.Log.error(self.__yamlPath + "中不存在該key:" + key + ":關閉程序") # self.__driver.quit() def getelementsintnum(self, key, intnum=0) -> WebElement: """ 經過yaml文件的key獲取一組WebElemnts,經過數組下標獲取對應的WebElemnt :param key: yaml文件的key :param intnum 數組下標 :type key : String :type intnum : int :return: 對應的WebElement對象 :rtype keyelements[intnum]: selenium.webdriver.remote.webelement """ dic = ReadyamlToElement(self.__driver, self.__yamlPath).__getAllValue() # 接受readyaml().getAllValue()返回的dict # print(dic) list_keyelements = [] if key in dic: list_value = dic.get(key) # list_Type_value = list_value[0].split(":")[1] #獲取type的值 # list_Value_value = list_value[1].split(":")[1] #獲取value的值 list_Type_value = list_value.get("Type") # 獲取type的值 list_Value_value = list_value.get("Value") # 獲取value的值 list_keyelements = FindWebElement(self.__driver, list_Type_value, list_Value_value).find_elements(self.__yamlPath, key) # 用於返回webelement對象 Primary.Log.info(self.__yamlPath + "中獲取到該element,經過該key:" + key) else: Primary.Log.error(self.__yamlPath + "中不存在該key:" + key + ":關閉程序") # self.__driver.quit() # 判斷輸入的值是否正確,正確則正確找到,不然就報空 if -len(list_keyelements) <= intnum < len(list_keyelements): return list_keyelements[intnum] else: Primary.Log.error("當前輸入的intnum大於" + str(len(list_keyelements)) + "有問題") return None def getelementsstringtext(self, key, strtext: str, attributename=None) -> WebElement: """ 經過yaml文件的key獲取一組WebElemnts,經過指定元素的值獲取到對應的WebElemnt :param key: yaml文件的key :param strtext 對應元素的值 :type key : str :type strtext : str :param attributename 元素的屬性值,Name of the attribute/property to retrieve :type attributename : str :return: 對應的WebElement對象 :rtype element: selenium.webdriver.remote.webelement """ dic = ReadyamlToElement(self.__driver, self.__yamlPath).__getAllValue() # 接受readyaml().getAllValue()返回的dict # print(dic) list_keyelements = [] if key in dic: list_value = dic.get(key) # list_Type_value = list_value[0].split(":")[1] #獲取type的值 # list_Value_value = list_value[1].split(":")[1] #獲取value的值 list_Type_value = list_value.get("Type") # 獲取type的值 list_Value_value = list_value.get("Value") # 獲取value的值 list_keyelements = FindWebElement(self.__driver, list_Type_value, list_Value_value).find_elements(self.__yamlPath, key) # 用於返回webelement對象 Primary.Log.info(self.__yamlPath + "中獲取到該element,經過該key:" + key) else: Primary.Log.error(self.__yamlPath + "中不存在該key:" + key + ":關閉程序") # self.__driver.quit() # 判斷輸入的值是否正確,正確則正確找到,不然就報空 booleanfind = False element = None # 當沒有設備屬性值時用元素的text值 if attributename is None: for webelement in list_keyelements: if webelement.text == strtext: element = webelement booleanfind = True break # 當設備屬性值時用元素的指定的屬性值的內容 else: for webelement in list_keyelements: if webelement.get_attribute(attributename) == strtext: element = webelement booleanfind = True break if booleanfind: return element else: Primary.Log.error(self.__yamlPath + "中未找到對應的元素值,請確認" + strtext + "的正確") return element def waitgetelement(self, key) -> WebElement: """ 經過yaml文件的key獲取到對應的Webelement,加入了顯示等待,WeblEment.is_displayed()爲真時返回該該webElement :param key: yaml文件的key :return: 對應的WebElement對象 """ try: inttime = Primary.readini.getvalue("webdriver", "implicit_waitTime") WebDriverWait(self, int(inttime)).until(lambda x: x.getelement(key).is_displayed()) return self.getelement(key) except Exception as e: Primary.Log.error(self.__yamlPath + "中該元素不存在:" + key + "致使錯誤:" + e.__str__()) return None # self.__driver.quit() def waitgetelements(self, key) -> list: """ 經過yaml文件的key獲取到對應的Webelement,加入了顯示等待,WeblEment.is_displayed()爲真時返回該該webElement :param key: yaml文件的key :return: 對應的WebElement對象 """ try: inttime = Primary.readini.getvalue("webdriver", "implicit_waitTime") WebDriverWait(self, int(inttime)).until(lambda x: x.getelement(key).is_displayed()) return self.getelements(key) except Exception as e: Primary.Log.error(self.__yamlPath + "中該元素不存在:" + key + "致使錯誤:" + e.__str__()) return None # self.__driver.quit() def waitgetelement_clickable(self, key) -> WebElement: """ 經過yaml文件的key獲取到對應的Webelement,當元素能夠點擊時返回webelement :param key: yaml文件的key :return: 對應的WebElement對象 :rtype keyelement: selenium.webdriver.remote.webelement """ dic = ReadyamlToElement(self.__driver, self.__yamlPath).__getAllValue() # 接受readyaml().getAllValue()返回的dict if key in dic: list_value = dic.get(key) list_Type_value = list_value.get("Type") # 獲取type的值 list_Value_value = list_value.get("Value") # 獲取value的值 try: # 顯式等待時間 inttime = Primary.readini.getvalue("webdriver", "implicit_waitTime") # 配合expected_conditions當元素能夠點擊時返回element elemnet = WebDriverWait(self.__driver, int(inttime)).until(EC.element_to_be_clickable(( FindBy(list_Type_value).find_by(), list_Value_value)), (self.__yamlPath + "中No such element : 請檢查該‘" + key + "’對應下的Value值是否能在頁面上定位成功")) return elemnet except TimeoutException as e: Primary.Log.error(e.__str__()) return None def getlocator(self, key) -> tuple: """ 返回location 元組類型的值,主要給EC模塊入參使用 :param key : yaml文件的key :return: tup_locator 元組類型的值如(By.Id,"value") :rtype tup_locator : tuple """ dic = ReadyamlToElement(self.__driver, self.__yamlPath).__getAllValue() # 接受readyaml().getAllValue()返回的dict if key in dic: list_value = dic.get(key) # list_Type_value = list_value[0].split(":")[1] #獲取type的值 # list_Value_value = list_value[1].split(":")[1] #獲取value的值 list_Type_value = list_value.get("Type") # 獲取type的值 list_Value_value = list_value.get("Value") # 獲取value的值 tup_locator = (FindBy(list_Type_value).find_by(), list_Value_value) if len(tup_locator) is None: Primary.Log.error(self.__yamlPath + "中請檢查該‘" + key + "’的值是否正確") return None else: return tup_locator yaml文件格式樣例 # -*- coding:utf-8 -*- # explain : 登陸頁面的元素定位 #Type : id, name, class, tag, link, plink, css, xpath #登陸用戶名輸入框 login_username : # ReadyamlToElement類對象方法的實參 Type : css # 八大定位方式 Value : i.iconfont.icon-login+span+label>input # 定位值
說明:須要三個主要方法來實現WebElement對象的值 css