Rebased ref, commits from common ancestor: commit e6e2af2cb6093ca287733f05f2289df3fddb3bc5 Author: Markus Mohrhard <markus.mohrh...@googlemail.com> Date: Thu Mar 24 01:21:13 2016 +0100
add test for tdf#98427 Change-Id: I4cc29cfd3b2ac0b4889e82c3565319455cafc1eb diff --git a/uitest/calc_tests/function_wizard.py b/uitest/calc_tests/function_wizard.py new file mode 100644 index 0000000..6d8aa32 --- /dev/null +++ b/uitest/calc_tests/function_wizard.py @@ -0,0 +1,42 @@ +# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-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/. +# + +from uitest_helper import UITest + +from helper import mkPropertyValues +import time + +try: + import pyuno + import uno + import unohelper +except ImportError: + print("pyuno not found: try to set PYTHONPATH and URE_BOOTSTRAP variables") + print("PYTHONPATH=/installation/opt/program") + print("URE_BOOTSTRAP=file:///installation/opt/program/fundamentalrc") + raise + +# tdf#98427 +def open_function_wizard(xContext): + xUITest = xContext.ServiceManager.createInstanceWithContext( + "org.libreoffice.uitest.UITest", xContext) + + ui_test = UITest(xUITest, xContext) + + ui_test.create_doc_in_start_center("calc") + + ui_test.execute_modeless_dialog_through_command(".uno:FunctionDialog") + + xFunctionDlg = xUITest.getTopFocusWindow() + + xArrayChkBox = xFunctionDlg.getChild("array") + xArrayChkBox.executeAction("CLICK", tuple()) + + xCancelBtn = xFunctionDlg.getChild("cancel") + xCancelBtn.executeAction("CLICK", tuple()) + +# vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 9d794a37a3a04eb5326ad382e59b74a42fea255a Author: Markus Mohrhard <markus.mohrh...@googlemail.com> Date: Thu Mar 24 00:45:44 2016 +0100 also remove the screenshot part from function names Change-Id: Iac4f1724ed9c2a470ea1a1fe1ab0e834eb3f1795 diff --git a/uitest/calc_tests/about_test.py b/uitest/calc_tests/about_test.py index a9beb8e..9766518 100644 --- a/uitest/calc_tests/about_test.py +++ b/uitest/calc_tests/about_test.py @@ -9,7 +9,7 @@ import time from uitest_helper import UITest -def test_about_dlg_with_screenshot(xContext): +def test_about_dlg(xContext): xUITest = xContext.ServiceManager.createInstanceWithContext( "org.libreoffice.uitest.UITest", xContext) diff --git a/uitest/main.py b/uitest/main.py index 11e92ee..e4d4f39 100644 --- a/uitest/main.py +++ b/uitest/main.py @@ -57,7 +57,7 @@ if __name__ == "__main__": generic_test(opts, line) elif "--calc-demo" in opts: - generic_test(opts, "calc_tests.about_test.test_about_dlg_with_screenshot") + generic_test(opts, "calc_tests.about_test.test_about_dlg") generic_test(opts, "calc_tests.create_range_name.create_range_name") else: usage() commit 8d60cadd3a4755be2892e9bf883b6831ef5e63a1 Author: Markus Mohrhard <markus.mohrh...@googlemail.com> Date: Thu Mar 24 00:43:51 2016 +0100 remove all references to the screenshot functionality Change-Id: I3fb853fafbb2bc8271597cc1743fee99913257af diff --git a/uitest/calc_tests/about_test.py b/uitest/calc_tests/about_test.py index d90ee06..a9beb8e 100644 --- a/uitest/calc_tests/about_test.py +++ b/uitest/calc_tests/about_test.py @@ -8,20 +8,6 @@ import time from uitest_helper import UITest -from helper import Screenshot - -def get_bounding_box(props): - size_str = None - pos_str = None - for prop in props: - if prop.Name == "AbsPosition": - pos_str = prop.Value - elif prop.Name == "Size": - size_str = prop.Value - - x1, y1 = pos_str.split("x") - dx, dy = size_str.split("x") - return x1, y1, str(int(x1) + int(dx)), str(int(y1) + int(dy)) def test_about_dlg_with_screenshot(xContext): xUITest = xContext.ServiceManager.createInstanceWithContext( @@ -35,13 +21,6 @@ def test_about_dlg_with_screenshot(xContext): xAboutDlg = xUITest.getTopFocusWindow() - # take the screenshot - time.sleep(1) - aboutDlgState = xAboutDlg.getState() - x1, y1, x2, y2 = get_bounding_box(aboutDlgState) - screenshot = Screenshot() - screenshot.take_screenshot(x1, y1, x2, y2) - xCloseBtn = xAboutDlg.getChild("close") xCloseBtn.executeAction("CLICK", tuple()) diff --git a/uitest/helper.py b/uitest/helper.py index e660739..2c57d11 100644 --- a/uitest/helper.py +++ b/uitest/helper.py @@ -49,36 +49,6 @@ class EventListener(XDocumentEventListener,unohelper.Base): def disposing(event): pass -class Screenshot(object): - - def __init__(self): - pass - - def _create_python_path(self): - """ creates a clean PATH env variable - - We need to avoid picking the LibreOffice python and - the corresponding PYTHONPATH, PYTHONHOME variables - """ - env = os.environ.copy() - - # remove any python properties pointing to soffice internal python - del env['PYTHONPATH'] - del env['PYTHONHOME'] - - # remove path pointing to instdir to avoid picking up the soffice provided python - path = env['PATH'] - path_parts = path.split(':') - cleaned_path = (path for path in path_parts if path.find("instdir") == -1) - new_path = ":".join( cleaned_path ) - env['PATH'] = new_path - return env - - def take_screenshot(self, x1, y1, x2, y2): - env = self._create_python_path() - popen = subprocess.Popen(" ".join(["./screenshot.py", x1, y1, x2, y2]), shell=True, env=env) - popen.wait() - def mkPropertyValue(name, value): """ Create a UNO ProertyValue from two input values. """ diff --git a/uitest/screenshot.py b/uitest/screenshot.py deleted file mode 100755 index af3cd44..0000000 --- a/uitest/screenshot.py +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env python - -import sys - -import pyscreenshot as ImageGrab - -if __name__ == "__main__": - # part of the screen - if len(sys.argv) != 5: - sys.exit(1) - im=ImageGrab.grab(bbox=(int(sys.argv[1]),int(sys.argv[2]),int(sys.argv[3]),int(sys.argv[4]))) # X1,Y1,X2,Y2 - im.show() commit bc3e166f85ef9562411fe72dfe89496a6659533b Author: Markus Mohrhard <markus.mohrh...@googlemail.com> Date: Thu Mar 24 00:35:18 2016 +0100 move uitest python part from dev-tools Change-Id: I5a6464cb4e110d1da48b5f525f63e0a7de6dea58 diff --git a/uitest/__init__.py b/uitest/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/uitest/calc_tests/__init__.py b/uitest/calc_tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/uitest/calc_tests/about_test.py b/uitest/calc_tests/about_test.py new file mode 100644 index 0000000..d90ee06 --- /dev/null +++ b/uitest/calc_tests/about_test.py @@ -0,0 +1,48 @@ +# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-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 + +from uitest_helper import UITest +from helper import Screenshot + +def get_bounding_box(props): + size_str = None + pos_str = None + for prop in props: + if prop.Name == "AbsPosition": + pos_str = prop.Value + elif prop.Name == "Size": + size_str = prop.Value + + x1, y1 = pos_str.split("x") + dx, dy = size_str.split("x") + return x1, y1, str(int(x1) + int(dx)), str(int(y1) + int(dy)) + +def test_about_dlg_with_screenshot(xContext): + xUITest = xContext.ServiceManager.createInstanceWithContext( + "org.libreoffice.uitest.UITest", xContext) + + ui_test = UITest(xUITest, xContext) + + ui_test.create_doc_in_start_center("calc") + + ui_test.execute_dialog_through_command(".uno:About") + + xAboutDlg = xUITest.getTopFocusWindow() + + # take the screenshot + time.sleep(1) + aboutDlgState = xAboutDlg.getState() + x1, y1, x2, y2 = get_bounding_box(aboutDlgState) + screenshot = Screenshot() + screenshot.take_screenshot(x1, y1, x2, y2) + + xCloseBtn = xAboutDlg.getChild("close") + xCloseBtn.executeAction("CLICK", tuple()) + +# vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/uitest/calc_tests/create_range_name.py b/uitest/calc_tests/create_range_name.py new file mode 100644 index 0000000..9019753 --- /dev/null +++ b/uitest/calc_tests/create_range_name.py @@ -0,0 +1,42 @@ +# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-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/. +# + +from uitest_helper import UITest + +from helper import mkPropertyValues + +try: + import pyuno + import uno + import unohelper +except ImportError: + print("pyuno not found: try to set PYTHONPATH and URE_BOOTSTRAP variables") + print("PYTHONPATH=/installation/opt/program") + print("URE_BOOTSTRAP=file:///installation/opt/program/fundamentalrc") + raise + +def create_range_name(xContext): + xUITest = xContext.ServiceManager.createInstanceWithContext( + "org.libreoffice.uitest.UITest", xContext) + + ui_test = UITest(xUITest, xContext) + + ui_test.create_doc_in_start_center("calc") + + ui_test.execute_modeless_dialog_through_command(".uno:AddName") + + xAddNameDlg = xUITest.getTopFocusWindow() + + props = {"TEXT": "simpleRangeName"} + actionProps = mkPropertyValues(props) + + xEdit = xAddNameDlg.getChild("edit") + xEdit.executeAction("TYPE", actionProps) + xAddBtn = xAddNameDlg.getChild("add") + xAddBtn.executeAction("CLICK", tuple()) + +# vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/uitest/connection.py b/uitest/connection.py new file mode 100644 index 0000000..0c87f30 --- /dev/null +++ b/uitest/connection.py @@ -0,0 +1,147 @@ +# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-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 os +import subprocess +import sys +import time +import uuid +import datetime + +try: + import pyuno + import uno + import unohelper +except ImportError: + print("pyuno not found: try to set PYTHONPATH and URE_BOOTSTRAP variables") + print("PYTHONPATH=/installation/opt/program") + print("URE_BOOTSTRAP=file:///installation/opt/program/fundamentalrc") + raise + +class OfficeConnection: + def __init__(self, args): + self.args = args + self.soffice = None + self.socket = None + self.xContext = None + self.pro = None + + def setUp(self): + (method, sep, rest) = self.args["--soffice"].partition(":") + if sep != ":": + raise Exception("soffice parameter does not specify method") + if method == "path": + socket = "pipe,name=pytest" + str(uuid.uuid1()) + try: + userdir = self.args["--userdir"] + except KeyError: + raise Exception("'path' method requires --userdir") + if not(userdir.startswith("file://")): + raise Exception("--userdir must be file URL") + self.soffice = self.bootstrap(rest, userdir, socket) + elif method == "connect": + socket = rest + else: + raise Exception("unsupported connection method: " + method) + self.xContext = self.connect(socket) + + def bootstrap(self, soffice, userdir, socket): + argv = [ soffice, "--accept=" + socket + ";urp", + "-env:UserInstallation=" + userdir, + "--quickstart=no", "--nofirststartwizard", + "--norestore", "--nologo" ] + if "--valgrind" in self.args: + argv.append("--valgrind") + self.pro = subprocess.Popen(argv) + return self.pro + + def connect(self, socket): + xLocalContext = uno.getComponentContext() + xUnoResolver = xLocalContext.ServiceManager.createInstanceWithContext( + "com.sun.star.bridge.UnoUrlResolver", xLocalContext) + url = "uno:" + socket + ";urp;StarOffice.ComponentContext" + print("OfficeConnection: connecting to: " + url) + while True: + try: + xContext = xUnoResolver.resolve(url) + return xContext +# except com.sun.star.connection.NoConnectException + except pyuno.getClass("com.sun.star.connection.NoConnectException"): + print("NoConnectException: sleeping...") + time.sleep(1) + + def tearDown(self): + if self.soffice: + if self.xContext: + try: + print("tearDown: calling terminate()...") + xMgr = self.xContext.ServiceManager + xDesktop = xMgr.createInstanceWithContext( + "com.sun.star.frame.Desktop", self.xContext) + xDesktop.terminate() + print("...done") +# except com.sun.star.lang.DisposedException: + except pyuno.getClass("com.sun.star.beans.UnknownPropertyException"): + print("caught UnknownPropertyException while TearDown") + pass # ignore, also means disposed + except pyuno.getClass("com.sun.star.lang.DisposedException"): + print("caught DisposedException while TearDown") + pass # ignore + else: + self.soffice.terminate() + ret = self.soffice.wait() + self.xContext = None + self.socket = None + self.soffice = None + if ret != 0: + raise Exception("Exit status indicates failure: " + str(ret)) + + def kill(self): + command = "kill " + str(self.pro.pid) + print(command) + os.system(command) + + @classmethod + def getHelpText(cls): + message = """ + --soffice=method:location + specify soffice instance to connect to + supported methods: 'path', 'connect' + --userdir=URL specify user installation directory for 'path' method + --valgrind pass --valgrind to soffice for 'path' method + + 'location' is a pathname, not a URL. 'userdir' is a URL. + """ + return message + + +class PersistentConnection: + def __init__(self, args): + self.args = args + self.connection = None + def getContext(self): + return self.connection.xContext + def setUp(self): + assert(not self.connection) + conn = OfficeConnection(self.args) + conn.setUp() + self.connection = conn + def preTest(self): + assert(self.connection) + def postTest(self): + assert(self.connection) + def tearDown(self): + if self.connection: + try: + self.connection.tearDown() + finally: + self.connection = None + def kill(self): + if self.connection: + self.connection.kill() + +# vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/uitest/demo_ui/checkbox.py b/uitest/demo_ui/checkbox.py new file mode 100644 index 0000000..b855652 --- /dev/null +++ b/uitest/demo_ui/checkbox.py @@ -0,0 +1,37 @@ +# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-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/. +# + +from uitest_helper import UITest + +from helper import mkPropertyValues + +import time + +try: + import pyuno + import uno + import unohelper +except ImportError: + print("pyuno not found: try to set PYTHONPATH and URE_BOOTSTRAP variables") + print("PYTHONPATH=/installation/opt/program") + print("URE_BOOTSTRAP=file:///installation/opt/program/fundamentalrc") + raise + +def toggle_checkbox(xContext): + xUITest = xContext.ServiceManager.createInstanceWithContext( + "org.libreoffice.uitest.UITest", xContext) + + ui_test = UITest(xUITest, xContext) + + ui_test.create_doc_in_start_center("calc") + + ui_test.execute_dialog_through_command(".uno:FormatCellDialog") + xCellsDlg = xUITest.getTopFocusWindow() + xNegativeNumRedCB = xCellsDlg.getChild("negnumred") + xNegativeNumRedCB.executeAction("CLICK",tuple()) + +# vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/uitest/demo_ui/combobox.py b/uitest/demo_ui/combobox.py new file mode 100644 index 0000000..8cb7ac8 --- /dev/null +++ b/uitest/demo_ui/combobox.py @@ -0,0 +1,28 @@ +# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-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/. +# + +from uitest_helper import UITest + +from helper import mkPropertyValues + +def select_entry_pos(xContext): + xUITest = xContext.ServiceManager.createInstanceWithContext( + "org.libreoffice.uitest.UITest", xContext) + + ui_test = UITest(xUITest, xContext) + + ui_test.create_doc_in_start_center("calc") + + ui_test.execute_modeless_dialog_through_command(".uno:AddName") + xAddNameDlg = xUITest.getTopFocusWindow() + + scopeCB = xAddNameDlg.getChild("scope") + props = {"POS": "1"} + actionProps = mkPropertyValues(props) + scopeCB.executeAction("SELECT", actionProps) + +# vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/uitest/demo_ui/edit.py b/uitest/demo_ui/edit.py new file mode 100644 index 0000000..dab55c5 --- /dev/null +++ b/uitest/demo_ui/edit.py @@ -0,0 +1,47 @@ +# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-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/. +# + +from uitest_helper import UITest + +from helper import mkPropertyValues + +try: + import pyuno + import uno + import unohelper +except ImportError: + print("pyuno not found: try to set PYTHONPATH and URE_BOOTSTRAP variables") + print("PYTHONPATH=/installation/opt/program") + print("URE_BOOTSTRAP=file:///installation/opt/program/fundamentalrc") + raise + +def type_text(xContext): + xUITest = xContext.ServiceManager.createInstanceWithContext( + "org.libreoffice.uitest.UITest", xContext) + + ui_test = UITest(xUITest, xContext) + + ui_test.create_doc_in_start_center("calc") + + ui_test.execute_modeless_dialog_through_command(".uno:AddName") + xAddNameDlg = xUITest.getTopFocusWindow() + + xEdit = xAddNameDlg.getChild("edit") + + props = {"TEXT": "simpleRangeName"} + actionProps = mkPropertyValues(props) + xEdit.executeAction("TYPE", actionProps) + + xAddBtn = xAddNameDlg.getChild("cancel") + xAddBtn.executeAction("CLICK", tuple()) + + xUITest.executeCommand(".uno:CloseDoc") + + ui_test.close_doc() + + +# vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/uitest/demo_ui/listbox.py b/uitest/demo_ui/listbox.py new file mode 100644 index 0000000..41c6e4d --- /dev/null +++ b/uitest/demo_ui/listbox.py @@ -0,0 +1,45 @@ +# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-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/. +# + +from uitest_helper import UITest + +from helper import mkPropertyValues + +def select_entry_pos(xContext): + xUITest = xContext.ServiceManager.createInstanceWithContext( + "org.libreoffice.uitest.UITest", xContext) + + ui_test = UITest(xUITest, xContext) + + ui_test.create_doc_in_start_center("calc") + + ui_test.execute_dialog_through_command(".uno:FormatCellDialog") + xCellsDlg = xUITest.getTopFocusWindow() + + categoryLB = xCellsDlg.getChild("categorylb") + props = {"POS": "4"} + actionProps = mkPropertyValues(props) + categoryLB.executeAction("SELECT", actionProps) + +def select_entry_text(xContext): + xUITest = xContext.ServiceManager.createInstanceWithContext( + "org.libreoffice.uitest.UITest", xContext) + + ui_test = UITest(xUITest, xContext) + + ui_test.create_doc_in_start_center("calc") + + ui_test.execute_dialog_through_command(".uno:FormatCellDialog") + xCellsDlg = xUITest.getTopFocusWindow() + + categoryLB = xCellsDlg.getChild("categorylb") + props = {"TEXT": "Time"} + + actionProps = mkPropertyValues(props) + categoryLB.executeAction("SELECT", actionProps) + +# vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/uitest/helper.py b/uitest/helper.py new file mode 100644 index 0000000..e660739 --- /dev/null +++ b/uitest/helper.py @@ -0,0 +1,93 @@ +# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-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 os +import subprocess + +try: + import pyuno + import uno + import unohelper +except ImportError: + print("pyuno not found: try to set PYTHONPATH and URE_BOOTSTRAP variables") + print("PYTHONPATH=/installation/opt/program") + print("URE_BOOTSTRAP=file:///installation/opt/program/fundamentalrc") + raise + +try: + from com.sun.star.document import XDocumentEventListener +except ImportError: + print("UNO API class not found: try to set URE_BOOTSTRAP variable") + print("URE_BOOTSTRAP=file:///installation/opt/program/fundamentalrc") + raise + +class EventListener(XDocumentEventListener,unohelper.Base): + + def __init__(self, xContext, eventName): + self.xGEB = xContext.ServiceManager.createInstanceWithContext( + "com.sun.star.frame.GlobalEventBroadcaster", xContext) + self.xContext = xContext + self.executed = False + self.eventName = eventName + + def __enter__(self): + self.xGEB.addDocumentEventListener(self) + return self + + def __exit__(self, type, value, traceback): + self.xGEB.removeDocumentEventListener(self) + + def documentEventOccured(self, event): + print(str(event.EventName)) + if event.EventName == self.eventName: + self.executed = True + + def disposing(event): + pass + +class Screenshot(object): + + def __init__(self): + pass + + def _create_python_path(self): + """ creates a clean PATH env variable + + We need to avoid picking the LibreOffice python and + the corresponding PYTHONPATH, PYTHONHOME variables + """ + env = os.environ.copy() + + # remove any python properties pointing to soffice internal python + del env['PYTHONPATH'] + del env['PYTHONHOME'] + + # remove path pointing to instdir to avoid picking up the soffice provided python + path = env['PATH'] + path_parts = path.split(':') + cleaned_path = (path for path in path_parts if path.find("instdir") == -1) + new_path = ":".join( cleaned_path ) + env['PATH'] = new_path + return env + + def take_screenshot(self, x1, y1, x2, y2): + env = self._create_python_path() + popen = subprocess.Popen(" ".join(["./screenshot.py", x1, y1, x2, y2]), shell=True, env=env) + popen.wait() + +def mkPropertyValue(name, value): + """ Create a UNO ProertyValue from two input values. + """ + return uno.createUnoStruct("com.sun.star.beans.PropertyValue", + name, 0, value, 0) + +def mkPropertyValues(vals): + """ Create UNO property values from a map. + """ + return tuple([mkPropertyValue(name, value) for (name, value) in vals.items()]) + +# vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/uitest/main.py b/uitest/main.py new file mode 100644 index 0000000..11e92ee --- /dev/null +++ b/uitest/main.py @@ -0,0 +1,66 @@ +# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-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 sys +import getopt +import os +import importlib + +from connection import PersistentConnection, OfficeConnection + +def load_test(name): + module_name, obj_name = name.rsplit(".", 1) + module = importlib.import_module(module_name) + obj = getattr(module, obj_name) + return obj + +def generic_test(opts, test_name): + connection = PersistentConnection(opts) + connection.setUp() + xContext = connection.getContext() + func = load_test(test_name) + func(xContext) + connection.tearDown() + +def parseArgs(argv): + (optlist,args) = getopt.getopt(argv[1:], "hr", + ["help", "soffice=", "userdir=", "calc-demo", "file="]) + return (dict(optlist), args) + +def usage(): + message = """usage: {program} [option]... [task_file]..." + -h | --help: print usage information + {connection_params} + the 'task_file' parameters should be + full absolute pathnames, not URLs.""" + print(message.format(program = os.path.basename(sys.argv[0]), \ + connection_params = OfficeConnection.getHelpText())) + +if __name__ == "__main__": + (opts,args) = parseArgs(sys.argv) + if "-h" in opts or "--help" in opts: + usage() + sys.exit() + elif not "--soffice" in opts: + usage() + sys.exit(1) + elif "--file" in opts: + file_name = opts["--file"] + with open(file_name) as f: + lines = f.readlines() + for line in lines: + line = line.strip() + generic_test(opts, line) + + elif "--calc-demo" in opts: + generic_test(opts, "calc_tests.about_test.test_about_dlg_with_screenshot") + generic_test(opts, "calc_tests.create_range_name.create_range_name") + else: + usage() + sys.exit(1) + +# vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/uitest/screenshot.py b/uitest/screenshot.py new file mode 100755 index 0000000..af3cd44 --- /dev/null +++ b/uitest/screenshot.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python + +import sys + +import pyscreenshot as ImageGrab + +if __name__ == "__main__": + # part of the screen + if len(sys.argv) != 5: + sys.exit(1) + im=ImageGrab.grab(bbox=(int(sys.argv[1]),int(sys.argv[2]),int(sys.argv[3]),int(sys.argv[4]))) # X1,Y1,X2,Y2 + im.show() diff --git a/uitest/uitest_helper.py b/uitest/uitest_helper.py new file mode 100644 index 0000000..3f46618 --- /dev/null +++ b/uitest/uitest_helper.py @@ -0,0 +1,77 @@ +# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-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 + +from helper import EventListener + +class UITest(object): + + def __init__(self, xUITest, xContext): + self._xUITest = xUITest + self._xContext = xContext + + def execute_dialog_through_command(self, command): + with EventListener(self._xContext, "DialogExecute") as event: + self._xUITest.executeCommand(command) + time_ = 0 + while time_ < 30: + if event.executed: + time.sleep(1) + return + time_ += 1 + time.sleep(1) + + # report a failure here + print("failure execute modal dialog") + + def execute_modeless_dialog_through_command(self, command): + with EventListener(self._xContext, "ModelessDialogVisible") as event: + self._xUITest.executeCommand(command) + time_ = 0 + while time_ < 30: + if event.executed: + time.sleep(1) + return + time_ += 1 + time.sleep(1) + + # report a failure here + print("failure execute modeless dialog") + + def create_doc_in_start_center(self, app): + xStartCenter = self._xUITest.getTopFocusWindow() + xBtn = xStartCenter.getChild(app + "_all") + with EventListener(self._xContext, "OnNew") as event: + xBtn.executeAction("CLICK", tuple()) + time_ = 0 + while time_ < 30: + if event.executed: + return + time_ += 1 + time.sleep(1) + + print("failure doc in start center") + + # report a failure here + + def close_doc(self): + # also need to handle "OnViewClosed" event + with EventListener(self._xContext, "DialogExecute") as event: + self._xUITest.executeCommand(".uno.CloseDoc") + time_ = 0 + while time_ < 30: + if event.executed: + xCloseDlg = self._xUITest.getTopFocusWindow() + xNoBtn = xCloseDlg.getChild("discard") + xNoBtn.executeAction("CLICK", tuple()) + return + + time_ += 1 + time.sleep(1) + +# vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 6586cf5289349dcc6af111b7364836e78386460d Author: Markus Mohrhard <markus.mohrh...@googlemail.com> Date: Tue Feb 16 10:41:06 2016 +0100 ignore crashreport if norestore was specified Change-Id: I849b3e693e59e6846ee5afed1b75790531b68696 diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx index 3166b34..65d4639 100644 --- a/desktop/source/app/app.cxx +++ b/desktop/source/app/app.cxx @@ -2259,6 +2259,11 @@ void Desktop::OpenClients() } } +#if HAVE_FEATURE_BREAKPAD + if (!rArgs.IsNoRestore() && crashReportInfoExists()) + handleCrashReport(); +#endif + // Disable AutoSave feature in case "--norestore" or a similar command line switch is set on the command line. // The reason behind: AutoSave/EmergencySave/AutoRecovery share the same data. // But the require that all documents, which are saved as backup should exists inside commit a07cdf67aad424fcaa702541fbe86736740d1d75 Author: Markus Mohrhard <markus.mohrh...@googlemail.com> Date: Mon Mar 28 18:35:51 2016 +0200 temp diff --git a/vcl/source/uitest/uno/uiobject_uno.cxx b/vcl/source/uitest/uno/uiobject_uno.cxx index 8f3a3c5..fc66839 100644 --- a/vcl/source/uitest/uno/uiobject_uno.cxx +++ b/vcl/source/uitest/uno/uiobject_uno.cxx @@ -24,7 +24,10 @@ css::uno::Reference<css::ui::test::XUIObject> SAL_CALL UIObjectUnoObj::getChild( throw (css::uno::RuntimeException, std::exception) { SolarMutexGuard aGuard; + SAL_DEBUG(mpObj->get_state()["ID"]); + SAL_DEBUG(rID); std::unique_ptr<UIObject> pObj = mpObj->get_child(rID); + assert(pObj); return new UIObjectUnoObj(std::move(pObj)); } diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx index 6585e9b..c48ba70 100644 --- a/vcl/source/window/window.cxx +++ b/vcl/source/window/window.cxx @@ -44,6 +44,9 @@ #include <vcl/settings.hxx> #include <vcl/sysdata.hxx> +#include "uitest/uiobject_impl.hxx" +#include <vcl/uitest/uitest.hxx> + #include <salframe.hxx> #include <salobj.hxx> #include <salinst.hxx> @@ -1831,7 +1834,35 @@ void Window::KeyInput( const KeyEvent& rKEvt ) if (cod.IsShift() && cod.IsMod1() && cod.GetCode() == KEY_F12) { + WindowUIObject aObject(this); + aObject.dumpState(); + + StringMap aMap; + aMap["TEXT"] = "asd%3"; + aObject.execute("TYPE", aMap); + } + if (cod.IsShift() && cod.IsMod1() && cod.GetCode() == KEY_F10) + { + WindowUIObject aObject(this); + std::unique_ptr<UIObject> pCancelBtn = aObject.get_child("edit"); + StringMap aMap; + aMap["TEXT"] = "asd%3"; + pCancelBtn->execute("SET", aMap); + return; + } + + if (cod.IsShift() && cod.IsMod1() && cod.GetCode() == KEY_F11) + { + WindowUIObject aObject(this); + aObject.dumpHierarchy(); + } + + if (cod.IsShift() && cod.IsMod1() && cod.GetCode() == KEY_F9) + { + UITest aTest; + std::unique_ptr<UIObject> pObject = aTest.getFocusTopWindow(); + pObject->dumpState(); } NotifyEvent aNEvt( MouseNotifyEvent::KEYINPUT, this, &rKEvt ); commit 834e240192604f5c268ee40e1a8a0021a3b35ff5 Author: Markus Mohrhard <markus.mohrh...@googlemail.com> Date: Mon Mar 28 18:35:14 2016 +0200 add todo comment Change-Id: Ie2f5f1342f3d91aeb43d5c9c62a2dbac4c801451 diff --git a/vcl/inc/uitest/uiobject_impl.hxx b/vcl/inc/uitest/uiobject_impl.hxx index 44e2084..a23d57fc 100644 --- a/vcl/inc/uitest/uiobject_impl.hxx +++ b/vcl/inc/uitest/uiobject_impl.hxx @@ -44,6 +44,7 @@ protected: }; +// TODO: moggi: what about push buttons? class ButtonUIObject : public WindowUIObject { VclPtr<Button> mxButton; commit 65f75d444ec7f1c4354749952d86d80d2e94f97c Author: Markus Mohrhard <markus.mohrh...@googlemail.com> Date: Mon Mar 28 18:34:44 2016 +0200 initial support for spinbuttons in uitesting Change-Id: I4e62cb65cecdff8ac1a89c3f9c3a14e5206a9115 diff --git a/include/vcl/uitest/uiobject.hxx b/include/vcl/uitest/uiobject.hxx index 63246e8..55f5088 100644 --- a/include/vcl/uitest/uiobject.hxx +++ b/include/vcl/uitest/uiobject.hxx @@ -23,6 +23,7 @@ enum class UIObjectType CHECKBOX, LISTBOX, COMBOBOX, + SPINBUTTON, TABPAGE, UNKNOWN }; diff --git a/vcl/inc/uitest/uiobject_impl.hxx b/vcl/inc/uitest/uiobject_impl.hxx index f8391b4..44e2084 100644 --- a/vcl/inc/uitest/uiobject_impl.hxx +++ b/vcl/inc/uitest/uiobject_impl.hxx @@ -15,6 +15,7 @@ class TabPage; class ComboBox; +class SpinButton; class WindowUIObject : public UIObject { @@ -183,4 +184,25 @@ protected: virtual OUString get_name() const override; }; +class SpinUIObject : public WindowUIObject +{ +private: + VclPtr<SpinButton> mxSpinButton; + +public: + + SpinUIObject(VclPtr<SpinButton> xSpinButton); + + virtual void execute(const OUString& rAction, + const StringMap& rParameters) override; + + virtual StringMap get_state() override; + + virtual UIObjectType get_type() const override; + +protected: + + virtual OUString get_name() const override; +}; + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/uitest/uiobject.cxx b/vcl/source/uitest/uiobject.cxx index 57ef1ec..259cb9f 100644 --- a/vcl/source/uitest/uiobject.cxx +++ b/vcl/source/uitest/uiobject.cxx @@ -14,6 +14,7 @@ #include <vcl/tabpage.hxx> #include <vcl/lstbox.hxx> #include <vcl/combobox.hxx> +#include <vcl/spin.hxx> #include <rtl/ustrbuf.hxx> @@ -548,4 +549,42 @@ OUString ComboBoxUIObject::get_name() const return OUString("ComboBoxUIObject"); } +SpinUIObject::SpinUIObject(VclPtr<SpinButton> xSpinButton): + WindowUIObject(xSpinButton), + mxSpinButton(xSpinButton) +{ +} + +void SpinUIObject::execute(const OUString& rAction, + const StringMap& rParameters) +{ + if (rAction == "UP") + { + /* code */ + } + else if (rAction == "DOWN") + { + } +} + +StringMap SpinUIObject::get_state() +{ + StringMap aMap = WindowUIObject::get_state(); + aMap["Min"] = OUString::number(mxSpinButton->GetRangeMin()); + aMap["Max"] = OUString::number(mxSpinButton->GetRangeMax()); + aMap["Step"] = OUString::number(mxSpinButton->GetValueStep()); + aMap["Value"] = OUString::number(mxSpinButton->GetValue()); + + return aMap; +} + +UIObjectType SpinUIObject::get_type() const +{ + return UIObjectType::SPINBUTTON; +} + +OUString SpinUIObject::get_name() const +{ + return OUString("SpinUIObject"); +} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 5102cd012be33c5d0ff182e7c2581a4b85b00e12 Author: Markus Mohrhard <markus.mohrh...@googlemail.com> Date: Mon Mar 28 18:33:30 2016 +0200 add initial support for combo boxes to uitesting Change-Id: I82aa2d877216bc1bb984bd16e2d1d54a15fcc4fa diff --git a/include/vcl/uitest/uiobject.hxx b/include/vcl/uitest/uiobject.hxx index 2754f67..63246e8 100644 --- a/include/vcl/uitest/uiobject.hxx +++ b/include/vcl/uitest/uiobject.hxx @@ -22,6 +22,7 @@ enum class UIObjectType EDIT, CHECKBOX, LISTBOX, + COMBOBOX, TABPAGE, UNKNOWN }; diff --git a/vcl/inc/uitest/uiobject_impl.hxx b/vcl/inc/uitest/uiobject_impl.hxx index 7a5bd04..f8391b4 100644 --- a/vcl/inc/uitest/uiobject_impl.hxx +++ b/vcl/inc/uitest/uiobject_impl.hxx @@ -14,6 +14,7 @@ #include <vcl/edit.hxx> class TabPage; +class ComboBox; class WindowUIObject : public UIObject { @@ -160,4 +161,26 @@ protected: virtual OUString get_name() const override; }; +// TODO: moggi: should it inherit from EditUIObject? +class ComboBoxUIObject : public WindowUIObject +{ +private: + VclPtr<ComboBox> mxComboBox; + +public: + + ComboBoxUIObject(VclPtr<ComboBox> xListBox); + + virtual void execute(const OUString& rAction, + const StringMap& rParameters) override; + + virtual StringMap get_state() override; + + virtual UIObjectType get_type() const override; + +protected: + + virtual OUString get_name() const override; +}; + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/uitest/factory.cxx b/vcl/source/uitest/factory.cxx index 9827c02..77c3eb9 100644 --- a/vcl/source/uitest/factory.cxx +++ b/vcl/source/uitest/factory.cxx @@ -12,6 +12,7 @@ #include <vcl/tabpage.hxx> #include <vcl/lstbox.hxx> +#include <vcl/combobox.hxx> std::unique_ptr<UIObject> UITestWrapperFactory::createObject(vcl::Window* pWindow) { @@ -68,6 +69,13 @@ std::unique_ptr<UIObject> UITestWrapperFactory::createObject(vcl::Window* pWindo return std::unique_ptr<UIObject>(new CheckBoxUIObject(pCheckBox)); } break; + case WINDOW_COMBOBOX: + { + ComboBox* pComboBox = dynamic_cast<ComboBox*>(pWindow); + assert(pComboBox); + return std::unique_ptr<UIObject>(new ComboBoxUIObject(pComboBox)); + } + break; case WINDOW_LISTBOX: { ListBox* pListBox = dynamic_cast<ListBox*>(pWindow); diff --git a/vcl/source/uitest/uiobject.cxx b/vcl/source/uitest/uiobject.cxx index d401ccb..57ef1ec 100644 --- a/vcl/source/uitest/uiobject.cxx +++ b/vcl/source/uitest/uiobject.cxx @@ -13,6 +13,7 @@ #include <vcl/event.hxx> #include <vcl/tabpage.hxx> #include <vcl/lstbox.hxx> +#include <vcl/combobox.hxx> #include <rtl/ustrbuf.hxx> @@ -508,4 +509,43 @@ OUString ListBoxUIObject::get_name() const return OUString("ListBoxUIObject"); } +ComboBoxUIObject::ComboBoxUIObject(VclPtr<ComboBox> xComboBox): + WindowUIObject(xComboBox), + mxComboBox(xComboBox) +{ +} + +void ComboBoxUIObject::execute(const OUString& rAction, + const StringMap& rParameters) +{ + if (rAction == "SELECT") + { + if (rParameters.find("POS") != rParameters.end()) + { + auto itr = rParameters.find("POS"); + OUString aVal = itr->second; + sal_Int32 nPos = aVal.toInt32(); + mxComboBox->SelectEntryPos(nPos); + } + mxComboBox->Select(); + } +} + +StringMap ComboBoxUIObject::get_state() +{ + StringMap aMap = WindowUIObject::get_state(); + + return aMap; +} + +UIObjectType ComboBoxUIObject::get_type() const +{ + return UIObjectType::COMBOBOX; +} + +OUString ComboBoxUIObject::get_name() const +{ + return OUString("ComboBoxUIObject"); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 22447f419f6ded1ee34344f452c2dda0d9b8a069 Author: Markus Mohrhard <markus.mohrh...@googlemail.com> Date: Mon Mar 28 18:30:57 2016 +0200 don't allow access to disabled or hidden listbox This should maybe be extended to other parts of the framework. Change-Id: I03137bc34a1e4b8e6ba4024f66d1dfde122bb9d2 diff --git a/vcl/source/uitest/uiobject.cxx b/vcl/source/uitest/uiobject.cxx index b266b7d..d401ccb 100644 --- a/vcl/source/uitest/uiobject.cxx +++ b/vcl/source/uitest/uiobject.cxx @@ -464,6 +464,9 @@ ListBoxUIObject::ListBoxUIObject(VclPtr<ListBox> xListBox): void ListBoxUIObject::execute(const OUString& rAction, const StringMap& rParameters) { + if (!mxListBox->IsEnabled() || !mxListBox->IsReallyVisible()) + return; + if (rAction == "SELECT") { bool bSelect = true; commit 0ab5e82ffc23ea7b4d26a43a803a8d7eabff74f6 Author: Markus Mohrhard <markus.mohrh...@googlemail.com> Date: Mon Mar 28 18:29:48 2016 +0200 initial work on tab page ui testing support Change-Id: I76fdaad1f84d3b18b130decd7bdb4eef82d341e9 diff --git a/include/vcl/uitest/uiobject.hxx b/include/vcl/uitest/uiobject.hxx index c982dfb..2754f67 100644 --- a/include/vcl/uitest/uiobject.hxx +++ b/include/vcl/uitest/uiobject.hxx @@ -22,6 +22,7 @@ enum class UIObjectType EDIT, CHECKBOX, LISTBOX, + TABPAGE, UNKNOWN }; diff --git a/vcl/inc/uitest/uiobject_impl.hxx b/vcl/inc/uitest/uiobject_impl.hxx index 3efeebe..7a5bd04 100644 --- a/vcl/inc/uitest/uiobject_impl.hxx +++ b/vcl/inc/uitest/uiobject_impl.hxx @@ -13,6 +13,8 @@ #include <vcl/dialog.hxx> #include <vcl/edit.hxx> +class TabPage; + class WindowUIObject : public UIObject { VclPtr<vcl::Window> mxWindow; @@ -117,6 +119,26 @@ protected: virtual OUString get_name() const override; }; +class TabPageUIObject : public WindowUIObject +{ +private: + VclPtr<TabPage> mxTabPage; +public: + TabPageUIObject(VclPtr<TabPage> xTabPage); + + virtual void execute(const OUString& rAction, + const StringMap& rParameters) override; + + virtual StringMap get_state() override; + + + virtual UIObjectType get_type() const override; + +protected: + + virtual OUString get_name() const override; +}; + class ListBoxUIObject : public WindowUIObject { private: diff --git a/vcl/source/uitest/factory.cxx b/vcl/source/uitest/factory.cxx index ef5c4f0..9827c02 100644 --- a/vcl/source/uitest/factory.cxx +++ b/vcl/source/uitest/factory.cxx @@ -10,6 +10,7 @@ #include "uitest/factory.hxx" #include "uitest/uiobject_impl.hxx" +#include <vcl/tabpage.hxx> #include <vcl/lstbox.hxx> std::unique_ptr<UIObject> UITestWrapperFactory::createObject(vcl::Window* pWindow) @@ -74,6 +75,13 @@ std::unique_ptr<UIObject> UITestWrapperFactory::createObject(vcl::Window* pWindo return std::unique_ptr<UIObject>(new ListBoxUIObject(pListBox)); } break; + case WINDOW_TABPAGE: + { + //TabPage* pTabPage = dynamic_cast<TabPage*>(pWindow); + //assert(pTabPage); + // return std::unique_ptr<UIObject>(new TabPageUIObject(pTabPage)); + } + break; default: break; } diff --git a/vcl/source/uitest/uiobject.cxx b/vcl/source/uitest/uiobject.cxx index 3082443..b266b7d 100644 --- a/vcl/source/uitest/uiobject.cxx +++ b/vcl/source/uitest/uiobject.cxx @@ -11,6 +11,7 @@ #include "uitest/factory.hxx" #include <vcl/event.hxx> +#include <vcl/tabpage.hxx> #include <vcl/lstbox.hxx> #include <rtl/ustrbuf.hxx> @@ -425,6 +426,35 @@ OUString CheckBoxUIObject::get_name() const return OUString("CheckBoxUIObject"); } +TabPageUIObject::TabPageUIObject(VclPtr<TabPage> xTabPage): + WindowUIObject(xTabPage), + mxTabPage(xTabPage) +{ +} + +void TabPageUIObject::execute(const OUString& rAction, + const StringMap& rParameters) +{ + +} + +StringMap TabPageUIObject::get_state() +{ + StringMap aMap = WindowUIObject::get_state(); + + return aMap; +} + +UIObjectType TabPageUIObject::get_type() const +{ + return UIObjectType::TABPAGE; +} + +OUString TabPageUIObject::get_name() const +{ + return OUString("TabPageUIObject"); +} + ListBoxUIObject::ListBoxUIObject(VclPtr<ListBox> xListBox): WindowUIObject(xListBox), mxListBox(xListBox) commit 13286dc9b657ef8d426296a7e794f2e62d597e44 Author: Markus Mohrhard <markus.mohrh...@googlemail.com> Date: Mon Mar 28 18:27:00 2016 +0200 provide a few more properties for list boxes Change-Id: I3d4af79a97daacb3d431a4018c88c0eb943e4723 diff --git a/vcl/source/uitest/uiobject.cxx b/vcl/source/uitest/uiobject.cxx index a130f17..3082443 100644 --- a/vcl/source/uitest/uiobject.cxx +++ b/vcl/source/uitest/uiobject.cxx @@ -459,6 +459,8 @@ StringMap ListBoxUIObject::get_state() StringMap aMap = WindowUIObject::get_state(); aMap["ReadOnly"] = OUString::boolean(mxListBox->IsReadOnly()); aMap["MultiSelect"] = OUString::boolean(mxListBox->IsMultiSelectionEnabled()); + aMap["EntryCount"] = OUString::number(mxListBox->GetEntryCount()); + aMap["SelectEntryCount"] = OUString::number(mxListBox->GetSelectEntryCount()); return aMap; } commit 9a41a17ea45f3ccbfbe5d42626ba2eb7dc91d0d8 Author: Markus Mohrhard <markus.mohrh...@googlemail.com> Date: Mon Mar 28 18:26:34 2016 +0200 provide a few more properties in the state map Change-Id: I0819a1bb2134d77852633e7a94bf94dadcdfdec0 diff --git a/vcl/source/uitest/uiobject.cxx b/vcl/source/uitest/uiobject.cxx index 0abfb51..a130f17 100644 --- a/vcl/source/uitest/uiobject.cxx +++ b/vcl/source/uitest/uiobject.cxx @@ -161,6 +161,8 @@ StringMap WindowUIObject::get_state() aPos += aParentPos; } aMap["AbsPosition"] = to_string(aPos); + aMap["Text"] = mxWindow->GetText(); + aMap["DisplayText"] = mxWindow->GetDisplayText(); return aMap; } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits