summaryrefslogtreecommitdiffstats
path: root/uitest/uitest/test.py
diff options
context:
space:
mode:
Diffstat (limited to 'uitest/uitest/test.py')
-rw-r--r--uitest/uitest/test.py260
1 files changed, 260 insertions, 0 deletions
diff --git a/uitest/uitest/test.py b/uitest/uitest/test.py
new file mode 100644
index 000000000..5ed20add7
--- /dev/null
+++ b/uitest/uitest/test.py
@@ -0,0 +1,260 @@
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+import time
+import threading
+import os.path
+from contextlib import contextmanager
+from uitest.uihelper.common import get_state_as_dict
+
+from com.sun.star.uno import RuntimeException
+
+from libreoffice.uno.eventlistener import EventListener
+
+DEFAULT_SLEEP = 0.1
+
+class UITest(object):
+
+ def __init__(self, xUITest, xContext):
+ self._xUITest = xUITest
+ self._xContext = xContext
+ self._desktop = None
+
+ def get_desktop(self):
+ if self._desktop:
+ return self._desktop
+
+ self._desktop = self._xContext.ServiceManager.createInstanceWithContext("com.sun.star.frame.Desktop", self._xContext)
+ return self._desktop
+
+ def get_frames(self):
+ desktop = self.get_desktop()
+ frames = desktop.getFrames()
+ return frames
+
+ def get_component(self):
+ desktop = self.get_desktop()
+ components = desktop.getComponents()
+ for component in components:
+ if component is not None:
+ return component
+
+ def wait_for_top_focus_window(self, id):
+ while True:
+ win = self._xUITest.getTopFocusWindow()
+ if get_state_as_dict(win)['ID'] == id:
+ return win
+ time.sleep(DEFAULT_SLEEP)
+
+ def wait_until_child_is_available(self, childName):
+ while True:
+ xDialog = self._xUITest.getTopFocusWindow()
+ if childName in xDialog.getChildren():
+ return xDialog.getChild(childName)
+ else:
+ time.sleep(DEFAULT_SLEEP)
+
+ def wait_until_property_is_updated(self, element, propertyName, value):
+ while True:
+ if get_state_as_dict(element)[propertyName] == value:
+ return
+ else:
+ time.sleep(DEFAULT_SLEEP)
+
+ def wait_until_file_is_available(self, fileName):
+ while True:
+ if os.path.isfile(fileName):
+ return
+ else:
+ time.sleep(DEFAULT_SLEEP)
+
+ @contextmanager
+ def wait_until_component_loaded(self):
+ with EventListener(self._xContext, "OnLoad") as event:
+ yield
+ while True:
+ if event.executed:
+ frames = self.get_frames()
+ if len(frames) == 1:
+ self.get_desktop().setActiveFrame(frames[0])
+ time.sleep(DEFAULT_SLEEP)
+ return
+ time.sleep(DEFAULT_SLEEP)
+
+ def load_component_from_url(self, url, eventName="OnLoad"):
+ with EventListener(self._xContext, eventName) as event:
+ component = self.get_desktop().loadComponentFromURL(url, "_default", 0, tuple())
+ while True:
+ if event.executed:
+ frames = self.get_frames()
+ #activate the newest frame
+ self.get_desktop().setActiveFrame(frames[-1])
+ return component
+ time.sleep(DEFAULT_SLEEP)
+
+ # Calls UITest.close_doc at exit
+ @contextmanager
+ def load_file(self, url):
+ try:
+ yield self.load_component_from_url(url)
+ finally:
+ self.close_doc()
+
+ # Calls UITest.close_doc at exit
+ @contextmanager
+ def load_empty_file(self, app):
+ try:
+ yield self.load_component_from_url("private:factory/s" + app, "OnNew")
+ finally:
+ self.close_doc()
+
+ # Calls UITest.close_dialog_through_button at exit
+ @contextmanager
+ def execute_dialog_through_command(self, command, printNames=False, close_button = "ok", eventName = "DialogExecute"):
+ with EventListener(self._xContext, eventName, printNames=printNames) as event:
+ if not self._xUITest.executeDialog(command):
+ raise Exception("Dialog not executed for: " + command)
+ while True:
+ if event.executed:
+ xDialog = self._xUITest.getTopFocusWindow()
+ try:
+ yield xDialog
+ except:
+ if not close_button:
+ if 'cancel' in xDialog.getChildren():
+ self.close_dialog_through_button(xDialog.getChild("cancel"))
+ raise
+ finally:
+ if close_button:
+ self.close_dialog_through_button(xDialog.getChild(close_button))
+ return
+ time.sleep(DEFAULT_SLEEP)
+
+ @contextmanager
+ def execute_modeless_dialog_through_command(self, command, printNames=False, close_button = "ok"):
+ with self.execute_dialog_through_command(command, printNames, close_button, "ModelessDialogVisible") as xDialog:
+ yield xDialog
+
+ # Calls UITest.close_dialog_through_button at exit
+ @contextmanager
+ def execute_dialog_through_action(self, ui_object, action, parameters = None, event_name = "DialogExecute", close_button = "ok"):
+ if parameters is None:
+ parameters = tuple()
+
+ with EventListener(self._xContext, event_name) as event:
+ ui_object.executeAction(action, parameters)
+ while True:
+ if event.executed:
+ xDialog = self._xUITest.getTopFocusWindow()
+ try:
+ yield xDialog
+ finally:
+ if close_button:
+ self.close_dialog_through_button(xDialog.getChild(close_button))
+ return
+ time.sleep(DEFAULT_SLEEP)
+
+ def _handle_crash_reporter(self):
+ xCrashReportDlg = self._xUITest.getTopFocusWindow()
+ state = get_state_as_dict(xCrashReportDlg)
+ print(state)
+ if state['ID'] != "CrashReportDialog":
+ return False
+ print("found a crash reporter")
+ xCancelBtn = xCrashReportDlg.getChild("btn_cancel")
+ self.close_dialog_through_button(xCancelBtn)
+ return True
+
+ # Calls UITest.close_doc at exit
+ @contextmanager
+ def create_doc_in_start_center(self, app):
+ xStartCenter = self._xUITest.getTopFocusWindow()
+ try:
+ xBtn = xStartCenter.getChild(app + "_all")
+ except RuntimeException:
+ if self._handle_crash_reporter():
+ xStartCenter = self._xUITest.getTopFocusWindow()
+ xBtn = xStartCenter.getChild(app + "_all")
+ else:
+ raise
+
+ with EventListener(self._xContext, "OnNew") as event:
+ xBtn.executeAction("CLICK", tuple())
+ while True:
+ if event.executed:
+ frames = self.get_frames()
+ self.get_desktop().setActiveFrame(frames[0])
+ component = self.get_component()
+ try:
+ yield component
+ finally:
+ self.close_doc()
+ return
+ time.sleep(DEFAULT_SLEEP)
+
+ def close_dialog_through_button(self, button):
+ with EventListener(self._xContext, "DialogClosed" ) as event:
+ button.executeAction("CLICK", tuple())
+ while True:
+ if event.executed:
+ time.sleep(DEFAULT_SLEEP)
+ return
+ time.sleep(DEFAULT_SLEEP)
+
+ def close_doc(self):
+ desktop = self.get_desktop()
+ active_frame = desktop.getActiveFrame()
+ if not active_frame:
+ print("close_doc: no active frame")
+ return
+ component = active_frame.getController().getModel()
+ if not component:
+ print("close_doc: active frame has no component")
+ return
+ component.dispose()
+ frames = desktop.getFrames()
+ if frames:
+ frames[0].activate()
+
+ @contextmanager
+ def execute_blocking_action(self, action, args=(), close_button="ok", printNames=False):
+ """Executes an action which blocks while a dialog is shown.
+
+ Click a button or perform some other action on the dialog when it
+ is shown.
+
+ Args:
+ action(callable): Will be called to show a dialog, and is expected
+ to block while the dialog is shown.
+ close_button(str): The name of a button which will be clicked to close
+ the dialog. if it's empty, the dialog won't be closed from here.
+ This is useful when consecutive dialogs are open one after the other.
+ args(tuple, optional): The arguments to be passed to `action`
+ printNames: print all received event names
+ """
+
+ thread = threading.Thread(target=action, args=args)
+ with EventListener(self._xContext, ["DialogExecute", "ModelessDialogExecute", "ModelessDialogVisible"], printNames=printNames) as event:
+ thread.start()
+ while True:
+ if event.executed:
+ xDialog = self._xUITest.getTopFocusWindow()
+ try:
+ yield xDialog
+ except:
+ if not close_button:
+ if 'cancel' in xDialog.getChildren():
+ self.close_dialog_through_button(xDialog.getChild("cancel"))
+ raise
+ finally:
+ if close_button:
+ self.close_dialog_through_button(xDialog.getChild(close_button))
+ thread.join()
+ return
+ time.sleep(DEFAULT_SLEEP)
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab: