import importlib
|
import time
|
|
from selenium.common import StaleElementReferenceException, ElementClickInterceptedException
|
from selenium.webdriver.remote.webelement import WebElement
|
from selenium.webdriver.support.wait import WebDriverWait
|
from selenium.webdriver.support import expected_conditions as EC
|
from selenium.webdriver.remote.webdriver import WebDriver
|
|
SimpleActions = ['clear()', 'send_keys()', 'click()', 'submit()', 'size', 'text', 'is_displayed()', 'get_attribute()']
|
complexActions = ['iframe()', 'select()', 'option()']
|
|
# 默认超时时间10秒
|
DEFAULT_TIMEOUT = 10
|
# 默认重试次数
|
DEFAULT_RETRY = 30
|
|
|
class BasePage:
|
|
retry_number = 0
|
|
# 初始化方法
|
def __init__(self, driver: WebDriver):
|
"""构造方法,传入webdriver"""
|
self.driver = driver
|
|
# def _get_page_elem(self, elem):
|
# """获取定位元素的by,以及操作action"""
|
# for each in self.elements:
|
# if each['name'] == elem:
|
# self.loc = each['loc']
|
# if each['action'] is not None:
|
# self.action = each['action']
|
# else:
|
# self.action = None
|
# if 'optionsLoc' in each:
|
# self.optionsLoc = each['optionsLoc']
|
# else:
|
# self.optionsLoc = None
|
# if 'wait' in each:
|
# self.wait = each['wait']
|
# else:
|
# self.wait = None
|
#
|
# def oper_elem(self, elem, args=None):
|
# self._get_page_elem(elem)
|
# cmd = self._selenium_cmd('find_element', args)
|
# return eval(cmd)
|
#
|
# def oper_elems(self, elem, args=None):
|
# self._get_page_elem(elem)
|
# cmd = self._selenium_cmd('find_elements', args)
|
# return eval(cmd)
|
#
|
# def _selenium_cmd(self, find_type='find_element', args=None):
|
# """拼接selenium查找命令,查找单个元素时find为'find_element',多个元素时为'find_elements'"""
|
# cmd = 'self.driver.' + find_type + '(*self.loc)'
|
# if self.action:
|
# cmd = 'self.' + self.action
|
# if args:
|
# cmd = cmd[:-1] + 'args' + ')'
|
# return cmd
|
#
|
# def iframe(self):
|
# self.driver.switch_to.frame(self.driver.find_element(*self.loc))
|
#
|
# def click(self):
|
# if self.wait:
|
# wait = WebDriverWait(self.driver, self.wait, 0.5)
|
# wait.until(EC.presence_of_element_located(self.loc)).click()
|
# else:
|
# self.driver.find_element(*self.loc).click()
|
#
|
# # 使用js语句点击
|
# def click_js(self):
|
# item = self.driver.find_element(*self.loc)
|
# self.driver.execute_script("arguments[0].click();", item)
|
#
|
# def send_keys(self, text):
|
# wait = WebDriverWait(self.driver, 10, 0.5)
|
# wait.until(EC.presence_of_element_located(self.loc)).send_keys(text)
|
#
|
# def text(self):
|
# wait = WebDriverWait(self.driver, 10, 0.5)
|
# return wait.until(EC.presence_of_element_located(self.loc)).text
|
#
|
def select(self, select_loc, options_loc, item):
|
"""
|
选择传入的选项
|
:param select_loc: 选择框定位
|
:param options_loc: 选项定位
|
:param item: 选项
|
:return:
|
"""
|
# 点击选择框对象
|
self.click(select_loc, timeout=10)
|
# 获取所有选项
|
options = self.get_eles(options_loc, timeout=10)
|
for option in options:
|
if option.text == item:
|
option.click()
|
break
|
#
|
# def value_js(self):
|
# """
|
# 使用js语句获取value值
|
# :return:
|
# """
|
# # 等待对象
|
# wait = WebDriverWait(self.driver, 10, 0.5)
|
# input_box = wait.until(EC.presence_of_element_located(self.loc))
|
# input_value = self.driver.execute_script("return arguments[0].value", input_box)
|
# return input_value
|
#
|
# def option(self, text):
|
# """
|
# 点击传入的选项
|
# :param text:
|
# :return:
|
# """
|
# wait = WebDriverWait(self.driver, 10, 0.5)
|
# wait.until(EC.presence_of_all_elements_located(self.loc))
|
# options = self.driver.find_elements(*self.loc)
|
# for option in options:
|
# if option.text == text:
|
# option.click()
|
|
# 元素定位
|
|
def goto(self, url):
|
"""访问url"""
|
self.driver.get(url)
|
|
def get_ele(self, loc, timeout=None) -> WebElement:
|
"""
|
获取元素
|
:param loc: 元素定位
|
:param timeout: 超时时间
|
:return:
|
"""
|
if timeout:
|
return self.wait_visible(loc, timeout)
|
else:
|
return self.driver.find_element(*loc)
|
|
def get_eles(self, loc, timeout=None):
|
"""
|
获取多个元素
|
:param loc: 元素定位
|
:param timeout: 超时时间
|
:return:
|
"""
|
if timeout:
|
return self.wait_visible(loc, timeout=timeout, find_type="elements")
|
else:
|
return self.driver.find_elements(*loc)
|
|
def clear(self, loc, timeout=None):
|
"""
|
清除文本框内容
|
:param loc:
|
:param timeout:
|
:return:
|
"""
|
ele = self.get_ele(loc, timeout=timeout)
|
ele.clear()
|
|
def fill(self, loc, text, timeout=None):
|
"""页面输入"""
|
|
ele = self.get_ele(loc, timeout=timeout)
|
# 先清除文本框内容
|
ele.clear()
|
# 填写内容
|
ele.send_keys(text)
|
|
def wait_visible(self, loc, timeout=DEFAULT_TIMEOUT, find_type="element") -> WebElement:
|
"""
|
等待元素可见
|
:param loc: 元素定位
|
:param timeout: 等待时间
|
:param find_type: 等待元素的类型
|
:return:
|
"""
|
wait = WebDriverWait(self.driver, timeout=timeout)
|
element = None
|
if find_type == "element":
|
element = wait.until(EC.visibility_of_element_located(loc))
|
elif find_type == "elements":
|
element = wait.until(EC.visibility_of_all_elements_located(loc))
|
return element
|
|
def click(self, loc, timeout=None):
|
"""
|
点击元素
|
:param loc: 元素定位
|
:param timeout: 超时时间
|
:return:
|
"""
|
try:
|
if timeout:
|
ele = self.wait_clickable(loc, timeout=timeout)
|
ele.click()
|
else:
|
ele = self.driver.find_element(*loc)
|
ele.click()
|
self.retry_number = 0
|
except (StaleElementReferenceException, ElementClickInterceptedException):
|
if self.retry_number >= DEFAULT_RETRY:
|
return
|
time.sleep(1)
|
self.retry_number += 1
|
self.click(loc, timeout=timeout)
|
|
def click_js(self, loc, timeout=None):
|
"""
|
JavaScript点击元素
|
:param loc:
|
:param timeout:
|
:return:
|
"""
|
item = self.get_ele(loc, timeout=timeout)
|
self.driver.execute_script("arguments[0].click();", item)
|
|
def wait_clickable(self, loc, timeout=DEFAULT_TIMEOUT) -> WebElement:
|
"""
|
等待元素可点击
|
:param loc: 元素定位
|
:param timeout: 超时时间
|
:return:
|
"""
|
wait = WebDriverWait(self.driver, timeout=timeout)
|
element = wait.until(EC.element_to_be_clickable(loc))
|
return element
|
|
def equals(self, loc, text):
|
"""
|
判断元素的value或者text是否与text相等
|
:param loc:
|
:param text:
|
:return:
|
"""
|
# 先获取value
|
ele_value = self.get_ele(loc, timeout=10).get_attribute("value")
|
# 如果为None则通过value_js获取value值
|
if not ele_value:
|
ele_value = self.get_value_js(loc, timeout=10)
|
# 如果还为空则获取text
|
if not ele_value:
|
ele_value = self.get_ele(loc, timeout=10).text
|
return ele_value == text
|
|
def contains(self, loc, text):
|
"""
|
判断元素的value或者text包含text
|
:param loc:
|
:param text:
|
:return:
|
"""
|
# 先获取value
|
ele_value = self.get_ele(loc).get_attribute("value")
|
# 如果为None则通过value_js获取value值
|
if not ele_value:
|
ele_value = self.get_value_js(loc)
|
# 如果还为空则获取text
|
if not ele_value:
|
ele_value = self.get_ele(loc).text
|
return text in ele_value
|
|
# 多个元素定位
|
def get_elements_wait(self, locator):
|
wait = WebDriverWait(self.driver, 10, 0.5)
|
wait.until(EC.presence_of_element_located(locator))
|
return self.driver.find_elements(*locator)
|
|
# 在指定元素中定位元素
|
def get_element_in(self, element, locator):
|
return element.find_element(*locator)
|
|
# 在指定元素中定位多个元素
|
def get_elements_in(self, element, *locator):
|
return element.find_elements(*locator)
|
|
# 元素定位
|
def get_element_wait(self, locator):
|
wait = WebDriverWait(self.driver, 10, 0.5)
|
wait.until(EC.presence_of_element_located(locator))
|
return self.driver.find_element(*locator)
|
|
def click_js_wait(self, *locator):
|
item = self.get_element_wait(*locator)
|
self.driver.execute_script("arguments[0].click();", item)
|
|
def click_element_js(self, element):
|
"""
|
使用js点击元素
|
:param element: 要点击的元素
|
:return:
|
"""
|
self.driver.execute_script("arguments[0].click();", element)
|
|
# # 点击
|
# def click(self, locator):
|
# """
|
# 点击元素
|
# :param locator: 元素定位
|
# :return:
|
# """
|
# self.get_element(locator).click()
|
|
def click_wait(self, *locator):
|
self.get_element_wait(*locator).click()
|
|
# # 输入
|
# def fill(self, text, locator):
|
# """
|
# 输入内容
|
# :param text: 内容
|
# :param locator: 元素定位
|
# :return:
|
# """
|
# self.get_element(locator).send_keys(text)
|
|
def send_text_wait(self, text, *locator):
|
self.get_element_wait(*locator).send_keys(text)
|
|
def get_value_js(self, loc, timeout=None):
|
"""
|
执行JavaScript获取value值
|
:param timeout:
|
:param loc:
|
:return:
|
"""
|
ele = self.get_ele(loc, timeout=timeout)
|
value = self.driver.execute_script("return arguments[0].value", ele)
|
return value
|
|
def get_input_value_js_wait(self, *locator):
|
input_box = self.get_element_wait(*locator)
|
input_value = self.driver.execute_script("return arguments[0].value", input_box)
|
return input_value
|
|
# 清除
|
def clear_text(self, *locator):
|
self.get_element(*locator).clear()
|
|
def clear_text_wait(self, *locator):
|
self.get_element_wait(*locator).clear()
|
|
# 表单切换
|
def switch_iframe(self, loc):
|
"""
|
切换表单
|
:param loc: 表单定位
|
:return:
|
"""
|
# 获取到iframe元素
|
iframe = self.get_ele(loc, timeout=10)
|
self.driver.switch_to.frame(iframe)
|
|
def switch_parent_iframe(self):
|
"""
|
切换到上一层的iframe
|
:return:
|
"""
|
self.driver.switch_to.parent_frame()
|
|
def switch_iframe_wait(self, locator):
|
self.driver.switch_to.frame(self.get_element_wait(locator))
|
|
# 窗口切换
|
def switch_window(self, n):
|
self.driver.switch_to.window(self.driver.window_handles[n])
|
|
# 检查元素是否可见可点击
|
def check_clickable(self, *locator):
|
wait = WebDriverWait(self.driver, 10, 0.5)
|
try:
|
e = wait.until(EC.element_to_be_clickable(locator))
|
if e is not None:
|
return True
|
except:
|
pass
|
return False
|
|
# 等待元素出现
|
def wait_appear(self, *locator):
|
wait = WebDriverWait(self.driver, 10, 0.5)
|
try:
|
e = wait.until(EC.presence_of_element_located(locator))
|
if e is not None:
|
return True
|
except:
|
pass
|
return False
|
|
# 滑动页面
|
def scroll_by(self, num):
|
self.driver.execute_script("window.scrollBy(0, " + num + ");")
|
|
# 滑动到底部
|
def scroll_to_bottom(self):
|
self.driver.execute_script("window.scrollBy(0,document.body.scrollHeight);")
|
|
# 滑动到顶部
|
def scroll_to_top(self):
|
self.driver.execute_script("window.scrollBy(0,0);")
|
|
# 截取当前窗口保存为图片
|
def get_png(self):
|
"""截取当前窗口保存为图片"""
|
return self.driver.get_screenshot_as_png()
|
|
def goto_new_table(self, url):
|
"""
|
打开一个新的标签页,并跳转到指定的url
|
:return:
|
"""
|
# 打开新标签页
|
self.driver.execute_script("window.open()")
|
# 切换到新的标签页
|
self.switch_window(-1)
|
# 在新标签页中加载指定url
|
self.driver.get(url)
|
|
def elements_is_visibility(self, locator):
|
"""
|
判断是否至少有一个元素在页面中可见
|
:param locator:
|
:return:
|
"""
|
wait = WebDriverWait(self.driver, 10, 0.5)
|
return wait.until(EC.visibility_of_any_elements_located(locator))
|
|
def add_elements(self, ele):
|
"""
|
在elements中新增元素
|
:param ele:
|
:return:
|
"""
|
self.elements.append(ele)
|
|
|
def get_page_elements(page):
|
"""
|
动态加载页面定义文件,获取文件中定义的元素列表elements
|
:param page:
|
:return:
|
"""
|
elements = None
|
if page:
|
try:
|
m = importlib.import_module(page)
|
elements = m.elements
|
except Exception as e:
|
pass
|
return elements
|