如何使用 Appium 和 Windows 上的 Python 从应用程序菜单中单击菜单项?

How do I click a menu item from the application menu using Appium and Python on Windows?

我正在为一个应用程序进行 UI 自动化测试,但在使用 Windows 上的菜单项时遇到了问题。 Fwiw,我正在为姐妹应用程序开发 Mac。 我正在使用来自 Python.

的 Appium

我可以使用 Inspect.exe 找到菜单树,点击顶级菜单,然后打开下拉菜单,在这里我找到了菜单项,我想点击,但是 WinAppDriver 失败了错误: {"status":105,"value":{"error":"element not interactable","message":"An element command could not be completed because the element is not pointer- or keyboard interactable."}}

下面的 python 重现了这个问题。

import time
import unittest
from appium import webdriver

app_exe_path = "C:\Program Files\Phase One\Capture One 12\CaptureOne.exe"
menu_name = "Select"
menu_item_name = "First"
switch_window = True
# app_exe_path = "C:\Windows\Notepad.exe"
# menu_name = "File"
# menu_item_name = "Open..."
# switch_window = False


class ClickApplicationMenuItem(unittest.TestCase):
    def test_click_application_menu_item(self):
        driver = webdriver.Remote(
            command_executor="http://localhost:4723",
            desired_capabilities={"app": app_exe_path},
        )
        if switch_window:
            time.sleep(5) # non-optimal code for the sake of a simple repro
            handles = driver.window_handles
            driver.switch_to.window(handles[0])
        menu = driver.find_element_by_name(menu_name)
        menu.click() # fails in the Notepad case
        item = menu.find_element_by_name(menu_item_name)
        item.click() # fails in the CaptureOne case


if __name__ == "__main__":
    unittest.main()

关于如何点击菜单项有什么建议吗?

既然您能够找到这些元素,我假设您可以访问它们的属性。 一个简单的解决方法是单击元素坐标而不是单击元素本身。通常,点击坐标不是一个好主意,但由于您是从元素本身获取坐标,所以我看不出这里有什么问题。

尝试这样的事情:

menu = driver.find_element_by_name(menu_name)
driver.Mouse.Click(menu.coordinates)
item = menu.find_element_by_name(menu_item_name)
driver.Mouse.Click(item.coordinates)

我确实收到一条警告,指出鼠标功能已过时,应该使用 ActionsActionBuilder class。您也可以探索这些选项,但我在 winappdriver 的 github 页面上发现了一个已于 2018 年 3 月关闭的问题,关于 Actions class。目前还不清楚它为什么关闭。您可以找到另一种点击坐标的方法。

资源: Actions issue

这是菜单项的最终效果(我保留 menu.click() 因为它对应用程序有效,我正在测试):

   from selenium.webdriver.common.action_chains import ActionChains
   actions = ActionChains(driver)
   actions.click(item)
   actions.perform()