Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is the best way to start google chrome and input a web address by pywinauto

I learn from blog (http://technapstar.blogspot.fi/2014/07/automation-with-pywinauto.html) about starting google chrome and input a web address by pywinauto as the following way:

Python 3.6.1rc1 (v3.6.1rc1^0:e0fbe5feee4f9c00f09eb9659c2182183036261a, Mar  4 2017, 20:00:12) [MSC v.1900 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import pywinauto
>>> pywinauto.__version__
'0.6.2'
>>> from pywinauto.application import Application
>>> app = Application().start("chrome.exe")

Warning (from warnings module):
  File "D:\Python\lib\site-packages\pywinauto\application.py", line 982
    UserWarning)
UserWarning: 32-bit application should be automated using 32-bit Python (you     use 64-bit Python)
>>> app.window_(title='New Tab')
<pywinauto.application.WindowSpecification object at 0x0000000002FFABE0>
>>> app.window_().TypeKeys('{F6}')
<pywinauto.controls.hwndwrapper.DialogWrapper object at 0x0000000004258320>
>>> app.window_().TypeKeys('{ESC}')
<pywinauto.controls.hwndwrapper.DialogWrapper object at 0x0000000004243518>
>>> app.window_().TypeKeys('www.google.com')
<pywinauto.controls.hwndwrapper.DialogWrapper object at 0x0000000004225D68>
>>> app.window_().TypeKeys('{ENTER}')
<pywinauto.controls.hwndwrapper.DialogWrapper object at 0x00000000042436D8>
>>> 

However, when I try to start another google chrome window with the same way, I meet the following error.

>>> app1 = Application().start("chrome.exe")

Warning (from warnings module):
  File "D:\Python\lib\site-packages\pywinauto\application.py", line 982
    UserWarning)
UserWarning: 32-bit application should be automated using 32-bit Python (you use 64-bit Python)
>>> app1.window_(title='New Tab')
<pywinauto.application.WindowSpecification object at 0x0000000004243470>
>>> app1.window_().TypeKeys('{F6}')
Traceback (most recent call last):
  File "D:\Python\lib\site-packages\pywinauto\application.py", line 243, in __resolve_control
    criteria)
  File "D:\Python\lib\site-packages\pywinauto\timings.py", line 424, in wait_until_passes
    raise err
pywinauto.timings.TimeoutError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<pyshell#11>", line 1, in <module>
    app1.window_().TypeKeys('{F6}')
  File "D:\Python\lib\site-packages\pywinauto\application.py", line 365, in __getattribute__
    ctrls = self.__resolve_control(self.criteria)
  File "D:\Python\lib\site-packages\pywinauto\application.py", line 246, in __resolve_control
    raise e.original_exception
  File "D:\Python\lib\site-packages\pywinauto\timings.py", line 402, in wait_until_passes
    func_val = func(*args)
  File "D:\Python\lib\site-packages\pywinauto\application.py", line 188, in __get_ctrl
    dialog = self.backend.generic_wrapper_class(findwindows.find_element(**criteria[0]))

I google a bit, but could not find the answers. Can somebody suggest what is the best way to operate google chrome by pywinauto? or pywinauto is not a proper tool to operate google chrome at the moment.

[EDIT] Still not working by following Vasily's student sample code, see here:

>>> app = Application(backend='uia');
>>> app.start('chrome.exe --force-renderer-accessibility')
<pywinauto.application.Application object at 0x00000000045D80B8>
>>> app.window().type_keys('{F6}')
<pywinauto.controls.uiawrapper.UIAWrapper object at 0x00000000045D8AC8>

So far it is ok, but when I try to have another chrome browser, I meet following error:

>>> app1 = Application(backend='uia');
>>> app1.start('chrome.exe --force-renderer-accessibility')
<pywinauto.application.Application object at 0x0000000003324F28>
>>> app1.window().type_keys('{F6}')
Traceback (most recent call last):
  File "D:\Python\lib\site-packages\pywinauto\application.py", line 243, in __resolve_control
    criteria)
  File "D:\Python\lib\site-packages\pywinauto\timings.py", line 424, in wait_until_passes
    raise err
pywinauto.timings.TimeoutError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<pyshell#18>", line 1, in <module>
    app1.window().type_keys('{F6}')
  File "D:\Python\lib\site-packages\pywinauto\application.py", line 365, in __getattribute__
    ctrls = self.__resolve_control(self.criteria)
  File "D:\Python\lib\site-packages\pywinauto\application.py", line 246, in __resolve_control
    raise e.original_exception
  File "D:\Python\lib\site-packages\pywinauto\timings.py", line 402, in wait_until_passes
    func_val = func(*args)
  File "D:\Python\lib\site-packages\pywinauto\application.py", line 188, in __get_ctrl
    dialog = self.backend.generic_wrapper_class(findwindows.find_element(**criteria[0]))
  File "D:\Python\lib\site-packages\pywinauto\findwindows.py", line 87, in find_element
    raise ElementNotFoundError(kwargs)
pywinauto.findwindows.ElementNotFoundError: {'backend': 'uia', 'process': 2832}
>>> 
like image 362
L. Ouyang Avatar asked Mar 21 '17 03:03

L. Ouyang


2 Answers

First you need to run Chrome with accessibility features enabled for all pages (here are some tips and tricks on that):

app = Application().start('chrome.exe --force-renderer-accessibility')

Second Chrome could be easier automated using backend='uia' (MS UI Automation technology) and you need to specify it explicitly. More details about backends and pywinauto fundamentals could be found in the Getting Started Guide (really recommend to read for everyone). It also explains where to find Inspect.exe to browse UI elements hierarchy and much-much more. Just a small example:

app = Application(backend='uia').start('chrome.exe --force-renderer-accessibility')

Third Chrome may start new tabs in different process. So you need to connect to this new process using title or title_re criterion.

app_new_tab = Application(backend='uia').connect(path='chrome.exe', title_re='New Tab')

Alternative way is to use Desktop object (process agnostic way):

NewTab = Desktop(backend='uia').NewTab
NewTab.print_control_identifiers() # prints UI elements subtree

[EDIT] My student wrote an example script dragging zip file from explorer.exe to Google Drive using Chrome in incognito mode: test_explorer_google_drive.py. Tested on English version.

# encoding: utf-8
from __future__ import print_function
from os import path
from pywinauto import Desktop, Application

chrome_dir = r'"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe"'
tab_log_in = u'Meet Google Drive - One place for all your files (Incognito)'
tab_drive = 'My Drive - Google Drive (Incognito)'

# # start google chrome
chrome = Application(backend='uia')
chrome.start(chrome_dir + ' --force-renderer-accessibility --incognito --start-maximized '
             'https://accounts.google.com/ServiceLogin?service=wise&passive=1209600&continue=https:'
             '//drive.google.com/?urp%3Dhttps://www.google.ru/_/chrome/newtab?espv%253D2%2526ie%253DUT%23&followup='
             'https://drive.google.com/?urp%3Dhttps://www.google.ru/_/chrome/newtab?espv%253D2%2526ie%253DUT'
             '&ltmpl=drive&emr=1#identifier')

# wait while a page is loading
chrome[tab_log_in].child_window(title_re='Reload.*', control_type='Button').wait('visible', timeout=10)
ch_window = chrome[tab_drive].child_window(title="Google Chrome", control_type="Custom")

# log in
chrome.window().type_keys('TestPywinauto{ENTER}')  # username
chrome[tab_log_in].child_window(title="Google Chrome", control_type="Custom").\
    child_window(title="Back", control_type="Image").wait(wait_for='visible', timeout=10)

chrome.window().type_keys('testpywinauto123{ENTER}')  # password
ch_window.child_window(title="Getting started PDF", control_type="ListItem").wait(wait_for='visible')

# start explorer in the current path
dir_path = path.join(path.dirname(path.realpath(__file__)), 'UIA_Drive')
explorer = Application().start('explorer.exe ' + dir_path)
Desktop(backend='uia').window(title='UIA_Drive', active_only=True).wait('visible', timeout=10)
dlg = Application(backend='uia').connect(path='explorer.exe', title='UIA_Drive')

# find file
file = dlg.UIA_Drive.ItemsView.wrapper_object().get_item('test.zip')

# drag n drop
destination = chrome.top_window().wrapper_object()
file.press_mouse_input(coords=file.rectangle().mid_point())
file.move_mouse_input(coords=destination.rectangle().mid_point())
chrome.top_window().set_focus()
file.release_mouse_input(coords=destination.rectangle().mid_point())

# wait upload file
ch_window.child_window(title="test.zip Compressed Archive", control_type="ListItem").wait('visible')

print('DONE')
like image 144
Vasily Ryabov Avatar answered Sep 30 '22 18:09

Vasily Ryabov


Simpler way to start is this :

from pywinauto.application import Application
chrome_dir = 'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
start_args = ' --force-renderer-accessibility --start-maximized https://www.google.com/'
app = Application(backend="uia").start(chrome_dir+start_args)
like image 21
Yeshwanth N Avatar answered Sep 30 '22 18:09

Yeshwanth N