Files
qiaoxinjiu 6994b185a3 addproject
2026-01-22 19:10:37 +08:00

504 lines
22 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- 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 | 浏览器模式webweb模式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()