Search code examples
python-appiumwinappdriver

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


I am working on automating UI-tests for an application and have trouble with menu items on Windows. Fwiw, I have it working on Mac for the sister-application. I am using Appium from Python.

I can find the menu tree using Inspect.exe, click the top-level menu, which then opens the dropdown, and in here I find the menu item, I want to click, but WinAppDriver fails with this error: {"status":105,"value":{"error":"element not interactable","message":"An element command could not be completed because the element is not pointer- or keyboard interactable."}}

The below python reproduces the problem.

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()

Any advice on how to click the menu item?


Solution

  • Here is what ended up working for the menu item (I am keeping the menu.click() since that works for the application, I am testing):

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