CristisS
CristisS

Reputation: 1163

Work with menuStrip and its items in python

I have to build an automation ui test for a WinForms application. I am using python 3.4 with python for windows extension and pywinauto.

The test is required to access the menu of the application and click on one of the sub menu items.

I used the code below to try and find the menu.

#arrays to store the controls found
classes = []
objects = []

#recursive method to get all the controls
def getClasses(childHwnd, lparam):
    objects.append(childHwnd)
    classes.append(win32gui.GetWindowText(childHwnd))
    return 1

#find handle of the main window
hwnd = win32gui.FindWindow(None, 'Form1')

#get all controls
win32gui.EnumChildWindows(hwnd, getClasses, "a")

# Result:    
# objects [1509794, 3344468] 
# classes ['Test', 'menuStrip1']

#trying to get the menu of the form
win32gui.GetMenu(hwnd) #Returns 0

Image of the form on which I tested the code above:

Image of the form used for the tests above

As you can see, the menuStrip1 is discovered, but I have not found a way to get to its children (Meniu 1, Meniu 2).

Any idea on how to find the menu and its children?

Upvotes: 3

Views: 1544

Answers (3)

Vineesh V
Vineesh V

Reputation: 21

In the case of Menustrip item an easy workaround is to use the pywinauto basic mouse input modules. by using this you can move to a specific position of the screen using (x,y) coordinates.

eg:

pywinauto.mouse.click(button='left', coords=(0, 0)) //Click at the specified coordinates

pywinauto.mouse.double_click(button='left', coords=(0, 0)) //Double click at the specified coordinates

pywinauto.mouse.move(coords=(0, 0))  //Move the mouse

pywinauto.mouse.press(button='left', coords=(0, 0))    //Press the mouse button

pywinauto.mouse.release(button='left', coords=(0, 0)) //Release the mouse button

pywinauto.mouse.right_click(coords=(0, 0)) //Right click at the specified coords

pywinauto.mouse.scroll(coords=(0, 0), wheel_dist=1) //Do mouse wheel

pywinauto.mouse.wheel_click(coords=(0, 0)) //Middle mouse button click at the specified coords  

Upvotes: 2

AdamMc331
AdamMc331

Reputation: 16730

While an answer has already been posted for an alternative solution, I would like to add a workaround that can be used in pywinauto.

On windows, the ALT key can be used to access a menu. For my specific example, I had a settings option "Settings -> Login Remotely". If I wanted to click this menu option I would first have to send ALT+S, and then type L. To do this using pywinauto, assuming you already have a reference to the window, you can do so like this:

myWindow.SetFocus()
myWindow.TypeKeys("%s") #Clicks Settings
myWindow.TypeKeys("l") #Clicks Login Remotely

The '%' character is used to represent the 'ALT' key on your keyboard. Another thing to note here is that if you have multiple menu options beginning with the same letter, you may have to send the key more than once to hit the one you want, and then send the enter key. If there is no ambiguity (in this case, only one submenu option began with L) it was selected automatically.

This requires you to know your menu well, and in what order, but as long as it doesn't change this should work for you.

Upvotes: 0

CristisS
CristisS

Reputation: 1163

After trying without success to use python 3.4 with python for windows extension and pywinauto to create automated tests for the respective project. I looked into other tools, and finally chose one called Sikuli, it's an automation tool based on image recognition of the elements on the screen. It may not be the perfect tool for the job, but it was enough for me.

Other observations about python for windows extension and pywinauto:

  • can only be used on controls they are aware of (e.g. not toolstripmenuitem)
  • it's impossible to test custom controls (for the reason above)

Observations regarding Sikuli:

  • all scripts are written in python
  • it may not use the latest python syntax
  • at the moment I used it, it had some small bugs

Upvotes: 1

Related Questions