From 143b3f5a5494cabf33c2af47424570cface7a068 Mon Sep 17 00:00:00 2001 From: Vasily Ryabov Date: Mon, 27 Feb 2017 12:52:57 +0300 Subject: [PATCH 1/3] Add MS Paint example (fix #310). --- examples/mspaint.py | 45 ++++++++++++++++++++++++++++++++++++++++ examples/walter_cat.jpg | Bin 0 -> 6067 bytes 2 files changed, 45 insertions(+) create mode 100644 examples/mspaint.py create mode 100644 examples/walter_cat.jpg diff --git a/examples/mspaint.py b/examples/mspaint.py new file mode 100644 index 000000000..58e51300d --- /dev/null +++ b/examples/mspaint.py @@ -0,0 +1,45 @@ +""" +Example script for MS Paint + +Requirements: + - tested on Windows 10 (should work on Win7+) + - pywinauto 0.6.1+ + +The example shows how to work with MS Paint application. It opens +JPEG image and resizes it using "Resize and Skew" dialog. +""" + +from pywinauto import Application + +app = Application(backend='uia').start(r'mspaint.exe') +dlg = app.window(title_re='.* - Paint') + +# File->Open menu selection +dlg.File_tab.click() +dlg.child_window(title='Open', control_type='MenuItem').invoke() + +# handle Open dialog +file_name_edit = dlg.Open.child_window(title="File name:", control_type="Edit") +file_name_edit.set_text('walter_cat.jpg') +# There are 2 Open buttons: +# dlg.Open.Open.click() will call drop down list of the file name combo box. +# The child_window statement is just copied from print_control_identifiers(). +dlg.Open.child_window(title="Open", auto_id="1", control_type="Button").click() + +dlg.ResizeButton.click() +dlg.ResizeAndSkew.Pixels.select() +if dlg.ResizeAndSkew.Maintain_aspect_ratio.get_toggle_state() != 1: + dlg.ResizeAndSkew.Maintain_aspect_ratio.toggle() +dlg.ResizeAndSkew.HorizontalEdit1.set_text('100') +dlg.ResizeAndSkew.OK.click() + +# Select menu "File->Save as->PNG picture" +dlg.File_tab.click() +dlg.SaveAsGroup.child_window(title="Save as", found_index=1).invoke() +dlg.child_window(title='PNG picture').invoke() +# Type output file name and save +dlg.SaveAs.File_name_ComboBox.Edit.set_text('walter_cat_resized.png') +dlg.SaveAs.Save.click() + +# Close application +dlg.close() diff --git a/examples/walter_cat.jpg b/examples/walter_cat.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cf8855fc8589298536da19c7746c31b7a487f904 GIT binary patch literal 6067 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 literal 0 HcmV?d00001 From ec1348f83d9c57c543390d748a10dd54afc61678 Mon Sep 17 00:00:00 2001 From: Vasily Ryabov Date: Mon, 27 Feb 2017 19:45:47 +0300 Subject: [PATCH 2/3] Update version, prepare Release Notes. --- docs/HISTORY.txt | 16 ++++++++++++++++ pywinauto/__init__.py | 2 +- setup.py | 7 +++---- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/docs/HISTORY.txt b/docs/HISTORY.txt index 9bcdfae02..2b3e9fd44 100644 --- a/docs/HISTORY.txt +++ b/docs/HISTORY.txt @@ -2,6 +2,22 @@ Change Log ========== +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 diff --git a/pywinauto/__init__.py b/pywinauto/__init__.py index c432beb43..c65c9a046 100644 --- a/pywinauto/__init__.py +++ b/pywinauto/__init__.py @@ -32,7 +32,7 @@ """Python package for automating GUI manipulation on Windows""" -__version__ = "0.6.1" +__version__ = "0.6.2" import sys diff --git a/setup.py b/setup.py index 3794c7de8..8c886c071 100644 --- a/setup.py +++ b/setup.py @@ -69,10 +69,9 @@ def setup_path(path = ""): packages = ["pywinauto", "pywinauto.linux"] setup(name='pywinauto', - version = '0.6.1', - description = 'pywinauto is a set of python ' - 'modules to automate the Microsoft Windows GUI', - keywords = "windows automation gui GuiAuto", + version = '0.6.2', + description = 'A set of Python modules to automate the Microsoft Windows GUI', + keywords = "windows gui automation GuiAuto testing test desktop mouse keyboard", url = "http://pywinauto.github.io/", author = 'Mark Mc Mahon and Contributors', author_email = 'pywinauto-users@lists.sourceforge.net', From 77eb463bde029956557a1e9abedbef22ec21f647 Mon Sep 17 00:00:00 2001 From: Vasily Ryabov Date: Tue, 28 Feb 2017 10:36:15 +0300 Subject: [PATCH 3/3] Add an example listing installed Windows updates. --- examples/list_windows_updates.py | 40 ++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 examples/list_windows_updates.py diff --git a/examples/list_windows_updates.py b/examples/list_windows_updates.py new file mode 100644 index 000000000..53d21ae67 --- /dev/null +++ b/examples/list_windows_updates.py @@ -0,0 +1,40 @@ +""" +Example script for listing installed updates on Windows 10 + +Requirements: + - Windows 10 (may work on Win7+) + - pywinauto 0.6.1+ + +This example opens "Control Panel", navigates to "Installed Updates" page +and lists all updates (for all apps) as well as OS Windows updates only. +""" + +from __future__ import print_function +from pywinauto import Application + +# Open "Control Panel" +Application().start('control.exe') +app = Application(backend='uia').connect(path='explorer.exe', title='Control Panel') + +# Go to "Programs" +app.window(title='Control Panel').ProgramsHyperlink.invoke() +app.wait_cpu_usage_lower(threshold=0.5, timeout=30, usage_interval=1.0) + +# Go to "Installed Updates" +app.window(title='Programs').child_window(title='View installed updates', control_type='Hyperlink').invoke() +app.wait_cpu_usage_lower(threshold=0.5, timeout=30, usage_interval=1.0) + +list_box = app.InstalledUpdates.FolderViewListBox + +# list all updates +items = list_box.descendants(control_type='ListItem') +all_updates = [item.window_text() for item in items] +print('\nAll updates ({}):\n'.format(len(all_updates))) +print(all_updates) + +# list updates from "Microsoft Windows" group only +windows_group_box = list_box.child_window(title_re='^Microsoft Windows.*', control_type='Group') +windows_items = windows_group_box.descendants(control_type='ListItem') +windows_updates = [item.window_text() for item in windows_items] +print('\nWindows updates only ({}):\n'.format(len(windows_updates))) +print(windows_updates) \ No newline at end of file