您的当前位置:首页python页面基类Page封装→driver层的封装(最底层的封装Page)

python页面基类Page封装→driver层的封装(最底层的封装Page)

2021-11-18 来源:乌哈旅游
python页⾯基类Page封装→driver层的封装(最底层的封装

Page)

# coding=utf-8import time

from selenium.common.exceptions import NoSuchElementExceptionfrom selenium.webdriver import ActionChains

from selenium.webdriver.common.keys import Keysfrom selenium.webdriver.support.select import Select

from selenium.webdriver.support.wait import WebDriverWait

from Common.LoggerBase import Logger # ⾃⼰封装的logger类from pathlib import *

'''--create a logger instance--'''Logger = Logger()

class BasePage(object): \"\"\"

定义⼀个页⾯基类,让所有页⾯都继承这个类,封装⼀些常⽤的页⾯操作⽅法到这个类 \"\"\"

'''--初始化--'''

def __init__(self, driver): self.driver = driver self.timeout = 10

self.poll_frequency = 0.5 '''--定义open⽅法--''' def open(self, url):

self.driver.maximize_window() self.driver.get(url)

'''--quit browser and end testing--''' def quit_browser(self): self.driver.quit()

'''--浏览器前进操作--''' def forward(self):

self.driver.forward()

Logger.info(\"Click forward on current page.\") '''--浏览器后退操作--''' def back(self):

self.driver.back()

Logger.info(\"Click back on current page.\") '''--隐式等待--'''

def wait(self, seconds):

self.driver.implicitly_wait(seconds)

Logger.info(\"wait for %d seconds.\" % seconds)

'''--点击关闭当前窗⼝--''' def close(self): try:

self.driver.close()

Logger.info(\"Closing and quit the browser.\") except NameError as e:

Logger.error(\"Failed to quit the browser with %s\" % e)

'''--保存图⽚--'''

def get_windows_img(self): \"\"\"

在这⾥我们把file_path这个参数写死,直接保存到我们项⽬根⽬录的⼀个⽂件夹.\\Screenshots下 \"\"\"

file_path = Path(Path.cwd().parent) / 'Screenshots'

rq = time.strftime('%Y%m%d%H%M', time.localtime(time.time())) screen_name = Path.joinpath(file_path, rq + '.png') try:

self.driver.get_screenshot_as_file(str(screen_name))

Logger.info(\"Had take screenshot and save to folder : /Screenshots\") except NameError as e:

Logger.error(\"Failed to take screenshot! %s\" % e) self.get_windows_img()

'''--重写定位元素⽅法--'''

def find_element(self, selector): \"\"\"

这个地⽅为什么是根据=>来切割字符串,请看页⾯⾥定位元素的⽅法 submit_btn = \"id=>su\"

login_lnk = \"xpath => //*[@id='u1']/a[7]\" # 百度⾸页登录链接定位

如果采⽤等号,结果很多xpath表达式中包含⼀个=,这样会造成切割不准确,影响元素定位

:param selector: :return: element \"\"\"

element = ''

if '=>' not in selector:

Logger.info(\"Not found '=>', default is ID\") return self.driver.find_element_by_id(selector) selector_by = selector.split('=>')[0] selector_value = selector.split('=>')[1]

if selector_by == \"i\" or selector_by == 'id': try:

element = self.driver.find_element_by_id(selector_value) Logger.info(\"Had find the element \\\" %s \\\" successful \"

\"by %s via value: %s \" % (element.text, selector_by, selector_value)) except NoSuchElementException as e:

Logger.error(\"NoSuchElementException: %s\" % e) self.get_windows_img() # take screenshot

elif selector_by == \"n\" or selector_by == 'name': try:

element = self.driver.find_element_by_name(selector_value) Logger.info(\"Had find the element \\\" %s \\\" successful \"

\"by %s via value: %s \" % (element.text, selector_by, selector_value)) except NoSuchElementException as e:

Logger.error(\"NoSuchElementException: %s\" % e) self.get_windows_img()

elif selector_by == \"c\" or selector_by == 'class_name': try:

element = self.driver.find_element_by_class_name(selector_value) Logger.info(\"Had find the element \\\" %s \\\" successful \"

\"by %s via value: %s \" % (element.text, selector_by, selector_value)) except NoSuchElementException as e:

Logger.error(\"NoSuchElementException: %s\" % e)

elif selector_by == \"l\" or selector_by == 'link_text': try:

element = self.driver.find_element_by_link_text(selector_value) Logger.info(\"Had find the element \\\" %s \\\" successful \"

\"by %s via value: %s \" % (element.text, selector_by, selector_value)) except NoSuchElementException as e:

Logger.error(\"NoSuchElementException: %s\" % e)

elif selector_by == \"p\" or selector_by == 'partial_link_text': try:

element = self.driver.find_element_by_partial_link_text(selector_value) Logger.info(\"Had find the element \\\" %s \\\" successful \"

\"by %s via value: %s \" % (element.text, selector_by, selector_value)) except NoSuchElementException as e:

Logger.error(\"NoSuchElementException: %s\" % e)

elif selector_by == \"t\" or selector_by == 'tag_name': try:

element = self.driver.find_element_by_tag_name(selector_value) Logger.info(\"Had find the element \\\" %s \\\" successful \"

\"by %s via value: %s \" % (element.text, selector_by, selector_value)) except NoSuchElementException as e:

Logger.error(\"NoSuchElementException: %s\" % e)

elif selector_by == \"x\" or selector_by == 'xpath': try:

element = self.driver.find_element_by_xpath(selector_value) Logger.info(\"Had find the element \\\" %s \\\" successful \"

\"by %s via value: %s \" % (element.text, selector_by, selector_value)) except NoSuchElementException as e:

Logger.error(\"NoSuchElementException: %s\" % e) self.get_windows_img()

elif selector_by == \"s\" or selector_by == 'selector_selector': try:

element = self.driver.find_element_by_css_selector(selector_value) Logger.info(\"Had find the element \\\" %s \\\" successful \"

\"by %s via value: %s \" % (element.text, selector_by, selector_value)) except NoSuchElementException as e:

Logger.error(\"NoSuchElementException: %s\" % e)

else:

raise NameError(\"Please enter a valid type of targeting elements.\") return element

'''--输⼊--'''

def input_text(self, selector, text):

el = self.find_element(selector) try:

el.send_keys(text)

Logger.info(\"Had type \\\" %s \\\" in inputBox\" % text) except NameError as e:

Logger.error(\"Failed to type in input box with %s\" % e) self.get_windows_img()

'''--清除⽂本框--'''

def clear(self, selector):

el = self.find_element(selector) try:

el.clear()

Logger.info('Clear text in input box before typing') except NameError as e:

Logger.error(\"Failed to clear in input box with %s\" % e) self.get_windows_img()

'''--点击元素--'''

def click(self, selector):

el = self.find_element(selector) try:

el.click()

Logger.info(\"The element \\\" %s \\\" was clicked.\" % el) except NameError as e:

Logger.error(\"Failed to click the element with %s\" % e) '''--获取⽹页标题--'''

def get_page_title(self):

Logger.info(\"Current page title is %s\" % self.driver.title) return self.driver.title

def send_key(self, locator, value): \"\"\"

@param locator: 定位器 @param value: value \"\"\"

elem = self.find_element(locator) try:

elem.send_keys(value)

Logger.info(\"元素对象输⼊值成功,值为:{}\".format(value)) except Exception as e:

Logger.error(\"元素对象输⼊值失败,错误信息为:{}\".format(e)) def get_text(self, locator): \"\"\"

@param locator:定位器 @return:元素⽂本值 \"\"\"

elem_text = None

elem = self.find_element(locator) try:

elem_text = elem.text except Exception as e:

Logger.error(\"元素text获取失败,错误信息为:{}\".format(e)) Logger.info(\"元素text值:{}\".format(elem_text)) return elem_text

'''--重写跳转switch_to_frame⽅法''' def switch_to_frame(self, selector): \"\"\"

:param selector: 传⼊定位器参数 :return: \"\"\"

elem = self.find_element(selector) try:

self.driver.switch_to.frame() Logger.info(\"frame切换成功\") except Exception as e:

Logger.error(\"frame切换失败,错误信息为:{}\".format(e)) '''--切回⽗级frame--'''

def turn_back_frame(self):

self.driver.switch_to.default_content() def switch_to_handle(self, index): \"\"\"

切换窗⼝句柄 \"\"\"

# 获取当前所有窗⼝句柄 global handles try:

handles = self.driver.window_handles

Logger.info(\"获取当前所有窗⼝句柄成功,句柄对象列表为:{}\".format(handles)) except Exception as e:

Logger.error(\"获取当前所有窗⼝句柄失败,错误信息为:{}\".format(e)) # 切换到新窗⼝句柄 try:

self.driver.switch_to.window(handles[index])

Logger.info(\"切换新窗⼝句柄成功,切换窗⼝的索引index为:{}\".format(index)) except Exception as e:

Logger.error(\"切换新窗⼝句柄失败,错误信息为:{}\".format(e))

\"\"\"--多选、单选元素获取⽅法--\"\"\"

def select_by_text(self, selectByText): if selectByText is not \"\":

select_by_text = self.find_element(\"xpath=>//*[text()=\\\"%s\\\"]\" % selectByText) select_by_text.click() else:

print(\"Not find the selectByText, get the default value!\") pass

def move_mouse_to_element(self, locator): \"\"\"

移动⿏标到某个元素上⾯ @param locator: @return: \"\"\"

elem = self.find_element(locator) action = ActionChains(self.driver)

action.move_to_element(elem).perform() def clear_input_value(self, locator): \"\"\"

清除输⼊框中的内容 @param locator: @return: \"\"\"

elem = self.find_element(locator)

elem.send_keys(Keys.CONTROL, \"a\") elem.send_keys(Keys.DELETE) def get_value(self, locator): \"\"\"

获取输⼊框的value @param locator: @return: \"\"\"

elem = self.find_element(locator) return elem.get_attribute(\"value\")

def double_click_elem(self, locator): \"\"\"

双击元素

@param locator: @return: \"\"\"

elem = self.find_element(locator)

ActionChains(self.driver).double_click(elem).perform() def elem_is_display(self, locator): \"\"\"

判断元素在页⾯是否显⽰,显⽰返回True,不显⽰返回false @param locator: @return: \"\"\"

elem = self.find_element(locator) return elem.is_displayed()

def elem_is_selected(self, locator): \"\"\"

判断元素是否被选中,⽤于多选框,如果多选框被选中状态,返回True,否则返回False @param locator: @return: \"\"\"

elem = self.find_element(locator) return elem.is_selected()

def elem_is_enable(self, locator): \"\"\"

判断页⾯元素是否可⽤ @param locator: @return: \"\"\"

elem = self.find_element(locator)

Logger.info(\"按钮的点击状态,是否可点击:{}\".format(elem.is_enabled())) return elem.is_enabled()

def choose_select_by_value(self, locator, value): \"\"\"

根据内置属性value值,选择下拉输⼊框 @param locator: @param value: @return: \"\"\"

elem = self.find_element(locator) Select(elem).select_by_value(value)

def choose_select_by_index(self, locator, index): \"\"\"

根据索引选择下拉框 @param locator: @param index: @return: \"\"\"

elem = self.find_element(locator) Select(elem).select_by_index(index)

def choose_select_by_visible_value(self, locator, value): \"\"\"

根据下拉选项的⽂本值选择下拉框 @param locator: @param value: @return: \"\"\"

elem = self.find_element(locator)

Select(elem).select_by_visible_text(value) def elem_object_click(self, elem): \"\"\"

元素点击,传⼊参数为元素对象 @param elem: @return: \"\"\"

elem.click()

def find_elements(self, selector): \"\"\"

:param selector: 传⼊定位器参数locator => 标识切割 :return: 返回元素对象列表 \"\"\"

Logger.info(\"输出定位器信息:{}\".format(selector)) element = ''

if '=>' not in selector:

Logger.info(\"Not found '=>', default is ID\") return self.driver.find_element_by_id(selector) selector_by = selector.split('=>')[0] selector_value = selector.split('=>')[1]

if selector_by is None and selector_value is None:

Logger.error('find_elements:selector_by and selector_value is empty:,Please pass the correct value)') else:

Logger.info(\"find_elements:正在定位元素信息:定位⽅式->%s,value值->%s\" % (selector_by, selector_value)) try:

time.sleep(1)

elems = WebDriverWait(self.driver, self.timeout, self.poll_frequency).until( lambda x: x.find_elements(*selector)) Logger.info(\"元素对象为:{}\".format(elems)) return elems

except Exception as e:

Logger.error(\"定位不到元素,错误信息为:{}\".format(e)) return False

def choose_elem_by_visible_value(self, locator, value): \"\"\"

根据⼀组元素对象中某⼀个元素对象的⽂本值确定,哪⼀个元素对象 @param locator: @param value:

@return: 单个元素对象 \"\"\"

elems = self.find_elements(locator) for item in elems:

if self.elem_object_get_text(item) == value: return item

def elem_object_get_text(self, elem): \"\"\"

元素对象获取text值,传⼊元素对象 @param elem: @return:

\"\"\"

elem_text = elem.text return elem_text

def get_text_by_elements(self, locator, index): \"\"\"

@param locator: 定位器

@return: 返回定位对象组的第⼀个元素的值 \"\"\"

global elem_text

elem = self.find_elements(locator) try:

elem_text = elem[index].text

Logger.info(\"获取元素组对象,索引位置{}的值成功,值为:{}\".format(index, elem_text)) except Exception as e:

Logger.error(\"获取元素组对象,索引位置{}的值失败,失败信息为: {}\".format(e, e)) return elem_text

'''--静态⽅法--''' @staticmethod def sleep(seconds): time.sleep(seconds)

Logger.info(\"Sleep for %d seconds\" % seconds)

因篇幅问题不能全部显示,请点此查看更多更全内容