Change Log

0.6.8 Bug Fixes

27-October-2019

Enhancements:
  • Add allow_magic_lookup flag for Application and Desktop object. Thanks pakal!
  • Don’t duplicate already pressed key in internal list in win32_hooks.py. Thanks TomRobo237!
  • Allow finding an edit box by title (its editable text).
  • Add option to send keyboard input for an application which doesn’t handle VK_PACKET properly. Use vk_packet=False in method type_keys, default value is vk_packet=True. Thanks philmbailey!
Bug Fixes:
  • Fix ctypes.windll usage conflicts with other libraries.
  • Minor fixes in top-level __init__.py. Thanks pakal!
  • Fix logging issues in remote_memory_block.py. Thanks TomRobo237!
  • Minor docs improvements. Thanks olesteban, caoyaxing221 and nuno-andre!

0.6.7 Bug Fixes

07-July-2019

Enhancements:
  • Reuse ctypes.wintypes more to avoid redundant definitions for Win32 API.
  • Add method EditWrapper.is_editable() for “uia” backend.
Bug Fixes:
  • Fix corner case with int/long conversion crash while getting text.
  • Fix UIA crash: handle InvalidControlType properly.
  • Fix menu_select() for one level main menu in WinForms apps.
  • Make Application object non-iterable (iterating was hang).
  • Fix type conversion crash in GetWindowRect (method .rectangle()).
  • Fix combo box fluttering/blinking in dump_tree() / print_control_identifiers().

0.6.6 Better WinForms/Qt5 Support, Bug Fixes

03-March-2019

Enhancements:
  • Improve support for WinForms and Qt5: ComboBox, ListBox, DataGrid/Table.
  • Add an ability to use MFC toolbar buttons by text. Thanks Nebyt!
  • Make method kill() hard (and fast) by default (can be used with param soft=True optionally).
  • Make visible_only=False a default option for method connect() (useful for minimized apps).
  • Add an ability to hold or release a key with params down and up for .type_keys() method. See the improved docs for keyboard module for more details. Thanks badari412!
  • Add method windows() to class Desktop.
  • Add Remote Execution Guide with all known RDP/VNC/psexec/etc tricks.
Bug Fixes:
  • Fix UnicodeDecodeError/UnicodeEncodeError in several cases while printing wrapper object representation.
  • Add static text to a list of best match names for backend="uia".
  • Fix COMError for runtime_id property.
  • Fix method click() for some radio buttons.
  • Improve error message when screen is locked.
  • Use utf-8 encoding while writing dump_tree() output to file.
  • Remove few incorrect warnings for backend="win32".
  • Fix crash in GetWindowRect call.
  • Fix black screenshot issue with second monitor. Thanks Nebyt!

0.6.5 Handling Privileges, AutomationID for Win32 etc.

30-July-2018

Enhancements:
  • Check admin privileges for both target app and Python process. This allows detecting cases when window messages won’t work.
  • Add automation_id and control_type properties for “win32” backend (the most useful for WinForms). Correct child_window() keywords are auto_id and control_type.
  • Switch pypiwin32 dependency to pywin32 which became official again.
  • New generators iter_children() and iter_descendants().
  • Add method is_checked() to “win32” check box.
Bug Fixes:
  • Method Application().connect(...) works better with timeout argument.
  • Fix .set_focus() for “uia” backend including minimized window case (issue #443).
  • maximize()/minimize() methods can be chained now.
  • Fix passing keyword arguments to a function for decorators @always_wait_until_passes and @always_wait_until.
  • Use correct types conversion for WaitGuiThreadIdle (issue #497).
  • Fix reporting code coverage on Linux.
  • Use .format() for logging BaseWrapper actions (issue #471).
  • Print warning in case binary type is not determined (issue #387).

0.6.4 NULL pointer access fix and enhancements

21-January-2018

Bug Fixes:
  • Final fix for ValueError: NULL COM pointer access.
Enhancements:
  • Multi-threading mode (MTA) for comtypes is enabled by default, if it’s not initialized by another library before importing pywinauto.

  • Method get_value() has been added to EditWrapper in UIA backend.

  • Method scroll() has been added for all UIA controls which have ScrollPattern implemented.

  • Added methods is_minimized/is_maximized/is_normal/get_show_state for UIAWrapper.

  • Added handling in-place controls inside ListView control and (row, column) indexing in a grid-like table mode. Examples:

    auto_detected_ctrl = list_view.get_item(0).inplace_control()
    
    combo = list_view.get_item(1,1).inplace_control("ComboBox")
    combo.select("Item name")
    
    edit = list_view.get_item(3,4).inplace_control("Edit")
    edit.type_keys("some text{ENTER}", set_foreground=False)
    
    dt_picker = list_view.get_item(2,0).inplace_control("DateTimePicker")
    

0.6.3 A lot of improvements and some optimizations

03-July-2017
  • Improved string representation for all wrapper objects. Thanks airelil!
  • Fixed several sporadic crashes for backend="uia".
  • Fixed several bugs in wait/wait_not methods:
    • Method wait('exists') doesn’t work for backend="uia". Thanks maollm!
    • Methods wait/wait_not take ~ default time (5 sec.) instead of customized timeout like 1 sec.
  • depth param can used in a WindowSpecification now. depth=1 means this control, depth=2 means immediate children only and so on (aligned with print_control_identifiers method). Thanks dmitrykazanbaev!
  • Significantly improved sending keys to an inactive window silently. Special thanks for antonlarin! Now 2 methods are available:
    • send_chars is supposed to send character input (this includes {Enter}, {Tab}, {Backspace}) without Alt/Shift/Ctrl modifiers.
    • send_keystrokes is for key input (including key combinations with Alt/Shift/Ctrl modifiers).
  • Method Application().connect(path='your.exe') uses default timeout Timings.app_connect_timeout. It can accept timeout and retry_interval keyword arguments. Thanks daniil-kukushkin!
  • Method print_control_identifiers is more consistent and minimum 2x faster now! Thanks cetygamer!
  • Fixed subclassing Application with your own methods. Thanks efremovd!
  • Param work_dir can be used in Application().start(...). Thanks efremovd!
  • Class Application has been enriched with methods is_process_running() and wait_for_process_exit(). Thanks efremovd!
  • Module timings uses time.clock() for Python 2.x and time.perf_counter() for Python 3.x so that accident system time change can’t affect on your script behavior. Thanks airelil!
  • Added WireShark example. Thanks ViktorRoy94!
  • Now print_control_identifiers() can dump UI elements tree to a file. Thanks sovrasov!
  • Improved logging actions for backend="uia", extended example for MS Paint. Thanks ArtemSkrebkov!
  • Extended CalendarWrapper for backend="win32" with these methods: get_month_delta, set_month_delta and get_month_range. Thanks Nikita-K!
  • Added method legacy_properties() to UIAWrapper. Thanks AsyaPronina!
  • Improved VB6 ListView detection for backend="win32". Thanks KirillMoizik!
  • Fixed 64-bit specific bug in TreeViewWrapper for backend="win32" (argument 4: <type 'exceptions.OverflowError'>: long int too long to convert).

0.6.2 More bug fixes

28-February-2017
  • Several bugs were fixed:
    • Maximized window is always resized (restored) when calling set_focus().
    • AttributeError: type object ‘_CustomLogger’ has no attribute ‘disable’.
    • print_control_identifiers() gets bytes string on Python 3.x.
    • Importing pywinauto causes debug messages to appear twice.
  • Improved click methods behaviour for Win32 ListView and TreeView: ensure_visible() is called inside before the click.
  • Made taskbar.SystemTrayIcons localization friendly.

0.6.1 Bug fixes and optimizations for UI Automation and beyond

08-February-2017
  • win32_hooks module is well tested and more reliable now. See detailed example.

  • Fixed several bugs and crashes here and there.

    • Crash when ctrl.window_text() becomes None at the right moment. Thanks mborus!
    • HwndWrapper.set_focus() fails when used via interpreter. Thanks Matthew Kennerly!
    • Fix LoadLibrary call error on just released Python 2.7.13. Thanks Kirill Moizik!
    • AttributeError: WindowSpecification class has no ‘CPUUsage’ method.
    • comtypes prints a lot of warnings at import pywinauto.
    • Methods is_dialog() and restore() are missed for UIA backend.
    • Method print_control_identifiers() crashes on some applications with Unicode symbols.
    • Installation by python setup.py install may fail if pyWin32 dependency was installed manually.
    • Bug in resolving attributes: ‘UIAWrapper’ object has no attribute ‘Menu’ for dlg = app.Custom.Menu
    • Method send_chars() can now send {ENTER} to some applications. Thanks Max Bolingbroke!
  • Searching UI elements is faster now especially if you use control_type or auto_id in a WindowSpecification. Method Application.kill() is also optimized in many cases.

  • Added an example for Win10 Calculator.

0.6.0 Introduce MS UI Automation support and many more improvements

30-October-2016
  • This big release introduces MS UI Automation (UIA) support:
    • Just start from app = Application(backend='uia').start('your_app.exe').
    • Supported controls: Menu, Button/CheckBox/RadioButton, ComboBox, Edit, Tab control, List (ListView), DataGrid, Tree, Toolbar, Tooltip, Slider.
  • Documentation is built continuously now on ReadTheDocs. See also improved Getting Started Guide.
  • New multi-backend architecture makes implementation of new platforms support easier in the future. The minimal set for new backend includes its name and two classes inherited from element_info.ElementInfo and from pywinauto.base_wrapper.BaseWrapper. New backend must be registered by function pywinauto.backend.register().
  • Code style is much closer to PEP8: i.e. click_input should be used instead of ClickInput.
  • Initial implementation of the win32_hooks module. Keyboard and mouse event handlers can be registered in the system. It was inspired by pyHook, pyhk, pyhooked and similar modules, but re-written from scratch. Thanks for Max Samokhvalov! The fork of the win32_hooks module is used in pyhooked 0.8 by Ethan Smith.
  • A lot of small improvements are not counted here.

0.5.4 Bug fixes and partial MFC Menu Bar support

30-October-2015
  • Fix bugs and inconsistencies:
    • Add where=”check” possible value to the ListViewWrapper.Click/ClickInput` methods.
    • Add CheckByClickInput and UncheckByClickInput methods for a plain check box.
    • Fix crash while waiting for the window start.
  • Add partial MFC Menu Bar support. The menu bar can be interpreted as a toolbar. Items are clickable by index through experimental MenuBarClickInput method of the ToolbarWrapper.
  • Python 3.5 is supported.

0.5.3 Better Unicode support for SetEditText/TypeKeys and menu items

25-September-2015
  • Better backward compatibility with pywinauto 0.4.2:
    • support Unicode symbols in the TypeKeys method again;
    • allow SetEditText/TypeKeys methods to take non-string arguments;
    • fix taking Unicode parameters in SetEditText/TypeKeys.
  • Fix bug in Wait("active"), raise a SyntaxError when waiting for an incorrect state.
  • Re-consider some timings, update docs for the default values etc.
  • Fix several issues with an owner-drawn menu.
  • MenuItem method Click is renamed to ClickInput while Click = Select now.
  • New SetTransparency method can make a window transparent in a specified degree.

0.5.2 Improve ListView, new methods for CPU usage, DPI awareness

07-September-2015

  • New Application methods: CPUUsage returns CPU usage as a percent (float number), WaitCPUUsageLower waits until the connected process’ CPU usage is lower than a specified value (2.5% by default).
  • A new class _listview_item. It is very similar to _treeview_element.
  • Add DPI awareness API support (Win8+). It allows correct work when all fonts are scaled at 125%, 150% etc (globally or per monitor).
  • “Tools overview” section in docs.
  • Fix number of bugs:
    • TreeViewWrapper.Select doesn’t work when the control is not in focus.
    • TabControlWrapper.Select doesn’t work in case of TCS_BUTTONS style set.
    • ListViewWrapper methods Check/UnCheck are fixed.
    • Toolbar button: incorrect access by a tooltip text.
    • Warning “Cannot retrieve text length for handle” uses print() instead of actionlogger.
    • ClientToScreen method doesn’t return a value (modifying mutable argument is not good practice).

0.5.1 Several fixes, more tests

13-July-2015

  • Resolve pip issues
  • Warn user about mismatched Python/application bitness (64-bit Python should be used for 64-bit application and 32-bit Python is for 32-bit app)
  • Add “TCheckBox” class name to ButtonWrapper detection list
  • Fix DebugMessage method
  • Disable logging (actionlogger.py) by default, provide shortcuts: actionlogger.enable() and actionlogger.disable(). For those who are familiar with standard logging module there’s method actionlogger.set_level(level)

0.5.0 64-bit Py2/Py3 compatibility

30-June-2015

  • 64-bit Python and 64-bit apps support (but 32-bit Python is recommended for 32-bit apps)
  • Python 2.x/3.x compatibility
  • Added pyWin32 dependency (silent install by pip for 2.7 and 3.1+)
  • Improvements for Toolbar, TreeView, UpDown and DateTimePicker wrappers
  • Improved best_match algorithm allows names like ToolbarFile
  • Clicks can be performed with pressed Ctrl or Shift
  • Drag-n-drop and scrolling methods (DragMouse, DragMouseInput, MouseWheelInput)
  • Improved menu support: handling OWNERDRAW menu items; access by command_id (like $23453)
  • Resolved issues with py2exe and cx_freeze
  • RemoteMemoryBlock can now detect memory corruption by checking guard signature
  • Upgraded taskbar module
  • sysinfo module for checking 32-bit or 64-bit OS and Python
  • set_foreground flag in TypeKeys method for typing into in-place controls
  • flags create_new_console and wait_for_idle in Application.start method

0.4.0 Various cleanup and bug fixes

03-April-2010

  • Gracefully Handle dir() calls on Application or WindowSpecification objects (which used hang for a while as these classes would search for windows matching __members__, __methods__ and __bases__). The code now checks for any attribute that starts with ‘__’ and ends with ‘__’ and raises AttributeError immediately. Thanks to Sebastian Haase for raising this.
  • Removed the reference to an Application object in WindowSpecification. It was not used in the class and made the class harder to use. WindowSpecification is now more useful as a utility class.
  • Add imports of application.WindowSpecification and application.Application to pywinauto.__init__.py so that these classes can be used more easily (without having to directly import pywinauto.application). Thanks again to Sebastian Haase.
  • Added a function to empty the clipboard (thanks to Tocer on Sourceforge)
  • Use ‘SendMessageTimeout’ to get the text of a window. (SendMessage will hang if the application is not processing messages)
  • Fixed references to PIL.ImageGrab. PIL add’s it’s module directly to the module path, so it should just be referenced by ImageGrab and not PIL.ImageGrab.
  • Use AttachThreadInput + PostMessage rather than SendMessageTimeout to send mouse clicks.
  • Fix how timeout retry times are calculated in timings.WaitUntil() and timings.Wait
  • Fixed some issues with application.Kill_() method, highlighted due to the changes in the HwndWrapper.Close() method.
  • Fix writing images to XML. It was broken with updates to PIL that I had not followed. Changed the method of knowing if it is an image by checking for various attributes.
  • Renamed WindowSpecification.(Ww)indow() to ChildWindow() and added deprecation messages for the other functions.
  • Improved the tests (fixed test failures which were not pywinauto issues)

0.3.9 Experimental! New Sendkeys, and various fixes

27-November-2009

  • Major change this release is that Sendkeys is no longer a requirement! A replacement that supports Unicode is included with pywinauto. (hopefully soon to be released as a standalone module). Please note - this is still quite untested so this release should be treated with some care..
  • Made sure that default for WindowSpecification.Window_() was to look for non top level windows. The defaults in find_windows() had been changed previously and it now needed to be explicitly overridden.
  • Fixed a missing reference to ‘win32defines’ when referencing WAIT_TIMEOUT another typo of false (changed to False)
  • Removed the restriction to only get the active windows for the process, now it will be possible to get the active windows, even if a process is not specified. From http://msdn.microsoft.com/en-us/library/ms633506%28VS.85%29.aspx it gets the active window for the foreground thread.
  • Hopefully improved Delphi TreeView and ListView handling (added window class names as supported window classes to the appropriate classes).
  • Added support for running UI tests with reference controls. (requried for some localization tests)
  • Various PyLint and PEP8 fixes made.

0.3.8 Collecting improvements from last 2 years

10-March-2009

  • Fixed toolbar button pressing - This required for HwndWrapper.NotifyParent() to be updated (to accept a new ID parameter)
  • Fixed a bug wherea listview without a column control would make pywinauto fail to capture the dialog.
  • Converted documenation from Pudge generated to Sphinx Generated
  • Added some baic support for Pager and Progress controls (no tests yet)
  • Added some more VB ‘edit’ window classes
  • Added some more VB ‘listbox’ window classes
  • Added some more VB ‘button’ window classes
  • Ensured that return value from ComboBoxWrapper.SelectedIndices is always a tuple (there was a bug where it would sometimes be a ctypes array)
  • Changed default for finding windows to find disabled windows as well as enabled ones (previous was to find enabled windows only) (note this may impact scripts that relied on the previous setting i.e. in cases where two dialogs have the same title!)
  • Much better handling of InvalidWindowHandle during automation runs. This could be raised when a closing window is still available when the automation was called, but is gone half way through whatever function was called.
  • Made clicking more robust by adding a tiny wait between each SendMessageTimeout in _perform_click().
  • Added attributes can_be_label and has_title to HwndWrapper and subclasses to specify whether a control can act as a label for other controls, and whether the title should be used for identifying the control. If you have created your own HwndWrapper subclasses you may need to override the defaults.
  • Added a control_id parameter to find_windows which allows finding windows based off of their control id’s
  • Added a FriendlyClassName method to MenuItem
  • Split up the functions for button truncation data
  • Commented out code to get a new font if the font could not be recovered
  • Moved code to get the control font from Truncation test to handleprops
  • Added a function to get the string representation of the bug. (need to refactor PrintBugs at some point).
  • Fixed a variable name (from fname -> font_attrib as fname was not a defined variable!)
  • Forced some return values from MissingExtraString test to be Unicode
  • Fixed the MiscValues test (converted to Unicode and removed some extraneous characters)
  • Updated the path for all unittests
  • Made two unit tests sligthly more robust and less dependent on computer/app settings
  • Updated timing settings for unit tests
  • Updated the examples to work in dev environment.

0.3.7 Merge of Wait changes and various bug fixes/improvements

10-April-2007

  • Added Timings.WaitUntil() and Timings.WaitUntilPasses() which handle the various wait until something in the code. Also refactored existing waits to use these two methods.
  • Fixed a major Handle leak in RemoteMemorBlock class (which is used extensively for ‘Common’ controls. I was using OpenHandle to open the process handle, but was not calling CloseHandle() for each corresponding OpenHandle().
  • Added an active_() method to Application class to return the active window of the application.
  • Added an ‘active’ option to WindowSpecification.Wait() and WaitNot().
  • Some cleanup of the clipboard module. GetFormatName() was improved and GetData() made a little more robust.
  • Added an option to findwindows.find_windows() to find only active windows (e.g. active_only = True). Default is False.
  • Fixed a bug in the timings.Timings class - timing values are Now accessed through the class (Timings) and not through the intance (self).
  • Updated ElementTree import in XMLHelpers so that it would work on Python 2.5 (where elementtree is a standard module) as well as other versions where ElementTree is a separate module.
  • Enhanced Item selection for ListViews, TreeViews - it is now possible to pass strings and they will be searched for. More documentation is required though.
  • Greatly enhanced Toolbar button clicking, selection, etc. Though more documentation is required.
  • Added option to ClickInput() to allow mouse wheel movements to be made.
  • menuwrapper.Menu.GetProperties() now returns a dict like all other GetProperties() methods. This dict for now only has one key ‘MenuItems’ which contains the list of menuitems (which had been the previous return value).

0.3.6b Changes not documented in 0.3.6 history

31-July-2006

  • Fixed a bug in how findbestmatch.FindBestMatches was working. It would match against text when it should not!
  • Updated how timings.Timings.Slow() worked, if any time setting was less then .2 after ‘slowing’ then set it to .2

0.3.6 Scrolling and Treview Item Clicking added

28-July-2006

  • Added parameter to _treeview_item.Rectangle() to have an option to get the Text rectangle of the item. And defaulted to this.
  • Added _treeview_item.Click() method to make it easy to click on tree view items.
  • Fixed a bug in TreeView.GetItem() that was expanding items when it shouldn’t.
  • Added HwndWrapper.Scroll() method to allow scrolling. This is a very minimal implementation - and if the scrollbars are implemented as separate controls (rather then a property of a control - this will probably not work for you!). It works for Notepad and Paint - that is all I have tried so far.
  • Added a call to HwndWrapper.SetFocus() in _perform_click_input() so that calls to HwndWrapper.ClickInput() will make sure to click on the correct window.

0.3.5 Moved to Metaclass control wrapping

24-May-2006

  • Moved to a metaclass implementation of control finding. This removes some cyclic importing that had to be worked around and other then metaclass magic makes the code a bit simpler.
  • Some of the sample files would not run - so I updated them so they would (Thanks to Stefaan Himpe for pointing this out)
  • Disabled saving application data (it was still being saved in Application.RecordMatch() even if the rest of the application data code is disabled. This was causing what appeared to be a memory leak where pywinauto would keep grabbing more and more memory (especially for controls that contain a lot of information). Thanks to Frank Martinez for leading me to this).
  • Added ListViewWrapper.GetItemRect() to enable retrieving the rectangle for a particular item in the listview.
  • Removed references to _ctrl() method within pywinauto as it was raising a DeprecationWarning internally even if the user was not using it.

0.3.4 Fixed issue with latest ctypes, speed gains, other changes

25-Apr-2006

  • The latest version of ctypes (0.9.9.6) removed the code generator I was using some generated code in win32functions.py (stdcall). I was not using those functions so I just commented them out.
  • Started the process of renaming methods of the Application and WindowSpecification classes. I will be converting names to UppercaseNames_(). The trailing _ is to disambiguate the method names from potential Window titles.
  • Updated how print_control_identifiers works so that it now always prints the disambiguated control name. (even for single controls)
  • Added __hash__ to HwndWrapper so that controls could be dictionary keys.
  • Caching various information at various points. For example I cache how well two pieces of text match. For short scripts this has little impact - but for larger script it could well have a major impact. Also caching information for controls that cannot change e.g. TopLeveParent, Parent, etc

0.3.3 Added some methods, and fixed some small bugs

19-Apr-2006

  • Added a wait for the control to be active and configurable sleeps after ‘modifying’ actions (e.g. Select, Deselect, etc)
  • Fixed Timings.Slow() and Timings.Fast() - they could in certain circumstances do the opposite! If you had already set a timing slower or faster then they would set it then they would blindly ignore that and set their own times. I added functionality that they will take either the slowest or fastest of the new/current setting rather then blindly setting to the new value.
  • Fixed some hidden bugs with HwndWrapper.CloseClick()
  • Fixed a bug in setup.py that would raise an error when no argument was specified
  • Added an argument to HwndWrapper.SendMessageTimeout so that the wait options could be passed in.
  • Added HwndWrapper.Close(), Maximize(), Minimize(), Restore() and GetShowState().
  • Commented out all deprecated methods (will be removed completely in some future release).
  • Added Application.kill_() method - which closes all windows and kills the application. If the application is asking if you want to save your changes - you will not be able to click yes or no and the application will be killed anyway!.

0.3.2 Fixed setup.py and some typos

31-Mar-2006

  • Fixed the spelling of Stefaan Himpe’s name
  • Fixed setup.py which was working for creating a distribution but not for installing it (again thanks to Stefaan for pointing it out!)

0.3.1 Performance tune-ups

30-Mar-2006

  • Change calculation of distance in findbestmatch.GetNonTextControlName() so that it does not need to square or get the square root to find the real distance - as we only need to compare values - not have the actual distance. (Thanks to Stefaan Himpe)
  • Compiled regular expression patterns before doing the match to avoid compiling the regular expression for window that is being tested (Thanks to Stefaan Himpe)
  • Made it easier to add your own control tests by adding a file extra_tests.py which needs to export a ModifyRegisteredTests() method. Also cleaned up the code a little.
  • Updated notepad_fast.py to make it easier to profile (adde a method)
  • Changed WrapHandle to use a cache for classes it has matched - this is to avoid having to match against all classes constantly.
  • Changed default timeout in SendMessageTimeout to .001 seconds from .4 seconds this results in a significant speedup. Will need to make this value modifiable via the timing module/routine.
  • WaitNot was raising an error if the control was not found - it should have returned (i.e. success - control is not in any particular state because it does not exist!).
  • Added ListViewWrapper.Deselect() per Chistophe Keller’s suggestion. While I was at it I added a check on the item value passed in and added a call to WaitGuiIdle(self) so that the control has a chance to process the message.
  • Changed doc templates and moved dependencies into pywinauto subversion to ensure that all files were availabe at www.openqa.org and that they are not broken when viewed there.
  • Moved all timing information into the timings.Timings class. There are some simple methods for changing the timings.

0.3.0 Added Application data - now useful for localization testing

20-Mar-2006

  • Added automatic Application data collection which can be used when running the same test on a different spoken language version. Support is still preliminary and is expected to change. Please treat as early Alpha.

    If you have a different language version of Windows then you can try this out by running the notepad_fast.py example with the langauge argument e.g.

    examples\notepad_fast.py language
    

    This will load the application data from the supplied file notepad_fast.pkl and use it for finding the right menu items and controls to select.

  • Test implementation to make it easier to start using an application. Previously you needed to write code like

    app = Application().connect_(title = 'Find')
    app.Find.Close.Click()
    app.NotePad.MenuSelect("File->Exit")
    

    1st change was to implement static methods start() and connect(). These methods return a new Application instance so the above code becomes:

    app = Application.connect(title = 'Find')
    app.Find.Close.Click()
    app.NotePad.MenuSelect("File->Exit")
    

    I also wanted to make it easier to start working with a simple application - that may or may not have only one dialog. To make this situation easier I made window_() not throw if the application has not been start()ed or connect()ed first. This leads to simpler code like:

    app = Application()
    app.Find.Close.Click()
    app.NotePad.MenuSelect("File->Exit")
    

    What happens here is that when you execute any of Application.window_(), Application.__getattr__() or Application.__getitem__() when the application hasn’t been connected or started. It looks for the window that best matches your specification and connects the application to that process.

    This is extra functionality - existing connect_() and start_() methods still exist

  • Fixed HwndWrapper.SetFocus() so that it would work even if the window was not in the foreground. (it now makes the window foreground as well as giving it focus). This overcomes a restriction in Windows where you can only change the foreground window if you own the foreground window.

  • Changed some 2.4’isms that an anonymous commenter left on my blog :-) with these changes pywinauto should run on Python 2.3 (though I haven’t done extensive testing).

  • Commented out controls.common_controls.TabControlWrapper.GetTabState() and TabStates() as these did not seem to be returning valid values anyway.

  • Fixed documentation issues were parts of the documentation were not getting generated to the HTML files.

  • Fixed issue where MenuSelect would sometimes not work as expected. Some Menu actions require that the window that owns the menu be active. Added a call to SetFocus() before selecting a menu item to ensure that the window was active.

  • Fixed Bug 1452832 where clipboard was not closed in clipboard.GetData()

  • Added more unit tests now up to 248 from 207

0.2.5 More refactoring, more tests

07-Mar-2006

  • Added wrapper classes for Menus and MenuItems this enabled cleaner interaction with Menu’s. It also gives more functionality - you can now programmatically Click() on menus, and query if a menu item is checked or not.

  • Added application.WindowSpecification.Wait() and WaitNot() methods. These methods allow you to wait for a control to exist, be visible, be enabled, be ready (both enabled and visible!) or to wait for the control to not be in any of these states. WaitReady(), WaitNotEnabled(), WaitNotVisible() now use these methods. I was able to also add the missing methods WaitNotReady(), WaitEnabled(), WaitVisible(), WaitExists(), WaitnotExists(). Please use Wait() and WaitNot() as I have Deprecated these Wait* methods.

  • Slightly modified timeout waits for control resolution so that a timed function more accurately follows the timeout value specified.

  • Added application.Application.start() and connect() static methods. These methods are factory methods in that they will return an initialized Application instance. They work exactly the same as start_() and connect() as they are implemented in terms of those.

    from pywinauto.application import Application notepad = Application.start(“notepad”) same_notepad = Application.connect(path = “notepad”)

  • Updated the examples to follow changes to the code - and to make them a little more robust.

  • Added a new Controls Overview document page which lists all the actions on all controls.

  • Added more unit tests now up to 207 from 134 (added 68 tests)

0.2.1 Small Release number - big changes

17-Feb-2006

  • Quick release to get many changes out there - but this release has been less tested then I would like for a .3 release.

  • Allow access to non text controls using the closest Text control. This closest text control will normally be the static/label associated with the control. For example in Notepad, Format->Font dialog, the 1st combobox can be refered to as “FontComboBox” rather than “ComboBox1”

  • Added a new control wrapper - PopupMenuWrapper for context menu’s You can now work easily with context menu’s e.g.

    app.Notepad.Edit.RightClick()
    # need to use MenuClick rather then MenuSelect
    app.PopupMenu.MenuClick("Select All")
    app.Notepad.Edit.RightClick()
    app.PopupMenu.MenuClick("Copy")
    

    I could think of merging the RightClick() and MenuSelect() into one method ContextMenuSelect() if that makes sense to most people.

  • Added Support for Up-Down controls

  • Not all top level windows now have a FriendlyClassName of “Dialog”. I changed this because it made it hard to get windows of a particular class. For example the main Notepad window has a class name of “Notepad”.

    This was primarily implemented due to work I did getting the System Tray.

  • Renamed StatusBarWrapper.PartWidths() to PartRightEdges() as this is more correct for what it returns.

  • Changed HwndWrapper.Text() and SetText() to WindowText() and SetWindowText() respectively to try and make it clearer that it is the text returned by GetWindowText and not the text that is visible on the control. This change also suggested that EditWrapper.SetText() be changed to SetEditText() (though this is not a hard requirement EditWrapper.SetText() still exists - but may be deprecated.

  • Added ClickInput, DoubleClickInput, RightClickInput, PressMouseInput ReleaseMouseInput to HwndWrapper - these use SendInput rather then WM_LBUTTONDOWN, WM_RBUTTONUP, etc used by Click, DoubleClick etc.

    I also added a MenuClick method that allows you to click on menu items. This means you can now ‘physically’ drop menus down.

  • Some further working with tooltips that need to be cleaned up.

  • Fixed a bug where coordinates passed to any of the Click operations had the X and Y coordinates swapped.

  • Added new MenuItem and Menu classes that are to the most part hidden but you can get a menu item by doing

    app.Notepad.MenuItem("View")
    app.Notepad.MenuItem("View->Status Bar")
    

    MenuItems have various actions so for example you can use MenuItem.IsChecked() to check if the menu item is checked. Among other methods there are Click() and Enabled().

  • Modified the ‘best match’ algorithm for finding controls. It now searches a couple of times, and tries to find the best fit for the text passed to it. The idea here is to make it more “Select what I want - not that other thing that looks a bit like what I want!”. It is possible this change could mean you need to use new identifiers in scripts - but in general very little modification should be necessary.

    There was also a change to the algorithm that looked for the closest text control. It missed some obvious controls in the previous implementation. It also had a bug for controls above the control rather than to the left.

  • Added a new example scripts SaveFromInternetExplorer.py and SaveFromFirefox.py which show automating downloading of a page from either of these browsers.

  • Added yet more unit tests, there are now a total of 134 tests.

0.2.0 Significant refactoring

06-Feb-2006

  • Changed how windows are searched for (from application) This chage should not be a significant change for users

  • Started adding unit tests (and the have already uncovered bugs that been fixed). They also point to areas of missing functionality that will be addded with future updates

  • Changed from property access to Control attributes to function access If your code was accessing properties of controls then this might be a significant change! The main reasons for doing this were due to the inheritability of properties (or lack there-of!) and the additional scafolding that was required to define them all.

  • Updated the DialogWrapper.MenuSelect() method to notify the parent that it needs to initialize the menu’s before it retrieves the items

  • Added functionality to associate ‘non-text’ controls with the ‘text’ control closest to them. This allows controls to be referenced by:

    app.dlg.<Nearby_text><Window_class>
    

    e.g. to reference the “Footer” edit control in the Page Setup dialog you could use:

    app.PageSetup.FooterEdit
    
  • Added a MoveWindow method to HwndWrapper

  • Did some more cleanup (fixing pylint warnings) but still not finished

  • Added some better support for .NET controls (not to be considered final)

0.1.3 Many changes, few visible

15-Jan-2006

  • Wrote doc strings for all modules, classes and functions

  • Ran pychecker and pylint and fixed some errors/warning

  • changed

    _connect, _start, _window, _control, _write
    

    respectively to

    connect_, start_, window_, connect_, write_
    

    If you forget to change _window, _connect and _start then you will probably get the following error.

    TypeError: '_DynamicAttributes' object is not callable
    
  • pywinauto is now a package name - you need to import it or its modules

  • Changes to the code to deal with pywinauto package name

  • Fixed searching for windows if a Parent is passed in

  • Added Index to retrieved MenuItem dictionary

  • Added a check to ensure that a windows Handle is a valid window

  • Refactored some of the methods in common_controls

  • Refactored how FriendlyClassName is discovered (and still not really happy!

0.1.2 Add Readme and rollup various changes

15-Jan-2006

  • Updated Readme (original readme was incorrect)
  • Added clipboard module
  • Fixed DrawOutline part of tests.__init__.print_bugs
  • Added a NotifyParent to HwndWrapper
  • Make sure that HwndWrapper.ref is initialized to None
  • Refactored some methods of ComboBox and ListBox
  • Updated Combo/ListBox selection methods
  • Removed hardcoded paths from test_application.py
  • Added section to save the document as UTF-8 in MinimalNotepadTest
  • Fixed EscapeSpecials and UnEscapeSpecials in XMLHelpers
  • Made sure that overly large bitmaps do not break XML writing

0.1.1 Minor bug fix release

12-Jan-2006

  • Fixed some minor bugs discovered after release

0.1.0 Initial Release

6-Jan-2006