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:Pythonlibsite-packagespywinautoapplication.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:Pythonlibsite-packagespywinautoapplication.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:Pythonlibsite-packagespywinautoapplication.py", line 243, in __resolve_control criteria) File "D:Pythonlibsite-packagespywinautotimings.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:Pythonlibsite-packagespywinautoapplication.py", line 365, in __getattribute__ ctrls = self.__resolve_control(self.criteria) File "D:Pythonlibsite-packagespywinautoapplication.py", line 246, in __resolve_control raise e.original_exception File "D:Pythonlibsite-packagespywinautotimings.py", line 402, in wait_until_passes func_val = func(*args) File "D:Pythonlibsite-packagespywinautoapplication.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:Pythonlibsite-packagespywinautoapplication.py", line 243, in __resolve_control criteria) File "D:Pythonlibsite-packagespywinautotimings.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:Pythonlibsite-packagespywinautoapplication.py", line 365, in __getattribute__ ctrls = self.__resolve_control(self.criteria) File "D:Pythonlibsite-packagespywinautoapplication.py", line 246, in __resolve_control raise e.original_exception File "D:Pythonlibsite-packagespywinautotimings.py", line 402, in wait_until_passes func_val = func(*args) File "D:Pythonlibsite-packagespywinautoapplication.py", line 188, in __get_ctrl dialog = self.backend.generic_wrapper_class(findwindows.find_element(**criteria[0])) File "D:Pythonlibsite-packagespywinautofindwindows.py", line 87, in find_element raise ElementNotFoundError(kwargs) pywinauto.findwindows.ElementNotFoundError: {'backend': 'uia', 'process': 2832} >>>
Answer
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' '<mpl=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')