桌面应用自动化winappdriver

关于winappdriver

介绍

  • WinAppDriver全称是Windows Application Driver,它提供了一些API,使得用户可以像selenium操作web一样来操作windows的应用程序
  • 它支持的系统是Windows 10 (Home and Pro) 和Windows Server 2016
  • 源码暂未开源
  • WinAppDriver可以独立运行,也可以作为appium的一个插件来使用

支持应用类型

  • UWP – Universal Windows Platform, also known as Universal Apps or Modern Apps, It's Microsoft’s latest desktop application technology. It's XAML based. Only runs on Windows 10 machines

  • WPF - also XAML based, much more mature, runs on any Windows version and has been around since 2006.

  • WinForms - one of the older technologies, now found mostly on legacy applications.

    WPF和WinForms 是两套界面渲染方式。一个是对传统windows界面元素的封装,通过gdi绘制。另一个是全新的dx渲染绘制的界面,也脱离了对传统windows控件的依赖,没有历史包袱,理论上可以展现更炫酷的界面。
  • MFC/Classic Windows - MFC is a UI library normally paired with Win32 applications. This option is normally chosen when more efficiency is needed with low-level C++ handling or when supporting non-Microsoft platforms.

资源

素材 地址 说明
FlaUInspect https://github.com/FlaUI/FlaUInspect/releases 定位工具
WinAppDriver https://github.com/microsoft/WinAppDriver/releases/tag/v1.2.1
UIRecorder https://github.com/microsoft/WinAppDriver/tree/master/Tools/UIRecorder 定位工具
inspect 微软官方工具集成于 Windows SDK 定位工具
  1. UIRecorder(下文不涉及,仅供参考与备忘)
  1. Open WinAppDriverUIRecorder.sln in Visual Studio
  2. Select Debug > Start Debugging or simply Run

支持的定位方式

Client API Locator Strategy Matched Attribute in inspect.exe Example
FindElementByAccessibilityId accessibility id AutomationId AppNameTitle
FindElementByClassName class name ClassName TextBlock
FindElementById id RuntimeId (decimal) 42.333896.3.1
FindElementByName name Name Calculator
FindElementByTagName tag name LocalizedControlType (upper camel case) Text
FindElementByXPath xpath Any //Button[0]

配置

开启windows的开发者模式

  • 你没看错,不是手机,windows也有
  • 第一步:搜开发者设置
  • 第二步:打开开发人员模式

  • 第三步:确认启用

启动winappdriver

  • 不开启开发人员模式的提示

    C:\Program Files (x86)\Windows Application Driver>WinAppDriver.exe
    Developer mode is not enabled. Enable it through Settings and restart Windows Application Driver
    Failed to initialize: 0x80004005
  • 开启后启动winappdriver

    C:\Program Files (x86)\Windows Application Driver>WinAppDriver.exe
    Windows Application Driver listening for requests at: http://127.0.0.1:4723/
    Press ENTER to exit.
  • 还可以这样启动

    WinAppDriver.exe 4727
    WinAppDriver.exe 10.0.0.10 4725
    WinAppDriver.exe 10.0.0.10 4723/wd/hub # 推荐

实例

appium-python-client 版本不要用2.0+,此处是1.2.0

记事本

  • 比如记事本

    from appium import webdriver
    des_cap = {}
    des_cap['app'] = r'C:\Windows\System32\notepad.exe'
    driver = webdriver.Remote(command_executor='http://127.0.0.1:4723/wd/hub',
    desired_capabilities=des_cap)
    driver.implicitly_wait(5)
    driver.find_element_by_name('文件(F)').click()
    from time import sleep
    sleep(2)
    driver.find_element_by_name('保存(S) Ctrl+S').click()
    # driver.find_element_by_name('退出(X)').click()
    sleep(1)
    import pyautogui
    pyautogui.PAUSE = 0.5
    pyautogui.typewrite(r'D:\hello.txt')
    pyautogui.press('enter')
  • 这里的难点是保存(S) Ctrl+S的获取

  • 这里需要用到inspect.exe

计算器

  • 你可能会写这样的代码
from appium import webdriver
des_cap = {}
des_cap['app'] = r'C:\Windows\System32\calc.exe'
driver = webdriver.Remote(command_executor='http://127.0.0.1:4723/wd/hub',
desired_capabilities=des_cap)
driver.implicitly_wait(5)
  • 但会报错
Traceback (most recent call last):
File "D:/demo_calc.py", line 5, in <module>
desired_capabilities=des_cap)
File "D:\Python37\lib\site-packages\appium\webdriver\webdriver.py", line 157, in __init__
AppiumConnection(command_executor, keep_alive=keep_alive), desired_capabilities, browser_profile, proxy
File "D:\Python37\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 157, in __init__
self.start_session(capabilities, browser_profile)
File "D:\Python37\lib\site-packages\appium\webdriver\webdriver.py", line 226, in start_session
response = self.execute(RemoteCommand.NEW_SESSION, parameters)
File "D:\Python37\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "D:\Python37\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: Failed to locate opened application window with appId: C:\Windows\System32\calc.exe, and processId: 4472 进程已结束,退出代码为 1
  • 打开计算器,然后在powershell中执行如下命令
Get-StartApps |Select-String "计算器"
# 输出
@{Name=计算器; AppID=Microsoft.WindowsCalculator_8wekyb3d8bbwe!App} # 你要的是这里的AppID
  • 代码
from appium import webdriver
des_cap = {}
des_cap['app'] = r'Microsoft.WindowsCalculator_8wekyb3d8bbwe!App'
driver = webdriver.Remote(command_executor='http://127.0.0.1:4723/wd/hub',
desired_capabilities=des_cap)
driver.implicitly_wait(5)
driver.find_element_by_name('一').click()
driver.find_element_by_name('二').click()
driver.find_element_by_name('加').click()
driver.find_element_by_name('三').click()
driver.find_element_by_name('四').click()
driver.find_element_by_name('等于').click()
# 通过inspect 获取 automationID
print(driver.find_element_by_accessibility_id('CalculatorResults').text) # 得到的是 ·显示为 46· 你仍然要处理才能做测试 driver.quit()

计算器测试(官网)

我没跑

# https://raw.githubusercontent.com/microsoft/WinAppDriver/master/Samples/Python/calculatortest.py
import unittest
from appium import webdriver class SimpleCalculatorTests(unittest.TestCase): @classmethod def setUpClass(self):
#set up appium
desired_caps = {}
desired_caps["app"] = "Microsoft.WindowsCalculator_8wekyb3d8bbwe!App"
self.driver = webdriver.Remote(
command_executor='http://127.0.0.1:4723',
desired_capabilities= desired_caps) @classmethod
def tearDownClass(self):
self.driver.quit() def getresults(self):
displaytext = self.driver.find_element_by_accessibility_id("CalculatorResults").text
displaytext = displaytext.strip("Display is " )
displaytext = displaytext.rstrip(' ')
displaytext = displaytext.lstrip(' ')
return displaytext def test_initialize(self):
self.driver.find_element_by_name("Clear").click()
self.driver.find_element_by_name("Seven").click()
self.assertEqual(self.getresults(),"7")
self.driver.find_element_by_name("Clear").click() def test_addition(self):
self.driver.find_element_by_name("One").click()
self.driver.find_element_by_name("Plus").click()
self.driver.find_element_by_name("Seven").click()
self.driver.find_element_by_name("Equals").click()
self.assertEqual(self.getresults(),"8") def test_combination(self):
self.driver.find_element_by_name("Seven").click()
self.driver.find_element_by_name("Multiply by").click()
self.driver.find_element_by_name("Nine").click()
self.driver.find_element_by_name("Plus").click()
self.driver.find_element_by_name("One").click()
self.driver.find_element_by_name("Equals").click()
self.driver.find_element_by_name("Divide by").click()
self.driver.find_element_by_name("Eight").click()
self.driver.find_element_by_name("Equals").click()
self.assertEqual(self.getresults(),"8") def test_division(self):
self.driver.find_element_by_name("Eight").click()
self.driver.find_element_by_name("Eight").click()
self.driver.find_element_by_name("Divide by").click()
self.driver.find_element_by_name("One").click()
self.driver.find_element_by_name("One").click()
self.driver.find_element_by_name("Equals").click()
self.assertEqual(self.getresults(),"8") def test_multiplication(self):
self.driver.find_element_by_name("Nine").click()
self.driver.find_element_by_name("Multiply by").click()
self.driver.find_element_by_name("Nine").click()
self.driver.find_element_by_name("Equals").click()
self.assertEqual(self.getresults(),"81") def test_subtraction(self):
self.driver.find_element_by_name("Nine").click()
self.driver.find_element_by_name("Minus").click()
self.driver.find_element_by_name("One").click()
self.driver.find_element_by_name("Equals").click()
self.assertEqual(self.getresults(),"8") if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(SimpleCalculatorTests)
unittest.TextTestRunner(verbosity=2).run(suite)

最新文章

  1. 微小,但是美好的改变 G2 2.2发布
  2. web前端
  3. [翻译]Autofac 解析服务
  4. Beyond IT
  5. C++ 面向对象的三个特点--多态性(二)
  6. linux crontab定时执行
  7. 【Todo】Java要学的一些比较好的框架和系统
  8. 66. Plus One
  9. vb eof详解
  10. maven tomcat1.7环境下构建javaweb 项目
  11. 前端模板文件化jQuery插件 $.loadTemplates
  12. 基础知识 mfc
  13. C# 通过Attribute制作的一个消息拦截器
  14. (七十三)iOS本地推送通知的实现
  15. PostgreSQL 10.7 linux 主从配置
  16. 使用特性将数据库返回的datatable转换成对象列表
  17. 移动端click事件无反应或反应慢 touchend事件页面滑动时频繁触发
  18. 浅谈servlet与jsp的关系
  19. CentOS 使用 Xfce 桌面并通过 xrdp 登录
  20. 3、redis之java client环境搭建

热门文章

  1. backward函数中gradient参数的一些理解
  2. FastReport报表金额数字转大写问题
  3. win10 + ubuntu 下右键新建md文件(转载)
  4. openvas漏洞扫描:使用openvas时扫描漏洞时,报告中显示的数据与数据库数据不同
  5. manjaro安装后配置与美化
  6. 游戏内存优化之使用16位纹理/NPOT
  7. Pytorch Cross Entropy
  8. 【ES6】迭代器
  9. 基于工业4g网关的危化品运输车监控方案
  10. vue +iview Select省市区联动