PywinAuto and the disappearing control Identifier

2.1k views Asked by At

I'm using pywinauto (the latest from the new github) to automate logging in to another program. The "Sign in" window has a bunch of buttons, and two fields, one for user name and one for password.

My problem is that the user name and password 'edit' control identifiers have the same Access name: ['1', '0', 'Edit']. There is no "Edit2".

When I use

sign_in.print_control_identifiers()

It still only shows the one edit property. How do I access this other edit control?

update with pictures with the demo company file:

Here is the LOGIN window: http://imgur.com/VwS9w0b

Here is the mouse hovering over password: http://imgur.com/6HWQVlZ

Password field clicked, its called edit1 as well! http://imgur.com/GUnTVrK

Swapy output : http://imgur.com/LJB99y1

A solution I found was to simulate a "tab" key

  sign_on.TypeKeys("{TAB}")

But this is not a great solution because if another window were to take focus at the time of the TAB then the script would sent the tab to that window.

2

There are 2 answers

6
vitswd On

I'm not sure which version of Pywinauto you are using. There is a revived one on GitHub (https://github.com/pywinauto/pywinauto). You can access controls as elements of a dictionary:

 sign_in['0']
 sign_in['1']

Highlighting a GUI element can also help to understand what element you refer to:

sign_in['0'].DrawOutline() # green by default
sign_in['1'].DrawOutline('red') # acceptable keywords: 'red','blue','green'
sign_in['Edit'].DrawOutline(0xff0000)   # blue

Update the answer with an example of walking through all control's children and highlight them. This way you can see if you have access to the "password" field.

import time
def drawContours(ctl):
    for c in ctl.Children():
        drawContours(c)
        time.sleep(1)
        c.DrawOutline()
    ctl.DrawOutline()

drawCountours(sign_in)
0
Vasily Ryabov On

Edit0 and Edit1 refers to the same first edit box. It's expected behavior (by design). Edit2 refers to the second edit box, Edit3 to the third one etc. If you get print_control_identifiers() output, you usually see something like that ("Find" dialog in Notepad, for example):

Edit - ''   (L152, T160, R323, B180)
    'Edit' 'Edit0' 'Edit1' 'Fi&nd what:Edit' ()

Edit - ''   (L152, T188, R323, B208)
    'Edit2' 'Re&place with:Edit' ()

So possible names for best_match search algorithm are listed for each control. These names are trying to be unique (not overlapping with other controls), but one control has several best names. It's normal situation. sign_in['Edit2'] is probably what you need.

If you disagree with such approach, you may raise design discussion here: https://github.com/pywinauto/pywinauto/issues