From a067f4e840ff15fae732e8ba29fbb99333cc0709 Mon Sep 17 00:00:00 2001 From: Eeva Date: Thu, 13 Jun 2019 13:33:26 +0300 Subject: [PATCH 1/4] Refactor --- src/WhiteLibrary/__init__.py | 5 ++--- src/WhiteLibrary/keywords/__init__.py | 5 +++-- src/WhiteLibrary/keywords/items/__init__.py | 1 - src/WhiteLibrary/keywords/{items => }/mouse.py | 0 4 files changed, 5 insertions(+), 6 deletions(-) rename src/WhiteLibrary/keywords/{items => }/mouse.py (100%) diff --git a/src/WhiteLibrary/__init__.py b/src/WhiteLibrary/__init__.py index 151cf35..b272f98 100644 --- a/src/WhiteLibrary/__init__.py +++ b/src/WhiteLibrary/__init__.py @@ -1,6 +1,5 @@ # pylint: disable=invalid-name import os -from robot.api import logger # noqa: F401 #pylint: disable=unused-import from robot.utils import is_truthy import clr DLL_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'bin', 'TestStack.White.dll') @@ -9,13 +8,13 @@ from System.Windows.Automation import AutomationElement, ControlType # noqa: E402 from TestStack.White.UIItems.Finders import SearchCriteria # noqa: E402 from TestStack.White.UIItems import UIItem # noqa: E402 -from WhiteLibrary.keywords import ApplicationKeywords, KeyboardKeywords, WindowKeywords, ScreenshotKeywords, WhiteConfigurationKeywords # noqa: E402 +from WhiteLibrary.keywords import (ApplicationKeywords, KeyboardKeywords, MouseKeywords, + WindowKeywords, ScreenshotKeywords, WhiteConfigurationKeywords) # noqa: E402 from WhiteLibrary.keywords.items import (ButtonKeywords, LabelKeywords, ListKeywords, ListViewKeywords, MenuKeywords, - MouseKeywords, ProgressbarKeywords, SliderKeywords, TabKeywords, diff --git a/src/WhiteLibrary/keywords/__init__.py b/src/WhiteLibrary/keywords/__init__.py index cb99e5a..c39cdb2 100644 --- a/src/WhiteLibrary/keywords/__init__.py +++ b/src/WhiteLibrary/keywords/__init__.py @@ -1,5 +1,6 @@ from .application import ApplicationKeywords # noqa: F401 #pylint: disable=unused-import +from .configuration import WhiteConfigurationKeywords # noqa: F401 #pylint: disable=unused-import from .keyboard import KeyboardKeywords # noqa: F401 #pylint: disable=unused-import -from .window import WindowKeywords # noqa: F401 #pylint: disable=unused-import +from .mouse import MouseKeywords # noqa: F401 #pylint: disable=unused-import from .screenshot import ScreenshotKeywords # noqa: F401 #pylint: disable=unused-import -from .configuration import WhiteConfigurationKeywords # noqa: F401 #pylint: disable=unused-import +from .window import WindowKeywords # noqa: F401 #pylint: disable=unused-import diff --git a/src/WhiteLibrary/keywords/items/__init__.py b/src/WhiteLibrary/keywords/items/__init__.py index aa345fd..13b3b2a 100644 --- a/src/WhiteLibrary/keywords/items/__init__.py +++ b/src/WhiteLibrary/keywords/items/__init__.py @@ -3,7 +3,6 @@ from .listcontrols import ListKeywords # noqa: F401 #pylint: disable=unused-import from .listview import ListViewKeywords # noqa: F401 #pylint: disable=unused-import from .menu import MenuKeywords # noqa: F401 #pylint: disable=unused-import -from .mouse import MouseKeywords # noqa: F401 #pylint: disable=unused-import from .progressbar import ProgressbarKeywords # noqa: F401 #pylint: disable=unused-import from .slider import SliderKeywords # noqa: F401 #pylint: disable=unused-import from .tab import TabKeywords # noqa: F401 #pylint: disable=unused-import diff --git a/src/WhiteLibrary/keywords/items/mouse.py b/src/WhiteLibrary/keywords/mouse.py similarity index 100% rename from src/WhiteLibrary/keywords/items/mouse.py rename to src/WhiteLibrary/keywords/mouse.py From 2ee3393958a694fd822bc531d47da768f8d7a7a7 Mon Sep 17 00:00:00 2001 From: Eeva Date: Thu, 13 Jun 2019 15:07:58 +0300 Subject: [PATCH 2/4] Update and refactor window tests --- atests/attach_application.robot | 26 ++++++++++++ atests/attatch_application.robot | 70 ------------------------------- atests/feature_tests/window.robot | 49 ++++++++++++++++++++++ 3 files changed, 75 insertions(+), 70 deletions(-) create mode 100644 atests/attach_application.robot delete mode 100644 atests/attatch_application.robot diff --git a/atests/attach_application.robot b/atests/attach_application.robot new file mode 100644 index 0000000..229a08c --- /dev/null +++ b/atests/attach_application.robot @@ -0,0 +1,26 @@ +*** Settings *** +Library WhiteLibrary +Library Process +Test Setup Start Test Application +Test Teardown Terminate Process ${handle} kill=true +Resource resource.robot + +*** Test Cases *** +Attach To A Running Application By Name + Attach Application By Name ${TEST APPLICATION NAME} + Application Should Be Attached + +Attach To A Running Application By Id + Attach Application By Id ${test application id} + Application Should Be Attached + +*** Keywords *** +Start Test Application + ${handle} = Start Process ${TEST APPLICATION} + Set Test Variable ${handle} + ${test application id} = Get Process Id ${handle} + Set Test Variable ${test application id} + +Application Should Be Attached + Attach Window UI Automation Test Window + Verify Label lblA Value 1 diff --git a/atests/attatch_application.robot b/atests/attatch_application.robot deleted file mode 100644 index 3a1a535..0000000 --- a/atests/attatch_application.robot +++ /dev/null @@ -1,70 +0,0 @@ -*** Settings *** -Library WhiteLibrary -Library Process -Test Setup Start Test Application -Test Teardown Terminate Process ${handle} kill=true -Resource resource.robot - -*** Test Cases *** -Attach To A Running Application By Name - Attach Application By Name ${TEST APPLICATION NAME} - Application Should Be Attached - -Attach To A Running Application By Id - Attach Application By Id ${test application id} - Application Should Be Attached - -Attach Window Successfully - Attach Application By Name ${TEST APPLICATION NAME} - Attach Main Window - -Attach Nonexisting Window - Attach Application By Id ${test application id} - Set White Find Window Timeout 2 s - ${status} ${error_msg} Run Keyword And Ignore Error Attach Window Bogus Window - Should Contain ${error_msg} after waiting for 2.0 seconds - Set White Find Window Timeout 30 s - -Close Nonexisting Window - Attach Application By Id ${test application id} - Set White Find Window Timeout 2 s - Attach Main Window - ${status} ${error_msg} Run Keyword And Ignore Error Close Window Bogus Window - Should Contain ${error_msg} after waiting for 2.0 seconds - Set White Find Window Timeout 30 s - -Minimize Current Window - Attach Application By Id ${test application id} - Attach Main Window - Minimize Window - Window Should Be Minimized ${TEST APPLICATION WINDOW TITLE} - ${status} ${error_msg} Run Keyword And Ignore Error Window Should Be Restored ${TEST APPLICATION WINDOW TITLE} - Should Contain ${error_msg} Expected window state to be restored - -Maximize Current Window - Attach Application By Id ${test application id} - Attach Main Window - Maximize Window - Window Should Be Maximized - ${status} ${error_msg} Run Keyword And Ignore Error Window Should Be Minimized - Should Contain ${error_msg} Expected window state to be minimized - -Restore Current Window - Attach Application By Id ${test application id} - Attach Main Window - Maximize Window - Restore Window - Window Should Be Restored - ${status} ${error_msg} Run Keyword And Ignore Error Window Should Be Maximized - Should Contain ${error_msg} Expected window state to be maximized - -*** Keywords *** -Start Test Application - ${handle} = Start Process ${TEST APPLICATION} - Set Test Variable ${handle} - ${test application id} = Get Process Id ${handle} - Set Test Variable ${test application id} - -Application Should Be Attached - Attach Window UI Automation Test Window - Verify Label lblA Value 1 diff --git a/atests/feature_tests/window.robot b/atests/feature_tests/window.robot index c575a45..d2aa600 100644 --- a/atests/feature_tests/window.robot +++ b/atests/feature_tests/window.robot @@ -36,6 +36,55 @@ Attach Window Object Attach Window ${windows[3]} Window Title Should Be Test title - 2 +Attach Nonexisting Window + Set White Find Window Timeout 2 s + ${status} ${error_msg} Run Keyword And Ignore Error Attach Window Bogus Window + Should Contain ${error_msg} after waiting for 2.0 seconds + [Teardown] Set White Find Window Timeout 30 s + +Close Nonexisting Window + Set White Find Window Timeout 2 s + Attach Main Window + ${status} ${error_msg} Run Keyword And Ignore Error Close Window Bogus Window + Should Contain ${error_msg} after waiting for 2.0 seconds + [Teardown] Set White Find Window Timeout 30 s + +Minimize Current Window + Maximize Window + Minimize Window + Window Should Be Minimized ${TEST APPLICATION WINDOW TITLE} + [Teardown] Restore Window + +Maximize Current Window + Minimize Window + Maximize Window + Window Should Be Maximized + [Teardown] Restore Window + +Restore Current Window + Maximize Window + Restore Window + Window Should Be Restored + [Teardown] Restore Window + +Failing Restored Check + Maximize Window + ${status} ${error_msg} Run Keyword And Ignore Error Window Should Be Restored + Should Contain ${error_msg} Expected window state to be Restored, but found Maximized + [Teardown] Restore Window + +Failing Minimized Check + Restore Window + ${status} ${error_msg} Run Keyword And Ignore Error Window Should Be Minimized + Should Contain ${error_msg} Expected window state to be Minimized, but found Restored + [Teardown] Restore Window + +Failing Maximized Check + Minimize Window + ${status} ${error_msg} Run Keyword And Ignore Error Window Should Be Maximized + Should Contain ${error_msg} Expected window state to be Maximized, but found Minimized + [Teardown] Restore Window + *** Keywords *** Window Test Suite Setup Attach Main Window From 58cea818f5a01c91fa7cc91640dd0d5199e6ed8f Mon Sep 17 00:00:00 2001 From: Eeva Date: Thu, 13 Jun 2019 15:08:50 +0300 Subject: [PATCH 3/4] Update window state error messages to use string representation of the window state --- src/WhiteLibrary/keywords/window.py | 65 ++++++++++++++--------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/src/WhiteLibrary/keywords/window.py b/src/WhiteLibrary/keywords/window.py index 405e20a..17bd14b 100644 --- a/src/WhiteLibrary/keywords/window.py +++ b/src/WhiteLibrary/keywords/window.py @@ -1,4 +1,4 @@ -from robot.api import logger # noqa: F401 #pylint: disable=unused-import +from System import Enum from TestStack.White import AutomationException, Desktop from TestStack.White.Configuration import CoreAppXmlConfiguration from TestStack.White.Factory import InitializeOption # noqa: E402 @@ -129,69 +129,59 @@ def maximize_window(self, locator=None): window.DisplayState = DisplayState.Maximized @keyword - def window_should_be_maximized(self, locator=None): - """Verifies that a window is maximized. + def minimize_window(self, locator=None): + """Minimizes a window. ``locator`` is the locator of the window or a window object (optional). - If no ``locator`` value is given, the status of the currently attached window is verified. + If no ``locator`` value is given, the currently attached window is minimized. See `Attach Window` for details about attaching a window and window locator syntax. """ if locator is not None: window = self._get_window(locator) else: window = self.state.window - if window.DisplayState != DisplayState.Maximized: - raise AssertionError("Expected window state to be maximized, but found {}".format(str(window.DisplayState))) + window.DisplayState = DisplayState.Minimized @keyword - def minimize_window(self, locator=None): - """Minimizes a window. + def restore_window(self, window_title=None): + """Restores a window. ``locator`` is the locator of the window or a window object (optional). - If no ``locator`` value is given, the currently attached window is minimized. + If no ``locator`` value is given, the currently attached window is restored. See `Attach Window` for details about attaching a window and window locator syntax. """ - if locator is not None: - window = self._get_window(locator) + if window_title is not None: + window = self._get_window(window_title) else: window = self.state.window - window.DisplayState = DisplayState.Minimized + window.DisplayState = DisplayState.Restored @keyword - def window_should_be_minimized(self, locator=None): - """Verifies that a window is minimized. + def window_should_be_maximized(self, locator=None): + """Verifies that a window is maximized. ``locator`` is the locator of the window or a window object (optional). If no ``locator`` value is given, the status of the currently attached window is verified. See `Attach Window` for details about attaching a window and window locator syntax. """ - if locator is not None: - window = self._get_window(locator) - else: - window = self.state.window - if window.DisplayState != DisplayState.Minimized: - raise AssertionError("Expected window state to be minimized, but found {}".format(str(window.DisplayState))) + self._verify_window_state("Maximized", locator) @keyword - def restore_window(self, window_title=None): - """Restores a window. + def window_should_be_minimized(self, locator=None): + """Verifies that a window is minimized. ``locator`` is the locator of the window or a window object (optional). - If no ``locator`` value is given, the currently attached window is restored. + If no ``locator`` value is given, the status of the currently attached window is verified. See `Attach Window` for details about attaching a window and window locator syntax. """ - if window_title is not None: - window = self._get_window(window_title) - else: - window = self.state.window - window.DisplayState = DisplayState.Restored + self._verify_window_state("Minimized", locator) @keyword - def window_should_be_restored(self, window_title=None): + def window_should_be_restored(self, locator=None): """Verifies that a window is restored. ``locator`` is the locator of the window or a window object (optional). @@ -199,12 +189,17 @@ def window_should_be_restored(self, window_title=None): If title is not given, currently attached window status is queried. See `Attach Window` for more details. """ - if window_title is not None: - window = self._get_window(window_title) + self._verify_window_state("Restored", locator) + + def _verify_window_state(self, expected_state, locator): + if locator is not None: + window = self._get_window(locator) else: window = self.state.window - if window.DisplayState != DisplayState.Restored: - raise AssertionError("Expected window state to be restored, but found {}".format(str(window.DisplayState))) + actual_state = window.DisplayState + if actual_state != getattr(DisplayState, expected_state): + raise AssertionError("Expected window state to be {}, but found {}" + .format(expected_state, self._window_state_to_str(actual_state))) def _get_window(self, locator): if isinstance(locator, Window): @@ -238,3 +233,7 @@ def _parse_window_locator(locator): locator = "title:" + locator idx = locator.index(":") return locator[:idx], locator[(idx + 1):] + + @staticmethod + def _window_state_to_str(state): + return Enum.GetName(DisplayState, state) From 2237b00e7699ef0b165dd6ccdcf8a7a5cf7995d4 Mon Sep 17 00:00:00 2001 From: Eeva Date: Mon, 17 Jun 2019 12:49:43 +0300 Subject: [PATCH 4/4] Include window state also as int in the error message of Window Should Be keywords --- src/WhiteLibrary/keywords/window.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WhiteLibrary/keywords/window.py b/src/WhiteLibrary/keywords/window.py index 17bd14b..4b3d073 100644 --- a/src/WhiteLibrary/keywords/window.py +++ b/src/WhiteLibrary/keywords/window.py @@ -198,8 +198,8 @@ def _verify_window_state(self, expected_state, locator): window = self.state.window actual_state = window.DisplayState if actual_state != getattr(DisplayState, expected_state): - raise AssertionError("Expected window state to be {}, but found {}" - .format(expected_state, self._window_state_to_str(actual_state))) + raise AssertionError("Expected window state to be {}, but found {} ({})" + .format(expected_state, self._window_state_to_str(actual_state), actual_state)) def _get_window(self, locator): if isinstance(locator, Window):