504 lines
22 KiB
Python
504 lines
22 KiB
Python
# -*- coding: UTF-8 -*-
|
||
import os
|
||
import time
|
||
import platform
|
||
from selenium import webdriver
|
||
from selenium.webdriver.support.wait import WebDriverWait
|
||
from selenium.webdriver.support import expected_conditions as ec
|
||
from selenium.webdriver.common.keys import Keys
|
||
from selenium.webdriver.common.by import By
|
||
from selenium.webdriver import ActionChains
|
||
from selenium.webdriver.support.select import Select
|
||
from base_framework.public_tools.read_config import get_current_config
|
||
|
||
cull_path = os.path.dirname(os.path.abspath(__file__))
|
||
plugs = os.path.abspath(os.path.join(cull_path, '../{}'.format('/platform_tools/plugins/headerenv.crx')))
|
||
DEFAULT_TIMEOUT = 5
|
||
|
||
|
||
class SeleniumWebUI:
|
||
def __init__(self):
|
||
self.driver = None
|
||
self.action = None # 用于鼠标类事件
|
||
self.business = get_current_config(section="run_evn_name", key="current_business")
|
||
self.jira_id = get_current_config(section="run_jira_id", key="huohua-podenv")
|
||
self.feature = get_current_config(section="run_jira_id", key="huohua-feature")
|
||
# print(self.jira_id)
|
||
|
||
def web_open_browser(self, url="", browser_type="chrome", enable_image=True, station='web'):
|
||
"""
|
||
| 功能说明: | 打开浏览器,默认chrome |
|
||
| 输入参数: | url | 网址,默认为空:仅打开浏览器 |
|
||
| | browser_type | 浏览器类型:chrome,firefox,edge |
|
||
| | enable_image | 浏览器是否加载图片 |
|
||
| | station | 浏览器模式:web:web模式,m:手机模式 |
|
||
| 作者信息: | 谢祥益 | 2022.06.01 |
|
||
"""
|
||
if browser_type == "chrome":
|
||
options = webdriver.ChromeOptions()
|
||
if platform.system() == 'Linux':
|
||
default_driver_path = r'/home/chrome_home/chromedriver'
|
||
options.add_argument("--headless")
|
||
options.add_argument("--no-sandbox")
|
||
options.add_argument('--disable-gpu')
|
||
options.add_argument('--disable-dev-shm-usage')
|
||
self.driver = webdriver.Chrome(executable_path=default_driver_path, options=options)
|
||
else:
|
||
# 将正确的chrome driver版本放在python根目录下
|
||
options.add_extension(plugs)
|
||
if not enable_image:
|
||
options.add_argument('blink-settings=imagesEnabled=false')
|
||
print('当前为无图片模式')
|
||
if station == 'm':
|
||
options.add_experimental_option('mobileEmulation', {'deviceName': 'iPhone 12 Pro'})
|
||
self.driver = webdriver.Chrome(options=options)
|
||
elif browser_type == "firefox":
|
||
self.driver = webdriver.Firefox()
|
||
elif browser_type == "edge":
|
||
self.driver = webdriver.Edge()
|
||
else:
|
||
raise Exception("传入的浏览器类型不正确,正确的浏览器类型(chrome, firefox, edge)")
|
||
if len(url) > 0:
|
||
self.web_open_url(url=url)
|
||
self.action = ActionChains(self.driver)
|
||
|
||
def web_open_url(self, url):
|
||
"""
|
||
| 功能说明: | 打开链接并最大化浏览器 |
|
||
| 输入参数: | url | 访问地址 |
|
||
| 作者信息: | 谢祥益 | 2022.06.01 |
|
||
"""
|
||
if not self.driver:
|
||
self.web_open_browser()
|
||
if self.jira_id.lower() not in ('', 'qa'):
|
||
# 判断并添加独立环境
|
||
self.web_set_independent_environment()
|
||
self.driver.maximize_window()
|
||
self.driver.get(url)
|
||
|
||
def web_close_browser(self):
|
||
"""
|
||
| 功能说明: | 关闭浏览器,但注意并没有销毁driver对象 |
|
||
| 输入参数: | 无 |
|
||
| 作者信息: | 谢祥益 at 2022.06.01 |
|
||
举例说明:
|
||
"""
|
||
self.driver.quit()
|
||
|
||
def web_refresh_page(self):
|
||
"""
|
||
| 功能说明: | 刷新浏览器当前页面 |
|
||
| 输入参数: | |
|
||
| 作者信息: | 谢祥益 at 2022.06.01 |
|
||
"""
|
||
self.driver.refresh()
|
||
|
||
def web_switch_handle(self, index):
|
||
"""
|
||
| 功能说明: | 切换浏览器页面标签,适用于新开页面,或多页面操作 |
|
||
| 输入参数: | index | 标签索引 |
|
||
| 作者信息: | 谢祥益 | 2022.06.01 |
|
||
"""
|
||
handles = self.driver.window_handles
|
||
self.driver.switch_to_window(handles[index])
|
||
|
||
def web_get_cookie(self):
|
||
"""
|
||
| 功能说明: | 返回浏览器当前application的cookie |
|
||
| 输入参数: | |
|
||
| 作者信息: | 谢祥益 at 2022.06.01 |
|
||
"""
|
||
return self.driver.get_cookies()
|
||
|
||
def web_find_element(self, locator, timeout=DEFAULT_TIMEOUT, raise_exception=True):
|
||
"""
|
||
| 功能说明: | 传入元素定位器,定位到该元素,返回第一个元素 |
|
||
| 输入参数: | locator | 元素路径 |
|
||
| | timeout | 超时时间,默认10秒 |
|
||
| 作者信息: | 谢祥益 | 2022.06.01 |
|
||
"""
|
||
if not isinstance(locator, tuple):
|
||
locator = (By.XPATH, locator)
|
||
element = WebDriverWait(self.driver, timeout).until(ec.presence_of_element_located(locator),
|
||
message=['The element is not exist,please check....\n'
|
||
'element xpath:{}'.format(locator)
|
||
if raise_exception else None])
|
||
return element
|
||
|
||
def web_find_elements(self, locator, timeout=DEFAULT_TIMEOUT, raise_exception=True):
|
||
"""
|
||
| 功能说明: | 传入元素定位器,定位到该元素,返回所有元素 |
|
||
| 输入参数: | locator | 元素路径 |
|
||
| | timeout | 超时时间,默认10秒 |
|
||
| | raise_exception | 当找不到元素时:True-阻断报错(默认),False-返回空list |
|
||
| 作者信息: | 谢祥益 | 2022.06.01 |
|
||
"""
|
||
if not isinstance(locator, tuple):
|
||
locator = (By.XPATH, locator)
|
||
element = []
|
||
try:
|
||
element = WebDriverWait(self.driver, timeout).until(ec.presence_of_all_elements_located(locator))
|
||
except:
|
||
if raise_exception:
|
||
raise Exception("The element is not exist,please check....\n element xpath:{}".format(locator))
|
||
return element
|
||
|
||
def web_click_element(self, locator, timeout=DEFAULT_TIMEOUT):
|
||
"""
|
||
| 功能说明: | 传入元素定位器,定位到该元素,普通方法点击 |
|
||
| 输入参数: | locator | 元素路径 |
|
||
| | timeout | 超时时间,默认10秒 |
|
||
| 作者信息: | 谢祥益 | 2022.06.01 |
|
||
"""
|
||
element = self.web_find_element(locator, timeout)
|
||
element.click()
|
||
|
||
def web_click_elements(self, locator, timeout=DEFAULT_TIMEOUT):
|
||
"""
|
||
| 功能说明: | 点击所有元素 |
|
||
| 输入参数: | locator | 元素路径 |
|
||
| | timeout | 超时时间,默认10秒 |
|
||
| 作者信息: | 谢祥益 | 2022.06.01 |
|
||
"""
|
||
elements = self.web_find_elements(locator, timeout)
|
||
for element in elements:
|
||
element.click()
|
||
|
||
def web_click_element_by_js(self, locator=None, element=None, timeout=DEFAULT_TIMEOUT):
|
||
"""
|
||
| 功能说明: | 传入元素定位器,定位到该元素,以JS的方式点击 |
|
||
| 输入参数: | locator | 元素路径,当没有element时输入 |
|
||
| | element | 元素对象,当没有locator时输入 |
|
||
| | timeout | 超时时间,默认10秒 |
|
||
| 作者信息: | 谢祥益 | 2022.06.01 |
|
||
"""
|
||
if not element and locator:
|
||
obj = self.web_find_element(locator, timeout)
|
||
self.driver.execute_script("arguments[0].click();", obj)
|
||
elif element and not locator:
|
||
self.driver.execute_script("arguments[0].click();", element)
|
||
else:
|
||
raise Exception('不支持的传参方式,locator和element必须且只能传一个')
|
||
|
||
def web_move_element_to_top(self, locator, timeout=DEFAULT_TIMEOUT):
|
||
"""
|
||
| 功能说明: | 将指定元素滑动到当前页面顶部 |
|
||
| 输入参数: | locator | 元素路径 |
|
||
| | timeout | 超时时间,默认10秒 |
|
||
| 作者信息: | 谢祥益 | 2022.08.12 |
|
||
"""
|
||
element = self.web_find_element(locator, timeout)
|
||
self.driver.execute_script("arguments[0].scrollIntoView();", element)
|
||
|
||
def web_move_element_to_bottom(self, locator, timeout=DEFAULT_TIMEOUT):
|
||
"""
|
||
| 功能说明: | 将指定元素滑动到当前页面底部 |
|
||
| 输入参数: | locator | 元素路径 |
|
||
| | timeout | 超时时间,默认10秒 |
|
||
| 作者信息: | 谢祥益 | 2022.08.12 |
|
||
"""
|
||
element = self.web_find_element(locator, timeout)
|
||
self.driver.execute_script("arguments[0].scrollIntoView(false);", element)
|
||
|
||
def web_move_to_top(self):
|
||
"""
|
||
| 功能说明: | 滑动到当前页面顶部 |
|
||
| 作者信息: | 谢祥益 | 2022.08.12 |
|
||
"""
|
||
self.driver.execute_script("window.scrollTo(document.body.scrollHeight,0)")
|
||
|
||
def web_move_to_bottom(self):
|
||
"""
|
||
| 功能说明: | 滑动到当前页面底部 |
|
||
| 作者信息: | 谢祥益 | 2022.08.12 |
|
||
"""
|
||
self.driver.execute_script("window.scrollTo(0,document.body.scrollHeight)")
|
||
|
||
def web_send_keys(self, locator, text, timeout=DEFAULT_TIMEOUT):
|
||
"""
|
||
| 功能说明: | 传入元素定位器,定位到该元素,清空输入框,写入text |
|
||
| 输入参数: | locator | 元素路径 |
|
||
| | text | 输入内容 |
|
||
| | timeout | 超时时间,默认10秒 |
|
||
| 作者信息: | 谢祥益 | 2022.06.01 |
|
||
"""
|
||
element = self.web_find_element(locator, timeout)
|
||
element.send_keys(Keys.CONTROL, 'a')
|
||
element.send_keys(text)
|
||
|
||
def web_get_element_text(self, locator, timeout=DEFAULT_TIMEOUT):
|
||
"""
|
||
| 功能说明: | 传入元素定位器,定位到该元素,返回该元素的文本值 |
|
||
| 输入参数: | locator | 元素路径 |
|
||
| | timeout | 超时时间,默认10秒 |
|
||
| 作者信息: | 谢祥益 | 2022.06.01 |
|
||
"""
|
||
element = self.web_find_element(locator, timeout)
|
||
return element.text
|
||
|
||
def web_click_single_box(self, locator, timeout=DEFAULT_TIMEOUT):
|
||
"""
|
||
| 功能说明: | 传入单选框元素定位器,定位到该元素,依次点击单选框 |
|
||
| 输入参数: | locator | 元素路径 |
|
||
| | timeout | 超时时间,默认10秒 |
|
||
| 作者信息: | 谢祥益 | 2022.06.01 |
|
||
"""
|
||
elements = self.web_find_elements(locator, timeout)
|
||
for element in elements:
|
||
self.driver.execute_script("arguments[0].click();", element)
|
||
time.sleep(1.5)
|
||
|
||
def web_select_drop_down_box(self, locator, index=0, timeout=DEFAULT_TIMEOUT):
|
||
"""
|
||
| 功能说明: | 传入下拉框定位器,定位到该元素,选择下拉框的第index个选项 |
|
||
| 输入参数: | locator | 元素路径 |
|
||
| | index | 第几个元素的下标 |
|
||
| | timeout | 超时时间,默认10秒 |
|
||
| 作者信息: | 谢祥益 | 2022.06.01 |
|
||
"""
|
||
select = Select(self.web_find_element(locator, timeout))
|
||
select.select_by_index(index)
|
||
|
||
def web_click_checkbox(self, locator, timeout=DEFAULT_TIMEOUT):
|
||
"""
|
||
| 功能说明: | 传入多选框元素定位器,定位到该元素,全选 |
|
||
| 输入参数: | locator | 元素路径 |
|
||
| | timeout | 超时时间,默认10秒 |
|
||
| 作者信息: | 谢祥益 | 2022.06.01 |
|
||
"""
|
||
checkbox = self.web_find_elements(locator, timeout)
|
||
for i in checkbox:
|
||
if not i.is_selected():
|
||
i.click()
|
||
|
||
def web_upload_file(self, locator, path, timeout=DEFAULT_TIMEOUT):
|
||
"""
|
||
| 功能说明: | 传入元素定位器,定位到该元素,传入文件路径,只适用于input标签 |
|
||
| 输入参数: | locator | 元素路径 |
|
||
| | path | 文件完整路径 |
|
||
| | timeout | 超时时间,默认10秒 |
|
||
| 作者信息: | 谢祥益 | 2022.06.01 |
|
||
"""
|
||
element = self.web_find_element(locator, timeout)
|
||
element.send_keys(path)
|
||
|
||
def web_move_windows(self, x=0, y=0):
|
||
"""
|
||
| 功能说明: | 传滑动窗口 |
|
||
| 输入参数: | x | x轴距离 |
|
||
| | y | y轴距离 |
|
||
| 作者信息: | 谢祥益 | 2022.06.01 |
|
||
"""
|
||
self.driver.execute_script("window.scrollBy({},{})".format(x, y))
|
||
|
||
def web_go_to_previous_page(self):
|
||
"""
|
||
| 功能说明: | 返回上一页(浏览器工具栏向左箭头) |
|
||
| 输入参数: | 无 |
|
||
| 作者信息: | 谢祥益 at 2022.06.01 |
|
||
"""
|
||
self.driver.back()
|
||
|
||
def web_go_to_next_page(self):
|
||
"""
|
||
| 功能说明: | 前进一页(浏览器工具栏向右箭头) |
|
||
| 输入参数: | 无 |
|
||
| 作者信息: | 谢祥益 at 2022.06.01 |
|
||
"""
|
||
self.driver.forward()
|
||
|
||
def web_close_current_page(self):
|
||
"""
|
||
| 功能说明: | 关闭当前窗口页面 |
|
||
| 输入参数: | 无 |
|
||
| 作者信息: | 谢祥益 at 2022.06.01 |
|
||
"""
|
||
self.driver.close()
|
||
|
||
def web_get_window_title(self):
|
||
"""
|
||
| 功能说明: | 获取当前浏览器标题 |
|
||
| 输入参数: | 无 |
|
||
| 作者信息: | 谢祥益 at 2022.06.01 |
|
||
"""
|
||
return self.driver.title
|
||
|
||
def web_get_element_attribute_value(self, locator, attr: str, timeout=DEFAULT_TIMEOUT):
|
||
"""
|
||
| 功能说明: | 获取元素属性值 |
|
||
| 输入参数: | locator | 元素路径 |
|
||
| | attr | 属性名 |
|
||
| | timeout | 超时时间,默认10秒 |
|
||
| 作者信息: | 谢祥益 | 2022.06.01 |
|
||
"""
|
||
obj = self.web_find_element(locator, timeout=timeout)
|
||
attr_value = obj.get_attribute(attr)
|
||
return attr_value
|
||
|
||
def web_modify_tag_attribution(self, locator, attr, value, timeout=DEFAULT_TIMEOUT):
|
||
"""
|
||
| 功能说明: | 修改页签属性 |
|
||
| 输入参数: | locator | 元素路径 |
|
||
| | attr | 修改属性名 |
|
||
| | value | 修改后的值 |
|
||
| | timeout | 超时时间,默认10秒 |
|
||
| 作者信息: | 谢祥益 | 2022.06.01 |
|
||
"""
|
||
obj = self.web_find_element(locator, timeout)
|
||
self.driver.execute_script("arguments[0].{attr}={value};".format(attr=attr, value=value), obj)
|
||
|
||
def web_input_to_readonly_tag(self, locator, text, timeout=DEFAULT_TIMEOUT):
|
||
"""
|
||
| 功能说明: | 带只读属性的标签输入 |
|
||
| 输入参数: | locator | 元素路径 |
|
||
| | text | 输入内容 |
|
||
| | timeout | 超时时间,默认10秒 |
|
||
| 作者信息: | 谢祥益 | 2022.06.01 |
|
||
"""
|
||
obj = self.web_find_element(locator, timeout)
|
||
self.driver.execute_script("arguments[0].removeAttribute('readonly');", obj)
|
||
self.web_send_keys(locator=locator, text=text)
|
||
|
||
def web_get_css_property_value(self, locator, css_property, timeout=DEFAULT_TIMEOUT):
|
||
"""
|
||
| 功能说明: | 获取css属性值 |
|
||
| 输入参数: | locator | 元素路径 |
|
||
| | text | 输入内容 |
|
||
| | timeout | 超时时间,默认10秒 |
|
||
| 作者信息: | 谢祥益 | 2022.07.08 |
|
||
"""
|
||
obj = self.web_find_element(locator, timeout)
|
||
value = obj.value_of_css_property(css_property)
|
||
return value
|
||
|
||
def web_take_screenshot(self, save_path, picture_name):
|
||
"""
|
||
| 功能说明: | 截屏浏览器当前页面 |
|
||
| 输入参数: | save_path | 保存地址 |
|
||
| | picture_name | 图片名称 |
|
||
| 作者信息: | 谢祥益 | 2022.06.01 |
|
||
"""
|
||
picture_path = os.path.join(save_path, picture_name + '.png')
|
||
self.driver.get_screenshot_as_file(picture_path)
|
||
|
||
def web_set_independent_environment(self):
|
||
"""
|
||
| 功能说明: | 设置独立环境 |
|
||
| 输入参数: | 无 |
|
||
| 作者信息: | 谢祥益 at 2022.06.01 |
|
||
"""
|
||
# 新增独立环境
|
||
new_loc = ('xpath', '/html/body/div/div[3]/button/div/div/i')
|
||
# 独立环境名称
|
||
rule_name_loc = ('id', 'rule-name')
|
||
# 规则类型
|
||
rule_type_loc = ('xpath', '//*[@id="edit-page"]/div[2]/div[1]/div/div[2]/div[2]/div[2]/div[3]/div')
|
||
# 头名称
|
||
rule_header_name_loc = ('id', 'rule-headerName')
|
||
# 头内容
|
||
rule_header_value_loc = ('id', 'rule-headerValue')
|
||
# 保存
|
||
create_loc = ('xpath', '//*[@id="edit-page"]/div[2]/div[2]/div[2]/div[2]/button/div/div')
|
||
|
||
self.driver.get("chrome-extension://eningockdidmgiojffjmkdblpjocbhgh/options/options.html")
|
||
|
||
if self.jira_id and self.jira_id.lower()!='qa':
|
||
rule_header_name = 'huohua-podenv'
|
||
rule_header_value = self.jira_id
|
||
self.web_click_element(new_loc)
|
||
self.web_send_keys(rule_name_loc, self.jira_id)
|
||
self.web_click_element(rule_type_loc)
|
||
self.web_send_keys(rule_header_name_loc, rule_header_name)
|
||
self.web_send_keys(rule_header_value_loc, rule_header_value)
|
||
self.web_click_element(create_loc)
|
||
rule_header_name = 'huohua-feature'
|
||
rule_header_value = self.feature
|
||
self.web_click_element(new_loc)
|
||
self.web_send_keys(rule_name_loc, "front")
|
||
self.web_click_element(rule_type_loc)
|
||
self.web_send_keys(rule_header_name_loc, rule_header_name)
|
||
self.web_send_keys(rule_header_value_loc, rule_header_value)
|
||
self.web_click_element(create_loc)
|
||
else:
|
||
print("无独立环境!")
|
||
|
||
def web_mouse_move_to_element(self, locator):
|
||
"""
|
||
| 功能 | 移动鼠标到元素位置 |
|
||
| 入参 | locator | 元素xpath路径 |
|
||
| 说明 | 多次刷新页面 | 容易导致此方法失效,慎用... |
|
||
| | 必要时 | 可以尝试直接点击对应控件:web_click_element |
|
||
"""
|
||
self.action.reset_actions()
|
||
obj = self.web_find_element(locator=locator)
|
||
self.action.move_to_element(obj)
|
||
self.action.perform()
|
||
|
||
def web_mouse_click(self):
|
||
"""功能:模拟鼠标点击"""
|
||
self.action.click().perform()
|
||
# self.action.perform()
|
||
|
||
def web_check_element_exist(self, locator, quantity=1):
|
||
"""
|
||
| 功能说明: | 检查页面元素是否存在:0-不存在,1-存在,>1-存在多少个,-1-仅判断存在不判断数量 |
|
||
| 输入参数: | locator | 元素路径 |
|
||
| | quantity | 对应locator的元素有多少个, 传入-1则仅检查存在,不判断数量 |
|
||
| 作者信息: | 吴勇刚 | 2022.08.01 |
|
||
"""
|
||
if int(quantity) == 0: # 当检查元素不存在时,设计设置为2秒
|
||
time_out = 2
|
||
else:
|
||
time_out = DEFAULT_TIMEOUT
|
||
elements = self.web_find_elements(locator=locator, raise_exception=False, timeout=time_out)
|
||
if quantity != -1:
|
||
if len(elements) != int(quantity):
|
||
raise Exception("the element [{}] expect exist {},but current is {}..."
|
||
.format(locator, quantity, len(elements)))
|
||
else:
|
||
if len(elements) == 0:
|
||
raise Exception("the element is not exist:{}...".format(locator))
|
||
|
||
def web_check_element_text(self, locator, exp_text):
|
||
"""
|
||
| 功能说明: | 检查源文本是否正确 | 转为字符串比较 |
|
||
| 输入参数: | locator | 元素路径 |
|
||
| | exp_text | 元素预期文本 |
|
||
| 作者信息: | 吴勇刚 | 2022.08.01 |
|
||
"""
|
||
act_text = self.web_get_element_text(locator=locator)
|
||
if act_text != str(exp_text):
|
||
raise Exception("The element [{}]'s text expect [{}],bug now it's [{}] "
|
||
.format(locator, exp_text, act_text))
|
||
|
||
def web_check_element_attribute(self, locator, attr_name, exp_value):
|
||
"""
|
||
| 功能说明: | 检查元素属性值是否正确 |
|
||
| 输入参数: | locator | 元素路径 |
|
||
| | attr_name | 元素属性名称 |
|
||
| | exp_value | 元素预期属性值 |
|
||
| 作者信息: | 吴勇刚 | 2022.08.01 |
|
||
"""
|
||
act_value = self.web_get_element_attribute_value(locator=locator, attr=attr_name)
|
||
if act_value != exp_value:
|
||
raise Exception("The element [{}] attribute [{}]'s value expect [{}],bug now it's [{}] "
|
||
.format(locator, attr_name, exp_value, act_value))
|
||
|
||
def web_get_current_url(self):
|
||
"""
|
||
| 功能说明: | 检查源文本是否正确 | 转为字符串比较 |
|
||
| 输入参数: | locator | 元素路径 |
|
||
| | exp_text | 元素预期文本 |
|
||
| 作者信息: | 吴勇刚 | 2022.08.01 |
|
||
"""
|
||
current_url = self.driver.current_url
|
||
return current_url
|
||
|
||
|
||
if __name__ == '__main__':
|
||
web_driver = SeleniumWebUI()
|
||
vispark_url = "https://sparkle.qa.huohua.cn/intl/schedule"
|
||
web_driver.web_open_url(url=vispark_url)
|
||
url = web_driver.web_get_current_url()
|
||
print(url)
|
||
web_driver.web_close_browser() |