219 lines
6.5 KiB
Python
219 lines
6.5 KiB
Python
import os
|
||
import sys
|
||
import time
|
||
import random
|
||
from selenium import webdriver
|
||
from selenium.webdriver.chrome.options import Options
|
||
from selenium.webdriver.chrome.service import Service
|
||
from selenium.webdriver.common.by import By
|
||
from selenium.webdriver.common.keys import Keys
|
||
from selenium.webdriver.common.action_chains import ActionChains
|
||
from selenium.webdriver.support import expected_conditions as EC
|
||
from selenium.webdriver.support.wait import WebDriverWait
|
||
|
||
__envset__ = [
|
||
os.environ.get('BROWSER_CHOOSE'),
|
||
os.environ.get('BROWSER_DRIVER'),
|
||
os.environ.get('BROWSER_BINARY')
|
||
]
|
||
__driver__ = webdriver.Chrome
|
||
globals().__setitem__('__driver__', getattr(webdriver, __envset__[0] or 'Chrome')) # 根据环境变量选择要继承并使用的浏览器
|
||
|
||
|
||
# 返回一个WebDriver对象
|
||
class Browser(__driver__):
|
||
def __init__(self, driver=None, binary=None, home=None):
|
||
# 根据环境变量可以指定浏览器驱动和主程序的路径,否则将使用对应浏览器类型的默认值;
|
||
driver = driver or __envset__[1]
|
||
binary = binary or __envset__[2]
|
||
service = Service()
|
||
options = Options()
|
||
if driver:
|
||
service.path = driver
|
||
else:
|
||
service = None
|
||
if binary:
|
||
options.binary_location = binary
|
||
else:
|
||
options = None
|
||
super().__init__(service=service, options=options)
|
||
self.maximize()
|
||
self.implicitly_wait(10)
|
||
home and self.turn(home)
|
||
|
||
@staticmethod
|
||
def wait(sec):
|
||
"""
|
||
强制等待,单位:秒;
|
||
"""
|
||
time.sleep(sec)
|
||
|
||
def turn(self, url=None):
|
||
"""
|
||
跳转新的网址;
|
||
"""
|
||
return self.get(url)
|
||
|
||
def find(self, value):
|
||
"""
|
||
使用XPATH查找元素;
|
||
"""
|
||
return self.find_element(By.XPATH, value)
|
||
|
||
def click(self, ele):
|
||
"""
|
||
调用元素的点击方法;
|
||
"""
|
||
actions = self.action_chains()
|
||
actions.click(ele)
|
||
actions.perform()
|
||
self.wait(0.1)
|
||
|
||
def input(self, ele, content):
|
||
"""
|
||
元素输入内容;
|
||
"""
|
||
actions = self.action_chains()
|
||
actions.send_keys_to_element(ele, content)
|
||
actions.perform()
|
||
self.wait(0.1)
|
||
|
||
def tab_create(self, url=None):
|
||
"""
|
||
打开新的标签页并切换至新标签页;
|
||
"""
|
||
self.switch_to.new_window('tab')
|
||
isinstance(url, str) and self.turn(url)
|
||
|
||
def tab_switch(self, tab):
|
||
"""
|
||
Index 按索引切换标签;
|
||
Previous 切换上一个标签;
|
||
Next 切换下一个标签;
|
||
Start 切换到起始标签;
|
||
End 切换到末尾标签;
|
||
"""
|
||
handles = self.window_handles
|
||
lengths = len(handles)
|
||
current = handles.index(self.current_window_handle)
|
||
if isinstance(tab, int):
|
||
handle = tab
|
||
elif tab == 'Previous':
|
||
handle = (current - 1)
|
||
elif tab == 'Next':
|
||
handle = (current + 1) % lengths
|
||
elif tab == 'Start':
|
||
handle = 0
|
||
elif tab == 'End':
|
||
handle = 0 - 1
|
||
else:
|
||
handle = None
|
||
self.switch_to.window(handles[handle])
|
||
self.wait(0.2)
|
||
|
||
def tab_cancel(self):
|
||
"""
|
||
关闭当前标签页并切换至前一个标签页;
|
||
"""
|
||
handles = self.window_handles
|
||
if len(handles):
|
||
current = handles.index(self.current_window_handle)
|
||
self.close()
|
||
current > 0 and self.switch_to.window(handles[current - 1])
|
||
self.wait(0.2)
|
||
|
||
def tab_cancel_all(self):
|
||
"""
|
||
关闭全部标签页;
|
||
"""
|
||
handles = self.window_handles
|
||
for i in handles:
|
||
self.tab_cancel()
|
||
self.wait(0.2)
|
||
|
||
def frame_switch_to(self, ele_of_frame):
|
||
"""
|
||
浏览器切换到指定框架当中;
|
||
"""
|
||
self.switch_to.frame(ele_of_frame)
|
||
self.wait(0.2)
|
||
|
||
def frame_switch_to_default(self):
|
||
"""
|
||
浏览器切换到默认框架;
|
||
"""
|
||
self.switch_to.default_content()
|
||
self.wait(0.2)
|
||
|
||
def scroll(self):
|
||
"""
|
||
向下滚动一屏;
|
||
"""
|
||
actions = self.action_chains()
|
||
actions.scroll_by_amount(0, self.execute_script('return document.documentElement.clientHeight;'))
|
||
actions.perform()
|
||
self.wait(0.8)
|
||
|
||
def scroll_to(self, pos):
|
||
"""
|
||
Index 滚动到指定位置;
|
||
Top 滚动到顶部;
|
||
Bottom 滚动到底部;
|
||
"""
|
||
if isinstance(pos, int):
|
||
self.execute_script('window.scrollTo(0, arguments[0]);', pos)
|
||
elif pos == 'Top':
|
||
self.execute_script('window.scrollTo(0, 0);')
|
||
elif pos == 'Bottom':
|
||
self.execute_script('window.scrollTo(0, document.body.scrollHeight);')
|
||
else:
|
||
pass
|
||
self.wait(0.8)
|
||
|
||
def scroll_to_element(self, ele):
|
||
"""
|
||
滚动到指定元素位置;
|
||
"""
|
||
actions = self.action_chains()
|
||
actions.scroll_to_element(ele)
|
||
actions.perform()
|
||
self.wait(0.8)
|
||
|
||
def action_chains(self):
|
||
"""
|
||
返回一个动作链对象;
|
||
"""
|
||
actions = ActionChains(self)
|
||
return actions
|
||
|
||
def minimize(self):
|
||
"""
|
||
浏览器窗口最小化;
|
||
"""
|
||
self.minimize_window()
|
||
|
||
def maximize(self):
|
||
"""
|
||
浏览器窗口最大化;
|
||
"""
|
||
self.maximize_window()
|
||
|
||
def fullscreen(self):
|
||
"""
|
||
浏览器进入全屏模式,注意:可能会因为新页面跳转导致全屏模式退出,并且浏览器窗口大小可能会被重设;
|
||
"""
|
||
self.fullscreen_window()
|
||
|
||
def screenshot_for_report(self):
|
||
"""
|
||
截图保存在报告当中,仅在使用HTMLTestRunner时有效;
|
||
"""
|
||
report_root = os.environ.get('HTML_REPORT_ROOT')
|
||
screenshot_relpath = './Screenshot'
|
||
if report_root:
|
||
screenshot_home = os.path.abspath(os.path.join(report_root, screenshot_relpath))
|
||
screenshot_file = '%s%s.png' % (time.strftime('%Y%m%d%H%M%S', time.localtime()), str(random.randint(1000, 9999)))
|
||
os.path.exists(screenshot_home) or os.mkdir(screenshot_home)
|
||
self.save_screenshot(screenshot_home + '/' + screenshot_file)
|
||
print('[TestErrorImg]%s[/TestErrorImg]' % (screenshot_relpath + '/' + screenshot_file), file=sys.stderr)
|