0.环境准备
- 安装jdk(8以上版本)及其环境配置
- 安装python3.10.4及其对应的三方包
- 安装winappdriver,下载地址:https://github.com/microsoft/WinAppDriver/releases/tag/v1.2.1
- windows开启开发者模式,本地开启服务:https://jingyan.baidu.com/article/91f5db1bfc57df5d7e05e31d.html
1.思路
整体思路:
1、封装appdriver服务、客户端启动关闭
2、封装鼠标基础行为 bat
3、封装元素定位基础行为 baseFunc
4、conftest中调用appdriver服务、客户端启动关闭,将driver暴露
5、调用文章来源地址https://www.toymoban.com/news/detail-515550.html
2.初试用
# -*- encoding: utf-8 -*-"
"""
@File: driver_win.py
@Author: cyl
@Desc: 对winappdriver服务、app的开启关闭进行封装
"""
import os
import time
import psutil
import platform
from selenium import webdriver
from settings import op_dir
WinAppDriver: str = "WinAppDriver.exe"
MyAppEXE: str = "xxx.exe"
# noinspection PyMethodMayBeStatic
class WinModelDriver:
def __init__(self, host='localhost', port=4723) -> None:
self.open_app_driver()
# 配置信息
self.desired_caps: dict = {
'platform_fame': platform.system(), # 平台名: 'Linux', 'Windows' or 'Java'
'deviceName': 'WindowsPC', # 系统
'app': op_dir, # 应用程序绝对路径
'pageLoadStrategy': 'none', # 加载策略
'disable-popup-blocking': True, # 禁用弹窗
}
self.host = host
self.port = port
self.driver = None
def open_app_driver(self) -> None:
"""启用winappdriver服务"""
result = os.system(r'start "" /d "C:\Program Files (x86)\Windows Application Driver\" "WinAppDriver.exe"')
if result == 1:
raise "开启服务失败, 确保启动WinAppDriver服务的地址正确!"
# noinspection HttpUrlsUsage
def open_platform(self) -> webdriver:
"""打开"""
try:
self.driver = webdriver.Remote('http://{}:{}'.format(self.host, self.port), self.desired_caps)
except Exception as e:
raise AssertionError(e)
# self.driver.implicitly_wait(3)
# self.driver.maximize_window()
# print("全部元素-> ", self.driver.page_source)
return self.driver
def close_platform(self) -> None:
"""关闭"""
self.driver.close()
self.driver.quit()
# 关闭所有客户端进程
time.sleep(1.5)
for proc in psutil.process_iter():
p_info = proc.as_dict(attrs=['pid', 'name'])
if p_info.get("name") == MyAppEXE:
_kill = 'taskkill -f -pid %s' % p_info.get("pid")
os.popen(_kill)
# -*- encoding: utf-8 -*-"
"""
@File: driver_impl.py.py
@Author: cyl
@Desc: 定义公共的driver实例
"""
class DriverImpl:
def __init__(self):
self.driver = None
self.module = ""
# 公共的driver类实例
driverImpl: DriverImpl = DriverImpl()
# -*- encoding: utf-8 -*-
"""
@File: base.py
@Author: cyl
@Desc: 鼠标事件pyautogui库的一些基础行为
"""
import pyautogui
from typing import Any
from pyautogui import Point
# noinspection PyMethodMayBeStatic,PyPep8Naming
class BaseAutoGui:
"""pyautogui基础封装"""
def position(self) -> Point:
return pyautogui.position()
def size(self) -> tuple:
"""获取屏幕的分辨率(高度、宽度)"""
wight, height = pyautogui.size()
return wight, height
def onScreen(self, x: Any, y: Any) -> bool:
"""判断坐标是否在屏幕上"""
res: bool = pyautogui.onScreen(x, y)
return res
def keyboard_keys(self) -> list:
"""返回所有支持的按键名称"""
return pyautogui.KEYBOARD_KEYS
def click(
self,
x: int | float,
y: int | float,
duration: int | float = 0.2,
_type: str = "single",
**kwargs
):
"""点击
Args:
x (int | float): x轴坐标点
y (int | float): y轴坐标点
duration (int | float, optional): 周期
_type (str, optional): single单击左键 right右键 double双击左键 three三击右键
"""
match _type:
case "single":
pyautogui.click(x, y, duration=duration, **kwargs)
case "right":
pyautogui.click(button="right", **kwargs)
case "double":
pyautogui.click(clicks=2, **kwargs)
case "three":
pyautogui.click(button='right', clicks=2, interval=0.25, **kwargs)
case _:
pyautogui.click(x, y, duration=duration, **kwargs)
return self
def doubleClick(self, x: int | float, y: int | float, duration: int | float = 0.5, **kwargs):
"""双击"""
pyautogui.doubleClick(x, y, duration=duration, **kwargs)
return self
def tripleClicks(self, x: int = 0, y: int = 0, **kwargs):
"""当前位置左击三下
Args:
x (int, optional): 指定位置x轴坐标点
y (int, optional): 指定位置y轴坐标点
"""
pyautogui.tripleClick(x=x, y=y, **kwargs)
return self
def press(self, keys: str):
"""按键
Args:
keys (str): 键名, eg: enter, esc, space
"""
if keys in self.keyboard_keys():
pyautogui.press(keys)
else:
raise "当前按键不在指定键程内!"
return self
3.结合pytest
# -*- encoding: utf-8 -*-
"""
@File: conftest.py
@Author: cyl
@Desc: ...
"""
import pytest
from common.driver_impl import driverImpl
from common.driver_win import WinModelDriver, webdriver
@pytest.fixture(scope="function", autouse=True)
def driver():
wl: WinModelDriver = WinModelDriver()
test_driver: webdriver = wl.open_platform()
driverImpl.driver = test_driver
logger.info("app启动~~~!")
yield test_driver
wl.close_platform()
driverImpl.driver = None
logger.info("app关闭~~~!")
# -*- encoding: utf-8 -*-
"""
@File: base_func.py
@Author: cyl
@Desc: driver以及基础行为封装
"""
import time
import win32api
import win32con
from utils.my_types import T, List
from common.driver_impl import driverImpl
from common.m_eles import getModelElement
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
# noinspection PyMethodMayBeStatic
class BaseModelFunc:
"""driver以及基础行为封装"""
def element_wait(self, driver=None, by_type: str = "xpath", formula: str = "", timeout: int = 3) -> T:
"""
显示等待, 默认xpath
:param driver: Windows driver
:param by_type: _id xpath name className linkTest tagName partialLinkText css
:param formula: elements.key
:param timeout: wait time setting, default 3s
"""
# 获取xpath(根据自己实际业务封装,如果没有可以直接将xptah作为形参传入)
xpath: str | int = getModelElement(formula)
driver = driverImpl.driver if driver is None else ...
handles: list = driver.window_handles
if not handles:
return
if len(handles) >= 1:
driver.switch_to.window(handles[0])
match by_type:
case "_id":
ele = WebDriverWait(driver, timeout, 0.5).until(ec.presence_of_element_located((By.ID, xpath)))
case "xpath":
ele = WebDriverWait(driver, timeout, 0.5).until(ec.presence_of_element_located((By.XPATH, xpath)))
case "name":
ele = WebDriverWait(driver, timeout, 0.5).until(ec.presence_of_element_located((By.NAME, xpath)))
case "className":
ele = WebDriverWait(driver, timeout, 0.5).until(ec.presence_of_element_located((By.CLASS_NAME, xpath)))
case "linkTest":
ele = WebDriverWait(driver, timeout, 0.5).until(ec.presence_of_element_located((By.LINK_TEXT, xpath)))
case "tagName":
ele = WebDriverWait(driver, timeout, 0.5).until(ec.presence_of_element_located((By.TAG_NAME, xpath)))
case "partialLinkText":
ele = WebDriverWait(driver, timeout, 0.5).until(ec.presence_of_element_located((By.PARTIAL_LINK_TEXT, xpath)))
case "css":
ele = WebDriverWait(driver, timeout, 0.5).until(ec.presence_of_element_located((By.CSS_SELECTOR, xpath)))
case _:
ele = WebDriverWait(driver, timeout, 0.5).until(ec.presence_of_element_located((By.XPATH, xpath)))
driver.switch_to.window(handles[-1])
return ele
baseFunc: BaseModelFunc = BaseModelFunc()
# -*- encoding: utf-8 -*-
"""
@File: m_eles_setting.py
@Author: cyl
@Desc: 实际应用中的方法调用
"""
from settings import app_cof
from utils.base_gui import bat
from utils.base_func import baseFunc
# noinspection PyMethodMayBeStatic
class ModuleElesSetting:
"""设置"""
def apply_and_determine(
self,
x_point: tuple = (1763, 852),
y_point: tuple = (1627, 855),
is_point: bool = app_cof.isPoint):
"""
设置-应用并确定
:param x_point: 应用
:param y_point: 确认
:param is_point: 是否使用坐标点
"""
if is_point:
bat.click(*x_point).click(*y_point)
else:
baseFunc.element_wait(formula="SETUP_APPLICATION").click()
baseFunc.element_wait(formula="POLYLINE_OK").click()
文章来源:https://www.toymoban.com/news/detail-515550.html
到了这里,关于【python】windows客户端的ui自动化框架搭建及使用(winappdriver)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!