summaryrefslogtreecommitdiffstats
path: root/uitest
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
commit940b4d1848e8c70ab7642901a68594e8016caffc (patch)
treeeb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /uitest
parentInitial commit. (diff)
downloadlibreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.tar.xz
libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.zip
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'uitest')
-rw-r--r--uitest/Makefile14
-rw-r--r--uitest/Module_uitest.mk27
-rw-r--r--uitest/README1
-rw-r--r--uitest/UITest_calc_demo.mk15
-rw-r--r--uitest/UITest_demo_ui.mk20
-rw-r--r--uitest/UITest_impress_demo.mk15
-rw-r--r--uitest/UITest_manual_tests.mk20
-rw-r--r--uitest/UITest_math_demo.mk15
-rw-r--r--uitest/UITest_writer_demo1.mk20
-rw-r--r--uitest/UITest_writer_demo2.mk20
-rw-r--r--uitest/UITest_writer_demo3.mk20
-rw-r--r--uitest/UITest_writer_demo4.mk20
-rw-r--r--uitest/UITest_writer_demo5.mk20
-rw-r--r--uitest/UITest_writer_demo6.mk20
-rw-r--r--uitest/UITest_writer_demo7.mk20
-rw-r--r--uitest/UITest_writer_demo8.mk20
-rw-r--r--uitest/__init__.py0
-rw-r--r--uitest/calc_tests/__init__.py0
-rw-r--r--uitest/calc_tests/about_test.py25
-rw-r--r--uitest/calc_tests/autofilter.py49
-rw-r--r--uitest/calc_tests/create_chart.py148
-rw-r--r--uitest/calc_tests/create_range_name.py50
-rw-r--r--uitest/calc_tests/data/autofilter.odsbin0 -> 7791 bytes
-rw-r--r--uitest/calc_tests/data/tdf96453.odsbin0 -> 8157 bytes
-rw-r--r--uitest/calc_tests/edit_chart.py69
-rw-r--r--uitest/calc_tests/function_wizard.py29
-rw-r--r--uitest/calc_tests/gridwin.py48
-rw-r--r--uitest/calc_tests/gridwindow.py43
-rw-r--r--uitest/calc_tests/input_window.py33
-rw-r--r--uitest/calc_tests/tdf117987.py25
-rw-r--r--uitest/demo_ui/char_dialog.py28
-rw-r--r--uitest/demo_ui/checkbox.py28
-rw-r--r--uitest/demo_ui/combobox.py30
-rw-r--r--uitest/demo_ui/command_with_parameters.py24
-rw-r--r--uitest/demo_ui/data/test.odsbin0 -> 7598 bytes
-rw-r--r--uitest/demo_ui/data/test2.odsbin0 -> 7339 bytes
-rw-r--r--uitest/demo_ui/edit.py55
-rw-r--r--uitest/demo_ui/gridwin.py51
-rw-r--r--uitest/demo_ui/handle_multiple_files.py62
-rw-r--r--uitest/demo_ui/hierarchy.py35
-rw-r--r--uitest/demo_ui/listbox.py48
-rw-r--r--uitest/demo_ui/radiobutton.py40
-rw-r--r--uitest/demo_ui/spinfield.py81
-rw-r--r--uitest/demo_ui/tabcontrol.py38
-rw-r--r--uitest/demo_ui/tabdialog.py45
-rw-r--r--uitest/demo_ui/treelist.py46
-rw-r--r--uitest/impress_tests/backgrounds.py146
-rw-r--r--uitest/impress_tests/drawinglayer.py52
-rw-r--r--uitest/impress_tests/layouts.py43
-rw-r--r--uitest/impress_tests/start.py80
-rw-r--r--uitest/libreoffice/calc/conditional_format.py17
-rw-r--r--uitest/libreoffice/calc/document.py51
-rw-r--r--uitest/libreoffice/connection.py189
-rw-r--r--uitest/libreoffice/linguistic/linguservice.py27
-rw-r--r--uitest/libreoffice/uno/eventlistener.py57
-rw-r--r--uitest/libreoffice/uno/propertyvalue.py40
-rwxr-xr-xuitest/loginterpreter.py209
-rw-r--r--uitest/manual_tests/__init__.py0
-rw-r--r--uitest/manual_tests/calc.py235
-rw-r--r--uitest/manual_tests/data/cell_recalc.odsbin0 -> 34064 bytes
-rw-r--r--uitest/manual_tests/more_calc.py52
-rw-r--r--uitest/math_tests/start.py92
-rw-r--r--uitest/packaging/Makefile16
-rw-r--r--uitest/packaging/README.rst4
-rw-r--r--uitest/packaging/setup.cfg0
-rw-r--r--uitest/packaging/setup.py34
-rw-r--r--uitest/test_main.py137
-rw-r--r--uitest/ui_logger_dsl/General_commands.tx29
-rw-r--r--uitest/ui_logger_dsl/Special_commands.tx209
-rw-r--r--uitest/ui_logger_dsl/UI_Object_commands.tx65
-rw-r--r--uitest/ui_logger_dsl/dialog_commands.tx24
-rw-r--r--uitest/ui_logger_dsl/dsl_core.py862
-rw-r--r--uitest/ui_logger_dsl/example.ul34
-rw-r--r--uitest/ui_logger_dsl/starter_commands.tx13
-rw-r--r--uitest/ui_logger_dsl/type_options.tx9
-rw-r--r--uitest/ui_logger_dsl/ui_logger_dsl_grammar.tx29
-rw-r--r--uitest/ui_logger_dsl/uno_commands.tx20
-rw-r--r--uitest/uitest/bisecting.py16
-rw-r--r--uitest/uitest/config.py14
-rw-r--r--uitest/uitest/debug.py16
-rw-r--r--uitest/uitest/framework.py67
-rw-r--r--uitest/uitest/path.py31
-rw-r--r--uitest/uitest/test.py223
-rw-r--r--uitest/uitest/uihelper/__init__.py0
-rw-r--r--uitest/uitest/uihelper/calc.py16
-rw-r--r--uitest/uitest/uihelper/common.py22
-rw-r--r--uitest/uitest/uihelper/keyboard.py13
-rw-r--r--uitest/uitest/uihelper/testDialog.py39
-rw-r--r--uitest/writer_tests/data/3pages.odtbin0 -> 8276 bytes
-rw-r--r--uitest/writer_tests/data/tdf104649.docxbin0 -> 75971 bytes
-rw-r--r--uitest/writer_tests/data/tdf114724.odtbin0 -> 9883 bytes
-rw-r--r--uitest/writer_tests1/pageDialog.py239
-rw-r--r--uitest/writer_tests2/tdf92611.py21
-rw-r--r--uitest/writer_tests3/tdf104649.py37
-rw-r--r--uitest/writer_tests4/insertTableDialog.py78
-rw-r--r--uitest/writer_tests4/start.py70
-rw-r--r--uitest/writer_tests5/spellDialog.py102
-rw-r--r--uitest/writer_tests5/tdf114724.py47
-rw-r--r--uitest/writer_tests6/insertBreakDialog.py85
-rw-r--r--uitest/writer_tests6/insertPageHeader.py72
-rw-r--r--uitest/writer_tests7/autoredactDialog.py198
-rw-r--r--uitest/writer_tests7/goToPage.py48
-rw-r--r--uitest/writer_tests8/customizeDialog.py92
-rw-r--r--uitest/writer_tests8/tdf79236.py124
104 files changed, 5862 insertions, 0 deletions
diff --git a/uitest/Makefile b/uitest/Makefile
new file mode 100644
index 000000000..0997e6284
--- /dev/null
+++ b/uitest/Makefile
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# 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/.
+#
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/uitest/Module_uitest.mk b/uitest/Module_uitest.mk
new file mode 100644
index 000000000..bd65a088e
--- /dev/null
+++ b/uitest/Module_uitest.mk
@@ -0,0 +1,27 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+#
+# This file is part of the LibreOffice project.
+#
+# 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/.
+#
+
+$(eval $(call gb_Module_Module,uitest))
+
+$(eval $(call gb_Module_add_uicheck_targets,uitest,\
+ UITest_calc_demo \
+ UITest_writer_demo1 \
+ UITest_writer_demo2 \
+ UITest_writer_demo3 \
+ UITest_writer_demo4 \
+ UITest_writer_demo5 \
+ UITest_writer_demo6 \
+ UITest_writer_demo7 \
+ UITest_writer_demo8 \
+ UITest_impress_demo \
+ UITest_demo_ui \
+ UITest_math_demo \
+ UITest_manual_tests \
+))
diff --git a/uitest/README b/uitest/README
new file mode 100644
index 000000000..c941673e7
--- /dev/null
+++ b/uitest/README
@@ -0,0 +1 @@
+The code for the UI testing framework and the UI tests.
diff --git a/uitest/UITest_calc_demo.mk b/uitest/UITest_calc_demo.mk
new file mode 100644
index 000000000..9869300a0
--- /dev/null
+++ b/uitest/UITest_calc_demo.mk
@@ -0,0 +1,15 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# 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/.
+#
+
+$(eval $(call gb_UITest_UITest,calc_demo))
+
+$(eval $(call gb_UITest_add_modules,calc_demo,$(SRCDIR)/uitest,\
+ calc_tests/ \
+))
+# vim: set noet sw=4 ts=4:
diff --git a/uitest/UITest_demo_ui.mk b/uitest/UITest_demo_ui.mk
new file mode 100644
index 000000000..bb67e21b8
--- /dev/null
+++ b/uitest/UITest_demo_ui.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# 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/.
+#
+
+$(eval $(call gb_UITest_UITest,demo_ui))
+
+$(eval $(call gb_UITest_add_modules,demo_ui,$(SRCDIR)/uitest,\
+ demo_ui/ \
+))
+
+$(eval $(call gb_UITest_set_defs,demo_ui, \
+ TDOC="$(SRCDIR)/uitest/demo_ui/data" \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/uitest/UITest_impress_demo.mk b/uitest/UITest_impress_demo.mk
new file mode 100644
index 000000000..e13d95494
--- /dev/null
+++ b/uitest/UITest_impress_demo.mk
@@ -0,0 +1,15 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# 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/.
+#
+
+$(eval $(call gb_UITest_UITest,impress_demo))
+
+$(eval $(call gb_UITest_add_modules,impress_demo,$(SRCDIR)/uitest,\
+ impress_tests/ \
+))
+# vim: set noet sw=4 ts=4:
diff --git a/uitest/UITest_manual_tests.mk b/uitest/UITest_manual_tests.mk
new file mode 100644
index 000000000..187ab8317
--- /dev/null
+++ b/uitest/UITest_manual_tests.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# 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/.
+#
+
+$(eval $(call gb_UITest_UITest,manual_tests))
+
+$(eval $(call gb_UITest_add_modules,manual_tests,$(SRCDIR)/uitest,\
+ manual_tests/ \
+))
+
+$(eval $(call gb_UITest_set_defs,manual_tests, \
+ TDOC="$(SRCDIR)/uitest/manual_tests/data" \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/uitest/UITest_math_demo.mk b/uitest/UITest_math_demo.mk
new file mode 100644
index 000000000..5c1a6dbd8
--- /dev/null
+++ b/uitest/UITest_math_demo.mk
@@ -0,0 +1,15 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# 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/.
+#
+
+$(eval $(call gb_UITest_UITest,math_demo))
+
+$(eval $(call gb_UITest_add_modules,math_demo,$(SRCDIR)/uitest,\
+ math_tests/ \
+))
+# vim: set noet sw=4 ts=4:
diff --git a/uitest/UITest_writer_demo1.mk b/uitest/UITest_writer_demo1.mk
new file mode 100644
index 000000000..e951e4ad2
--- /dev/null
+++ b/uitest/UITest_writer_demo1.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# 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/.
+#
+
+$(eval $(call gb_UITest_UITest,writer_demo1))
+
+$(eval $(call gb_UITest_add_modules,writer_demo1,$(SRCDIR)/uitest,\
+ writer_tests1/ \
+))
+
+$(eval $(call gb_UITest_set_defs,writer_demo1, \
+ TDOC="$(SRCDIR)/uitest/writer_tests/data" \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/uitest/UITest_writer_demo2.mk b/uitest/UITest_writer_demo2.mk
new file mode 100644
index 000000000..6f74f97ab
--- /dev/null
+++ b/uitest/UITest_writer_demo2.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# 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/.
+#
+
+$(eval $(call gb_UITest_UITest,writer_demo2))
+
+$(eval $(call gb_UITest_add_modules,writer_demo2,$(SRCDIR)/uitest,\
+ writer_tests2/ \
+))
+
+$(eval $(call gb_UITest_set_defs,writer_demo2, \
+ TDOC="$(SRCDIR)/uitest/writer_tests/data" \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/uitest/UITest_writer_demo3.mk b/uitest/UITest_writer_demo3.mk
new file mode 100644
index 000000000..9f6302670
--- /dev/null
+++ b/uitest/UITest_writer_demo3.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# 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/.
+#
+
+$(eval $(call gb_UITest_UITest,writer_demo3))
+
+$(eval $(call gb_UITest_add_modules,writer_demo3,$(SRCDIR)/uitest,\
+ writer_tests3/ \
+))
+
+$(eval $(call gb_UITest_set_defs,writer_demo3, \
+ TDOC="$(SRCDIR)/uitest/writer_tests/data" \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/uitest/UITest_writer_demo4.mk b/uitest/UITest_writer_demo4.mk
new file mode 100644
index 000000000..5ad99203e
--- /dev/null
+++ b/uitest/UITest_writer_demo4.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# 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/.
+#
+
+$(eval $(call gb_UITest_UITest,writer_demo4))
+
+$(eval $(call gb_UITest_add_modules,writer_demo4,$(SRCDIR)/uitest,\
+ writer_tests4/ \
+))
+
+$(eval $(call gb_UITest_set_defs,writer_demo4, \
+ TDOC="$(SRCDIR)/uitest/writer_tests/data" \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/uitest/UITest_writer_demo5.mk b/uitest/UITest_writer_demo5.mk
new file mode 100644
index 000000000..1f44c6666
--- /dev/null
+++ b/uitest/UITest_writer_demo5.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# 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/.
+#
+
+$(eval $(call gb_UITest_UITest,writer_demo5))
+
+$(eval $(call gb_UITest_add_modules,writer_demo5,$(SRCDIR)/uitest,\
+ writer_tests5/ \
+))
+
+$(eval $(call gb_UITest_set_defs,writer_demo5, \
+ TDOC="$(SRCDIR)/uitest/writer_tests/data" \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/uitest/UITest_writer_demo6.mk b/uitest/UITest_writer_demo6.mk
new file mode 100644
index 000000000..9c1e040a0
--- /dev/null
+++ b/uitest/UITest_writer_demo6.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# 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/.
+#
+
+$(eval $(call gb_UITest_UITest,writer_demo6))
+
+$(eval $(call gb_UITest_add_modules,writer_demo6,$(SRCDIR)/uitest,\
+ writer_tests6/ \
+))
+
+$(eval $(call gb_UITest_set_defs,writer_demo6, \
+ TDOC="$(SRCDIR)/uitest/writer_tests/data" \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/uitest/UITest_writer_demo7.mk b/uitest/UITest_writer_demo7.mk
new file mode 100644
index 000000000..10fc45008
--- /dev/null
+++ b/uitest/UITest_writer_demo7.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# 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/.
+#
+
+$(eval $(call gb_UITest_UITest,writer_demo7))
+
+$(eval $(call gb_UITest_add_modules,writer_demo7,$(SRCDIR)/uitest,\
+ writer_tests7/ \
+))
+
+$(eval $(call gb_UITest_set_defs,writer_demo7, \
+ TDOC="$(SRCDIR)/uitest/writer_tests/data" \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/uitest/UITest_writer_demo8.mk b/uitest/UITest_writer_demo8.mk
new file mode 100644
index 000000000..7c9eabceb
--- /dev/null
+++ b/uitest/UITest_writer_demo8.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# 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/.
+#
+
+$(eval $(call gb_UITest_UITest,writer_demo8))
+
+$(eval $(call gb_UITest_add_modules,writer_demo8,$(SRCDIR)/uitest,\
+ writer_tests8/ \
+))
+
+$(eval $(call gb_UITest_set_defs,writer_demo8, \
+ TDOC="$(SRCDIR)/uitest/writer_tests/data" \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/uitest/__init__.py b/uitest/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/uitest/__init__.py
diff --git a/uitest/calc_tests/__init__.py b/uitest/calc_tests/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/uitest/calc_tests/__init__.py
diff --git a/uitest/calc_tests/about_test.py b/uitest/calc_tests/about_test.py
new file mode 100644
index 000000000..c6dc75b93
--- /dev/null
+++ b/uitest/calc_tests/about_test.py
@@ -0,0 +1,25 @@
+# -*- 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/.
+#
+
+from uitest.framework import UITestCase
+
+class AboutDlgTest(UITestCase):
+
+ def test_about_dlg(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ self.ui_test.execute_dialog_through_command(".uno:About")
+
+ xAboutDlg = self.xUITest.getTopFocusWindow()
+
+ xCloseBtn = xAboutDlg.getChild("btnClose")
+ self.ui_test.close_dialog_through_button(xCloseBtn)
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/calc_tests/autofilter.py b/uitest/calc_tests/autofilter.py
new file mode 100644
index 000000000..431043b02
--- /dev/null
+++ b/uitest/calc_tests/autofilter.py
@@ -0,0 +1,49 @@
+# -*- 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/.
+#
+
+from uitest.framework import UITestCase
+from uitest.path import get_srcdir_url
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+import time
+
+def get_url_for_data_file(file_name):
+ return get_srcdir_url() + "/uitest/calc_tests/data/" + file_name
+
+class AutofilterTest(UITestCase):
+
+ def test_launch_autofilter(self):
+ doc = self.ui_test.load_file(get_url_for_data_file("autofilter.ods"))
+
+ xGridWin = self.xUITest.getTopFocusWindow().getChild("grid_window")
+ xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "1", "ROW": "1"}))
+
+ time.sleep(1)
+
+ self.ui_test.close_doc()
+
+ def test_hierarchy(self):
+ doc = self.ui_test.load_file(get_url_for_data_file("autofilter.ods"))
+
+ xGridWin = self.xUITest.getTopFocusWindow().getChild("grid_window")
+ xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"}))
+
+ xFloatWindow = self.xUITest.getFloatWindow()
+ xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+
+ xTreeList = xCheckListMenu.getChild("check_list_box")
+ xFirstEntry = xTreeList.getChild("0")
+
+ xFirstEntry.executeAction("CLICK", tuple())
+
+ xOkBtn = xFloatWindow.getChild("ok")
+ xOkBtn.executeAction("CLICK", tuple())
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/calc_tests/create_chart.py b/uitest/calc_tests/create_chart.py
new file mode 100644
index 000000000..cced0ac63
--- /dev/null
+++ b/uitest/calc_tests/create_chart.py
@@ -0,0 +1,148 @@
+# -*- 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/.
+#
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+from uitest.framework import UITestCase
+from uitest.uihelper.calc import enter_text_to_cell
+
+import time
+import unittest
+
+class CalcChartUIDemo(UITestCase):
+
+ def create_insert_chart_dialog(self):
+ self.ui_test.execute_dialog_through_command(".uno:InsertObjectChart")
+ # time.sleep(1) # ideally wait for a creation event
+ return self.xUITest.getTopFocusWindow()
+
+ def fill_spreadsheet(self):
+ xCalcDoc = self.xUITest.getTopFocusWindow()
+ xGridWindow = xCalcDoc.getChild("grid_window")
+
+ enter_text_to_cell(xGridWindow, "A1", "col1")
+ enter_text_to_cell(xGridWindow, "B1", "col2")
+ enter_text_to_cell(xGridWindow, "C1", "col3")
+ enter_text_to_cell(xGridWindow, "A2", "1")
+ enter_text_to_cell(xGridWindow, "B2", "3")
+ enter_text_to_cell(xGridWindow, "C2", "5")
+
+ xGridWindow.executeAction("SELECT", mkPropertyValues({"RANGE": "A1:C2"}))
+
+ def test_cancel_immediately(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ self.fill_spreadsheet()
+
+ xChartDlg = self.create_insert_chart_dialog();
+
+ xCancelBtn = xChartDlg.getChild("cancel")
+ self.ui_test.close_dialog_through_button(xCancelBtn)
+
+ self.ui_test.close_doc()
+
+ def test_create_from_first_page(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ self.fill_spreadsheet()
+
+ xChartDlg = self.create_insert_chart_dialog();
+
+ xOkBtn = xChartDlg.getChild("finish")
+ self.ui_test.close_dialog_through_button(xOkBtn)
+
+ self.ui_test.close_doc()
+
+ def test_create_from_second_page(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ self.fill_spreadsheet()
+
+ xChartDlg = self.create_insert_chart_dialog();
+
+ xNextBtn = xChartDlg.getChild("next")
+ xNextBtn.executeAction("CLICK", tuple())
+
+ xDataInRows = xChartDlg.getChild("RB_DATAROWS")
+ xDataInRows.executeAction("CLICK", tuple())
+
+ xDataInCols = xChartDlg.getChild("RB_DATACOLS")
+ xDataInCols.executeAction("CLICK", tuple())
+
+ xCancelBtn = xChartDlg.getChild("finish")
+ self.ui_test.close_dialog_through_button(xCancelBtn)
+
+ self.ui_test.close_doc()
+
+ def test_deselect_chart(self):
+ self.ui_test.create_doc_in_start_center("calc")
+
+ self.fill_spreadsheet()
+
+ xCalcDoc = self.xUITest.getTopFocusWindow()
+ xGridWindow = xCalcDoc.getChild("grid_window")
+
+ xChartDlg = self.create_insert_chart_dialog();
+
+ xNextBtn = xChartDlg.getChild("finish")
+ self.ui_test.close_dialog_through_button(xNextBtn)
+
+ xGridWindow.executeAction("DESELECT", mkPropertyValues({"OBJECT": ""}))
+
+ time.sleep(2)
+
+ self.ui_test.close_doc()
+
+ def test_activate_chart(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ self.fill_spreadsheet()
+
+ xCalcDoc = self.xUITest.getTopFocusWindow()
+ xGridWindow = xCalcDoc.getChild("grid_window")
+
+ xChartDlg = self.create_insert_chart_dialog();
+
+ xNextBtn = xChartDlg.getChild("finish")
+ self.ui_test.close_dialog_through_button(xNextBtn)
+
+ xGridWindow.executeAction("DESELECT", mkPropertyValues({"OBJECT": ""}))
+
+ xGridWindow.executeAction("SELECT", mkPropertyValues({"OBJECT": "Object 1"}))
+ xGridWindow.executeAction("ACTIVATE", tuple())
+
+ xGridWindow.executeAction("DESELECT", mkPropertyValues({"OBJECT": ""}))
+
+ self.ui_test.close_doc()
+
+ def select_chart_element(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ self.fill_spreadsheet()
+
+ xCalcDoc = self.xUITest.getTopFocusWindow()
+ xGridWindow = xCalcDoc.getChild("grid_window")
+
+ xChartDlg = self.create_insert_chart_dialog();
+
+ xNextBtn = xChartDlg.getChild("finish")
+ self.ui_test.close_dialog_through_button(xNextBtn)
+
+ xGridWindow.executeAction("DESELECT", mkPropertyValues({"OBJECT": ""}))
+
+ xGridWindow.executeAction("SELECT", mkPropertyValues({"OBJECT": "Object 1"}))
+ xGridWindow.executeAction("ACTIVATE", tuple())
+
+ xCalcDoc = self.xUITest.getTopFocusWindow()
+ self.ui_test.close_doc()
+
+# 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 000000000..1babca7c0
--- /dev/null
+++ b/uitest/calc_tests/create_range_name.py
@@ -0,0 +1,50 @@
+# -*- 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/.
+#
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+from uitest.framework import UITestCase
+from uitest.uihelper.common import type_text, select_pos
+
+class CreateRangeNameTest(UITestCase):
+
+ def test_create_range_name(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ self.ui_test.execute_modeless_dialog_through_command(".uno:AddName")
+
+ xAddNameDlg = self.xUITest.getTopFocusWindow()
+
+ xEdit = xAddNameDlg.getChild("edit")
+ type_text(xEdit, "simpleRangeName")
+
+ xAddBtn = xAddNameDlg.getChild("add")
+ self.ui_test.close_dialog_through_button(xAddBtn)
+
+ self.ui_test.close_doc()
+
+ def test_create_local_range_name(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ self.ui_test.execute_modeless_dialog_through_command(".uno:AddName")
+
+ xAddNameDlg = self.xUITest.getTopFocusWindow()
+
+ xEdit = xAddNameDlg.getChild("edit")
+ type_text(xEdit, "simpleRangeName")
+
+ xScope = xAddNameDlg.getChild("scope")
+ select_pos(xScope, "1")
+
+ xAddBtn = xAddNameDlg.getChild("add")
+ self.ui_test.close_dialog_through_button(xAddBtn)
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/calc_tests/data/autofilter.ods b/uitest/calc_tests/data/autofilter.ods
new file mode 100644
index 000000000..a03dba608
--- /dev/null
+++ b/uitest/calc_tests/data/autofilter.ods
Binary files differ
diff --git a/uitest/calc_tests/data/tdf96453.ods b/uitest/calc_tests/data/tdf96453.ods
new file mode 100644
index 000000000..89114f636
--- /dev/null
+++ b/uitest/calc_tests/data/tdf96453.ods
Binary files differ
diff --git a/uitest/calc_tests/edit_chart.py b/uitest/calc_tests/edit_chart.py
new file mode 100644
index 000000000..d74a8c2ec
--- /dev/null
+++ b/uitest/calc_tests/edit_chart.py
@@ -0,0 +1,69 @@
+# -*- 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/.
+#
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+from uitest.framework import UITestCase
+from uitest.uihelper.calc import enter_text_to_cell
+
+import unittest
+
+class CalcChartEditUIDemo(UITestCase):
+
+ def fill_spreadsheet(self):
+ xCalcDoc = self.xUITest.getTopFocusWindow()
+ xGridWindow = xCalcDoc.getChild("grid_window")
+
+ enter_text_to_cell(xGridWindow, "A1", "col1")
+ enter_text_to_cell(xGridWindow, "B1", "col2")
+ enter_text_to_cell(xGridWindow, "C1", "col3")
+ enter_text_to_cell(xGridWindow, "A2", "1")
+ enter_text_to_cell(xGridWindow, "B2", "3")
+ enter_text_to_cell(xGridWindow, "C2", "5")
+
+ xGridWindow.executeAction("SELECT", mkPropertyValues({"RANGE": "A1:C2"}))
+
+ def test_select_secondary_axis(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ self.fill_spreadsheet()
+
+ xCalcDoc = self.xUITest.getTopFocusWindow()
+ xGridWindow = xCalcDoc.getChild("grid_window")
+
+ self.ui_test.execute_dialog_through_command(".uno:InsertObjectChart")
+
+ xChartDlg = self.xUITest.getTopFocusWindow()
+
+ xNextBtn = xChartDlg.getChild("finish")
+ self.ui_test.close_dialog_through_button(xNextBtn)
+
+ xGridWindow.executeAction("DESELECT", mkPropertyValues({"OBJECT": ""}))
+
+ xGridWindow.executeAction("SELECT", mkPropertyValues({"OBJECT": "Object 1"}))
+
+ xGridWindow.executeAction("ACTIVATE", tuple())
+
+ xChartMainTop = self.xUITest.getTopFocusWindow()
+ xChartMain = xChartMainTop.getChild("chart_window")
+
+ xSeriesObj = xChartMain.getChild("CID/D=0:CS=0:CT=0:Series=0")
+ self.ui_test.execute_dialog_through_action(xSeriesObj, "COMMAND", mkPropertyValues({"COMMAND": "FormatDataSeries"}))
+
+ xSeriesFormatDlg = self.xUITest.getTopFocusWindow()
+ xAxis2 = xSeriesFormatDlg.getChild("RBT_OPT_AXIS_2")
+ xAxis2.executeAction("CLICK", tuple())
+
+ xCancelBtn = xSeriesFormatDlg.getChild("ok")
+ xCancelBtn.executeAction("CLICK", tuple())
+
+ xGridWindow.executeAction("DESELECT", mkPropertyValues({"OBJECT": ""}))
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/calc_tests/function_wizard.py b/uitest/calc_tests/function_wizard.py
new file mode 100644
index 000000000..13b833509
--- /dev/null
+++ b/uitest/calc_tests/function_wizard.py
@@ -0,0 +1,29 @@
+# -*- 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/.
+#
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+from uitest.framework import UITestCase
+
+class FunctionWizardTest(UITestCase):
+ # tdf#98427
+ def test_open_function_wizard(self):
+ self.ui_test.create_doc_in_start_center("calc")
+
+ self.ui_test.execute_modeless_dialog_through_command(".uno:FunctionDialog")
+
+ xFunctionDlg = self.xUITest.getTopFocusWindow()
+
+ xArrayChkBox = xFunctionDlg.getChild("array")
+ xArrayChkBox.executeAction("CLICK", tuple())
+
+ xCancelBtn = xFunctionDlg.getChild("cancel")
+ self.ui_test.close_dialog_through_button(xCancelBtn)
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/calc_tests/gridwin.py b/uitest/calc_tests/gridwin.py
new file mode 100644
index 000000000..7c9c87de0
--- /dev/null
+++ b/uitest/calc_tests/gridwin.py
@@ -0,0 +1,48 @@
+# -*- 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/.
+#
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from uitest.uihelper.common import get_state_as_dict
+
+from uitest.framework import UITestCase
+
+class GridWinTest(UITestCase):
+
+ def test_select_object(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+ xCalcDoc = self.xUITest.getTopFocusWindow()
+ xGridWindow = xCalcDoc.getChild("grid_window")
+
+ selectProps = mkPropertyValues({"CELL": "B10"})
+ xGridWindow.executeAction("SELECT", selectProps)
+
+ xGridWindow.executeAction("SELECT", mkPropertyValues({"OBJECT": "Object 1"}))
+
+ xGridWindow.executeAction("ACTIVATE", tuple())
+
+ xGridWindow.executeAction("DESELECT", tuple())
+
+ self.ui_test.close_doc()
+
+ def test_select_sheet(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+ xCalcDoc = self.xUITest.getTopFocusWindow()
+ xGridWindow = xCalcDoc.getChild("grid_window")
+
+ for i in range(3):
+ self.ui_test.execute_dialog_through_command(".uno:Insert")
+ current_dialog = self.xUITest.getTopFocusWindow()
+
+ xOkButton = current_dialog.getChild("ok")
+ self.ui_test.close_dialog_through_button(xOkButton)
+
+ xGridWindow.executeAction("SELECT", mkPropertyValues({"TABLE": "2"}))
+ self.assertEqual(get_state_as_dict(xGridWindow)["SelectedTable"], "2")
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/calc_tests/gridwindow.py b/uitest/calc_tests/gridwindow.py
new file mode 100644
index 000000000..37afacd00
--- /dev/null
+++ b/uitest/calc_tests/gridwindow.py
@@ -0,0 +1,43 @@
+# -*- 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/.
+#
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+from uitest.uihelper.calc import enter_text_to_cell
+
+from uitest.framework import UITestCase
+
+class GridWindowTest(UITestCase):
+
+ def test_input(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+ xTopWindow = self.xUITest.getTopFocusWindow()
+
+ xGridWindow = xTopWindow.getChild("grid_window")
+
+ enter_text_to_cell(xGridWindow, "C3", "=A1")
+ enter_text_to_cell(xGridWindow, "A1", "2")
+
+ self.ui_test.close_doc()
+
+ def test_special_keys(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+ xTopWindow = self.xUITest.getTopFocusWindow()
+
+ xGridWindow = xTopWindow.getChild("grid_window")
+
+ selectProps = mkPropertyValues({"CELL": "C3"})
+ xGridWindow.executeAction("SELECT", selectProps)
+
+ typeProps = mkPropertyValues({"KEYCODE": "CTRL+DOWN"})
+ xGridWindow.executeAction("TYPE", typeProps)
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/calc_tests/input_window.py b/uitest/calc_tests/input_window.py
new file mode 100644
index 000000000..eea8b53d9
--- /dev/null
+++ b/uitest/calc_tests/input_window.py
@@ -0,0 +1,33 @@
+# -*- 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/.
+#
+
+from uitest.framework import UITestCase
+from uitest.uihelper.common import get_state_as_dict, type_text
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+from libreoffice.calc.document import get_cell_by_position
+
+import time
+
+class InputWindowTest(UITestCase):
+
+ def test_input_window(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ xCalcDoc = self.xUITest.getTopFocusWindow()
+ document = self.ui_test.get_component()
+
+ xInputWin = xCalcDoc.getChild("sc_input_window")
+
+ type_text(xInputWin, "test")
+ xInputWin.executeAction("TYPE", mkPropertyValues({"KEYCODE": "RETURN"}))
+ self.assertEqual(get_cell_by_position(document, 0, 0, 0).getString(), "test")
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/calc_tests/tdf117987.py b/uitest/calc_tests/tdf117987.py
new file mode 100644
index 000000000..3de0b176e
--- /dev/null
+++ b/uitest/calc_tests/tdf117987.py
@@ -0,0 +1,25 @@
+#
+# 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.framework import UITestCase
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from libreoffice.calc.document import get_cell_by_position
+
+class tdf117987(UITestCase):
+
+ def test_highlight_cell_after_moving_cursor(self):
+ self.ui_test.create_doc_in_start_center("calc")
+ xCalcDoc = self.xUITest.getTopFocusWindow()
+ gridwin = xCalcDoc.getChild("grid_window")
+
+ colorProperty = mkPropertyValues({"BackgroundColor": 16776960})
+ gridwin.executeAction("SELECT", mkPropertyValues({"CELL": "A1"}))
+ self.xUITest.executeCommandWithParameters(".uno:BackgroundColor", colorProperty)
+ gridwin.executeAction("TYPE", mkPropertyValues({"KEYCODE": "DOWN"}))
+ self.xUITest.executeCommandWithParameters(".uno:BackgroundColor", colorProperty)
+
+ document = self.ui_test.get_component()
+ self.assertEqual(get_cell_by_position(document, 0, 0, 1).CellBackColor, 16776960)
+ self.ui_test.close_doc()
diff --git a/uitest/demo_ui/char_dialog.py b/uitest/demo_ui/char_dialog.py
new file mode 100644
index 000000000..5dd0212ee
--- /dev/null
+++ b/uitest/demo_ui/char_dialog.py
@@ -0,0 +1,28 @@
+# -*- 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/.
+#
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from uitest.framework import UITestCase
+
+class CharDialogText(UITestCase):
+
+ def test_select_char(self):
+ self.ui_test.create_doc_in_start_center("calc")
+
+ self.ui_test.execute_dialog_through_command(".uno:InsertSymbol")
+ xCharDialog = self.xUITest.getTopFocusWindow()
+
+ xCharSet = xCharDialog.getChild("showcharset")
+
+ xCharSet.executeAction("SELECT", mkPropertyValues({"COLUMN": "2", "ROW": "2"}))
+
+ xCancelBtn = xCharDialog.getChild("cancel")
+ self.ui_test.close_dialog_through_button(xCancelBtn)
+
+ self.ui_test.close_doc()
+
+# 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 000000000..114473d53
--- /dev/null
+++ b/uitest/demo_ui/checkbox.py
@@ -0,0 +1,28 @@
+# -*- 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/.
+#
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+from uitest.framework import UITestCase
+
+class CheckBoxTest(UITestCase):
+
+ def test_toggle_checkbox(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ self.ui_test.execute_dialog_through_command(".uno:FormatCellDialog")
+ xCellsDlg = self.xUITest.getTopFocusWindow()
+ xNegativeNumRedCB = xCellsDlg.getChild("negnumred")
+ xNegativeNumRedCB.executeAction("CLICK",tuple())
+
+ okBtn = xCellsDlg.getChild("ok")
+ self.ui_test.close_dialog_through_button(okBtn)
+
+ self.ui_test.close_doc()
+
+# 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 000000000..8b47f8338
--- /dev/null
+++ b/uitest/demo_ui/combobox.py
@@ -0,0 +1,30 @@
+# -*- 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/.
+#
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+from uitest.framework import UITestCase
+from uitest.uihelper.common import select_pos
+
+class ComboBoxTest(UITestCase):
+
+ def test_select_entry_pos(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ self.ui_test.execute_modeless_dialog_through_command(".uno:AddName")
+ xAddNameDlg = self.xUITest.getTopFocusWindow()
+
+ scopeCB = xAddNameDlg.getChild("scope")
+ select_pos(scopeCB, "1")
+
+ xCancelBtn = xAddNameDlg.getChild("cancel")
+ self.ui_test.close_dialog_through_button(xCancelBtn)
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/demo_ui/command_with_parameters.py b/uitest/demo_ui/command_with_parameters.py
new file mode 100644
index 000000000..c82d33595
--- /dev/null
+++ b/uitest/demo_ui/command_with_parameters.py
@@ -0,0 +1,24 @@
+# -*- 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/.
+#
+from uitest.framework import UITestCase
+from uitest.uihelper.common import type_text
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+class CommandWithParametersTest(UITestCase):
+
+ def test_text_color_change(self):
+
+ self.ui_test.create_doc_in_start_center("writer")
+
+ self.xUITest.executeCommandWithParameters(".uno:Color",
+ mkPropertyValues({"Color": 16776960}))
+ xWriterEdit = self.xUITest.getTopFocusWindow().getChild("writer_edit")
+ type_text(xWriterEdit, "LibreOffice")
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/demo_ui/data/test.ods b/uitest/demo_ui/data/test.ods
new file mode 100644
index 000000000..571291d26
--- /dev/null
+++ b/uitest/demo_ui/data/test.ods
Binary files differ
diff --git a/uitest/demo_ui/data/test2.ods b/uitest/demo_ui/data/test2.ods
new file mode 100644
index 000000000..550115cb9
--- /dev/null
+++ b/uitest/demo_ui/data/test2.ods
Binary files differ
diff --git a/uitest/demo_ui/edit.py b/uitest/demo_ui/edit.py
new file mode 100644
index 000000000..48ada3b1d
--- /dev/null
+++ b/uitest/demo_ui/edit.py
@@ -0,0 +1,55 @@
+# -*- 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/.
+#
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+from uitest.framework import UITestCase
+from uitest.uihelper.common import type_text, get_state_as_dict, select_text
+
+import time
+
+class EditTest(UITestCase):
+
+ def test_type_text(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ self.ui_test.execute_modeless_dialog_through_command(".uno:AddName")
+ xAddNameDlg = self.xUITest.getTopFocusWindow()
+
+ xEdit = xAddNameDlg.getChild("edit")
+
+ type_text(xEdit, "simpleRangeName")
+
+ xAddBtn = xAddNameDlg.getChild("cancel")
+ self.ui_test.close_dialog_through_button(xAddBtn)
+
+ self.ui_test.close_doc()
+
+ def test_select_text(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ self.ui_test.execute_modeless_dialog_through_command(".uno:AddName")
+ xAddNameDlg = self.xUITest.getTopFocusWindow()
+
+ xEdit = xAddNameDlg.getChild("edit")
+
+ type_text(xEdit, "simpleRangeName")
+ xEdit.executeAction("SELECT", mkPropertyValues({"FROM": "2", "TO": "9"}))
+ type_text(xEdit, "otherChars")
+ self.assertEqual("siotherCharsgeName", get_state_as_dict(xEdit)["Text"])
+
+ select_text(xEdit, from_pos="2", to="12")
+ self.assertEqual("otherChars", get_state_as_dict(xEdit)["SelectedText"])
+
+ xAddBtn = xAddNameDlg.getChild("cancel")
+ self.ui_test.close_dialog_through_button(xAddBtn)
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/demo_ui/gridwin.py b/uitest/demo_ui/gridwin.py
new file mode 100644
index 000000000..ddfb13273
--- /dev/null
+++ b/uitest/demo_ui/gridwin.py
@@ -0,0 +1,51 @@
+# -*- 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/.
+#
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+from uitest.framework import UITestCase
+
+class GridWinTest(UITestCase):
+
+ def test_select_cell(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+ xCalcDoc = self.xUITest.getTopFocusWindow()
+ xGridWindow = xCalcDoc.getChild("grid_window")
+
+ selectProps = mkPropertyValues({"CELL": "B10"})
+ xGridWindow.executeAction("SELECT", selectProps)
+
+ self.ui_test.close_doc()
+
+ def test_select_range(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+ xCalcDoc = self.xUITest.getTopFocusWindow()
+ xGridWindow = xCalcDoc.getChild("grid_window")
+
+ selectProps = mkPropertyValues({"RANGE": "B10:C20"})
+ xGridWindow.executeAction("SELECT", selectProps)
+
+ self.ui_test.close_doc()
+
+ def test_extend_range(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+ xTopWindow = self.xUITest.getTopFocusWindow()
+
+ xGridWindow = xTopWindow.getChild("grid_window")
+
+ selectProps = mkPropertyValues({"RANGE": "B10:C20"})
+ xGridWindow.executeAction("SELECT", selectProps)
+
+ select2Props = mkPropertyValues({"RANGE": "D3:F5", "EXTEND": "true"})
+ xGridWindow.executeAction("SELECT", select2Props)
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/demo_ui/handle_multiple_files.py b/uitest/demo_ui/handle_multiple_files.py
new file mode 100644
index 000000000..e60d3884b
--- /dev/null
+++ b/uitest/demo_ui/handle_multiple_files.py
@@ -0,0 +1,62 @@
+# -*- 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/.
+#
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from libreoffice.uno.eventlistener import EventListener
+
+from uitest.framework import UITestCase
+
+from uitest.debug import sleep
+
+import time
+import org.libreoffice.unotest
+import os
+import pathlib
+
+def get_url_for_data_file(file_name):
+ return pathlib.Path(org.libreoffice.unotest.makeCopyFromTDOC(file_name)).as_uri()
+
+class HandleFiles(UITestCase):
+
+ def test_load_file(self):
+
+ calc_file = self.ui_test.load_file(get_url_for_data_file("test.ods"))
+
+ calc_file2 = self.ui_test.load_file(get_url_for_data_file("test2.ods"))
+
+ frames = self.ui_test.get_frames()
+ self.assertEqual(len(frames), 2)
+
+ self.ui_test.close_doc()
+
+ frames = self.ui_test.get_frames()
+ self.assertEqual(len(frames), 1)
+
+ # this is currently still necessary as otherwise
+ # the command is not forwarded to the correct frame
+ # TODO: provide an additional event that we can use
+ # and get rid of the sleep
+ time.sleep(1)
+
+ self.ui_test.close_doc()
+
+ def test_select_frame(self):
+ calc_file = self.ui_test.load_file(get_url_for_data_file("test.ods"))
+
+ calc_file2 = self.ui_test.load_file(get_url_for_data_file("test2.ods"))
+ frames = self.ui_test.get_frames()
+ self.assertEqual(len(frames), 2)
+ frames[0].activate()
+
+ self.ui_test.close_doc()
+
+ frames = self.ui_test.get_frames()
+ self.assertEqual(len(frames), 1)
+
+ self.assertTrue(frames[0].getTitle().startswith("test2.ods"))
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/demo_ui/hierarchy.py b/uitest/demo_ui/hierarchy.py
new file mode 100644
index 000000000..f5434366f
--- /dev/null
+++ b/uitest/demo_ui/hierarchy.py
@@ -0,0 +1,35 @@
+# -*- 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/.
+#
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+from uitest.framework import UITestCase
+
+import json
+
+class CheckBoxTest(UITestCase):
+
+ def test_get_json(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ self.ui_test.execute_dialog_through_command(".uno:About")
+
+ xAboutDlg = self.xUITest.getTopFocusWindow()
+
+ json_string = xAboutDlg.getHierarchy()
+ print(json_string)
+ json_content = json.loads(json_string)
+ print(json_content)
+ print(json.dumps(json_content, indent=4))
+
+ closeBtn = xAboutDlg.getChild("btnClose")
+ self.ui_test.close_dialog_through_button(closeBtn)
+
+ self.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 000000000..780da1ff2
--- /dev/null
+++ b/uitest/demo_ui/listbox.py
@@ -0,0 +1,48 @@
+# -*- 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/.
+#
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+from uitest.framework import UITestCase
+from uitest.uihelper.common import select_pos
+
+class ListBoxTest(UITestCase):
+
+ def test_select_entry_pos(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ self.ui_test.execute_dialog_through_command(".uno:FormatCellDialog")
+ xCellsDlg = self.xUITest.getTopFocusWindow()
+
+ categoryLB = xCellsDlg.getChild("categorylb")
+ select_pos(categoryLB, "4")
+
+ xOkBtn = xCellsDlg.getChild("ok")
+ self.ui_test.close_dialog_through_button(xOkBtn)
+
+ self.ui_test.close_doc()
+
+ def test_select_entry_text(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ self.ui_test.execute_dialog_through_command(".uno:FormatCellDialog")
+ xCellsDlg = self.xUITest.getTopFocusWindow()
+
+ categoryLB = xCellsDlg.getChild("categorylb")
+ props = {"TEXT": "Time"}
+
+ actionProps = mkPropertyValues(props)
+ categoryLB.executeAction("SELECT", actionProps)
+
+ xOkBtn = xCellsDlg.getChild("ok")
+ self.ui_test.close_dialog_through_button(xOkBtn)
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/demo_ui/radiobutton.py b/uitest/demo_ui/radiobutton.py
new file mode 100644
index 000000000..bb2f5bd07
--- /dev/null
+++ b/uitest/demo_ui/radiobutton.py
@@ -0,0 +1,40 @@
+# -*- 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/.
+#
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+from uitest.framework import UITestCase
+
+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
+
+class RadioButtonTest(UITestCase):
+
+ def test_toggle_radiobutton(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ self.ui_test.execute_dialog_through_command(".uno:FormatCellDialog")
+ xCellsDlg = self.xUITest.getTopFocusWindow()
+ xNegativeNumRedCB = xCellsDlg.getChild("negnumred")
+ xNegativeNumRedCB.executeAction("CLICK",tuple())
+
+ okBtn = xCellsDlg.getChild("ok")
+ self.ui_test.close_dialog_through_button(okBtn)
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/demo_ui/spinfield.py b/uitest/demo_ui/spinfield.py
new file mode 100644
index 000000000..3f73006b1
--- /dev/null
+++ b/uitest/demo_ui/spinfield.py
@@ -0,0 +1,81 @@
+# -*- 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/.
+#
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+from uitest.framework import UITestCase
+from uitest.uihelper.common import get_state_as_dict, type_text, select_pos
+
+class SpinFieldTest(UITestCase):
+
+ def test_up(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ self.ui_test.execute_dialog_through_command(".uno:FormatCellDialog")
+ xCellsDlg = self.xUITest.getTopFocusWindow()
+
+ # select the numbers tab page
+ select_pos(xCellsDlg, "0")
+
+ xDecimalPlaces = xCellsDlg.getChild("leadzerosed")
+ xDecimalPlaces.executeAction("UP", tuple())
+
+ decimal_places_state = get_state_as_dict(xDecimalPlaces)
+ assert(decimal_places_state["Text"] == "2")
+
+ okBtn = xCellsDlg.getChild("ok")
+ self.ui_test.close_dialog_through_button(okBtn)
+
+ self.ui_test.close_doc()
+
+ def test_down(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ self.ui_test.execute_dialog_through_command(".uno:FormatCellDialog")
+ xCellsDlg = self.xUITest.getTopFocusWindow()
+
+ # select the numbers tab page
+ select_pos(xCellsDlg, "0")
+
+ xDecimalPlaces = xCellsDlg.getChild("leadzerosed")
+ xDecimalPlaces.executeAction("UP", tuple())
+ xDecimalPlaces.executeAction("UP", tuple())
+
+ decimal_places_state = get_state_as_dict(xDecimalPlaces)
+ assert(decimal_places_state["Text"] == "3")
+
+ xDecimalPlaces.executeAction("DOWN", tuple())
+
+ decimal_places_state = get_state_as_dict(xDecimalPlaces)
+ assert(decimal_places_state["Text"] == "2")
+
+ okBtn = xCellsDlg.getChild("ok")
+ self.ui_test.close_dialog_through_button(okBtn)
+
+ self.ui_test.close_doc()
+
+ def test_text(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ self.ui_test.execute_dialog_through_command(".uno:FormatCellDialog")
+ xCellsDlg = self.xUITest.getTopFocusWindow()
+
+ xDecimalPlaces = xCellsDlg.getChild("leadzerosed")
+ type_text(xDecimalPlaces, "4")
+
+ decimal_places_state = get_state_as_dict(xDecimalPlaces)
+ assert(decimal_places_state["Text"] == "41")
+
+ okBtn = xCellsDlg.getChild("ok")
+ self.ui_test.close_dialog_through_button(okBtn)
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/demo_ui/tabcontrol.py b/uitest/demo_ui/tabcontrol.py
new file mode 100644
index 000000000..47b3f33a3
--- /dev/null
+++ b/uitest/demo_ui/tabcontrol.py
@@ -0,0 +1,38 @@
+# -*- 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/.
+#
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+from uitest.uihelper.calc import enter_text_to_cell
+from uitest.uihelper.common import select_pos
+
+from uitest.framework import UITestCase
+
+class TabControlTest(UITestCase):
+
+ def test_select_pos(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ xCalcDoc = self.xUITest.getTopFocusWindow()
+ xGridWindow = xCalcDoc.getChild("grid_window")
+ enter_text_to_cell(xGridWindow, "B2", "=2+3+4")
+ xGridWindow.executeAction("SELECT", mkPropertyValues({"CELL": "B2"}))
+
+ self.ui_test.execute_modeless_dialog_through_command(".uno:FunctionDialog")
+
+ xFunctionDlg = self.xUITest.getTopFocusWindow()
+
+ xTabs = xFunctionDlg.getChild("tabcontrol")
+ select_pos(xTabs, "1")
+
+ xCancelBtn = xFunctionDlg.getChild("cancel")
+ xCancelBtn.executeAction("CLICK", tuple())
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/demo_ui/tabdialog.py b/uitest/demo_ui/tabdialog.py
new file mode 100644
index 000000000..ed46379ab
--- /dev/null
+++ b/uitest/demo_ui/tabdialog.py
@@ -0,0 +1,45 @@
+# -*- 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/.
+#
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+from uitest.framework import UITestCase
+from uitest.uihelper.common import select_pos
+
+class TabDialogTest(UITestCase):
+
+ def test_select_tab_page_pos(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ self.ui_test.execute_dialog_through_command(".uno:FormatCellDialog")
+ xCellsDlg = self.xUITest.getTopFocusWindow()
+
+ select_pos(xCellsDlg, "1")
+
+ xOkBtn = xCellsDlg.getChild("ok")
+ self.ui_test.close_dialog_through_button(xOkBtn)
+
+ self.ui_test.close_doc()
+
+ def test_select_tab_page_name(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ self.ui_test.execute_dialog_through_command(".uno:FormatCellDialog")
+ xCellsDlg = self.xUITest.getTopFocusWindow()
+
+ props = {"NAME": "Borders"}
+ propsUNO = mkPropertyValues(props)
+ xCellsDlg.executeAction("SELECT", propsUNO)
+
+ xOkBtn = xCellsDlg.getChild("ok")
+ self.ui_test.close_dialog_through_button(xOkBtn)
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/demo_ui/treelist.py b/uitest/demo_ui/treelist.py
new file mode 100644
index 000000000..265fa8b97
--- /dev/null
+++ b/uitest/demo_ui/treelist.py
@@ -0,0 +1,46 @@
+# -*- 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/.
+#
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from uitest.uihelper.calc import enter_text_to_cell
+
+from uitest.uihelper.common import get_state_as_dict, select_pos
+
+from uitest.framework import UITestCase
+
+class TreeListTest(UITestCase):
+
+ def test_expand(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ xCalcDoc = self.xUITest.getTopFocusWindow()
+ xGridWindow = xCalcDoc.getChild("grid_window")
+ enter_text_to_cell(xGridWindow, "B2", "=2+3+4")
+ xGridWindow.executeAction("SELECT", mkPropertyValues({"CELL": "B2"}))
+
+ self.ui_test.execute_modeless_dialog_through_command(".uno:FunctionDialog")
+
+ xFunctionDlg = self.xUITest.getTopFocusWindow()
+
+ xTabs = xFunctionDlg.getChild("tabcontrol")
+ select_pos(xTabs, "1")
+
+ xTreelist = xTabs.getChild("struct")
+
+ xTreeEntry = xTreelist.getChild('0')
+
+ xTreeEntry.executeAction("COLLAPSE", tuple())
+
+ xTreeEntry.executeAction("EXPAND", tuple())
+
+ xCancelBtn = xFunctionDlg.getChild("cancel")
+ xCancelBtn.executeAction("CLICK", tuple())
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/impress_tests/backgrounds.py b/uitest/impress_tests/backgrounds.py
new file mode 100644
index 000000000..6e2493b06
--- /dev/null
+++ b/uitest/impress_tests/backgrounds.py
@@ -0,0 +1,146 @@
+#
+# 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.framework import UITestCase
+from uitest.uihelper.common import select_pos
+from com.sun.star.awt.GradientStyle import LINEAR
+from com.sun.star.drawing.HatchStyle import SINGLE
+from com.sun.star.drawing.BitmapMode import REPEAT
+from com.sun.star.drawing.RectanglePoint import MIDDLE_MIDDLE
+
+class ImpressBackgrounds(UITestCase):
+
+ def checkDefaultBackground(self, btn):
+ document = self.ui_test.get_component()
+ if btn == 'btnnone':
+ self.assertEqual(document.DrawPages.getByIndex(0).Background, None)
+ elif btn == 'btncolor':
+ self.assertEqual(
+ hex(document.DrawPages.getByIndex(0).Background.FillColor), '0x729fcf')
+ self.assertEqual(
+ hex(document.DrawPages.getByIndex(0).Background.FillColor), '0x729fcf')
+ elif btn == 'btngradient':
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillGradient.Style, LINEAR)
+ self.assertEqual(
+ hex(document.DrawPages.getByIndex(0).Background.FillGradient.StartColor), '0xdde8cb')
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillGradient.Angle, 300)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillGradient.Border, 0)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillGradient.XOffset, 0)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillGradient.YOffset, 0)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillGradient.StartIntensity, 100)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillGradient.EndIntensity, 100)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillGradientName, 'Pastel Bouquet')
+ elif btn == 'btnhatch':
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillHatch.Style, SINGLE )
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillHatch.Color, 0)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillHatch.Distance, 102)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillHatch.Angle, 0)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillHatchName, 'Black 0 Degrees')
+ elif btn == 'btnbitmap':
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillBitmapMode, REPEAT)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillBitmapPositionOffsetX, 0)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillBitmapPositionOffsetY, 0)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillBitmapRectanglePoint, MIDDLE_MIDDLE)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillBitmapStretch, False)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillBitmapTile, True)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillBitmapOffsetX, 0)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillBitmapOffsetY, 0)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillBitmapLogicalSize, True)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillBitmapSizeX, 0)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillBitmapSizeY, 0)
+ self.assertEqual(document.DrawPages.getByIndex(0).Background.FillBitmapName, 'Painted White')
+ elif btn == 'btnpattern':
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillBitmapMode, REPEAT)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillBitmapPositionOffsetX, 0)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillBitmapPositionOffsetY, 0)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillBitmapRectanglePoint, MIDDLE_MIDDLE)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillBitmapStretch, True)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillBitmapTile, True)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillBitmapOffsetX, 0)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillBitmapOffsetY, 0)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillBitmapLogicalSize, True)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillBitmapSizeX, 0)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillBitmapSizeY, 0)
+ self.assertEqual(
+ document.DrawPages.getByIndex(0).Background.FillBitmapName, '5 Percent')
+
+
+ def test_background_dialog(self):
+
+ self.ui_test.create_doc_in_start_center("impress")
+
+ xTemplateDlg = self.xUITest.getTopFocusWindow()
+ xCancelBtn = xTemplateDlg.getChild("cancel")
+ self.ui_test.close_dialog_through_button(xCancelBtn)
+
+ buttons = ['btnbitmap', 'btncolor', 'btngradient', 'btnhatch', 'btnpattern']
+ for index, button in enumerate(buttons):
+ self.ui_test.execute_dialog_through_command(".uno:PageSetup")
+
+ xPageSetupDlg = self.xUITest.getTopFocusWindow()
+ tabcontrol = xPageSetupDlg.getChild("tabcontrol")
+ select_pos(tabcontrol, "1")
+
+ xBtn = xPageSetupDlg.getChild(button)
+ xBtn.executeAction("CLICK", tuple())
+
+ xOkBtn = xPageSetupDlg.getChild("ok")
+ xOkBtn.executeAction("CLICK", tuple())
+
+ self.checkDefaultBackground(button)
+
+ self.ui_test.execute_dialog_through_command(".uno:PageSetup")
+
+ xPageSetupDlg = self.xUITest.getTopFocusWindow()
+ tabcontrol = xPageSetupDlg.getChild("tabcontrol")
+ select_pos(tabcontrol, "1")
+
+ xBtn = xPageSetupDlg.getChild('btnnone')
+ xBtn.executeAction("CLICK", tuple())
+
+ xOkBtn = xPageSetupDlg.getChild("ok")
+ xOkBtn.executeAction("CLICK", tuple())
+
+ self.checkDefaultBackground('btnnone')
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/impress_tests/drawinglayer.py b/uitest/impress_tests/drawinglayer.py
new file mode 100644
index 000000000..d6a8920e7
--- /dev/null
+++ b/uitest/impress_tests/drawinglayer.py
@@ -0,0 +1,52 @@
+# -*- 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/.
+#
+
+from uitest.uihelper.common import get_state_as_dict
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+from uitest.framework import UITestCase
+
+from uitest.debug import time
+
+class ImpressDrawinglayerTest(UITestCase):
+
+ def test_move_object(self):
+ self.ui_test.create_doc_in_start_center("impress")
+
+ xTemplateDlg = self.xUITest.getTopFocusWindow()
+ xCancelBtn = xTemplateDlg.getChild("cancel")
+ self.ui_test.close_dialog_through_button(xCancelBtn)
+
+ xImpressDoc = self.xUITest.getTopFocusWindow()
+
+ xEditWin = xImpressDoc.getChild("impress_win")
+
+ xDrawinglayerObject = xEditWin.getChild("Unnamed Drawinglayer object 1")
+ print(get_state_as_dict(xDrawinglayerObject))
+ xDrawinglayerObject.executeAction("MOVE", mkPropertyValues({"X": "1000", "Y":"1000"}))
+
+ self.ui_test.close_doc()
+
+ def test_resize_object(self):
+ self.ui_test.create_doc_in_start_center("impress")
+
+ xTemplateDlg = self.xUITest.getTopFocusWindow()
+ xCancelBtn = xTemplateDlg.getChild("cancel")
+ self.ui_test.close_dialog_through_button(xCancelBtn)
+
+ xImpressDoc = self.xUITest.getTopFocusWindow()
+
+ xEditWin = xImpressDoc.getChild("impress_win")
+
+ xDrawinglayerObject = xEditWin.getChild("Unnamed Drawinglayer object 1")
+ print(get_state_as_dict(xDrawinglayerObject))
+ xDrawinglayerObject.executeAction("RESIZE", mkPropertyValues({"X": "500", "Y":"4000", "FRAC_X": "0.5", "FRAC_Y": "0.5"}))
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/impress_tests/layouts.py b/uitest/impress_tests/layouts.py
new file mode 100644
index 000000000..8e108913d
--- /dev/null
+++ b/uitest/impress_tests/layouts.py
@@ -0,0 +1,43 @@
+#
+# 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.framework import UITestCase
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+class ImpressLayouts(UITestCase):
+
+ def test_impress_layouts(self):
+
+ self.ui_test.create_doc_in_start_center("impress")
+
+ xTemplateDlg = self.xUITest.getTopFocusWindow()
+ xCancelBtn = xTemplateDlg.getChild("cancel")
+ self.ui_test.close_dialog_through_button(xCancelBtn)
+
+ layouts= (".uno:AssignLayout?WhatLayout:long=20", ".uno:AssignLayout?WhatLayout:long=19",
+ ".uno:AssignLayout?WhatLayout:long=0", ".uno:AssignLayout?WhatLayout:long=1",
+ ".uno:AssignLayout?WhatLayout:long=32", ".uno:AssignLayout?WhatLayout:long=3",
+ ".uno:AssignLayout?WhatLayout:long=12", ".uno:AssignLayout?WhatLayout:long=15",
+ ".uno:AssignLayout?WhatLayout:long=14", ".uno:AssignLayout?WhatLayout:long=16",
+ ".uno:AssignLayout?WhatLayout:long=18", ".uno:AssignLayout?WhatLayout:long=34",
+ ".uno:AssignLayout?WhatLayout:long=28", ".uno:AssignLayout?WhatLayout:long=27",
+ ".uno:AssignLayout?WhatLayout:long=29", ".uno:AssignLayout?WhatLayout:long=30")
+
+ for i in layouts:
+ self.xUITest.executeCommand(i)
+
+ xImpressDoc = self.xUITest.getTopFocusWindow()
+
+ xEditWin = xImpressDoc.getChild("impress_win")
+
+ # There's a layout with 7 objects
+ for j in range(0,6):
+ xEditWin.executeAction("SELECT", mkPropertyValues({"OBJECT":"Unnamed Drawinglayer object " + str(j)}))
+ xEditWin.executeAction("DESELECT", tuple())
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/impress_tests/start.py b/uitest/impress_tests/start.py
new file mode 100644
index 000000000..de7a6ece7
--- /dev/null
+++ b/uitest/impress_tests/start.py
@@ -0,0 +1,80 @@
+# -*- 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/.
+#
+
+from uitest.uihelper.common import get_state_as_dict
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+from uitest.framework import UITestCase
+
+import time
+
+class SimpleImpressTest(UITestCase):
+ def test_start_impress(self):
+
+ self.ui_test.create_doc_in_start_center("impress")
+
+ xTemplateDlg = self.xUITest.getTopFocusWindow()
+ xCancelBtn = xTemplateDlg.getChild("cancel")
+ self.ui_test.close_dialog_through_button(xCancelBtn)
+
+ xImpressDoc = self.xUITest.getTopFocusWindow()
+
+ xEditWin = xImpressDoc.getChild("impress_win")
+ xEditWin.executeAction("SET", mkPropertyValues({"ZOOM": "200"}))
+
+ self.ui_test.close_doc()
+
+ def test_select_page(self):
+
+ self.ui_test.create_doc_in_start_center("impress")
+
+ xTemplateDlg = self.xUITest.getTopFocusWindow()
+ xCancelBtn = xTemplateDlg.getChild("cancel")
+ self.ui_test.close_dialog_through_button(xCancelBtn)
+
+ xImpressDoc = self.xUITest.getTopFocusWindow()
+
+ xEditWin = xImpressDoc.getChild("impress_win")
+
+ xEditWin.executeAction("GOTO", mkPropertyValues({"PAGE": "2"}))
+
+ self.ui_test.close_doc()
+
+ def test_select_text(self):
+
+ self.ui_test.create_doc_in_start_center("impress")
+
+ xTemplateDlg = self.xUITest.getTopFocusWindow()
+ xCancelBtn = xTemplateDlg.getChild("cancel")
+ self.ui_test.close_dialog_through_button(xCancelBtn)
+
+ xImpressDoc = self.xUITest.getTopFocusWindow()
+
+ xEditWin = xImpressDoc.getChild("impress_win")
+
+ self.ui_test.close_doc()
+
+ def test_select_object(self):
+
+ self.ui_test.create_doc_in_start_center("impress")
+
+ xTemplateDlg = self.xUITest.getTopFocusWindow()
+ xCancelBtn = xTemplateDlg.getChild("cancel")
+ self.ui_test.close_dialog_through_button(xCancelBtn)
+
+ xImpressDoc = self.xUITest.getTopFocusWindow()
+ print(xImpressDoc.getChildren())
+
+ xEditWin = xImpressDoc.getChild("impress_win")
+
+ xEditWin.executeAction("SELECT", mkPropertyValues({"OBJECT":"Unnamed Drawinglayer object 1"}))
+ xEditWin.executeAction("DESELECT", tuple())
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/libreoffice/calc/conditional_format.py b/uitest/libreoffice/calc/conditional_format.py
new file mode 100644
index 000000000..40e766943
--- /dev/null
+++ b/uitest/libreoffice/calc/conditional_format.py
@@ -0,0 +1,17 @@
+# -*- 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/.
+#
+
+# this file provides methods to interact with the new conditional format API
+
+def get_conditional_format_from_sheet(sheet):
+ """ Returns a conditional format object belonging to a sheet
+
+ Keyword arguments:
+ sheet -- a XSheet object"""
+ return sheet.getPropertyValue("ConditionalFormats")
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/libreoffice/calc/document.py b/uitest/libreoffice/calc/document.py
new file mode 100644
index 000000000..c4eac000a
--- /dev/null
+++ b/uitest/libreoffice/calc/document.py
@@ -0,0 +1,51 @@
+# -*- 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/.
+#
+
+def get_sheet_from_doc(document, index=None, name=None):
+ """ Returns a sheet object for a Spreadsheet document
+
+ Keyword arguments:
+ index -- the 0-based index of the sheet (may not be used together with name)
+ name -- the name of the sheet (may not be used together with index)
+ """
+ return document.getSheets().getByIndex(index)
+
+def get_cell_by_position(document, tab, column, row):
+ """ Get the cell object through its position in a document
+
+ Keyword arguments:
+ document -- The document that should be used
+ tab -- The 0-based sheet number
+ column -- The 0-based column number
+ row -- The 0-based row number
+ """
+ sheet = get_sheet_from_doc(document, tab)
+ return sheet.getCellByPosition(column, row)
+
+def get_column(document, column, tab = 0):
+ """ Get the column object through the column index
+
+ Keyword arguments:
+ document -- The document that should be used
+ tab -- The 0-based sheet number
+ column -- The 0-based column number
+ """
+ sheet = get_sheet_from_doc(document, tab)
+ return sheet.getColumns().getByIndex(column)
+
+def get_row(document, row, tab = 0):
+ """ Get the row object through the row index
+
+ Keyword arguments:
+ document -- The document that should be used
+ tab -- The 0-based sheet number
+ column -- The 0-based row number
+ """
+ sheet = get_sheet_from_doc(document, tab)
+ return sheet.getRows().getByIndex(row)
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/libreoffice/connection.py b/uitest/libreoffice/connection.py
new file mode 100644
index 000000000..cb3ae1a01
--- /dev/null
+++ b/uitest/libreoffice/connection.py
@@ -0,0 +1,189 @@
+# -*- 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 subprocess
+import time
+import uuid
+import os
+
+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):
+ """ Create a new connection to a LibreOffice process
+
+ If the connection method is path the instance will be created as a
+ new subprocess. If the connection method is connect the instance tries
+ to connect to an existing instance with the specified socket string """
+ (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)
+
+ # connect to the soffice instance
+ self.xContext = self.connect(socket)
+
+ def bootstrap(self, soffice, userdir, socket):
+ """ Creates a new LibreOffice process
+
+ @param soffice Path to the soffice installation
+ @param userdir Directory of the user profile, only one process per user
+ profile is possible
+ @param socket The socket string used for the PyUNO connection """
+
+ argv = [soffice, "--accept=" + socket + ";urp",
+ "-env:UserInstallation=" + userdir,
+ "--quickstart=no", "--nofirststartwizard",
+ "--norestore", "--nologo"]
+ if "--valgrind" in self.args:
+ argv.append("--valgrind")
+
+ if "--gdb" in self.args:
+ argv.insert(0, "gdb")
+ argv.insert(1, "-ex")
+ argv.insert(2, "run")
+ argv.insert(3, "--args")
+ argv[4] = argv[4].replace("soffice", "soffice.bin")
+
+ env = None
+ environ = dict(os.environ)
+ if 'LIBO_LANG' in environ:
+ env = environ
+ env['LC_ALL'] = environ['LIBO_LANG']
+
+ self.pro = subprocess.Popen(argv, env=env)
+ return self.pro
+
+ def connect(self, socket):
+ """ Tries to connect to the LibreOffice instance through the specified 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:
+ if self.soffice and self.soffice.poll() is not None:
+ raise Exception("soffice has stopped.")
+
+ try:
+ xContext = xUnoResolver.resolve(url)
+ return xContext
+ except pyuno.getClass("com.sun.star.connection.NoConnectException"):
+ print("NoConnectException: sleeping...")
+ time.sleep(1)
+
+ def tearDown(self):
+ """Terminate a LibreOffice instance created with the path connection method.
+
+ First tries to terminate the soffice instance through the normal
+ XDesktop::terminate method and waits for about 30 seconds before
+ considering this attempt failed. After the 30 seconds the subprocess
+ is terminated """
+
+ 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 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))
+
+ @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):
+ """ Returns the XContext corresponding to the LibreOffice instance
+
+ This is the starting point for any PyUNO access to the LibreOffice
+ instance."""
+ return self.connection.xContext
+
+ def setUp(self):
+ # don't create two connections
+ if self.connection:
+ return
+
+ conn = OfficeConnection(self.args)
+ conn.setUp()
+ self.connection = conn
+
+ def tearDown(self):
+ if self.connection:
+ try:
+ self.connection.tearDown()
+ finally:
+ self.connection = None
+
+ def kill(self):
+ """ Kills the LibreOffice instance if it was created through the connection
+
+ Only works with the connection method path"""
+ if self.connection and self.connection.soffice:
+ self.connection.soffice.kill()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/libreoffice/linguistic/linguservice.py b/uitest/libreoffice/linguistic/linguservice.py
new file mode 100644
index 000000000..7ff9c1ac6
--- /dev/null
+++ b/uitest/libreoffice/linguistic/linguservice.py
@@ -0,0 +1,27 @@
+# -*- 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/.
+#
+
+
+def get_lingu_service_manager(xContext):
+ """ Returns the com.sun.star.linguistic2.LinguServiceManager
+
+ Further information: https://api.libreoffice.org/docs/idl/ref/servicecom_1_1sun_1_1star_1_1linguistic2_1_1LinguServiceManager.html
+ """
+ xServiceManager = xContext.getServiceManager()
+ xLinguServiceManager = xServiceManager.createInstanceWithContext("com.sun.star.linguistic2.LinguServiceManager", xContext)
+ return xLinguServiceManager
+
+
+def get_spellchecker(xContext):
+ """ Returns the com.sun.star.linguistic2.XSpellChecker through the
+ com.sun.star.linguistic2.LinguServiceManager
+
+ Further information: https://api.libreoffice.org/docs/idl/ref/servicecom_1_1sun_1_1star_1_1linguistic2_1_1SpellChecker.html"""
+ xLinguServiceManager = get_lingu_service_manager(xContext)
+ return xLinguServiceManager.getSpellChecker()
+
+# vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/uitest/libreoffice/uno/eventlistener.py b/uitest/libreoffice/uno/eventlistener.py
new file mode 100644
index 000000000..ba7faec76
--- /dev/null
+++ b/uitest/libreoffice/uno/eventlistener.py
@@ -0,0 +1,57 @@
+# -*- 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/.
+#
+
+try:
+ import pyuno
+ import uno
+ import unohelper
+ from com.sun.star.document import XDocumentEventListener
+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 EventListener(XDocumentEventListener,unohelper.Base):
+
+ def __init__(self, xContext, eventNames, **kwargs):
+ self.xGEB = xContext.ServiceManager.createInstanceWithContext(
+ "com.sun.star.frame.GlobalEventBroadcaster", xContext)
+ self.xContext = xContext
+ self.executed = False
+ self.eventExecuted = []
+ self.printEvents = kwargs.get('printNames', False)
+ if isinstance(eventNames, str):
+ self.eventNames = [eventNames]
+ elif isinstance(eventNames, list):
+ self.eventNames = eventNames
+
+ def __enter__(self):
+ self.xGEB.addDocumentEventListener(self)
+ return self
+
+ def __exit__(self, type, value, traceback):
+ self.xGEB.removeDocumentEventListener(self)
+
+ def documentEventOccured(self, event):
+ if self.printEvents is True:
+ print(event.EventName)
+
+ if event.EventName in self.eventNames:
+ self.executed = True
+ self.eventExecuted.append(event.EventName)
+ else:
+ print(self.eventNames)
+ print(event.EventName)
+
+ def hasExecuted(self, eventName):
+ return eventName in self.eventExecuted
+
+ def disposing(event):
+ pass
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/libreoffice/uno/propertyvalue.py b/uitest/libreoffice/uno/propertyvalue.py
new file mode 100644
index 000000000..a05c6a967
--- /dev/null
+++ b/uitest/libreoffice/uno/propertyvalue.py
@@ -0,0 +1,40 @@
+# -*- 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/.
+#
+
+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 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()])
+
+def convert_property_values_to_dict(propMap):
+ """ Create a dictionary from a sequence of property values
+ """
+ ret = {}
+ for entry in propMap:
+ name = entry.Name
+ val = entry.Value
+ ret[name] = val
+
+ return ret
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/loginterpreter.py b/uitest/loginterpreter.py
new file mode 100755
index 000000000..e84d9a0ed
--- /dev/null
+++ b/uitest/loginterpreter.py
@@ -0,0 +1,209 @@
+#!/usr/bin/env python3
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# 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 sys
+import argparse
+
+def parse_line(line):
+ """
+ This function parses a line from log file
+ and returns the parsed values as a python dictionary
+ """
+ if (line == ""):
+ return
+ dict = {}
+ if "{" in line:
+ start_index_of_parameters = line.find("{")
+ end_index_of_parameters = line.find("}") + 1
+ parameters = line[start_index_of_parameters:end_index_of_parameters]
+ if parameters != "":
+ dict["parameters"] = parameters
+ line = line[:start_index_of_parameters-1]
+ word_list = line.split()
+ dict["keyword"] = word_list[0]
+
+ for index in range(1,len(word_list)):
+ key, val = word_list[index].split(":",1)
+ dict[key] = val
+ return dict
+
+def parse_args():
+ """
+ This function parses the command-line arguments
+ to get the input and output file details
+ """
+ parser = argparse.ArgumentParser(description = "Generate a UI test file from log")
+ parser.add_argument("input_address", type = str, help = "The log file address")
+ parser.add_argument("output_address", type = str, help = "The test file address")
+ parser.add_argument("-d", "--document", metavar = "", help = "Address of the document to be opened")
+ args = parser.parse_args()
+ return args
+
+def get_log_file(input_address):
+ try:
+ with open(input_address) as f:
+ content = f.readlines()
+ except IOError as err:
+ print("IO error: {0}".format(err))
+ print("Use " + os.path.basename(sys.argv[0]) + " -h to get usage instructions")
+ sys.exit(1)
+
+ content = [x.strip() for x in content if not x.startswith("Action on element")]
+ return content
+
+def initiate_test_generation(address):
+ try:
+ f = open(address,"w")
+ except IOError as err:
+ print("IO error: {0}".format(err))
+ print("Use " + os.path.basename(sys.argv[0]) + " -h to get usage instructions")
+ sys.exit(1)
+ initial_text = \
+ "# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-\n\n" + \
+ "from uitest.framework import UITestCase\n" + \
+ "from libreoffice.uno.propertyvalue import mkPropertyValues\n" + \
+ "import importlib\n\n" + \
+ "class TestClass(UITestCase):\n" + \
+ " def test_function(self):\n"
+ f.write(initial_text)
+ return f
+
+def get_coupling_type(line1, line2):
+ """
+ This function checks if two consecutive lines of log file
+ refer to the same event
+ """
+ action_dict1 = parse_line(line1)
+ action_dict2 = parse_line(line2)
+
+ if action_dict1["keyword"] == "CommandSent" and \
+ action_dict2["keyword"] == "ModalDialogExecuted":
+ return "COMMAND_MODAL_COUPLE"
+
+ elif action_dict1["keyword"] == "CommandSent" and \
+ action_dict2["keyword"] == "ModelessDialogConstructed":
+ return "COMMAND_MODELESS_COUPLE"
+
+ elif action_dict1["keyword"] == "ButtonUIObject" and \
+ action_dict2["keyword"] == "DialogClosed":
+ return "BUTTON_DIALOGCLOSE_COUPLE"
+
+ elif "parameters" in action_dict1 and \
+ "KEYCODE" in action_dict1["parameters"] and \
+ action_dict2["keyword"] == "CommandSent":
+ return "REDUNDANT_COUPLE"
+
+ return "NOT_A_COUPLE"
+
+def check_app_starting_action(action_dict):
+ app_starter_button_ids = \
+ set(["draw_all", "impress_all", "calc_all" , "writer_all", "database_all", "math_all"])
+
+ if action_dict["keyword"] == "ButtonUIObject" and action_dict["Action"] == "CLICK" and \
+ action_dict["Id"] in app_starter_button_ids:
+ return True
+ return False
+
+def get_test_line_from_one_log_line(log_line):
+ action_dict = parse_line(log_line)
+ test_line = " "
+ if action_dict["keyword"].endswith("UIObject"):
+ parent = action_dict["Parent"]
+ if (check_app_starting_action(action_dict)):
+ test_line +=\
+ "MainDoc = self.ui_test.create_doc_in_start_center(\"" + \
+ action_dict["Id"][:-4] +"\")\n MainWindow = " + \
+ "self.xUITest.getTopFocusWindow()\n"
+ return test_line
+ else:
+ if (parent == ""):
+ parent = "MainWindow"
+ test_line += \
+ action_dict["Id"] + " = " + parent + ".getChild(\"" + \
+ action_dict["Id"] + "\")\n " + \
+ action_dict["Id"] + ".executeAction(\"" + \
+ action_dict["Action"] + "\""
+ if "parameters" in action_dict:
+ test_line += ", mkPropertyValues(" + \
+ action_dict["parameters"] + "))\n"
+ else:
+ test_line += ",tuple())\n"
+ return test_line
+ elif action_dict["keyword"] == "CommandSent":
+ if "parameters" not in action_dict:
+ test_line += "self.xUITest.executeCommand(\"" + \
+ action_dict["Name"] + "\")\n"
+ return test_line
+ else:
+ test_line += "self.xUITest.executeCommandWithParameters(\"" + \
+ action_dict["Name"] + "\", mkPropertyValues(" + action_dict["parameters"] + \
+ "))\n"
+ return test_line
+ elif action_dict["keyword"] == "ModalDialogExecuted" or \
+ action_dict["keyword"] == "ModelessDialogConstructed":
+ test_line += action_dict["Id"] + " = " + "self.xUITest.getTopFocusWindow()\n"
+ return test_line
+
+ return ""
+
+def get_test_line_from_two_log_lines(log_line1,log_line2):
+ coupling_type = get_coupling_type(log_line1, log_line2)
+ action_dict1 = parse_line(log_line1)
+ action_dict2 = parse_line(log_line2)
+ test_line = " "
+ if coupling_type == "COMMAND_MODAL_COUPLE":
+ test_line += \
+ "self.ui_test.execute_dialog_through_command(\"" + \
+ action_dict1["Name"] + "\")\n " + \
+ action_dict2["Id"] + " = self.xUITest.getTopFocusWindow()\n"
+ elif coupling_type == "COMMAND_MODELESS_COUPLE":
+ test_line += \
+ "self.ui_test.execute_modeless_dialog_through_command(\"" + \
+ action_dict1["Name"] + "\")\n " + \
+ action_dict2["Id"] + " = self.xUITest.getTopFocusWindow()\n"
+ elif coupling_type == "BUTTON_DIALOGCLOSE_COUPLE":
+ test_line += \
+ action_dict1["Id"] + " = " + action_dict1["Parent"] + ".getChild(\"" + \
+ action_dict1["Id"] + "\")\n self.ui_test.close_dialog_through_button(" + \
+ action_dict1["Id"] + ")\n"
+ return test_line
+
+def main():
+ args = parse_args()
+ log_lines = get_log_file(args.input_address)
+ output_stream = initiate_test_generation(args.output_address)
+ if args.document is not None:
+ output_line = " pathmodule = importlib.import_module(\"uitest.path\")\n" + \
+ " doc_path = pathmodule.get_srcdir_url() + \"" + args.document + "\"\n" + \
+ " MainDoc = self.ui_test.load_file(doc_path)\n" + \
+ " MainWindow = self.xUITest.getTopFocusWindow()\n"
+ output_stream.write(output_line)
+ line_number = 0
+ while line_number < len(log_lines):
+ if line_number == len(log_lines)-1 or \
+ get_coupling_type(log_lines[line_number],log_lines[line_number + 1]) == "NOT_A_COUPLE":
+ test_line = get_test_line_from_one_log_line(log_lines[line_number])
+ output_stream.write(test_line)
+ line_number += 1
+ elif get_coupling_type(log_lines[line_number],log_lines[line_number + 1]) == "REDUNDANT_COUPLE":
+ line_number += 1
+ else:
+ test_line = get_test_line_from_two_log_lines(log_lines[line_number],log_lines[line_number + 1])
+ output_stream.write(test_line)
+ line_number += 2
+ output_stream.write(" self.ui_test.close_doc()")
+ output_stream.write("\n\n# vim: set shiftwidth=4 softtabstop=4 expandtab:")
+ output_stream.close()
+
+if __name__ == '__main__':
+ main()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/manual_tests/__init__.py b/uitest/manual_tests/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/uitest/manual_tests/__init__.py
diff --git a/uitest/manual_tests/calc.py b/uitest/manual_tests/calc.py
new file mode 100644
index 000000000..1b7897983
--- /dev/null
+++ b/uitest/manual_tests/calc.py
@@ -0,0 +1,235 @@
+# -*- 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/.
+#
+
+from uitest.framework import UITestCase
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from libreoffice.calc.document import get_cell_by_position
+
+from uitest.uihelper.common import get_state_as_dict, type_text
+from uitest.uihelper.calc import enter_text_to_cell
+
+import org.libreoffice.unotest
+import pathlib
+import time
+
+def get_url_for_data_file(file_name):
+ return pathlib.Path(org.libreoffice.unotest.makeCopyFromTDOC(file_name)).as_uri()
+
+class ManualCalcTests(UITestCase):
+
+ # http://manual-test.libreoffice.org/manage/case/189/
+ def test_define_database_range(self):
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ # Select range A1:D10
+ xGridWin = self.xUITest.getTopFocusWindow().getChild("grid_window")
+ xGridWin.executeAction("SELECT", mkPropertyValues({"RANGE": "A1:D10"}))
+
+ # Execute "Define DB Range dialog"
+ self.ui_test.execute_modeless_dialog_through_command(".uno:DefineDBName")
+
+ xDefineNameDlg = self.xUITest.getTopFocusWindow()
+
+ xEntryBox = xDefineNameDlg.getChild("entry")
+ type_text(xEntryBox, "my_database")
+
+ xOkBtn = xDefineNameDlg.getChild("ok")
+ self.ui_test.close_dialog_through_button(xOkBtn)
+
+ # Deselect range
+ xGridWin.executeAction("SELECT", mkPropertyValues({"CELL": "A1"}))
+
+ # Execute "Select DB Range dialog"
+ self.ui_test.execute_dialog_through_command(".uno:SelectDB")
+ xSelectNameDlg = self.xUITest.getTopFocusWindow()
+
+ xListBox = xSelectNameDlg.getChild("treeview")
+ xListBoxState = get_state_as_dict(xListBox)
+ self.assertEqual(xListBoxState["SelectionCount"], "1")
+ self.assertEqual(xListBoxState["SelectEntryText"], "my_database")
+
+ xOkBtn = xSelectNameDlg.getChild("ok")
+ self.ui_test.close_dialog_through_button(xOkBtn)
+
+ # Assert that the correct range has been selected
+ gridWinState = get_state_as_dict(xGridWin)
+ self.assertEqual(gridWinState["MarkedArea"], "Sheet1.A1:Sheet1.D10")
+
+ self.ui_test.close_doc()
+
+ # http://manual-test.libreoffice.org/manage/case/190/
+ def test_sort_data(self):
+ self.ui_test.create_doc_in_start_center("calc")
+
+ # Insert data
+ xGridWin = self.xUITest.getTopFocusWindow().getChild("grid_window")
+ enter_text_to_cell(xGridWin, "B1", "3")
+ enter_text_to_cell(xGridWin, "B2", "25")
+ enter_text_to_cell(xGridWin, "B3", "17")
+ enter_text_to_cell(xGridWin, "B4", "9")
+ enter_text_to_cell(xGridWin, "B5", "19")
+ enter_text_to_cell(xGridWin, "B6", "0")
+ enter_text_to_cell(xGridWin, "B7", "107")
+ enter_text_to_cell(xGridWin, "B8", "89")
+ enter_text_to_cell(xGridWin, "B9", "8")
+ enter_text_to_cell(xGridWin, "B10", "33")
+
+ xGridWin.executeAction("SELECT", mkPropertyValues({"RANGE": "B1:B10"}))
+
+ # Execute "Sort" dialog
+ self.ui_test.execute_dialog_through_command(".uno:DataSort")
+ xSortDlg = self.xUITest.getTopFocusWindow()
+
+ xOkBtn = xSortDlg.getChild("ok")
+ self.ui_test.close_dialog_through_button(xOkBtn)
+
+ document = self.ui_test.get_component()
+
+ self.assertEqual(get_cell_by_position(document, 0, 1, 0).getValue(), 0)
+ self.assertEqual(get_cell_by_position(document, 0, 1, 1).getValue(), 3)
+ self.assertEqual(get_cell_by_position(document, 0, 1, 2).getValue(), 8)
+ self.assertEqual(get_cell_by_position(document, 0, 1, 3).getValue(), 9)
+ self.assertEqual(get_cell_by_position(document, 0, 1, 4).getValue(), 17)
+ self.assertEqual(get_cell_by_position(document, 0, 1, 5).getValue(), 19)
+ self.assertEqual(get_cell_by_position(document, 0, 1, 6).getValue(), 25)
+ self.assertEqual(get_cell_by_position(document, 0, 1, 7).getValue(), 33)
+ self.assertEqual(get_cell_by_position(document, 0, 1, 8).getValue(), 89)
+ self.assertEqual(get_cell_by_position(document, 0, 1, 9).getValue(), 107)
+
+ time.sleep(2)
+ self.ui_test.close_doc()
+
+ # http://manual-test.libreoffice.org/manage/case/191/
+ def test_validation(self):
+ self.ui_test.create_doc_in_start_center("calc")
+
+ xGridWin = self.xUITest.getTopFocusWindow().getChild("grid_window")
+ xGridWin.executeAction("SELECT", mkPropertyValues({"RANGE": "A1:C10"}))
+
+ self.ui_test.execute_dialog_through_command(".uno:Validation")
+ xValidationDlg = self.xUITest.getTopFocusWindow()
+
+ xAllowList = xValidationDlg.getChild("allow")
+ xAllowList.executeAction("SELECT", mkPropertyValues({"POS": "1"}))
+
+ xData = xValidationDlg.getChild("data")
+ xData.executeAction("SELECT", mkPropertyValues({"POS": "5"}))
+
+ xVal = xValidationDlg.getChild("max")
+ xVal.executeAction("TYPE", mkPropertyValues({"TEXT":"0"}))
+
+ xOkBtn = xValidationDlg.getChild("ok")
+ self.ui_test.close_dialog_through_button(xOkBtn)
+
+ def enter_text(cell, text):
+ enter_text_to_cell(xGridWin, cell, text)
+
+ self.ui_test.execute_blocking_action(enter_text, "ok", args=("A1", "abc"))
+ self.ui_test.execute_blocking_action(enter_text, "ok", args=("B6", "2.18"))
+
+ enter_text_to_cell(xGridWin, "C2", "24")
+
+ self.ui_test.close_doc()
+
+ # http://manual-test.libreoffice.org/manage/case/187/
+ def test_transpose(self):
+ self.ui_test.create_doc_in_start_center("calc")
+
+ xGridWin = self.xUITest.getTopFocusWindow().getChild("grid_window")
+ enter_text_to_cell(xGridWin, "B3", "abcd")
+ enter_text_to_cell(xGridWin, "B4", "edfg")
+ enter_text_to_cell(xGridWin, "C3", "35")
+ enter_text_to_cell(xGridWin, "C4", "5678")
+
+ xGridWin.executeAction("SELECT", mkPropertyValues({"RANGE": "A1:C10"}))
+
+ self.xUITest.executeCommand(".uno:Cut")
+
+ xGridWin.executeAction("SELECT", mkPropertyValues({"CELL": "A1"}))
+
+ self.ui_test.execute_dialog_through_command(".uno:PasteSpecial")
+
+ xPasteSpecialDlg = self.xUITest.getTopFocusWindow()
+
+ xAllChkBox = xPasteSpecialDlg.getChild("paste_all")
+ xAllChkBox.executeAction("CLICK", tuple())
+
+ xTransposeChkBox = xPasteSpecialDlg.getChild("transpose")
+ xTransposeChkBox.executeAction("CLICK", tuple())
+
+ xOkBtn = xPasteSpecialDlg.getChild("ok")
+ self.ui_test.close_dialog_through_button(xOkBtn)
+
+ document = self.ui_test.get_component()
+ self.assertEqual(get_cell_by_position(document, 0, 2, 1).getString(), "abcd")
+ self.assertEqual(get_cell_by_position(document, 0, 2, 2).getValue(), 35)
+ self.assertEqual(get_cell_by_position(document, 0, 3, 1).getString(), "edfg")
+ self.assertEqual(get_cell_by_position(document, 0, 3, 2).getValue(), 5678)
+
+ self.ui_test.close_doc()
+
+ # http://manual-test.libreoffice.org/manage/case/151/
+ def test_cell_recalc(self):
+ doc = self.ui_test.load_file(get_url_for_data_file("cell_recalc.ods"))
+
+ xGridWin = self.xUITest.getTopFocusWindow().getChild("grid_window")
+ xGridWin.executeAction("SELECT", mkPropertyValues({"RANGE": "D2:D9"}))
+ self.xUITest.executeCommand(".uno:Cut")
+
+ self.assertEqual(get_cell_by_position(doc, 0, 3, 15).getValue(), 0)
+
+ self.xUITest.executeCommand(".uno:Undo")
+
+ for i in range(1, 9):
+ self.assertTrue(get_cell_by_position(doc, 0, 3, i).getValue() != 0)
+
+ self.assertEqual(get_cell_by_position(doc, 0, 3, 15).getValue(), 195)
+
+ self.ui_test.close_doc()
+
+ # http://manual-test.libreoffice.org/manage/case/143/
+ def test_random_numbers(self):
+ self.ui_test.create_doc_in_start_center("calc")
+ xGridWin = self.xUITest.getTopFocusWindow().getChild("grid_window")
+
+ xGridWin.executeAction("SELECT", mkPropertyValues({"RANGE": "A2:A10"}))
+
+ self.ui_test.execute_modeless_dialog_through_command(".uno:RandomNumberGeneratorDialog")
+ xRandomNumberDlg = self.xUITest.getTopFocusWindow()
+ xDistributionLstBox = xRandomNumberDlg.getChild("distribution-combo")
+ xDistributionLstBox.executeAction("SELECT", mkPropertyValues({"POS": "1"}))
+
+ xMin = xRandomNumberDlg.getChild("parameter1-spin")
+ xMin.executeAction("TYPE", mkPropertyValues({"KEYCODE": "CTRL+A"}))
+ xMin.executeAction("TYPE", mkPropertyValues({"TEXT": "-2"}))
+ xMax = xRandomNumberDlg.getChild("parameter2-spin")
+ xMax.executeAction("TYPE", mkPropertyValues({"KEYCODE": "CTRL+A"}))
+ xMax.executeAction("TYPE", mkPropertyValues({"TEXT": "10"}))
+
+ xApplyBtn = xRandomNumberDlg.getChild("apply")
+ xApplyBtn.executeAction("CLICK", tuple())
+
+ doc = self.ui_test.get_component()
+
+ def check_random_values():
+ for i in range(1, 9):
+ val = get_cell_by_position(doc, 0, 0, i).getValue()
+ self.assertTrue(val <= 10 and val >= -2)
+
+ check_random_values()
+
+ xOkBtn = xRandomNumberDlg.getChild("ok")
+ self.ui_test.close_dialog_through_button(xOkBtn)
+
+ # we might want to check that clicking 'ok' actually changes the values
+ check_random_values()
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/manual_tests/data/cell_recalc.ods b/uitest/manual_tests/data/cell_recalc.ods
new file mode 100644
index 000000000..4b125fd2e
--- /dev/null
+++ b/uitest/manual_tests/data/cell_recalc.ods
Binary files differ
diff --git a/uitest/manual_tests/more_calc.py b/uitest/manual_tests/more_calc.py
new file mode 100644
index 000000000..08aeb654e
--- /dev/null
+++ b/uitest/manual_tests/more_calc.py
@@ -0,0 +1,52 @@
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# 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.framework import UITestCase
+
+from libreoffice.calc.document import get_cell_by_position
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+from uitest.uihelper.calc import enter_text_to_cell
+
+
+class ManualCalcTests(UITestCase):
+ def test_paste_special(self):
+ # EN-8:Paste special with options
+ # This test is to check that paste special combined with some options and link is ok.
+ # Refers to tdf#84810
+
+ self.ui_test.create_doc_in_start_center("calc")
+
+ # Write text to cell A1
+ xGridWin = self.xUITest.getTopFocusWindow().getChild("grid_window")
+ enter_text_to_cell(xGridWin, "A1", "abcd")
+
+ # Copy cell A1 to clipboard
+ xGridWin.executeAction("SELECT", mkPropertyValues({"CELL": "A1"}))
+ self.xUITest.executeCommand(".uno:Copy")
+
+ # Set cursor to cell A3
+ xGridWin.executeAction("SELECT", mkPropertyValues({"CELL": "A3"}))
+
+ # Choose Paste Special Options and paste data
+ self.ui_test.execute_dialog_through_command(".uno:PasteSpecial")
+ xPasteSpecialDlg = self.xUITest.getTopFocusWindow()
+ xAllChkBox = xPasteSpecialDlg.getChild("paste_all")
+ xAllChkBox.executeAction("CLICK", tuple())
+ xLinkChkBox = xPasteSpecialDlg.getChild("link")
+ xLinkChkBox.executeAction("CLICK", tuple())
+ xOkBtn = xPasteSpecialDlg.getChild("ok")
+ self.ui_test.close_dialog_through_button(xOkBtn)
+
+ # Assert successful paste
+ document = self.ui_test.get_component()
+ self.assertEqual(get_cell_by_position(document, 0, 0, 2).getString(), "abcd")
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/math_tests/start.py b/uitest/math_tests/start.py
new file mode 100644
index 000000000..425cb9679
--- /dev/null
+++ b/uitest/math_tests/start.py
@@ -0,0 +1,92 @@
+# -*- 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/.
+#
+
+from uitest.uihelper.common import get_state_as_dict
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+from uitest.framework import UITestCase
+from uitest.uihelper.common import type_text, select_pos
+from uitest.debug import sleep
+
+import unittest
+
+class SimpleMathTest(UITestCase):
+
+ def test_start_math(self):
+
+ self.ui_test.create_doc_in_start_center("math")
+
+ xMathDoc = self.xUITest.getTopFocusWindow()
+
+ self.ui_test.close_doc()
+
+ def test_docking_window_listbox(self):
+
+ self.ui_test.create_doc_in_start_center("math")
+
+ xMathDoc = self.xUITest.getTopFocusWindow()
+
+ xList = xMathDoc.getChild("listbox")
+ state = get_state_as_dict(xList)
+ self.assertEqual(state["SelectEntryText"], "Unary/Binary Operators")
+ select_pos(xList, "1")
+ state = get_state_as_dict(xList)
+ self.assertEqual(state["SelectEntryText"], "Relations")
+
+ self.ui_test.close_doc()
+
+ def test_math_edit(self):
+ self.ui_test.create_doc_in_start_center("math")
+
+ xMathDoc = self.xUITest.getTopFocusWindow()
+
+ xMathEdit = xMathDoc.getChild("math_edit")
+
+ type_text(xMathEdit, "E=mc^2")
+
+ self.ui_test.close_doc()
+
+ def test_math_selector(self):
+ self.ui_test.create_doc_in_start_center("math")
+
+ xMathDoc = self.xUITest.getTopFocusWindow()
+
+ xMathSelector = xMathDoc.getChild("element_selector")
+
+ xElement = xMathSelector.getChild("1")
+ xElement.executeAction("SELECT", tuple())
+
+ self.ui_test.close_doc()
+
+ @unittest.skip("on windows the f4 does not always work")
+ def test_complete_math(self):
+ self.ui_test.create_doc_in_start_center("math")
+
+ xMathDoc = self.xUITest.getTopFocusWindow()
+
+ xList = xMathDoc.getChild("listbox")
+ state = get_state_as_dict(xList)
+ self.assertEqual(state["SelectEntryText"], "Unary/Binary Operators")
+ select_pos(xList, "1")
+
+ xMathSelector = xMathDoc.getChild("element_selector")
+
+ xElement = xMathSelector.getChild("1")
+ xElement.executeAction("SELECT", tuple())
+
+ xMathEdit = xMathDoc.getChild("math_edit")
+ type_text(xMathEdit, "1")
+ xMathEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE":"F4"}))
+ type_text(xMathEdit, "2")
+
+ edit_state = get_state_as_dict(xMathEdit)
+ self.assertEqual("1 <> 2 ", edit_state["Text"])
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/packaging/Makefile b/uitest/packaging/Makefile
new file mode 100644
index 000000000..af63c946e
--- /dev/null
+++ b/uitest/packaging/Makefile
@@ -0,0 +1,16 @@
+all:
+ @echo "Packaging the libreoffice-connection code"
+ @mkdir -p libreoffice
+ @cp ../libreoffice/connection.py libreoffice/.
+ @touch libreoffice/__init__.py
+ @python3 setup.py sdist
+
+clean:
+ rm -r dist/
+ rm -r libreoffice_connection.egg-info/
+ rm -r libreoffice/
+ rm -r build/
+
+publish:
+ @echo "Uploading the release to pypi"
+ twine upload dist/*
diff --git a/uitest/packaging/README.rst b/uitest/packaging/README.rst
new file mode 100644
index 000000000..45d8716f6
--- /dev/null
+++ b/uitest/packaging/README.rst
@@ -0,0 +1,4 @@
+Connection code for LibreOffice's pyUNO
+=======================================
+
+This code allows out-of-process communication with a LibreOffice instance. The instance can either be started by the script or a connection to a running LibreOffice instance. The code contains several safety checks for hanging and crashed LibreOffice instances.
diff --git a/uitest/packaging/setup.cfg b/uitest/packaging/setup.cfg
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/uitest/packaging/setup.cfg
diff --git a/uitest/packaging/setup.py b/uitest/packaging/setup.py
new file mode 100644
index 000000000..9aa32054c
--- /dev/null
+++ b/uitest/packaging/setup.py
@@ -0,0 +1,34 @@
+from setuptools import setup, find_packages
+from codecs import open
+from os import path
+
+here = path.abspath(path.dirname(__file__))
+
+# Get the long description from the README file
+with open(path.join(here, 'README.rst'), encoding='utf-8') as f:
+ long_description = f.read()
+
+setup(
+ name="libreoffice-connection",
+ version="0.0.1",
+ description="Connection code for LibreOffice's pyUNO",
+ long_description=long_description,
+ url="http://www.libreoffice.org",
+ author="The LibreOffice developers",
+ author_email="libreoffice@lists.freedesktop.org",
+ license="MPL2",
+ classifiers=[
+ "Development Status :: 3 - Alpha",
+ "Intended Audience :: Developers",
+ "License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)",
+ "Programming Language :: Python :: 3.2",
+ "Programming Language :: Python :: 3.3",
+ "Programming Language :: Python :: 3.4",
+ "Programming Language :: Python :: 3.5",
+ "Programming Language :: Python :: 3.6",
+ "Topic :: Office/Business :: Office Suites",
+ "Topic :: Software Development :: Libraries",
+ ],
+ keywords="office automation",
+ packages=find_packages(),
+)
diff --git a/uitest/test_main.py b/uitest/test_main.py
new file mode 100644
index 000000000..e1737947f
--- /dev/null
+++ b/uitest/test_main.py
@@ -0,0 +1,137 @@
+# -*- 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 sys
+import getopt
+import os
+import unittest
+import calc_tests
+import importlib
+import importlib.machinery
+
+import uitest.config
+
+from uitest.framework import UITestCase
+
+from libreoffice.connection import OfficeConnection
+
+test_name_limit_found = False
+
+def parseArgs(argv):
+ (optlist,args) = getopt.getopt(argv[1:], "hdr",
+ ["help", "debug", "soffice=", "userdir=", "dir=", "file=", "gdb"])
+ 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()))
+
+
+def find_test_files(dir_path):
+ valid_files = []
+ for f in os.listdir(dir_path):
+ file_path = os.path.join(dir_path, f)
+
+ # don't go through the sub-directories
+ if not os.path.isfile(file_path):
+ continue
+
+ if os.path.splitext(file_path)[1] == ".swp":
+ continue # ignore VIM swap files
+
+ # fail on any non .py files
+ if not os.path.splitext(file_path)[1] == ".py":
+ raise Exception("file with an extension which is not .py: " + file_path)
+
+ # ignore the __init__.py file
+ # it is obviously not a test file
+ if f == "__init__.py":
+ continue
+
+ valid_files.append(file_path)
+
+ return valid_files
+
+def get_classes_of_module(module):
+ md = module.__dict__
+ return [ md[c] for c in md if (
+ isinstance(md[c], type) and md[c].__module__ == module.__name__ ) ]
+
+def get_test_case_classes_of_module(module):
+ classes = get_classes_of_module(module)
+ return [ c for c in classes if issubclass(c, UITestCase) ]
+
+def add_tests_for_file(test_file, test_suite):
+ test_name_limit = os.environ.get('UITEST_TEST_NAME', '')
+ test_loader = unittest.TestLoader()
+ module_name = os.path.splitext(os.path.split(test_file)[1])[0]
+
+ loader = importlib.machinery.SourceFileLoader(module_name, test_file)
+ mod = loader.load_module()
+ classes = get_test_case_classes_of_module(mod)
+ global test_name_limit_found
+ for c in classes:
+ test_names = test_loader.getTestCaseNames(c)
+ for test_name in test_names:
+ full_name = ".".join([module_name, c.__name__, test_name])
+ if len(test_name_limit) > 0:
+ if test_name_limit != full_name:
+ continue
+ test_name_limit_found = True
+
+ obj = c(test_name, opts)
+ test_suite.addTest(obj)
+
+def get_test_suite_for_dir(opts):
+ test_suite = unittest.TestSuite()
+
+ valid_test_files = find_test_files(opts['--dir'])
+ for test_file in valid_test_files:
+ add_tests_for_file(test_file, test_suite)
+ return test_suite
+
+
+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 "--dir" in opts:
+ test_suite = get_test_suite_for_dir(opts)
+ test_name_limit = os.environ.get('UITEST_TEST_NAME', '')
+ print(test_name_limit_found)
+ if len(test_name_limit) > 0 and not test_name_limit_found:
+ print("UITEST_TEST_NAME '%s' does not match any test" % test_name_limit)
+ sys.exit(1)
+ elif "--file" in opts:
+ test_suite = unittest.TestSuite()
+ add_tests_for_file(opts['--file'], test_suite)
+ else:
+ usage()
+ sys.exit()
+
+ if "-d" in opts or "--debug" in opts:
+ uitest.config.use_sleep = True
+
+ result = unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run(test_suite)
+ print("Tests run: %d" % result.testsRun)
+ print("Tests failed: %d" % len(result.failures))
+ print("Tests errors: %d" % len(result.errors))
+ print("Tests skipped: %d" % len(result.skipped))
+ if not result.wasSuccessful():
+ sys.exit(1)
+ sys.exit(0)
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/ui_logger_dsl/General_commands.tx b/uitest/ui_logger_dsl/General_commands.tx
new file mode 100644
index 000000000..5f5c40440
--- /dev/null
+++ b/uitest/ui_logger_dsl/General_commands.tx
@@ -0,0 +1,29 @@
+/*
+ This file for the log statements that is general for all application
+ we can use it as general commands then relate it to its application
+ as we have in the starter command
+ //====================================
+ also I make set zoom to be general as it will be better
+*/
+
+import type_options
+
+GeneralCommand:
+ SideBar | setZoom_command | Select_command | General_type_command_on_UI_Object
+;
+SideBar:
+ 'From SIDEBAR ' 'Choose ' '{"PANEL":' name=STRING '}'
+;
+setZoom_command:
+ 'Set Zoom to ' zoom_value=INT
+;
+Select_command:
+ 'Select ' '{"OBJECT":' name=STRING '}'
+;
+
+//==================================================
+//This Part if you want to type text in any of these UI elements This will be handled with this Grammar
+
+General_type_command_on_UI_Object:
+ 'Type on' UI_Obj=STRING what_to_type=Type_options 'from' parent_id=ID
+; \ No newline at end of file
diff --git a/uitest/ui_logger_dsl/Special_commands.tx b/uitest/ui_logger_dsl/Special_commands.tx
new file mode 100644
index 000000000..071cfb9dc
--- /dev/null
+++ b/uitest/ui_logger_dsl/Special_commands.tx
@@ -0,0 +1,209 @@
+import type_options
+
+/*
+ This file for the log statements that relates to each different applications
+ Each Grammar Command here is related to his own application
+*/
+
+SpecialCommand:
+ writer_command | calc_command | impress_command | math_command | draw_command
+;
+
+/*
+ This part for all the writer log statements:
+
+ 1) Type
+ 2) Select
+ 3) GOTO page
+ 4) Create Table
+ 5) Copy Text
+ 6) Cut Text
+ 7) Paste Text
+ 8) Insert Break Page
+
+ then we can add whatever we need in the future
+*/
+writer_command:
+ writer_Type_command | writer_Select_command | writer_GOTO_command |
+ writer_Create_table | writer_Copy_Text | writer_Cut_Text |
+ writer_Paste_Text | writer_Insert_BreakPage
+;
+writer_Type_command:
+ 'Type on writer' what_to_type=Type_options
+;
+writer_Select_command:
+ 'Select from Pos' from_pos=INT 'to Pos' to_pos=INT
+;
+writer_GOTO_command:
+ 'GOTO page number' page_num=INT
+;
+writer_Create_table:
+ 'Create Table with Columns :' cols=INT ', Rows :' rows=INT
+;
+writer_Copy_Text:
+ 'Copy the Selected Text'
+;
+writer_Cut_Text:
+ 'Cut the Selected Text'
+;
+writer_Paste_Text:
+ 'Paste in the Current Cursor Location'
+;
+writer_Insert_BreakPage:
+ 'Insert Break Page'
+;
+
+//=================================================================//
+/*
+ This part for all the calc log statements:
+
+ 1) select sheet
+ 2) Select cell or range
+ 3) launch AutoFill
+ 4) Delete Cells
+ 5) Remove Content of a cell
+ 6) Insert new Cells
+ 7) Cut Cells
+ 8) Copy Cells
+ 9) Paste Cells
+ 10) Merge Cells
+ 11) Unmerge Cells
+
+ then we can add whatever we need in the future
+*/
+calc_command:
+ calc_Type_command | calc_switch_sheet | calc_Select_cell | calc_AutoFill_filter |
+ calc_Delete_Cells | calc_Remove_Content | calc_insert_cells | calc_Cut_Cells |
+ calc_Copy_Cells | calc_Paste_Cells | calc_UNMerge_Cells | calc_Merge_Cells |
+ calc_Rename_Sheet | calc_Insert_sheet
+;
+calc_Type_command:
+ 'Type on current cell' what_to_type=Type_options
+;
+calc_switch_sheet:
+ 'Switch to sheet number' sheet_num=INT
+;
+calc_Select_cell:
+ 'Select from calc' select_op=select_options
+;
+calc_AutoFill_filter:
+ 'Launch AutoFilter from Col' col_num=INT 'and Row' row_num=INT
+;
+range_of_cells:
+ '{' '"RANGE":' input_range=STRING '}'
+;
+one_cell:
+ '{' '"CELL":' input_cell=STRING '}'
+;
+calc_Delete_Cells:
+ 'Delete The Cells in' '{' '"RANGE":' input_range=STRING '}'
+;
+calc_Remove_Content:
+ 'Remove Content from This' '{' '"RANGE":' input_range=STRING '}'
+;
+calc_insert_cells:
+ 'Insert Cell around the ' '{' '"RANGE":' input_range=STRING '}'
+;
+calc_Cut_Cells:
+ 'CUT the selected ' '{' '"RANGE":' input_range=STRING '}'
+;
+calc_Copy_Cells:
+ 'COPY the selected ' '{' '"RANGE":' input_range=STRING '}'
+;
+calc_Paste_Cells:
+ 'Paste in the' '{' '"RANGE":' input_range=STRING '}'
+;
+calc_Merge_Cells:
+ 'Merge' '{' '"RANGE":' input_range=STRING '}'
+;
+calc_UNMerge_Cells:
+ 'Delete the merge between' '{' '"CELL":' input_range=STRING '}'
+;
+calc_Rename_Sheet:
+ 'Rename The Selected Tab to ' new_name=STRING
+;
+calc_Insert_sheet:
+ 'Insert New Tab '
+;
+//this is the select options
+select_options:
+ one_cell | range_of_cells
+;
+
+//=================================================================//
+/*
+ This part for all the impress log statements:
+
+ 1) Type
+ 2) Insert New Slide
+ 3) Delete Slide
+ 4) Duplicate Slide
+ 5) Rename Slide
+
+ then we can add whatever we need in the future
+*/
+impress_command:
+ impress_Type_command | impress_Insert_Slide | impress_Delete_Page |
+ impress_Duplicate_Slide | impress_Rename_Slide
+;
+impress_Type_command:
+ 'Type on impress ' what_to_type=Type_options
+;
+impress_Insert_Slide:
+ 'Insert New Slide at Position ' position_num=INT
+;
+impress_Delete_Page:
+ 'Delete Slide number ' position_num=INT
+;
+impress_Duplicate_Slide:
+ 'Duplicate The Selected Slide '
+;
+impress_Rename_Slide:
+ 'Rename The Selected Slide from ' old_name=STRING 'to' new_name=STRING
+;
+//=================================================================//
+/*
+ This part for all the math log statements:
+
+ 1) element selector
+ 2) Type
+
+ then we can add whatever we need in the future
+*/
+math_command:
+ math_element_selector | math_Type_command
+;
+math_element_selector:
+ 'Select element no ' element_no=INT 'From' place=ID
+;
+math_Type_command:
+ 'Type on math ' what_to_type=Type_options
+;
+
+//=================================================================//
+/*
+ This part for all the draw log statements:
+
+ 1) Type
+ 2) Insert New Page
+ 3) Delete Page
+ 4) Rename Page
+
+ then we can add whatever we need in the future
+*/
+draw_command:
+ draw_Type_command | draw_Insert_Page | draw_Delete_Page |
+ draw_Rename_Page
+;
+draw_Type_command:
+ 'Type on draw ' what_to_type=Type_options
+;
+draw_Insert_Page:
+ 'Insert New Page at Position ' position_num=INT
+;
+draw_Delete_Page:
+ 'Delete Page number ' position_num=INT
+;
+draw_Rename_Page:
+ 'Rename The Selected Page from ' old_name=STRING 'to' new_name=STRING
+; \ No newline at end of file
diff --git a/uitest/ui_logger_dsl/UI_Object_commands.tx b/uitest/ui_logger_dsl/UI_Object_commands.tx
new file mode 100644
index 000000000..0f766d87a
--- /dev/null
+++ b/uitest/ui_logger_dsl/UI_Object_commands.tx
@@ -0,0 +1,65 @@
+import type_options
+
+/*
+ this file is for The Grammar of:
+ 1) ButtonUIObject : ( Click event )
+ 2) EditUIObject : ( Type event - Clear event - Select Text event )
+ 3) CheckBoxUIObject : ( Toggle the value )
+ 4) RadioButtonUIObject : ( Select event )
+ 5) ListBoxUIObject : ( Select event )
+ 6) ComboBoxUIObject ( Select event )
+ 7) SpinUIObject ( Increase event - Decrease event )
+ 8) TabControlUIObject ( Change tab event )
+*/
+
+UIObjectCommand:
+ ButtonUIObject | CheckBoxUIObject | EditUIObject |
+ RadioButtonUIObject | ListBoxUIObject | ComboBoxUIObject |
+ SpinFieldUIObject | TabControlUIObject
+;
+
+ButtonUIObject:
+ 'Click on' ui_button=STRING ('from' parent_id=ID)?
+;
+CheckBoxUIObject:
+ 'Toggle' Check_box_id=STRING 'CheckBox' ('from' parent_id=ID)?
+;
+RadioButtonUIObject:
+ 'Select' Radio_button_id=STRING 'RadioButton' ('from' parent_id=ID)?
+;
+ComboBoxUIObject:
+ 'Select in' Combo_box_id=STRING 'ComboBox' 'item number' item_num=INT ('from' parent_id=ID)?
+;
+TabControlUIObject:
+ 'Choose Tab number' tab_page_number=INT 'in' tab_id=STRING ('from' parent_id=ID)?
+;
+EditUIObject:
+ action=action_on_UIObject ('from' parent_id=ID)?
+;
+SpinFieldUIObject:
+ change=increase_or_ecrease Spin_id=STRING ('from' parent_id=ID)?
+;
+ListBoxUIObject:
+ 'Select element with position ' POS=INT 'in' list_id=STRING ('from' parent_id=ID)?
+;
+//=============================================================
+//helper grammar for EditUIObject
+action_on_UIObject:
+ Type_action | SELECT | Clear
+;
+Type_action:
+ 'Type on' edit_button=STRING what_to_type=Type_options
+;
+SELECT:
+ 'Select in ' edit_button=STRING
+ '{"FROM": "' from_pos=INT '" , "TO" : "'to_pos=INT '"}'
+;
+Clear:
+ 'Clear' edit_button=STRING
+;
+
+//=============================================================
+//helper functions for SpinUIObject
+increase_or_ecrease:
+ 'Increase' | 'Decrease'
+;
diff --git a/uitest/ui_logger_dsl/dialog_commands.tx b/uitest/ui_logger_dsl/dialog_commands.tx
new file mode 100644
index 000000000..b1837f7ef
--- /dev/null
+++ b/uitest/ui_logger_dsl/dialog_commands.tx
@@ -0,0 +1,24 @@
+/*
+ this file for the Dialog commands
+ It handle all types of Dialog the Modeless and the Modal
+ Also It handle the Close Dialog Commands
+*/
+DialogCommand:
+ OpenDialog | CloseDialog
+;
+
+OpenDialog:
+ OpenModalDialog | OpenModelessDialog
+;
+OpenModalDialog :
+ 'Open Modal ' dialog_name=ID
+;
+OpenModelessDialog :
+ 'Open Modeless ' dialog_name=ID
+;
+
+CloseDialog:
+ //the additional_note=STRING? if you need to add name in the future
+ //Also it's used to make instance of the command of type CloseDialog
+ 'Close Dialog' additional_note=STRING?
+;
diff --git a/uitest/ui_logger_dsl/dsl_core.py b/uitest/ui_logger_dsl/dsl_core.py
new file mode 100644
index 000000000..7390ec03f
--- /dev/null
+++ b/uitest/ui_logger_dsl/dsl_core.py
@@ -0,0 +1,862 @@
+#!/usr/bin/env python3
+# This file is part of the LibreOffice UI_logger project.
+#
+# This file contain the implementation of the Compiler
+# for the new logger grammar
+#
+# ul stands for Ui_Logger
+
+import os
+import sys
+import argparse
+import keyword
+
+try:
+ from textx.metamodel import metamodel_from_file
+except ImportError:
+ print("textx is a required package.")
+ print('Please install the package for example with "pip3 install --user textx"')
+ sys.exit(1)
+
+tab = " "
+double_tab = " "
+
+
+def parse_args():
+ """
+ This function parses the command-line arguments
+ to get the input and output file details
+ """
+ parser = argparse.ArgumentParser(description="Generate a UI test file from log")
+ parser.add_argument("input_address", type=str, help="The log file address")
+ parser.add_argument("output_address", type=str, help="The test file address")
+ args = parser.parse_args()
+ return args
+
+
+class ul_Compiler:
+ prev_command = ""
+ variables = []
+ objects = dict()
+ current_app = ""
+ parent_hierarchy_count = 0
+ last_parent = []
+ flag_for_QuerySaveDialog = False
+ math_element_selector_initializer= False;
+
+ def __init__(self, input_address, output_address):
+ self.ui_dsl_mm = metamodel_from_file("ui_logger_dsl_grammar.tx")
+ self.output_stream = self.initiate_test_generation(output_address)
+ self.input_address = input_address
+
+ def get_log_file(self, input_address):
+ try:
+ # load the program
+ content = self.ui_dsl_mm.model_from_file(input_address)
+ except IOError as err:
+ print("IO error: {0}".format(err))
+ print(
+ "Use " + os.path.basename(sys.argv[0]) + " -h to get usage instructions"
+ )
+ sys.exit(1)
+
+ return content
+
+ def initiate_test_generation(self, output_address):
+ self.last_parent.append("MainWindow")
+ try:
+ f = open(output_address, "w")
+ except IOError as err:
+ print("IO error: {0}".format(err))
+ print(
+ "Use " + os.path.basename(sys.argv[0]) + " -h to get usage instructions"
+ )
+ sys.exit(1)
+ line = (
+ "# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-\n\n"
+ + "from uitest.framework import UITestCase\n"
+ + "from libreoffice.uno.propertyvalue import mkPropertyValues\n"
+ + "import importlib\n\n"
+ + "class TestClass(UITestCase):\n"
+ + tab
+ + "def test_function(self):\n"
+ )
+
+ self.variables.append(line)
+
+ return f
+
+ def compile(self):
+ self.ui_dsl_mm.register_obj_processors(
+ {
+ "UNOCommand": self.handle_uno,
+ "StarterCommand": self.handle_start,
+ "CloseDialog": self.handle_Dialog,
+ "OpenModelessDialog": self.handle_Dialog,
+ "OpenModalDialog": self.handle_Dialog,
+ "ButtonUIObject": self.handle_button,
+ "CheckBoxUIObject": self.handle_check_box,
+ "TabControlUIObject": self.handle_tab,
+ "ComboBoxUIObject": self.handle_Combo_box,
+ "RadioButtonUIObject": self.handle_Radio_button,
+ "ListBoxUIObject": self.handle_List_box,
+ "SpinFieldUIObject": self.handle_spin_field,
+ "EditUIObject": self.handle_Edit_uiObject,
+ "writer_Type_command": self.handle_writer_type,
+ "writer_Select_command": self.handle_writer_select,
+ "writer_GOTO_command": self.handle_writer_goto,
+ "calc_Select_cell": self.handle_calc_select,
+ "calc_switch_sheet": self.handle_calc_switch_sheet,
+ "calc_Type_command": self.handle_calc_Type_command,
+ "calc_AutoFill_filter": self.handle_calc_AutoFill_filter,
+ "impress_Type_command": self.handle_impress_Type_command,
+ "math_element_selector": self.handle_math_element_selector,
+ "math_Type_command": self.handle_math_Type_command,
+ "setZoom_command": self.handle_setZoom_command,
+ "draw_Type_command": self.handle_draw_Type_command,
+ "SideBar": self.handle_SideBar,
+ "writer_Copy_Text": self.do_nothing,
+ "writer_Cut_Text": self.do_nothing,
+ "writer_Paste_Text": self.do_nothing,
+ "writer_Insert_BreakPage": self.do_nothing,
+ "writer_Create_table": self.do_nothing,
+ "calc_Remove_Content": self.do_nothing,
+ "calc_Delete_Cells": self.do_nothing,
+ "calc_insert_cells": self.do_nothing,
+ "calc_Cut_Cells": self.do_nothing,
+ "calc_Copy_Cells": self.do_nothing,
+ "calc_Merge_Cells": self.do_nothing,
+ "calc_UNMerge_Cells": self.do_nothing,
+ "calc_Rename_Sheet": self.do_nothing,
+ "calc_Insert_sheet": self.do_nothing,
+ "impress_Insert_Slide": self.do_nothing,
+ "impress_Delete_Page": self.do_nothing,
+ "impress_Duplicate_Slide": self.do_nothing,
+ "impress_Rename_Slide": self.do_nothing,
+ "draw_Insert_Page": self.do_nothing,
+ "draw_Delete_Page": self.do_nothing,
+ "draw_Rename_Page": self.do_nothing,
+ }
+ )
+
+ self.log_lines = self.get_log_file(self.input_address)
+
+ def init_app(self):
+ if self.current_app in self.objects:
+ self.objects[self.current_app] += 1
+ else:
+ self.objects[self.current_app] = 1
+ line = (
+ double_tab
+ + self.current_app
+ + ' = MainWindow.getChild("'
+ + self.current_app
+ + '")\n'
+ )
+ self.variables.append(line)
+
+ def init_Object(self, Id_of_Object, name_of_child, Obj_parent):
+
+ if Id_of_Object in self.objects:
+ self.objects[Id_of_Object] += 1
+ else:
+ self.objects[Id_of_Object] = 1
+ line = (
+ double_tab
+ + Id_of_Object
+ + " = "
+ + Obj_parent
+ + '.getChild("'
+ + name_of_child
+ + '")\n'
+ )
+
+ self.variables.append(line)
+
+ def write_line_without_parameters(self, Action_holder, Action, Action_type):
+ line = (
+ double_tab
+ + Action_holder
+ + '.executeAction("'
+ + Action
+ + '",'
+ + Action_type
+ + "())\n"
+ )
+ self.variables.append(line)
+
+ def write_line_with_one_parameters(
+ self, Action_holder, Action, Paramerter_name, parameter_value
+ ):
+ line = (
+ double_tab
+ + Action_holder
+ + '.executeAction("'
+ + Action
+ + '", mkPropertyValues({"'
+ + Paramerter_name
+ + '": "'
+ + str(parameter_value)
+ + '"}))\n'
+ )
+ self.variables.append(line)
+
+ def write_line_with_two_parameters(
+ self,
+ Action_holder,
+ Action,
+ Paramerter_name_1,
+ parameter_value_1,
+ Paramerter_name_2,
+ parameter_value_2,
+ ):
+
+ line = (
+ double_tab
+ + Action_holder
+ + '.executeAction("'
+ + Action
+ + '", mkPropertyValues({"'
+ + Paramerter_name_1
+ + '": "'
+ + str(parameter_value_1)
+ + '", "'
+ + Paramerter_name_2
+ + '": "'
+ + str(parameter_value_2)
+ + '"}))\n'
+ )
+ self.variables.append(line)
+
+ def handle_uno(self, UNOCommand):
+ if UNOCommand.parameters == None:
+ line = (
+ double_tab
+ + 'self.xUITest.executeCommand("'
+ + UNOCommand.uno_command_name
+ + '")\n'
+ )
+ else:
+ parameters = ""
+ for p in UNOCommand.parameters.parameter_data:
+ parameters = parameters + '"' + p.key + '" : ' + str(p.value) + " ,"
+ parameters = parameters[:-1]
+
+ line = (
+ double_tab
+ + 'self.xUITest.executeCommandWithParameters("'
+ + UNOCommand.uno_command_name
+ + '", mkPropertyValues({'
+ + parameters
+ + "}) )\n"
+ )
+
+ self.variables.append(line)
+ self.prev_command = UNOCommand
+
+ def handle_start(self, StarterCommand):
+ line = (
+ double_tab
+ + 'MainDoc = self.ui_test.create_doc_in_start_center("'
+ + StarterCommand.program_name
+ + '")\n'
+ )
+ self.variables.append(line)
+
+ line = double_tab + "MainWindow = self.xUITest.getTopFocusWindow()\n"
+ self.variables.append(line)
+ app = {
+ "writer": "writer_edit",
+ "calc": "grid_window",
+ "impress": "impress_win",
+ "math": "math_edit",
+ "draw": "draw_win",
+ }
+ self.current_app = app[StarterCommand.program_name]
+ self.prev_command = StarterCommand
+
+ def handle_SideBar(self, SideBar):
+
+ line = ' self.xUITest.executeCommand(".uno:Sidebar")\n'
+ self.variables.append(line)
+
+ self.write_line_with_one_parameters(
+ "MainWindow", "SIDEBAR", "PANEL", SideBar.name
+ )
+
+ self.prev_command = SideBar
+
+ def handle_Dialog(self, DialogCommand):
+
+ if DialogCommand.__class__.__name__ == "OpenModalDialog":
+
+ if DialogCommand.dialog_name != "QuerySaveDialog":
+ # This part is just to ignore saving the Save dialog while closing the app
+
+ old_line = self.variables.pop()
+ if self.prev_command.__class__.__name__ == "UNOCommand":
+ key_word = self.prev_command.uno_command_name[-6:]
+ else:
+ key_word = old_line[-9:-3]
+
+ if key_word == "Dialog":
+ old_line = (
+ double_tab
+ + 'self.ui_test.execute_dialog_through_command("'
+ + self.prev_command.uno_command_name
+ + '")\n'
+ )
+ self.variables.append(old_line)
+ line = (
+ double_tab
+ + DialogCommand.dialog_name
+ + " = self.xUITest.getTopFocusWindow()\n"
+ )
+ self.variables.append(line)
+ self.last_parent.append(DialogCommand.dialog_name)
+ self.parent_hierarchy_count = self.parent_hierarchy_count + 1
+
+ else:
+ self.flag_for_QuerySaveDialog = True
+
+ elif DialogCommand.__class__.__name__ == "OpenModelessDialog":
+ old_line = self.variables.pop()
+ if self.prev_command.__class__.__name__ == "UNOCommand":
+ key_word = self.prev_command.uno_command_name[-6:]
+ else:
+ key_word = old_line[-9:-3]
+
+ if key_word == "Dialog":
+ old_line = (
+ double_tab
+ + 'self.ui_test.execute_modeless_dialog_through_command("'
+ + self.prev_command.uno_command_name
+ + '")\n'
+ )
+ self.variables.append(old_line)
+ line = (
+ double_tab
+ + DialogCommand.dialog_name
+ + " = self.xUITest.getTopFocusWindow()\n"
+ )
+ self.variables.append(line)
+ self.last_parent.append(DialogCommand.dialog_name)
+ self.parent_hierarchy_count = self.parent_hierarchy_count + 1
+
+ elif DialogCommand.__class__.__name__ == "CloseDialog":
+
+ if not (self.flag_for_QuerySaveDialog):
+ # This part is just to ignore saving the Save dialog while closing the app
+
+ if self.prev_command.__class__.__name__ == "ButtonUIObject":
+ old_line = self.variables.pop()
+ line = ""
+ if keyword.iskeyword(self.prev_command.ui_button):
+ line = (
+ double_tab
+ + "self.ui_test.close_dialog_through_button(x"
+ + self.prev_command.ui_button
+ + ")\n"
+ )
+ else:
+ line = (
+ double_tab
+ + "self.ui_test.close_dialog_through_button("
+ + self.prev_command.ui_button
+ + ")\n"
+ )
+ self.variables.append(line)
+ self.last_parent.pop()
+ self.parent_hierarchy_count = self.parent_hierarchy_count - 1
+ else:
+ self.flag_for_QuerySaveDialog = False
+
+ # This is to solve the problem of re-using the same id again in different Dialogs
+
+ self.objects.clear()
+
+ self.prev_command = DialogCommand
+
+ def handle_button(self, ButtonUIObject):
+
+ if ButtonUIObject.parent_id != "QuerySaveDialog":
+ # This part is just to ignore saving the Save dialog while closing the app
+
+ name_of_obj = ""
+ if keyword.iskeyword(ButtonUIObject.ui_button):
+ name_of_obj = "x" + ButtonUIObject.ui_button
+ else:
+ name_of_obj = ButtonUIObject.ui_button
+
+ if ButtonUIObject.parent_id == "":
+ self.init_Object(
+ name_of_obj,
+ ButtonUIObject.ui_button,
+ self.last_parent[self.parent_hierarchy_count],
+ )
+ else:
+ self.init_Object(
+ name_of_obj, ButtonUIObject.ui_button, ButtonUIObject.parent_id
+ )
+
+ self.write_line_without_parameters(name_of_obj, "CLICK", "tuple")
+
+ self.prev_command = ButtonUIObject
+
+ def handle_check_box(self, CheckBoxUIObject):
+
+ name_of_obj = ""
+ if keyword.iskeyword(CheckBoxUIObject.Check_box_id):
+ name_of_obj = "x" + CheckBoxUIObject.Check_box_id
+ else:
+ name_of_obj = CheckBoxUIObject.Check_box_id
+
+ if CheckBoxUIObject.parent_id == "":
+ self.init_Object(
+ name_of_obj,
+ CheckBoxUIObject.Check_box_id,
+ self.last_parent[self.parent_hierarchy_count],
+ )
+ else:
+ self.init_Object(
+ name_of_obj, CheckBoxUIObject.Check_box_id, CheckBoxUIObject.parent_id
+ )
+
+ self.write_line_without_parameters(name_of_obj, "CLICK", "tuple")
+
+ self.prev_command = CheckBoxUIObject
+
+ def handle_tab(self, TabControlUIObject):
+
+ name_of_obj = ""
+ if keyword.iskeyword(TabControlUIObject.tab_id):
+ name_of_obj = "x" + TabControlUIObject.tab_id
+ else:
+ name_of_obj = TabControlUIObject.tab_id
+
+ if TabControlUIObject.parent_id == "":
+ self.init_Object(
+ name_of_obj,
+ TabControlUIObject.tab_id,
+ self.last_parent[self.parent_hierarchy_count],
+ )
+ else:
+ self.init_Object(
+ name_of_obj, TabControlUIObject.tab_id, TabControlUIObject.parent_id
+ )
+
+ self.write_line_with_one_parameters(
+ name_of_obj, "SELECT", "POS", TabControlUIObject.tab_page_number
+ )
+
+ self.prev_command = TabControlUIObject
+
+ def handle_Combo_box(self, ComboBoxUIObject):
+
+ name_of_obj = ""
+ if keyword.iskeyword(ComboBoxUIObject.Combo_box_id):
+ name_of_obj = "x" + ComboBoxUIObject.Combo_box_id
+ else:
+ name_of_obj = ComboBoxUIObject.Combo_box_id
+
+ if ComboBoxUIObject.parent_id == "":
+ self.init_Object(
+ name_of_obj,
+ ComboBoxUIObject.Combo_box_id,
+ self.last_parent[self.parent_hierarchy_count],
+ )
+ else:
+ self.init_Object(
+ name_of_obj, ComboBoxUIObject.Combo_box_id, ComboBoxUIObject.parent_id
+ )
+
+ self.write_line_with_one_parameters(
+ name_of_obj, "SELECT", "POS", ComboBoxUIObject.item_num
+ )
+
+ self.prev_command = ComboBoxUIObject
+
+ def handle_Radio_button(self, RadioButtonUIObject):
+
+ name_of_obj = ""
+ if keyword.iskeyword(RadioButtonUIObject.Radio_button_id):
+ name_of_obj = "x" + RadioButtonUIObject.Radio_button_id
+ else:
+ name_of_obj = RadioButtonUIObject.Radio_button_id
+
+ if RadioButtonUIObject.parent_id == "":
+ self.init_Object(
+ name_of_obj,
+ RadioButtonUIObject.Radio_button_id,
+ self.last_parent[self.parent_hierarchy_count],
+ )
+ else:
+ self.init_Object(
+ name_of_obj,
+ RadioButtonUIObject.Radio_button_id,
+ RadioButtonUIObject.parent_id,
+ )
+
+ self.write_line_without_parameters(name_of_obj, "CLICK", "tuple")
+
+ self.prev_command = RadioButtonUIObject
+
+ def handle_List_box(self, ListBoxUIObject):
+
+ name_of_obj = ""
+ if keyword.iskeyword(ListBoxUIObject.list_id):
+ name_of_obj = "x" + ListBoxUIObject.list_id
+ else:
+ name_of_obj = ListBoxUIObject.list_id
+
+ if ListBoxUIObject.parent_id == "":
+ self.init_Object(
+ name_of_obj,
+ ListBoxUIObject.list_id,
+ self.last_parent[self.parent_hierarchy_count],
+ )
+ else:
+ self.init_Object(
+ name_of_obj, ListBoxUIObject.list_id, ListBoxUIObject.parent_id
+ )
+
+ self.write_line_with_one_parameters(
+ name_of_obj, "SELECT", "POS", ListBoxUIObject.POS
+ )
+
+ self.prev_command = ListBoxUIObject
+
+ def handle_spin_field(self, SpinFieldUIObject):
+
+ name_of_obj = ""
+ if keyword.iskeyword(SpinFieldUIObject.Spin_id):
+ name_of_obj = "x" + SpinFieldUIObject.Spin_id
+ else:
+ name_of_obj = SpinFieldUIObject.Spin_id
+
+ if SpinFieldUIObject.parent_id == "":
+ self.init_Object(
+ name_of_obj,
+ SpinFieldUIObject.Spin_id,
+ self.last_parent[self.parent_hierarchy_count],
+ )
+ else:
+ self.init_Object(
+ name_of_obj, SpinFieldUIObject.Spin_id, SpinFieldUIObject.parent_id
+ )
+
+ if SpinFieldUIObject.change == "Increase":
+ self.write_line_without_parameters(name_of_obj, "UP", "tuple")
+ elif SpinFieldUIObject.change == "Decrease":
+ self.write_line_without_parameters(name_of_obj, "DOWN", "tuple")
+ self.prev_command = SpinFieldUIObject
+
+ def handle_Edit_uiObject(self, EditUIObject):
+
+ name_of_obj = ""
+ if keyword.iskeyword(EditUIObject.action.edit_button):
+ name_of_obj = "x" + EditUIObject.action.edit_button
+ else:
+ name_of_obj = EditUIObject.action.edit_button
+
+ if EditUIObject.parent_id == "":
+ self.init_Object(
+ name_of_obj,
+ EditUIObject.action.edit_button,
+ self.last_parent[self.parent_hierarchy_count],
+ )
+ else:
+ self.init_Object(
+ name_of_obj, EditUIObject.action.edit_button, EditUIObject.parent_id
+ )
+
+ if EditUIObject.action.__class__.__name__ == "Type_action":
+
+ if EditUIObject.action.what_to_type.__class__.__name__ == "char":
+ self.write_line_with_one_parameters(
+ name_of_obj,
+ "TYPE",
+ "TEXT",
+ EditUIObject.action.what_to_type.input_char,
+ )
+
+ elif EditUIObject.action.what_to_type.__class__.__name__ == "KeyCode":
+ self.write_line_with_one_parameters(
+ name_of_obj,
+ "TYPE",
+ "KEYCODE",
+ EditUIObject.action.what_to_type.input_key_code,
+ )
+
+ if EditUIObject.action.__class__.__name__ == "SELECT":
+
+ self.write_line_with_two_parameters(
+ name_of_obj,
+ "SELECT",
+ "FROM",
+ EditUIObject.action.from_pos,
+ "TO",
+ EditUIObject.action.to_pos,
+ )
+
+ if EditUIObject.action.__class__.__name__ == "Clear":
+
+ self.write_line_without_parameters(name_of_obj, "CLEAR", "tuple")
+
+ self.prev_command = EditUIObject
+
+ def handle_writer_type(self, writer_Type_command):
+
+ self.init_app()
+
+ if writer_Type_command.what_to_type.__class__.__name__ == "char":
+ self.write_line_with_one_parameters(
+ self.current_app,
+ "TYPE",
+ "TEXT",
+ writer_Type_command.what_to_type.input_char,
+ )
+
+ elif writer_Type_command.what_to_type.__class__.__name__ == "KeyCode":
+ self.write_line_with_one_parameters(
+ self.current_app,
+ "TYPE",
+ "KEYCODE",
+ writer_Type_command.what_to_type.input_key_code,
+ )
+
+ self.prev_command = writer_Type_command
+
+ def handle_writer_select(self, writer_Select_command):
+
+ self.init_app()
+
+ self.write_line_with_two_parameters(
+ self.current_app,
+ "SELECT",
+ "END_POS",
+ writer_Select_command.from_pos,
+ "START_POS",
+ writer_Select_command.to_pos,
+ )
+
+ self.prev_command = writer_Select_command
+
+ def handle_writer_goto(self, writer_GOTO_command):
+
+ self.init_app()
+
+ self.write_line_with_one_parameters(
+ self.current_app, "GOTO", "PAGE", writer_GOTO_command.page_num
+ )
+
+ self.prev_command = writer_GOTO_command
+
+ def handle_calc_select(self, calc_Select_cell):
+
+ self.init_app()
+
+ if calc_Select_cell.select_op.__class__.__name__ == "range_of_cells":
+ self.write_line_with_one_parameters(
+ self.current_app,
+ "SELECT",
+ "RANGE",
+ calc_Select_cell.select_op.input_range,
+ )
+
+ elif calc_Select_cell.select_op.__class__.__name__ == "one_cell":
+ self.write_line_with_one_parameters(
+ self.current_app,
+ "SELECT",
+ "CELL",
+ calc_Select_cell.select_op.input_cell,
+ )
+
+ self.prev_command = calc_Select_cell
+
+ def handle_calc_switch_sheet(self, calc_switch_sheet):
+
+ self.init_app()
+
+ self.write_line_with_one_parameters(
+ self.current_app, "SELECT", "TABLE", calc_switch_sheet.sheet_num
+ )
+
+ self.prev_command = calc_switch_sheet
+
+ def handle_calc_Type_command(self, calc_Type_command):
+
+ self.init_app()
+
+ if calc_Type_command.what_to_type.__class__.__name__ == "char":
+ self.write_line_with_one_parameters(
+ self.current_app,
+ "TYPE",
+ "TEXT",
+ calc_Type_command.what_to_type.input_char,
+ )
+
+ elif calc_Type_command.what_to_type.__class__.__name__ == "KeyCode":
+ self.write_line_with_one_parameters(
+ self.current_app,
+ "TYPE",
+ "KEYCODE",
+ calc_Type_command.what_to_type.input_key_code,
+ )
+
+ self.prev_command = calc_Type_command
+
+ def handle_calc_AutoFill_filter(self, calc_AutoFill_filter):
+
+ self.init_app()
+
+ line = (
+ double_tab
+ + self.current_app
+ + '.executeAction("LAUNCH", mkPropertyValues'
+ + '({"AUTOFILTER": "", "COL": "'
+ + str(calc_AutoFill_filter.col_num)
+ + '"'
+ + ', "ROW": "'
+ + str(calc_AutoFill_filter.row_num)
+ + '"}))\n'
+ )
+
+ self.variables.append(line)
+ self.prev_command = calc_AutoFill_filter
+
+ def handle_impress_Type_command(self, impress_Type_command):
+
+ self.init_app()
+
+ if impress_Type_command.what_to_type.__class__.__name__ == "char":
+ self.write_line_with_one_parameters(
+ self.current_app,
+ "TYPE",
+ "TEXT",
+ impress_Type_command.what_to_type.input_char,
+ )
+
+ elif impress_Type_command.what_to_type.__class__.__name__ == "KeyCode":
+ self.write_line_with_one_parameters(
+ self.current_app,
+ "TYPE",
+ "KEYCODE",
+ impress_Type_command.what_to_type.input_key_code,
+ )
+
+ self.prev_command = impress_Type_command
+
+ def handle_math_Type_command(self, math_Type_command):
+
+ self.init_app()
+ if math_Type_command.what_to_type.__class__.__name__ == "char":
+ self.write_line_with_one_parameters(
+ self.current_app,
+ "TYPE",
+ "TEXT",
+ math_Type_command.what_to_type.input_char,
+ )
+
+ elif math_Type_command.what_to_type.__class__.__name__ == "KeyCode":
+ self.write_line_with_one_parameters(
+ self.current_app,
+ "TYPE",
+ "KEYCODE",
+ math_Type_command.what_to_type.input_key_code,
+ )
+
+ self.prev_command = math_Type_command
+
+ def handle_draw_Type_command(self, draw_Type_command):
+
+ self.init_app()
+ if draw_Type_command.what_to_type.__class__.__name__ == "char":
+ self.write_line_with_one_parameters(
+ self.current_app,
+ "TYPE",
+ "TEXT",
+ draw_Type_command.what_to_type.input_char,
+ )
+
+ elif draw_Type_command.what_to_type.__class__.__name__ == "KeyCode":
+ self.write_line_with_one_parameters(
+ self.current_app,
+ "TYPE",
+ "KEYCODE",
+ draw_Type_command.what_to_type.input_key_code,
+ )
+
+ self.prev_command = draw_Type_command
+
+ def handle_math_element_selector(self, math_element_selector):
+
+ if( self.math_element_selector_initializer == False ):
+ # This part to initialize the element selector in math application
+ self.math_element_selector_initializer = True
+ line = (
+ double_tab
+ + "element_selector"
+ + ' = MainWindow.getChild("'
+ + "element_selector"
+ + '")\n'
+ )
+ self.variables.append(line)
+
+ # this put a prefix of char 'x' to avoid variable with name equal to number only
+ element_name="x"+str(math_element_selector.element_no)
+
+ line = (
+ double_tab
+ + str(element_name)
+ + ' = element_selector.getChild("'
+ + str(math_element_selector.element_no)
+ + '")\n'
+ )
+ self.variables.append(line)
+
+ self.write_line_without_parameters(
+ str(element_name), "SELECT", "tuple"
+ )
+
+ self.prev_command = math_element_selector
+
+ def handle_setZoom_command(self, setZoom_command):
+
+ self.init_app()
+
+ self.write_line_with_one_parameters(
+ self.current_app, "SET", "ZOOM", setZoom_command.zoom_value
+ )
+
+ self.prev_command = setZoom_command
+
+ def Generate_UI_test(self):
+ line = double_tab + "self.ui_test.close_doc()"
+ self.variables.append(line)
+
+ line = "\n\n# vim: set shiftwidth=4 softtabstop=4 expandtab:"
+ self.variables.append(line)
+
+ for line in self.variables:
+ self.output_stream.write(str(line))
+
+ def do_nothing(self, Command):
+ line = "to be added in the future"
+
+ def __del__(self):
+ self.output_stream.close()
+
+
+def main():
+ args = parse_args()
+ ui_logger = ul_Compiler(args.input_address, args.output_address)
+ ui_logger.compile()
+ for statement in ui_logger.log_lines.commands:
+ print(statement)
+ ui_logger.Generate_UI_test()
+ del ui_logger
+
+
+if __name__ == "__main__":
+ main()
diff --git a/uitest/ui_logger_dsl/example.ul b/uitest/ui_logger_dsl/example.ul
new file mode 100644
index 000000000..d82c71a29
--- /dev/null
+++ b/uitest/ui_logger_dsl/example.ul
@@ -0,0 +1,34 @@
+Start writer
+Send UNO Command (".uno:UpdateInputFields")
+Send UNO Command (".uno:FontDialog")
+Open Modal CharacterPropertiesDialog
+Choose Tab number 0 in 'tabcontrol' from CharacterPropertiesDialog
+Select in 'westfontnamelb-cjk' ComboBox item number 66 from CharacterPropertiesDialog
+Choose Tab number 1 in 'tabcontrol' from CharacterPropertiesDialog
+Select element with position 3 in 'effectslb' fromCharacterPropertiesDialog
+Toggle 'shadowcb' CheckBox from CharacterPropertiesDialog
+Choose Tab number 2 in 'tabcontrol' from CharacterPropertiesDialog
+Select '270deg' RadioButton from CharacterPropertiesDialog
+Select '90deg' RadioButton from CharacterPropertiesDialog
+Increase 'scalewidthsb' from CharacterPropertiesDialog
+Increase 'scalewidthsb' from CharacterPropertiesDialog
+Increase 'scalewidthsb' from CharacterPropertiesDialog
+Decrease 'scalewidthsb' from CharacterPropertiesDialog
+Decrease 'scalewidthsb' from CharacterPropertiesDialog
+Decrease 'scalewidthsb' from CharacterPropertiesDialog
+Toggle 'pairkerning' CheckBox from CharacterPropertiesDialog
+Click on 'cancel' from CharacterPropertiesDialog
+Close Dialog
+Type on writer {"TEXT": "a"}
+Type on writer {"TEXT": "n"}
+Type on writer {"TEXT": "a"}
+Type on writer {"TEXT": " "}
+Type on writer {"TEXT": "a"}
+Type on writer {"TEXT": "h"}
+Type on writer {"TEXT": "m"}
+Type on writer {"TEXT": "e"}
+Type on writer {"TEXT": "d"}
+Select from Pos 4 to Pos 9
+Open Modal QuerySaveDialog
+Click on 'discard' from QuerySaveDialog
+Close Dialog \ No newline at end of file
diff --git a/uitest/ui_logger_dsl/starter_commands.tx b/uitest/ui_logger_dsl/starter_commands.tx
new file mode 100644
index 000000000..93fb0c2e0
--- /dev/null
+++ b/uitest/ui_logger_dsl/starter_commands.tx
@@ -0,0 +1,13 @@
+//this file for the starters commands when you open any LO application
+//It's translate automatic that the button you push to open the app is a starter button
+
+StarterCommand:
+ 'Start' program_name=Program
+;
+
+
+Program:
+ "writer"|"calc"|"impress"|"draw"|"math"|"database"
+;
+
+
diff --git a/uitest/ui_logger_dsl/type_options.tx b/uitest/ui_logger_dsl/type_options.tx
new file mode 100644
index 000000000..b106e7f03
--- /dev/null
+++ b/uitest/ui_logger_dsl/type_options.tx
@@ -0,0 +1,9 @@
+Type_options:
+ char | KeyCode
+;
+char:
+ '{' '"TEXT":' input_char=STRING '}'
+;
+KeyCode:
+ '{' '"KEYCODE":' input_key_code=STRING '}'
+;
diff --git a/uitest/ui_logger_dsl/ui_logger_dsl_grammar.tx b/uitest/ui_logger_dsl/ui_logger_dsl_grammar.tx
new file mode 100644
index 000000000..123c9b6f3
--- /dev/null
+++ b/uitest/ui_logger_dsl/ui_logger_dsl_grammar.tx
@@ -0,0 +1,29 @@
+//this file is to define the new dsl grammar
+/*
+ This file just Import all Grammar Statements from all other files to this file
+ The Compiler just work with this file to Compile it
+ Each file of these imported file has a Comments related to it's content
+*/
+
+import dialog_commands
+import starter_commands
+import uno_commands
+import UI_Object_commands
+import Special_commands
+import General_commands
+
+UILogger:
+ commands*=Command
+;
+
+Command:
+ UNOCommand | StarterCommand | UIObjectCommand | DialogCommand |
+ SpecialCommand | GeneralCommand | Comment
+;
+/*
+ The Comment Command is just for give the ability to write a Comment
+ if you want to write a test Case in the new dsl language
+*/
+Comment:
+ /\/\/.*$/
+;
diff --git a/uitest/ui_logger_dsl/uno_commands.tx b/uitest/ui_logger_dsl/uno_commands.tx
new file mode 100644
index 000000000..15df9ef86
--- /dev/null
+++ b/uitest/ui_logger_dsl/uno_commands.tx
@@ -0,0 +1,20 @@
+/*
+ This file is for the grammar of the UNO Command Statements
+ It's Automatically have 2 modes one with parameters and one without
+*/
+
+UNOCommand:
+ 'Send UNO Command' '(' uno_command_name=STRING ')' (parameters=parameter)?
+;
+
+parameter:
+ '{' parameter_data *= data ','? '}'
+;
+
+data:
+ ','? key=STRING ':' value= value_type
+;
+
+value_type:
+ INT|ID
+; \ No newline at end of file
diff --git a/uitest/uitest/bisecting.py b/uitest/uitest/bisecting.py
new file mode 100644
index 000000000..7d2f07441
--- /dev/null
+++ b/uitest/uitest/bisecting.py
@@ -0,0 +1,16 @@
+# -*- 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/.
+#
+
+from functools import wraps
+
+def requires(revision):
+ def decorator(f):
+ f.requires = revision
+ return f
+ return decorator
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/uitest/config.py b/uitest/uitest/config.py
new file mode 100644
index 000000000..d9a86baae
--- /dev/null
+++ b/uitest/uitest/config.py
@@ -0,0 +1,14 @@
+# -*- 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/.
+#
+
+use_sleep = False
+
+DEFAULT_SLEEP = 0.1
+
+MAX_WAIT = 60
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/uitest/debug.py b/uitest/uitest/debug.py
new file mode 100644
index 000000000..234559174
--- /dev/null
+++ b/uitest/uitest/debug.py
@@ -0,0 +1,16 @@
+# -*- 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 uitest.config
+
+import time
+
+def sleep(seconds):
+ if uitest.config.use_sleep:
+ time.sleep(seconds)
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/uitest/framework.py b/uitest/uitest/framework.py
new file mode 100644
index 000000000..7149132c3
--- /dev/null
+++ b/uitest/uitest/framework.py
@@ -0,0 +1,67 @@
+# -*- 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 signal
+import unittest
+import time
+
+from uitest.test import UITest
+
+from libreoffice.connection import PersistentConnection, OfficeConnection
+
+class UITestCase(unittest.TestCase):
+
+ def __init__(self, test_name, opts):
+ unittest.TestCase.__init__(self, test_name)
+ self.opts = opts
+
+ def setUp(self):
+ self.setSignalHandler()
+ self.connection = PersistentConnection(self.opts)
+ self.connection.setUp()
+ self.xContext = self.connection.getContext()
+ self.xUITest = self.xContext.ServiceManager.createInstanceWithContext(
+ "org.libreoffice.uitest.UITest", self.xContext)
+
+ self.ui_test = UITest(self.xUITest, self.xContext)
+ self.startTime = time.time()
+
+ def tearDown(self):
+ try:
+ t = time.time() - self.startTime
+ print("Execution time for %s: %.3f" % (self.id(), t))
+ if self.xContext is not None:
+ try:
+ desktop = self.ui_test.get_desktop()
+ components = desktop.getComponents()
+ for component in components:
+ component.close(False)
+ except Exception as e:
+ print(e)
+
+ self.connection.tearDown()
+ finally:
+ self.resetSignalHandler()
+ self.connection.kill()
+
+ def signalHandler(self, signum, frame):
+ if self.connection:
+ self.connection.kill()
+
+ def setSignalHandler(self):
+ signal.signal(signal.SIGABRT, self.signalHandler)
+ signal.signal(signal.SIGSEGV, self.signalHandler)
+ signal.signal(signal.SIGTERM, self.signalHandler)
+ signal.signal(signal.SIGILL, self.signalHandler)
+
+ def resetSignalHandler(self):
+ signal.signal(signal.SIGABRT, signal.SIG_IGN)
+ signal.signal(signal.SIGSEGV, signal.SIG_IGN)
+ signal.signal(signal.SIGTERM, signal.SIG_IGN)
+ signal.signal(signal.SIGILL, signal.SIG_IGN)
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/uitest/path.py b/uitest/uitest/path.py
new file mode 100644
index 000000000..5a3aeff22
--- /dev/null
+++ b/uitest/uitest/path.py
@@ -0,0 +1,31 @@
+# -*- 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 os
+from urllib.parse import urljoin
+from urllib.request import pathname2url
+
+def get_src_dir_fallback():
+ current_dir = os.path.dirname(os.path.realpath(__file__))
+ return os.path.abspath(os.path.join(current_dir, "../../"))
+
+def path2url(path):
+ return urljoin('file:', pathname2url(os.path.normpath(path)))
+
+def get_workdir_url():
+ workdir_path = os.environ.get('WORKDIR', os.path.join(get_src_dir_fallback(), 'workdir'))
+ return path2url(workdir_path)
+
+def get_srcdir_url():
+ srcdir_path = os.environ.get('SRCDIR', get_src_dir_fallback())
+ return path2url(srcdir_path)
+
+def get_instdir_url():
+ instdir_path = os.environ.get('INSTDIR', os.path.join(get_src_dir_fallback(), 'instdir'))
+ return path2url(instdir_path)
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/uitest/test.py b/uitest/uitest/test.py
new file mode 100644
index 000000000..556fb511c
--- /dev/null
+++ b/uitest/uitest/test.py
@@ -0,0 +1,223 @@
+# -*- 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
+from uitest.config import DEFAULT_SLEEP
+from uitest.config import MAX_WAIT
+from uitest.uihelper.common import get_state_as_dict
+
+from com.sun.star.uno import RuntimeException
+
+from libreoffice.uno.eventlistener import EventListener
+
+class DialogNotExecutedException(Exception):
+ def __init__(self, command):
+ self.command = command
+
+ def __str__(self):
+ return "Dialog not executed for: " + self.command
+
+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_until_child_is_available(self, parent, childName):
+ time_ = 0
+ while time_ < MAX_WAIT:
+ if childName in parent.getChildren():
+ break
+ else:
+ time_ += DEFAULT_SLEEP
+ time.sleep(DEFAULT_SLEEP)
+
+ def wait_until_property_is_updated(self, element, propertyName, value):
+ time_ = 0
+ while time_ < MAX_WAIT:
+ if get_state_as_dict(element)[propertyName] == value:
+ break
+ else:
+ time_ += DEFAULT_SLEEP
+ time.sleep(DEFAULT_SLEEP)
+
+ def load_file(self, url):
+ desktop = self.get_desktop()
+ with EventListener(self._xContext, "OnLoad") as event:
+ component = desktop.loadComponentFromURL(url, "_default", 0, tuple())
+ time_ = 0
+ while time_ < MAX_WAIT:
+ if event.executed:
+ frames = self.get_frames()
+ if len(frames) == 1:
+ self.get_desktop().setActiveFrame(frames[0])
+ time.sleep(DEFAULT_SLEEP)
+ return component
+ time_ += DEFAULT_SLEEP
+ time.sleep(DEFAULT_SLEEP)
+
+ def execute_dialog_through_command(self, command, printNames=False):
+ with EventListener(self._xContext, "DialogExecute", printNames=printNames) as event:
+ if not self._xUITest.executeDialog(command):
+ raise DialogNotExecutedException(command)
+ while True:
+ if event.executed:
+ time.sleep(DEFAULT_SLEEP)
+ return
+ time.sleep(DEFAULT_SLEEP)
+
+ def execute_modeless_dialog_through_command(self, command, printNames=False):
+ with EventListener(self._xContext, "ModelessDialogVisible", printNames = printNames) as event:
+ if not self._xUITest.executeCommand(command):
+ raise DialogNotExecutedException(command)
+ time_ = 0
+ while time_ < MAX_WAIT:
+ if event.executed:
+ time.sleep(DEFAULT_SLEEP)
+ return
+ time_ += DEFAULT_SLEEP
+ time.sleep(DEFAULT_SLEEP)
+
+ raise DialogNotExecutedException(command)
+
+ def execute_dialog_through_action(self, ui_object, action, parameters = None, event_name = "DialogExecute"):
+ if parameters is None:
+ parameters = tuple()
+
+ with EventListener(self._xContext, event_name) as event:
+ ui_object.executeAction(action, parameters)
+ time_ = 0
+ while time_ < MAX_WAIT:
+ if event.executed:
+ time.sleep(DEFAULT_SLEEP)
+ return
+ time_ += DEFAULT_SLEEP
+ time.sleep(DEFAULT_SLEEP)
+ raise DialogNotExecutedException(action)
+
+ 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
+
+ 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())
+ time_ = 0
+ while time_ < MAX_WAIT:
+ if event.executed:
+ frames = self.get_frames()
+ self.get_desktop().setActiveFrame(frames[0])
+ print(len(frames))
+ return
+ time_ += DEFAULT_SLEEP
+ time.sleep(DEFAULT_SLEEP)
+
+ print("failure doc in start center")
+
+ # report a failure here
+
+ 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()
+
+ def execute_blocking_action(self, action, dialog_element=None,
+ args=(), dialog_handler=None, 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.
+ dialog_element(str, optional): The name of a button on the dialog
+ which will be clicked when the dialog is shown.
+ args(tuple, optional): The arguments to be passed to `action`
+ dialog_handler(callable, optional): Will be called when the dialog
+ is shown, with the dialog object passed as a parameter.
+ 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()
+ time_ = 0
+ # we are not necessarily opening a dialog, so wait much longer
+ while time_ < 10 * MAX_WAIT:
+ if event.executed:
+ xDlg = self._xUITest.getTopFocusWindow()
+ if dialog_element:
+ xUIElement = xDlg.getChild(dialog_element)
+ xUIElement.executeAction("CLICK", tuple())
+ if dialog_handler:
+ dialog_handler(xDlg)
+ thread.join()
+ return
+
+ time_ += DEFAULT_SLEEP
+ time.sleep(DEFAULT_SLEEP)
+ raise DialogNotExecutedException("did not execute a dialog for a blocking action")
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/uitest/uihelper/__init__.py b/uitest/uitest/uihelper/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/uitest/uitest/uihelper/__init__.py
diff --git a/uitest/uitest/uihelper/calc.py b/uitest/uitest/uihelper/calc.py
new file mode 100644
index 000000000..e34304c69
--- /dev/null
+++ b/uitest/uitest/uihelper/calc.py
@@ -0,0 +1,16 @@
+# -*- 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/.
+#
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from uitest.uihelper.common import type_text
+
+def enter_text_to_cell(gridwin, cell, text):
+ gridwin.executeAction("SELECT", mkPropertyValues({"CELL": cell}))
+ type_text(gridwin, text)
+ gridwin.executeAction("TYPE", mkPropertyValues({"KEYCODE": "RETURN"}))
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/uitest/uihelper/common.py b/uitest/uitest/uihelper/common.py
new file mode 100644
index 000000000..5056ef764
--- /dev/null
+++ b/uitest/uitest/uihelper/common.py
@@ -0,0 +1,22 @@
+# -*- 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/.
+#
+
+from libreoffice.uno.propertyvalue import convert_property_values_to_dict, mkPropertyValues
+
+def get_state_as_dict(ui_object):
+ return convert_property_values_to_dict(ui_object.getState())
+
+def type_text(ui_object, text):
+ ui_object.executeAction("TYPE", mkPropertyValues({"TEXT": text}))
+
+def select_pos(ui_object, pos):
+ ui_object.executeAction("SELECT", mkPropertyValues({"POS": pos}))
+
+def select_text(ui_object, from_pos, to):
+ ui_object.executeAction("SELECT", mkPropertyValues({"FROM": from_pos, "TO": to}))
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/uitest/uihelper/keyboard.py b/uitest/uitest/uihelper/keyboard.py
new file mode 100644
index 000000000..f2d8890af
--- /dev/null
+++ b/uitest/uitest/uihelper/keyboard.py
@@ -0,0 +1,13 @@
+# -*- 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/.
+#
+
+from libreoffice.uno.propertyvalue import convert_property_values_to_dict, mkPropertyValues
+
+def select_all(ui_object):
+ ui_object.executeAction("TYPE", mkPropertyValues({"KEYCODE":"CTRL+A"}))
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/uitest/uihelper/testDialog.py b/uitest/uitest/uihelper/testDialog.py
new file mode 100644
index 000000000..43f0a5bc0
--- /dev/null
+++ b/uitest/uitest/uihelper/testDialog.py
@@ -0,0 +1,39 @@
+# -*- 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/.
+#
+
+from uitest.framework import UITestCase
+from uitest.uihelper.common import get_state_as_dict
+
+# opens the dialogs, closes it with the given close button
+# and if there is an "OK" button open the dialog again and close it by using the OK button
+# the test only checks if LibreOffice crashes by opening the dialog
+def testDialog(UITestCase, app, dialog):
+ doc = UITestCase.ui_test.create_doc_in_start_center(app)
+ UITestCase.ui_test.execute_dialog_through_command(dialog['command'])
+ xDialog = UITestCase.xUITest.getTopFocusWindow()
+
+ xCloseBtn = xDialog.getChild(dialog['closeButton'])
+ if 'skipTestOK' in dialog and dialog['skipTestOK'] == True:
+ xOKBtn = None
+ else:
+ try:
+ xOKBtn = xDialog.getChild("ok")
+ if (get_state_as_dict(xOKBtn)["Enabled"] != "true"):
+ xOKBtn = None
+ except:
+ xOKBtn = None
+
+ UITestCase.ui_test.close_dialog_through_button(xCloseBtn)
+ if (xOKBtn != None):
+ print("check also OK button")
+ UITestCase.ui_test.execute_dialog_through_command(dialog['command'])
+ xDialog = UITestCase.xUITest.getTopFocusWindow()
+ xOKBtn = xDialog.getChild("ok")
+ UITestCase.ui_test.close_dialog_through_button(xOKBtn)
+ UITestCase.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/writer_tests/data/3pages.odt b/uitest/writer_tests/data/3pages.odt
new file mode 100644
index 000000000..0f2512903
--- /dev/null
+++ b/uitest/writer_tests/data/3pages.odt
Binary files differ
diff --git a/uitest/writer_tests/data/tdf104649.docx b/uitest/writer_tests/data/tdf104649.docx
new file mode 100644
index 000000000..7b1e4fd3c
--- /dev/null
+++ b/uitest/writer_tests/data/tdf104649.docx
Binary files differ
diff --git a/uitest/writer_tests/data/tdf114724.odt b/uitest/writer_tests/data/tdf114724.odt
new file mode 100644
index 000000000..6c5110868
--- /dev/null
+++ b/uitest/writer_tests/data/tdf114724.odt
Binary files differ
diff --git a/uitest/writer_tests1/pageDialog.py b/uitest/writer_tests1/pageDialog.py
new file mode 100644
index 000000000..73e523444
--- /dev/null
+++ b/uitest/writer_tests1/pageDialog.py
@@ -0,0 +1,239 @@
+#
+# 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.framework import UITestCase
+from uitest.uihelper.common import select_pos, get_state_as_dict
+from com.sun.star.uno import RuntimeException
+from com.sun.star.awt.GradientStyle import LINEAR
+from com.sun.star.drawing.HatchStyle import SINGLE
+from com.sun.star.drawing.BitmapMode import REPEAT
+from com.sun.star.drawing.RectanglePoint import MIDDLE_MIDDLE
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+class WriterPageDialog(UITestCase):
+
+ def launch_dialog_and_select_tab(self, tab):
+ self.ui_test.execute_dialog_through_command(".uno:PageDialog")
+
+ xDialog = self.xUITest.getTopFocusWindow()
+ tabcontrol = xDialog.getChild("tabcontrol")
+ select_pos(tabcontrol, str(tab))
+
+ return xDialog
+
+ def click_button(self, dialog, button):
+ xButton = dialog.getChild(button)
+ xButton.executeAction("CLICK", tuple())
+
+ def check_default_area(self, btn):
+ document = self.ui_test.get_component()
+ if btn == 'btnnone':
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.BackColor, -1)
+ elif btn == 'btncolor':
+ self.assertEqual(
+ hex(document.StyleFamilies.PageStyles.Standard.BackColor), '0x729fcf')
+ self.assertEqual(
+ hex(document.StyleFamilies.PageStyles.Standard.FillColor), '0x729fcf')
+ self.assertEqual(
+ hex(document.StyleFamilies.PageStyles.Standard.FillColor), '0x729fcf')
+ elif btn == 'btngradient':
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillGradient.Style, LINEAR)
+ self.assertEqual(
+ hex(document.StyleFamilies.PageStyles.Standard.FillGradient.StartColor), '0xdde8cb')
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillGradient.Angle, 300)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillGradient.Border, 0)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillGradient.XOffset, 0)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillGradient.YOffset, 0)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillGradient.StartIntensity, 100)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillGradient.EndIntensity, 100)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillGradientName, 'Pastel Bouquet')
+ elif btn == 'btnhatch':
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillHatch.Style, SINGLE )
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillHatch.Color, 0)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillHatch.Distance, 102)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillHatch.Angle, 0)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillHatchName, 'Black 0 Degrees')
+ elif btn == 'btnbitmap':
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillBitmapMode, REPEAT)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillBitmapPositionOffsetX, 0)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillBitmapPositionOffsetY, 0)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillBitmapRectanglePoint, MIDDLE_MIDDLE)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillBitmapStretch, False)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillBitmapTile, True)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillBitmapOffsetX, 0)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillBitmapOffsetY, 0)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillBitmapLogicalSize, True)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillBitmapSizeX, 0)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillBitmapSizeY, 0)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillBitmapName, 'Painted White')
+ elif btn == 'btnpattern':
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillBitmapMode, REPEAT)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillBitmapPositionOffsetX, 0)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillBitmapPositionOffsetY, 0)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillBitmapRectanglePoint, MIDDLE_MIDDLE)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillBitmapStretch, False)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillBitmapTile, True)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillBitmapOffsetX, 0)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillBitmapOffsetY, 0)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillBitmapLogicalSize, True)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillBitmapSizeX, 0)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillBitmapSizeY, 0)
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.FillBitmapName, '5 Percent')
+
+ def test_area_tab(self):
+
+ self.ui_test.create_doc_in_start_center("writer")
+
+ buttons = ['btnbitmap', 'btncolor', 'btngradient', 'btnhatch', 'btnpattern']
+ for index, button in enumerate(buttons):
+
+ xDialog = self.launch_dialog_and_select_tab(2)
+
+ self.click_button(xDialog, button)
+
+ self.click_button(xDialog, 'ok')
+
+ self.check_default_area(button)
+
+ xDialog = self.launch_dialog_and_select_tab(2)
+
+ self.click_button(xDialog, 'btnnone')
+
+ self.click_button(xDialog, 'ok')
+
+ self.check_default_area('btnnone')
+
+ self.ui_test.close_doc()
+
+ def test_paper_format(self):
+
+ lPaperFormat = ["A6", "A5", "A4", "A3", "B6 (ISO)", "B5 (ISO)", "B4 (ISO)", "Letter",
+ "Legal", "Long Bond", "Tabloid", "B6 (JIS)", "B5 (JIS)", "B4 (JIS)", "16 Kai",
+ "32 Kai", "Big 32 Kai", "User", "DL Envelope", "C6 Envelope", "C6/5 Envelope",
+ "C5 Envelope", "C4 Envelope", "#6¾ Envelope", "#7¾ (Monarch) Envelope",
+ "#9 Envelope", "#10 Envelope", "#11 Envelope", "#12 Envelope", "Japanese Postcard"]
+
+ self.ui_test.create_doc_in_start_center("writer")
+
+ for i in range(30):
+ with self.subTest(i=i):
+ xDialog = self.launch_dialog_and_select_tab(1)
+
+ xFormatList = xDialog.getChild("comboPageFormat")
+ select_pos(xFormatList, str(i))
+
+ self.assertEqual(
+ get_state_as_dict(xFormatList)["SelectEntryText"], lPaperFormat[i])
+
+ self.click_button(xDialog, 'ok')
+
+ self.ui_test.close_doc()
+
+ def test_orientation(self):
+
+ self.ui_test.create_doc_in_start_center("writer")
+
+ document = self.ui_test.get_component()
+
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.IsLandscape, False)
+
+ xDialog = self.launch_dialog_and_select_tab(1)
+
+ self.click_button(xDialog, 'radiobuttonLandscape')
+
+ self.click_button(xDialog, 'ok')
+
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.IsLandscape, True)
+
+ xDialog = self.launch_dialog_and_select_tab(1)
+
+ self.click_button(xDialog, 'radiobuttonPortrait')
+
+ self.click_button(xDialog, 'ok')
+
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.IsLandscape, False)
+
+ self.ui_test.close_doc()
+
+ def test_text_direction(self):
+
+ lTextDirection = ['Left-to-right (horizontal)', 'Right-to-left (horizontal)',
+ 'Right-to-left (vertical)', 'Left-to-right (vertical)']
+
+ self.ui_test.create_doc_in_start_center("writer")
+
+ document = self.ui_test.get_component()
+
+ for i in range(4):
+ with self.subTest(i=i):
+ xDialog = self.launch_dialog_and_select_tab(1)
+
+ xTextDirectionList = xDialog.getChild("comboTextFlowBox")
+ select_pos(xTextDirectionList, str(i))
+
+ self.assertEqual(
+ get_state_as_dict(xTextDirectionList)["SelectEntryText"], lTextDirection[i])
+
+ self.click_button(xDialog, 'ok')
+
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.WritingMode, i)
+
+ self.ui_test.close_doc()
+
+ def test_cancel_button_page_dialog(self):
+ self.ui_test.create_doc_in_start_center("writer")
+
+ self.ui_test.execute_dialog_through_command(".uno:PageDialog")
+ xDialog = self.xUITest.getTopFocusWindow()
+ xCancelBtn = xDialog.getChild("cancel")
+ self.ui_test.close_dialog_through_button(xCancelBtn)
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/writer_tests2/tdf92611.py b/uitest/writer_tests2/tdf92611.py
new file mode 100644
index 000000000..8fee6143c
--- /dev/null
+++ b/uitest/writer_tests2/tdf92611.py
@@ -0,0 +1,21 @@
+#
+# 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.framework import UITestCase
+
+class tdf92611(UITestCase):
+
+ def test_launch_and_close_bibliography(self):
+
+ self.ui_test.create_doc_in_start_center("writer")
+
+ self.xUITest.executeCommand(".uno:BibliographyComponent")
+
+ self.xUITest.executeCommand(".uno:CloseWin")
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/writer_tests3/tdf104649.py b/uitest/writer_tests3/tdf104649.py
new file mode 100644
index 000000000..f6541feee
--- /dev/null
+++ b/uitest/writer_tests3/tdf104649.py
@@ -0,0 +1,37 @@
+#
+# 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.framework import UITestCase
+
+import org.libreoffice.unotest
+import pathlib
+
+def get_url_for_data_file(file_name):
+ return pathlib.Path(org.libreoffice.unotest.makeCopyFromTDOC(file_name)).as_uri()
+
+class tdf104649(UITestCase):
+
+ def test_delete_and_undo(self):
+
+ writer_doc = self.ui_test.load_file(get_url_for_data_file("tdf104649.docx"))
+
+ document = self.ui_test.get_component()
+
+ self.assertEqual(document.Text.String[0:4], "Test")
+
+ selection = self.xUITest.executeCommand(".uno:SelectAll")
+
+ self.xUITest.executeCommand(".uno:Delete")
+
+ self.assertEqual(document.Text.String, "")
+
+ self.xUITest.executeCommand(".uno:Undo")
+
+ self.assertEqual(document.Text.String[0:4], "Test")
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/writer_tests4/insertTableDialog.py b/uitest/writer_tests4/insertTableDialog.py
new file mode 100644
index 000000000..427920e19
--- /dev/null
+++ b/uitest/writer_tests4/insertTableDialog.py
@@ -0,0 +1,78 @@
+#
+# 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.framework import UITestCase
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from uitest.uihelper.common import get_state_as_dict
+
+class WriterInsertTableDialog(UITestCase):
+
+ def insert_table(self, name, rows, cols):
+
+ self.ui_test.create_doc_in_start_center("writer")
+
+ self.ui_test.execute_dialog_through_command(".uno:InsertTable")
+ xDialog = self.xUITest.getTopFocusWindow()
+
+ xNameEdit = xDialog.getChild("nameedit")
+
+ xNameEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE":"CTRL+A"}))
+ xNameEdit.executeAction("TYPE", mkPropertyValues({"TEXT": name}))
+
+ xColSpin = xDialog.getChild("colspin")
+ xColSpin.executeAction("TYPE", mkPropertyValues({"KEYCODE":"CTRL+A"}))
+ xColSpin.executeAction("TYPE", mkPropertyValues({"TEXT": str(cols)}))
+
+ xRowSpin = xDialog.getChild("rowspin")
+ xRowSpin.executeAction("TYPE", mkPropertyValues({"KEYCODE":"CTRL+A"}))
+ xRowSpin.executeAction("TYPE", mkPropertyValues({"TEXT": str(rows)}))
+
+ self.assertEqual(get_state_as_dict(xNameEdit)["Text"], name)
+ self.assertEqual(get_state_as_dict(xColSpin)["Text"], str(cols))
+ self.assertEqual(get_state_as_dict(xRowSpin)["Text"], str(rows))
+
+ xOkBtn = xDialog.getChild("ok")
+ xOkBtn.executeAction("CLICK", tuple())
+
+ document = self.ui_test.get_component()
+
+ tables = document.getTextTables()
+
+ self.assertEqual(tables[0].getName(), name)
+ self.assertEqual(len(tables[0].getRows()), rows)
+ self.assertEqual(len(tables[0].getColumns()), cols)
+
+ def insertTextIntoCell(self, table, cellName, text ):
+ tableText = table.getCellByName( cellName )
+ tableText.setString( text )
+
+ def test_tdf104158(self):
+
+ self.insert_table("Test3", 2, 2)
+
+ self.ui_test.execute_dialog_through_command(".uno:TableNumberFormatDialog")
+
+ xNumberFormatDlg = self.xUITest.getTopFocusWindow()
+
+ xOkBtn = xNumberFormatDlg.getChild("ok")
+ xOkBtn.executeAction("CLICK", tuple())
+
+ self.ui_test.close_doc()
+
+ def test_cancel_button_insert_table_dialog(self):
+ self.ui_test.create_doc_in_start_center("writer")
+ self.ui_test.execute_dialog_through_command(".uno:InsertTable")
+ Dialog = self.xUITest.getTopFocusWindow()
+ CancelBtn = Dialog.getChild("cancel")
+ self.ui_test.close_dialog_through_button(CancelBtn)
+
+ document = self.ui_test.get_component()
+ tables = document.getTextTables()
+ self.assertEqual(len(tables), 0)
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/writer_tests4/start.py b/uitest/writer_tests4/start.py
new file mode 100644
index 000000000..5851e8eff
--- /dev/null
+++ b/uitest/writer_tests4/start.py
@@ -0,0 +1,70 @@
+# -*- 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/.
+#
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+from uitest.framework import UITestCase
+from uitest.uihelper.common import get_state_as_dict, type_text
+
+import time
+
+class SimpleWriterTest(UITestCase):
+
+ def test_start_writer(self):
+
+ self.ui_test.create_doc_in_start_center("writer")
+
+ xWriterDoc = self.xUITest.getTopFocusWindow()
+
+ xWriterEdit = xWriterDoc.getChild("writer_edit")
+
+ xWriterEdit.executeAction("SET", mkPropertyValues({"ZOOM": "200"}))
+
+ self.ui_test.close_doc()
+
+ def test_type_text(self):
+
+ self.ui_test.create_doc_in_start_center("writer")
+
+ xWriterDoc = self.xUITest.getTopFocusWindow()
+ xWriterEdit = xWriterDoc.getChild("writer_edit")
+
+ type_text(xWriterEdit, "This is my first writer text written through the UI testing")
+
+ self.ui_test.close_doc()
+
+ def test_goto_first_page(self):
+
+ self.ui_test.create_doc_in_start_center("writer")
+
+ xWriterDoc = self.xUITest.getTopFocusWindow()
+ xWriterEdit = xWriterDoc.getChild("writer_edit")
+
+ state = get_state_as_dict(xWriterEdit)
+ while state["CurrentPage"] == "1":
+ xWriterEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE": "RETURN"}))
+ state = get_state_as_dict(xWriterEdit)
+
+ xWriterEdit.executeAction("GOTO", mkPropertyValues({"PAGE": "1"}))
+
+ self.ui_test.close_doc()
+
+
+ def test_select_text(self):
+
+ self.ui_test.create_doc_in_start_center("writer")
+
+ xWriterDoc = self.xUITest.getTopFocusWindow()
+ xWriterEdit = xWriterDoc.getChild("writer_edit")
+
+ type_text(xWriterEdit, "This is my first writer text written through the UI testing")
+
+ xWriterEdit.executeAction("SELECT", mkPropertyValues({"START_POS": "0", "END_POS": "4"}))
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/writer_tests5/spellDialog.py b/uitest/writer_tests5/spellDialog.py
new file mode 100644
index 000000000..e678afea5
--- /dev/null
+++ b/uitest/writer_tests5/spellDialog.py
@@ -0,0 +1,102 @@
+#
+# 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 re
+
+from uitest.framework import UITestCase
+from uitest.uihelper.common import get_state_as_dict
+
+from libreoffice.linguistic.linguservice import get_spellchecker
+from com.sun.star.lang import Locale
+
+class SpellingAndGrammarDialog(UITestCase):
+
+ def is_supported_locale(self, language, country):
+ xSpellChecker = get_spellchecker(self.ui_test._xContext)
+ locales = xSpellChecker.getLocales()
+ for locale in locales:
+ if language != None:
+ if locale.Language != language:
+ continue
+
+ if country != None:
+ if locale.Country != country:
+ continue
+
+ # we found the correct combination
+ return True
+
+ def launch_dialog(self):
+ self.ui_test.execute_modeless_dialog_through_command(
+ ".uno:SpellingAndGrammarDialog")
+
+ return self.xUITest.getTopFocusWindow()
+
+ TDF46852_INPUT = """\
+dogg
+dogg
+catt dogg
+frogg frogg
+frogg catt dogg
+dogg catt
+frog, dogg, catt"""
+
+ TDF46852_REGEX = """\
+([a-z]+)
+\\1
+([a-z]+) \\1
+([a-z]+) \\3
+\\3 \\2 \\1
+\\1 \\2
+\\3, \\1, \\2"""
+
+ def test_tdf46852(self):
+ supported_locale = self.is_supported_locale("en", "US")
+ if not supported_locale:
+ self.skipTest("no dictionary support for en_US available")
+ # This automates the steps described in the bug report tdf#46852
+
+ # Step 1: Create a document with repetitious misspelled words
+ self.ui_test.create_doc_in_start_center("writer")
+ document = self.ui_test.get_component()
+ cursor = document.getCurrentController().getViewCursor()
+ # Inserted text must be en_US, so make sure to set language in current location
+ cursor.CharLocale = Locale("en", "US", "")
+ input_text = self.TDF46852_INPUT.replace('\n', '\r') # \r = para break
+ document.Text.insertString(cursor, input_text, False)
+
+ # Step 2: Place cursor on 4th line after second "frogg"
+ cursor.goUp(2, False)
+ cursor.goLeft(1, False)
+
+ # Step 3: Initiate spellchecking, and make sure "Check grammar" is
+ # unchecked
+ spell_dialog = self.launch_dialog()
+ checkgrammar = spell_dialog.getChild('checkgrammar')
+ if get_state_as_dict(checkgrammar)['Selected'] == 'true':
+ checkgrammar.executeAction('CLICK', ())
+ self.assertTrue(get_state_as_dict(checkgrammar)['Selected'] == 'false')
+
+ # Step 4: Repetitively click on "Correct all" for each misspelling
+ # prompt until end of document is reached.
+ changeall = spell_dialog.getChild('changeall')
+ changeall.executeAction("CLICK", ())
+ changeall.executeAction("CLICK", ())
+ # The third time we click on changeall, the click action is going to
+ # block while two message boxes are shown, so we need to do this third
+ # click specially:
+ self.ui_test.execute_blocking_action(
+ changeall.executeAction, args=('CLICK', ()),
+ # Step 5: Confirm to "Continue check at beginning of document"
+ dialog_handler=lambda dialog :
+ self.ui_test.execute_blocking_action(
+ dialog.getChild('yes').executeAction, 'ok', ('CLICK', ())
+ )
+ )
+
+ output_text = document.Text.getString().replace('\r\n', '\n')
+ self.assertTrue(re.match(self.TDF46852_REGEX, output_text))
+
diff --git a/uitest/writer_tests5/tdf114724.py b/uitest/writer_tests5/tdf114724.py
new file mode 100644
index 000000000..09341149c
--- /dev/null
+++ b/uitest/writer_tests5/tdf114724.py
@@ -0,0 +1,47 @@
+#
+# 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.framework import UITestCase
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from uitest.uihelper.common import get_state_as_dict
+from uitest.path import get_srcdir_url
+
+def get_url_for_data_file(file_name):
+ return get_srcdir_url() + "/uitest/writer_tests/data/" + file_name
+
+class tdf114724(UITestCase):
+
+ def test_track_headings_outline(self):
+ writer_doc = self.ui_test.load_file(get_url_for_data_file("tdf114724.odt"))
+ xWriterDoc = self.xUITest.getTopFocusWindow()
+ xWriterEdit = xWriterDoc.getChild("writer_edit")
+
+ self.xUITest.executeCommand(".uno:Sidebar")
+ xWriterEdit.executeAction("SIDEBAR", mkPropertyValues({"PANEL": "SwNavigatorPanel"}))
+
+ xNavigatorPanel = xWriterEdit.getChild("NavigatorPanelParent")
+ xNavigatorPanel.executeAction("ROOT", tuple())
+
+ xWriterEdit.executeAction("FOCUS", tuple())
+
+ self.ui_test.wait_until_property_is_updated(xNavigatorPanel, "selectedtext", "Headings")
+ self.assertEqual(get_state_as_dict(xNavigatorPanel)["selectedtext"], "Headings")
+ self.assertEqual(get_state_as_dict(xNavigatorPanel)["selectioncount"], "1")
+ for _ in range(0,3):
+ xWriterEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE": "DOWN"}))
+
+ self.ui_test.wait_until_property_is_updated(xNavigatorPanel, "selectedtext", "HEADING 4")
+ self.assertEqual(get_state_as_dict(xNavigatorPanel)["selectedtext"], "HEADING 4")
+ self.assertEqual(get_state_as_dict(xNavigatorPanel)["selectioncount"], "1")
+
+ for _ in range(0,3):
+ xWriterEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE": "UP"}))
+
+ self.ui_test.wait_until_property_is_updated(xNavigatorPanel, "selectedtext", "HEADING 1")
+ self.assertEqual(get_state_as_dict(xNavigatorPanel)["selectedtext"], "HEADING 1")
+ self.assertEqual(get_state_as_dict(xNavigatorPanel)["selectioncount"], "1")
+
+ self.xUITest.executeCommand(".uno:Sidebar")
+ self.ui_test.close_doc()
diff --git a/uitest/writer_tests6/insertBreakDialog.py b/uitest/writer_tests6/insertBreakDialog.py
new file mode 100644
index 000000000..291ffdac5
--- /dev/null
+++ b/uitest/writer_tests6/insertBreakDialog.py
@@ -0,0 +1,85 @@
+#
+# 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.framework import UITestCase
+from libreoffice.uno.propertyvalue import mkPropertyValues
+
+class WriterInsertBreakDialog(UITestCase):
+
+ def launch_dialog_and_select_option(self, child):
+
+ self.ui_test.execute_dialog_through_command(".uno:InsertBreak")
+ xDialog = self.xUITest.getTopFocusWindow()
+
+ xOption = xDialog.getChild(child)
+ xOption.executeAction("CLICK", tuple())
+
+ return xDialog
+
+ def getPages(self, total):
+ document = self.ui_test.get_component()
+
+ xCursor = document.getCurrentController().getViewCursor()
+ xCursor.jumpToLastPage()
+
+ self.assertEqual(xCursor.getPage(), total)
+
+ def test_insert_line_break(self):
+
+ self.ui_test.create_doc_in_start_center("writer")
+
+ xDialog = self.launch_dialog_and_select_option("linerb")
+ xOkBtn = xDialog.getChild("ok")
+ xOkBtn.executeAction("CLICK", tuple())
+
+ self.getPages(1)
+
+ self.ui_test.close_doc()
+
+ def test_insert_column_break(self):
+
+ self.ui_test.create_doc_in_start_center("writer")
+
+ xDialog = self.launch_dialog_and_select_option("columnrb")
+ xOkBtn = xDialog.getChild("ok")
+ xOkBtn.executeAction("CLICK", tuple())
+
+ self.getPages(1)
+
+ self.ui_test.close_doc()
+
+ def test_insert_page_break(self):
+
+ self.ui_test.create_doc_in_start_center("writer")
+
+ for i in range(9):
+ with self.subTest(i=i):
+ xDialog = self.launch_dialog_and_select_option("pagerb")
+
+ xStyleList = xDialog.getChild("stylelb")
+ xStyleList.executeAction("SELECT", mkPropertyValues({"POS": str(i)}))
+
+ xOkBtn = xDialog.getChild("ok")
+ xOkBtn.executeAction("CLICK", tuple())
+
+ self.getPages(i + 2)
+
+ self.ui_test.close_doc()
+
+ def test_cancel_button_insert_line_break_dialog(self):
+
+ self.ui_test.create_doc_in_start_center("writer")
+
+ self.ui_test.execute_dialog_through_command(".uno:InsertBreak")
+ xDialog = self.xUITest.getTopFocusWindow()
+ xCancelBtn = xDialog.getChild("cancel")
+ self.ui_test.close_dialog_through_button(xCancelBtn)
+
+ self.getPages(1)
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/writer_tests6/insertPageHeader.py b/uitest/writer_tests6/insertPageHeader.py
new file mode 100644
index 000000000..245073ace
--- /dev/null
+++ b/uitest/writer_tests6/insertPageHeader.py
@@ -0,0 +1,72 @@
+#
+# 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.framework import UITestCase
+
+class WriterInsertPageHeader(UITestCase):
+
+ def insert_header(self):
+ document = self.ui_test.get_component()
+
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.HeaderIsOn, False)
+
+ self.xUITest.executeCommand(
+ ".uno:InsertPageHeader?PageStyle:string=Default%20Page%20Style&On:bool=true")
+
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.HeaderIsOn, True)
+
+ def delete_header(self):
+ document = self.ui_test.get_component()
+
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.HeaderIsOn, True)
+
+ self.ui_test.execute_dialog_through_command(
+ ".uno:InsertPageHeader?PageStyle:string=Default%20Page%20Style&On:bool=false")
+
+ xDialog = self.xUITest.getTopFocusWindow()
+
+ xOption = xDialog.getChild("yes")
+ xOption.executeAction("CLICK", tuple())
+
+ self.assertEqual(
+ document.StyleFamilies.PageStyles.Standard.HeaderIsOn, False)
+
+ def test_header(self):
+ self.ui_test.create_doc_in_start_center("writer")
+
+ self.insert_header()
+
+ self.delete_header()
+
+ self.ui_test.close_doc()
+
+ def test_tdf107427(self):
+ self.ui_test.create_doc_in_start_center("writer")
+
+ self.insert_header()
+
+ self.ui_test.execute_dialog_through_command(".uno:InsertTable")
+
+ xInsertDlg = self.xUITest.getTopFocusWindow()
+
+ xOkBtn = xInsertDlg.getChild("ok")
+ xOkBtn.executeAction("CLICK", tuple())
+
+ document = self.ui_test.get_component()
+
+ tables = document.getTextTables()
+ self.assertEqual(len(tables[0].getRows()), 2)
+ self.assertEqual(len(tables[0].getColumns()), 2)
+
+ self.xUITest.executeCommand(".uno:SelectAll")
+
+ self.delete_header()
+
+ self.ui_test.close_doc()
+
diff --git a/uitest/writer_tests7/autoredactDialog.py b/uitest/writer_tests7/autoredactDialog.py
new file mode 100644
index 000000000..015081431
--- /dev/null
+++ b/uitest/writer_tests7/autoredactDialog.py
@@ -0,0 +1,198 @@
+# -*- 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/.
+
+from uitest.framework import UITestCase
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from uitest.uihelper.common import get_state_as_dict
+from uitest.uihelper.common import type_text
+from uitest.uihelper.common import select_pos
+from uitest.uihelper.common import select_text
+import time
+import re
+from uitest.debug import sleep
+
+class AutoRedactDialog(UITestCase):
+
+ add_target_counter = 0
+
+ # Open the Auto Redact Dialog
+ def launch_and_get_autoredact_dialog(self):
+ self.ui_test.execute_dialog_through_command(".uno:AutoRedactDoc")
+ xDialog = self.xUITest.getTopFocusWindow()
+ self.assertTrue(xDialog is not None)
+ return xDialog
+
+ def getText(self, xObj):
+ return get_state_as_dict(xObj)["Text"]
+
+ def parseTargetContent(self, xObj):
+ return re.split(r'\t+', self.getText(xObj))
+
+ def clearTargetsbox(self, xDialog):
+ xTargetsListbox = xDialog.getChild("targets")
+ xDeleteBtn = xDialog.getChild("delete")
+
+ child_count = len(xTargetsListbox.getChildren())
+
+ if child_count < 1:
+ return
+
+ for i in range(0, child_count):
+ child = xTargetsListbox.getChild(0)
+ child.executeAction("SELECT", tuple())
+ xDeleteBtn.executeAction("CLICK", tuple())
+
+ # Verify
+ self.assertEqual(len(xTargetsListbox.getChildren()), 0)
+
+
+ def test_open_AutoRedactDialog_writer(self):
+ self.ui_test.create_doc_in_start_center("writer")
+ xDialog = self.launch_and_get_autoredact_dialog()
+ xcancBtn = xDialog.getChild("cancel")
+ self.ui_test.close_dialog_through_button(xcancBtn)
+ self.ui_test.close_doc()
+
+ def test_add_target(self):
+ self.ui_test.create_doc_in_start_center("writer")
+ xDialog = self.launch_and_get_autoredact_dialog()
+ xAddBtn = xDialog.getChild("add")
+
+ # Make sure we are starting with an empty targets list
+ self.clearTargetsbox(xDialog)
+
+ # Names need to be distinct
+ # ["target name", "target content"],
+ targets_list = [
+ ["target1", "content1"],
+ ["target2", "content2"],
+ ["target3", "content3"],
+ ]
+
+ def handle_add_dlg(dialog): #handle add target dialog - need special handling
+ xNewNameTxt=dialog.getChild("name")
+ xNewContentTxt=dialog.getChild("content")
+ xOKBtn = dialog.getChild("close")
+ xTypeList = dialog.getChild("type") #0: Text, 1: Regex, 2: Predefined
+
+ select_pos(xTypeList, 0) #Text
+ self.assertEqual(int(get_state_as_dict(xTypeList)["SelectEntryPos"]), 0)
+
+ type_text(xNewNameTxt, targets_list[self.add_target_counter][0])
+ type_text(xNewContentTxt, targets_list[self.add_target_counter][1])
+
+ self.ui_test.close_dialog_through_button(xOKBtn)
+
+ for i in range(0, len(targets_list)):
+ self.add_target_counter = i
+ self.ui_test.execute_blocking_action(xAddBtn.executeAction, args=('CLICK', ()),
+ dialog_handler=handle_add_dlg) #close add target dialog with OK button
+
+ # Make sure targets are added successfully
+ xTargetsListbox = xDialog.getChild("targets")
+ targets_box_state_dict = get_state_as_dict(xTargetsListbox)
+ self.assertEqual(int(targets_box_state_dict["Children"]), len(targets_list))
+
+ # Make sure targets are added with correct names and contents
+ for i in range(0, len(targets_list)):
+ child = xTargetsListbox.getChild(i)
+ child_text = self.parseTargetContent(child)
+ self.assertEqual(child_text[0], targets_list[i][0]) #name
+ self.assertEqual(child_text[2], targets_list[i][1]) #content
+
+ xcancBtn = xDialog.getChild("cancel")
+ self.ui_test.close_dialog_through_button(xcancBtn)
+
+ # Now let's make sure the dialog remembers last state
+ xDialog = self.launch_and_get_autoredact_dialog()
+ xTargetsListbox = xDialog.getChild("targets")
+ targets_box_state_dict = get_state_as_dict(xTargetsListbox)
+ self.assertEqual(int(targets_box_state_dict["Children"]), len(targets_list))
+
+ # Make sure targets are remembered with correct names and contents
+ for i in range(0, len(targets_list)):
+ child = xTargetsListbox.getChild(i)
+ child_text = self.parseTargetContent(child)
+ self.assertEqual(child_text[0], targets_list[i][0]) #name
+ self.assertEqual(child_text[2], targets_list[i][1]) #content
+
+ xcancBtn = xDialog.getChild("cancel")
+ self.ui_test.close_dialog_through_button(xcancBtn)
+
+ self.ui_test.close_doc()
+
+
+ def test_edit_target(self):
+ self.ui_test.create_doc_in_start_center("writer")
+ xDialog = self.launch_and_get_autoredact_dialog()
+ xAddBtn = xDialog.getChild("add")
+ xEditBtn = xDialog.getChild("edit")
+
+ # Make sure we are starting with an empty targets list
+ self.clearTargetsbox(xDialog)
+
+ # We first need to add a target so that we can edit it
+ def handle_add_dlg(dialog): #handle add target dialog - need special handling
+ xNewNameTxt=dialog.getChild("name")
+ xNewContentTxt=dialog.getChild("content")
+ xOKBtn = dialog.getChild("close")
+ xTypeList = dialog.getChild("type") #0: Text, 1: Regex, 2: Predefined
+
+ select_pos(xTypeList, 0) #Text
+ self.assertEqual(int(get_state_as_dict(xTypeList)["SelectEntryPos"]), 0)
+
+ type_text(xNewNameTxt, "TestTarget")
+ type_text(xNewContentTxt, "TestContent")
+
+ self.ui_test.close_dialog_through_button(xOKBtn)
+
+ self.ui_test.execute_blocking_action(xAddBtn.executeAction, args=('CLICK', ()),
+ dialog_handler=handle_add_dlg) #close add target dialog with OK button
+
+ # Make sure target is added successfully
+ xTargetsListbox = xDialog.getChild("targets")
+ targets_box_state_dict = get_state_as_dict(xTargetsListbox)
+ self.assertEqual(int(targets_box_state_dict["Children"]), 1)
+
+ # Select the added target
+ target_entry = xTargetsListbox.getChild(0)
+ target_entry.executeAction("SELECT", tuple())
+
+ # Now edit the target
+ def handle_edit_dlg(dialog): #handle add target dialog - need special handling
+ xNameTxt=dialog.getChild("name")
+ xContentTxt=dialog.getChild("content")
+ xOKBtn = dialog.getChild("close")
+
+ xNameTxt.executeAction("CLEAR", tuple())
+ xContentTxt.executeAction("CLEAR", tuple())
+
+ type_text(xNameTxt, "TestTargetEdited")
+ type_text(xContentTxt, "TestContentEdited")
+
+ self.ui_test.close_dialog_through_button(xOKBtn)
+
+ self.ui_test.execute_blocking_action(xEditBtn.executeAction, args=('CLICK', ()),
+ dialog_handler=handle_edit_dlg) #close add target dialog with OK button
+
+ # Make sure target is still there
+ xTargetsListbox = xDialog.getChild("targets")
+ targets_box_state_dict = get_state_as_dict(xTargetsListbox)
+ self.assertEqual(int(targets_box_state_dict["Children"]), 1)
+
+ # Make sure target has the new values
+ target_entry = xTargetsListbox.getChild(0)
+ target_text = self.parseTargetContent(target_entry)
+ self.assertEqual(target_text[0], "TestTargetEdited") #name
+ self.assertEqual(target_text[2], "TestContentEdited") #content
+
+ xcancBtn = xDialog.getChild("cancel")
+ self.ui_test.close_dialog_through_button(xcancBtn)
+
+ self.ui_test.close_doc()
+
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/writer_tests7/goToPage.py b/uitest/writer_tests7/goToPage.py
new file mode 100644
index 000000000..d20f042df
--- /dev/null
+++ b/uitest/writer_tests7/goToPage.py
@@ -0,0 +1,48 @@
+#
+# 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.framework import UITestCase
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from uitest.uihelper.common import get_state_as_dict
+import time
+from uitest.path import get_srcdir_url
+
+def get_url_for_data_file(file_name):
+ return get_srcdir_url() + "/uitest/writer_tests/data/" + file_name
+
+class GoToPage_dialog(UITestCase):
+
+ def test_go_to_page(self):
+ writer_doc = self.ui_test.load_file(get_url_for_data_file("3pages.odt"))
+ xWriterDoc = self.xUITest.getTopFocusWindow()
+ xWriterEdit = xWriterDoc.getChild("writer_edit")
+
+ self.ui_test.execute_dialog_through_command(".uno:GotoPage")
+ xDialog = self.xUITest.getTopFocusWindow()
+ xPageText = xDialog.getChild("page")
+ xPageText.executeAction("TYPE", mkPropertyValues({"TEXT":"2"}))
+ xOkBtn = xDialog.getChild("ok")
+ xOkBtn.executeAction("CLICK", tuple())
+
+ self.assertEqual(get_state_as_dict(xWriterEdit)["CurrentPage"], "2")
+
+ self.ui_test.execute_dialog_through_command(".uno:GotoPage")
+ xDialog = self.xUITest.getTopFocusWindow()
+ xPageText = xDialog.getChild("page")
+ xPageText.executeAction("TYPE", mkPropertyValues({"TEXT":"3a"}))
+ xOkBtn = xDialog.getChild("ok")
+ xOkBtn.executeAction("CLICK", tuple())
+
+ self.assertEqual(get_state_as_dict(xWriterEdit)["CurrentPage"], "3")
+
+ # check cancel button
+ self.ui_test.execute_dialog_through_command(".uno:GotoPage")
+ xDialog = self.xUITest.getTopFocusWindow()
+ xCancelBtn = xDialog.getChild("cancel")
+ self.ui_test.close_dialog_through_button(xCancelBtn)
+
+ self.assertEqual(get_state_as_dict(xWriterEdit)["CurrentPage"], "3")
+
+ self.ui_test.close_doc()
diff --git a/uitest/writer_tests8/customizeDialog.py b/uitest/writer_tests8/customizeDialog.py
new file mode 100644
index 000000000..92fddfdff
--- /dev/null
+++ b/uitest/writer_tests8/customizeDialog.py
@@ -0,0 +1,92 @@
+# -*- 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
+
+from uitest.framework import UITestCase
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from uitest.uihelper.common import get_state_as_dict
+from uitest.uihelper.common import select_pos
+
+class ConfigureDialog(UITestCase):
+
+ def test_open_ConfigureDialog_writer(self):
+
+ self.ui_test.create_doc_in_start_center("writer")
+ self.ui_test.execute_dialog_through_command(".uno:ConfigureDialog")
+ xDialog = self.xUITest.getTopFocusWindow()
+
+ xcancBtn = xDialog.getChild("cancel")
+ xcancBtn.executeAction("CLICK", tuple())
+
+ self.ui_test.close_doc()
+
+ def test_search_filter(self):
+ self.ui_test.create_doc_in_start_center("writer")
+ self.ui_test.execute_dialog_through_command(".uno:ConfigureDialog")
+ xDialog = self.xUITest.getTopFocusWindow()
+
+ xfunc = xDialog.getChild("functions")
+ xSearch = xDialog.getChild("searchEntry")
+
+ initialEntryCount = get_state_as_dict(xfunc)["Children"]
+ self.assertTrue(initialEntryCount != 0)
+
+ xSearch.executeAction("SET", mkPropertyValues({"TEXT":"format"}))
+
+ # Wait for the search/filter op to be completed
+ timeout = time.time() + 1
+ while time.time() < timeout:
+ filteredEntryCount = get_state_as_dict(xfunc)["Children"]
+ if filteredEntryCount != initialEntryCount:
+ break
+ time.sleep(0.1)
+
+ self.assertTrue(filteredEntryCount < initialEntryCount)
+
+ xSearch.executeAction("CLEAR", tuple())
+
+ # Wait for the search/filter op to be completed
+ timeout = time.time() + 1
+ while time.time() < timeout:
+ finalEntryCount = get_state_as_dict(xfunc)["Children"]
+ if finalEntryCount != filteredEntryCount:
+ break
+ time.sleep(0.1)
+
+ self.assertEqual(initialEntryCount, finalEntryCount)
+
+
+ xcancBtn = xDialog.getChild("cancel") #button Cancel
+ xcancBtn.executeAction("CLICK", tuple()) #click the button
+
+ self.ui_test.close_doc()
+
+ def test_category_listbox(self):
+ self.ui_test.create_doc_in_start_center("writer")
+ self.ui_test.execute_dialog_through_command(".uno:ConfigureDialog")
+ xDialog = self.xUITest.getTopFocusWindow()
+
+ xFunc = xDialog.getChild("functions")
+ xCategory = xDialog.getChild("commandcategorylist")
+
+ initialEntryCount = get_state_as_dict(xFunc)["Children"]
+ self.assertTrue(initialEntryCount != 0)
+
+ select_pos(xCategory, "1")
+ filteredEntryCount = get_state_as_dict(xFunc)["Children"]
+ self.assertTrue(filteredEntryCount < initialEntryCount)
+
+ select_pos(xCategory, "0")
+ finalEntryCount = get_state_as_dict(xFunc)["Children"]
+ self.assertEqual(initialEntryCount, finalEntryCount)
+
+ xcancBtn = xDialog.getChild("cancel") #button Cancel
+ xcancBtn.executeAction("CLICK", tuple()) #click the button
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/writer_tests8/tdf79236.py b/uitest/writer_tests8/tdf79236.py
new file mode 100644
index 000000000..8585e48d8
--- /dev/null
+++ b/uitest/writer_tests8/tdf79236.py
@@ -0,0 +1,124 @@
+#
+# 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.framework import UITestCase
+import time
+from uitest.uihelper.common import get_state_as_dict, type_text
+
+class tdf79236(UITestCase):
+
+ def test_paragraph(self):
+
+ self.ui_test.create_doc_in_start_center("writer")
+
+ xWriterDoc = self.xUITest.getTopFocusWindow()
+ xWriterEdit = xWriterDoc.getChild("writer_edit")
+
+ type_text(xWriterEdit, "Test for tdf79236")
+
+ document = self.ui_test.get_component()
+
+ selection = self.xUITest.executeCommand(".uno:SelectAll")
+
+ self.assertEqual(document.CurrentSelection.getByIndex(0).ParaLeftMargin, 0)
+ self.assertEqual(document.CurrentSelection.getByIndex(0).ParaRightMargin, 0)
+ self.assertEqual(document.CurrentSelection.getByIndex(0).ParaTopMargin, 0)
+ self.assertEqual(document.CurrentSelection.getByIndex(0).ParaBottomMargin, 0)
+ self.assertEqual(document.CurrentSelection.getByIndex(0).ParaFirstLineIndent, 0)
+
+ self.assertEqual(document.CurrentSelection.getByIndex(0).String, "Test for tdf79236")
+
+ self.ui_test.execute_dialog_through_command(".uno:ParagraphDialog")
+
+ xParagraphDlg = self.xUITest.getTopFocusWindow()
+
+
+ xLeftSpnBtn = xParagraphDlg.getChild("spinED_LEFTINDENT")
+ for _ in range(0,20):
+ xLeftSpnBtn.executeAction("UP", tuple())
+
+ xRightSpnBtn = xParagraphDlg.getChild("spinED_RIGHTINDENT")
+ for _ in range(0,20):
+ xRightSpnBtn.executeAction("UP", tuple())
+
+
+ xLineSpnBtn = xParagraphDlg.getChild("spinED_FLINEINDENT")
+ for _ in range(0,20):
+ xLineSpnBtn.executeAction("UP", tuple())
+
+
+ xBottomSpnBtn = xParagraphDlg.getChild("spinED_BOTTOMDIST")
+ for _ in range(0,20):
+ xBottomSpnBtn.executeAction("UP", tuple())
+
+ xTopSpnBtn = xParagraphDlg.getChild("spinED_TOPDIST")
+ for _ in range(0,20):
+ xTopSpnBtn.executeAction("UP", tuple())
+
+ xOkBtn = xParagraphDlg.getChild("ok")
+ xOkBtn.executeAction("CLICK", tuple())
+
+ self.assertEqual(document.CurrentSelection.getByIndex(0).ParaLeftMargin, 3704)
+ self.assertEqual(document.CurrentSelection.getByIndex(0).ParaRightMargin, 3704)
+ self.assertEqual(document.CurrentSelection.getByIndex(0).ParaTopMargin, 5503)
+ self.assertEqual(document.CurrentSelection.getByIndex(0).ParaBottomMargin, 5503)
+ self.assertEqual(document.CurrentSelection.getByIndex(0).ParaFirstLineIndent, 3704)
+
+ self.ui_test.execute_dialog_through_command(".uno:ParagraphDialog")
+
+ xParagraphDlg = self.xUITest.getTopFocusWindow()
+
+ xLeftSpnBtn = xParagraphDlg.getChild("spinED_LEFTINDENT")
+ for _ in range(0,20):
+ xLeftSpnBtn.executeAction("DOWN", tuple())
+
+ xRightSpnBtn = xParagraphDlg.getChild("spinED_RIGHTINDENT")
+ for _ in range(0,20):
+ xRightSpnBtn.executeAction("DOWN", tuple())
+
+
+ xLineSpnBtn = xParagraphDlg.getChild("spinED_FLINEINDENT")
+ for _ in range(0,20):
+ xLineSpnBtn.executeAction("DOWN", tuple())
+
+ xBottomSpnBtn = xParagraphDlg.getChild("spinED_BOTTOMDIST")
+ for _ in range(0,20):
+ xBottomSpnBtn.executeAction("DOWN", tuple())
+
+ xTopSpnBtn = xParagraphDlg.getChild("spinED_TOPDIST")
+ for _ in range(0,20):
+ xTopSpnBtn.executeAction("DOWN", tuple())
+
+ xOkBtn = xParagraphDlg.getChild("ok")
+ self.ui_test.close_dialog_through_button(xOkBtn)
+
+ self.assertEqual(document.CurrentSelection.getByIndex(0).ParaLeftMargin, 0)
+ self.assertEqual(document.CurrentSelection.getByIndex(0).ParaRightMargin, 0)
+ self.assertEqual(document.CurrentSelection.getByIndex(0).ParaTopMargin, 0)
+ self.assertEqual(document.CurrentSelection.getByIndex(0).ParaBottomMargin, 0)
+ self.assertEqual(document.CurrentSelection.getByIndex(0).ParaFirstLineIndent, 0)
+
+ self.xUITest.executeCommand(".uno:Undo")
+
+ self.assertEqual(document.CurrentSelection.getByIndex(0).ParaLeftMargin, 3704)
+ self.assertEqual(document.CurrentSelection.getByIndex(0).ParaRightMargin, 3704)
+ self.assertEqual(document.CurrentSelection.getByIndex(0).ParaTopMargin, 5503)
+ self.assertEqual(document.CurrentSelection.getByIndex(0).ParaBottomMargin, 5503)
+ self.assertEqual(document.CurrentSelection.getByIndex(0).ParaFirstLineIndent, 3704)
+
+ self.xUITest.executeCommand(".uno:Undo")
+
+ self.assertEqual(document.CurrentSelection.getByIndex(0).ParaLeftMargin, 0)
+ self.assertEqual(document.CurrentSelection.getByIndex(0).ParaRightMargin, 0)
+ self.assertEqual(document.CurrentSelection.getByIndex(0).ParaTopMargin, 0)
+ self.assertEqual(document.CurrentSelection.getByIndex(0).ParaBottomMargin, 0)
+ self.assertEqual(document.CurrentSelection.getByIndex(0).ParaFirstLineIndent, 0)
+
+ self.assertEqual(document.CurrentSelection.getByIndex(0).String, "Test for tdf79236")
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab: