经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » 编程经验 » 查看文章
桌面应用自动化WinAppDriver入门
来源:cnblogs  作者:松勤吴老师  时间:2023/3/31 8:59:23  对本文有异议

桌面应用自动化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.

    1. WPFWinForms 是两套界面渲染方式。一个是对传统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

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

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

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

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

实例

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

记事本

  • 比如记事本

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

  • 这里需要用到inspect.exe

计算器

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

计算器测试(官网)

我没跑,仅供参考,你可以认为是为了增加篇幅

  1. # https://raw.githubusercontent.com/microsoft/WinAppDriver/master/Samples/Python/calculatortest.py
  2. import unittest
  3. from appium import webdriver
  4. class SimpleCalculatorTests(unittest.TestCase):
  5. @classmethod
  6. def setUpClass(self):
  7. #set up appium
  8. desired_caps = {}
  9. desired_caps["app"] = "Microsoft.WindowsCalculator_8wekyb3d8bbwe!App"
  10. self.driver = webdriver.Remote(
  11. command_executor='http://127.0.0.1:4723',
  12. desired_capabilities= desired_caps)
  13. @classmethod
  14. def tearDownClass(self):
  15. self.driver.quit()
  16. def getresults(self):
  17. displaytext = self.driver.find_element_by_accessibility_id("CalculatorResults").text
  18. displaytext = displaytext.strip("Display is " )
  19. displaytext = displaytext.rstrip(' ')
  20. displaytext = displaytext.lstrip(' ')
  21. return displaytext
  22. def test_initialize(self):
  23. self.driver.find_element_by_name("Clear").click()
  24. self.driver.find_element_by_name("Seven").click()
  25. self.assertEqual(self.getresults(),"7")
  26. self.driver.find_element_by_name("Clear").click()
  27. def test_addition(self):
  28. self.driver.find_element_by_name("One").click()
  29. self.driver.find_element_by_name("Plus").click()
  30. self.driver.find_element_by_name("Seven").click()
  31. self.driver.find_element_by_name("Equals").click()
  32. self.assertEqual(self.getresults(),"8")
  33. def test_combination(self):
  34. self.driver.find_element_by_name("Seven").click()
  35. self.driver.find_element_by_name("Multiply by").click()
  36. self.driver.find_element_by_name("Nine").click()
  37. self.driver.find_element_by_name("Plus").click()
  38. self.driver.find_element_by_name("One").click()
  39. self.driver.find_element_by_name("Equals").click()
  40. self.driver.find_element_by_name("Divide by").click()
  41. self.driver.find_element_by_name("Eight").click()
  42. self.driver.find_element_by_name("Equals").click()
  43. self.assertEqual(self.getresults(),"8")
  44. def test_division(self):
  45. self.driver.find_element_by_name("Eight").click()
  46. self.driver.find_element_by_name("Eight").click()
  47. self.driver.find_element_by_name("Divide by").click()
  48. self.driver.find_element_by_name("One").click()
  49. self.driver.find_element_by_name("One").click()
  50. self.driver.find_element_by_name("Equals").click()
  51. self.assertEqual(self.getresults(),"8")
  52. def test_multiplication(self):
  53. self.driver.find_element_by_name("Nine").click()
  54. self.driver.find_element_by_name("Multiply by").click()
  55. self.driver.find_element_by_name("Nine").click()
  56. self.driver.find_element_by_name("Equals").click()
  57. self.assertEqual(self.getresults(),"81")
  58. def test_subtraction(self):
  59. self.driver.find_element_by_name("Nine").click()
  60. self.driver.find_element_by_name("Minus").click()
  61. self.driver.find_element_by_name("One").click()
  62. self.driver.find_element_by_name("Equals").click()
  63. self.assertEqual(self.getresults(),"8")
  64. if __name__ == '__main__':
  65. suite = unittest.TestLoader().loadTestsFromTestCase(SimpleCalculatorTests)
  66. unittest.TextTestRunner(verbosity=2).run(suite)

原文链接:https://www.cnblogs.com/wuxianfeng023/p/17269050.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号