dbaccess/qa/uitest/edit_field/tdf75509.py | 21 ++-------- dbaccess/qa/uitest/query/insert_relation.py | 23 ++--------- dbaccess/qa/uitest/query/tdf99619_create_join_undo_redo.py | 27 +++---------- include/vcl/uitest/uitest.hxx | 5 ++ offapi/com/sun/star/ui/test/XUITest.idl | 3 + uitest/libreoffice/uno/eventlistener.py | 2 vcl/source/uitest/uitest.cxx | 11 +++++ vcl/source/uitest/uno/uitest_uno.cxx | 12 +++++ 8 files changed, 53 insertions(+), 51 deletions(-)
New commits: commit ce5f2d2dd480a4345781cae435c95420de560bc1 Author: Neil Roberts <[email protected]> AuthorDate: Fri Nov 21 21:47:52 2025 +0100 Commit: Noel Grandin <[email protected]> CommitDate: Sat Nov 22 19:37:29 2025 +0100 EventListener: Store the supplement from the event Some of the events have really useful supplements. This will be used later to extract the frame from the OnSubComponentOpened event. Change-Id: Id62e8bf7d4658aa4df8920992a622f51e007ff41 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194349 Tested-by: Jenkins Reviewed-by: Noel Grandin <[email protected]> diff --git a/uitest/libreoffice/uno/eventlistener.py b/uitest/libreoffice/uno/eventlistener.py index f7092836c935..dd1fcdaeae06 100644 --- a/uitest/libreoffice/uno/eventlistener.py +++ b/uitest/libreoffice/uno/eventlistener.py @@ -22,6 +22,7 @@ class EventListener(XDocumentEventListener,unohelper.Base): self.xContext = xContext self.executed = False self.eventExecuted = [] + self.supplements = [] self.printEvents = kwargs.get('printNames', False) if isinstance(eventNames, str): self.eventNames = [eventNames] @@ -41,6 +42,7 @@ class EventListener(XDocumentEventListener,unohelper.Base): if event.EventName in self.eventNames: self.executed = True self.eventExecuted.append(event.EventName) + self.supplements.append(event.Supplement) def hasExecuted(self, eventName): return eventName in self.eventExecuted commit 46968eff8eb1a1a7ad52c268fe8ba579ae96e7f3 Author: Neil Roberts <[email protected]> AuthorDate: Fri Nov 21 21:36:00 2025 +0100 Commit: Noel Grandin <[email protected]> CommitDate: Sat Nov 22 19:37:18 2025 +0100 UITest: Add method to execute a command for particular XDispatchProvider The existing methods of XUITest to execute a command always use the active frame to dispatch the command. All of the dbaccess UI tests end up creating subcomponents (such as the table edit view) and need to send commands to that. The frames for those are not the “active” frame but only the “current” frame. All of the tests have ended up making a copy of a helper function to dispatch to a particular provider. To avoid that duplication this patch moves it to a common helper directly in XUITest. This will also make it possible to use the method from test.py in a later patch. Note that the order of the arguments has been swapped around to match that of comphelper::dispatchCommand. Change-Id: I274fe12e4dfec0bf78359d0e2b70a3cf4db5528c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194348 Reviewed-by: Noel Grandin <[email protected]> Tested-by: Jenkins diff --git a/dbaccess/qa/uitest/edit_field/tdf75509.py b/dbaccess/qa/uitest/edit_field/tdf75509.py index 0efbd11d117e..4fb3c125de7a 100644 --- a/dbaccess/qa/uitest/edit_field/tdf75509.py +++ b/dbaccess/qa/uitest/edit_field/tdf75509.py @@ -11,21 +11,9 @@ from uitest.uihelper.common import get_url_for_data_file, get_state_as_dict from libreoffice.uno.propertyvalue import mkPropertyValues -from com.sun.star.util import URL - #Bug 75509 - Incorrect display of digits in default Numeric formatting # of a field when language isn't English class tdf75509(UITestCase): - def execute_for_frame(self, xFrame, command): - url = URL() - url.Complete = command - xUrlTransformer = self.xContext.ServiceManager.createInstanceWithContext( - "com.sun.star.util.URLTransformer", self.xContext) - _, url = xUrlTransformer.parseStrict(url) - - xDispatch = xFrame.queryDispatch(url, "", 0) - xDispatch.dispatch(url, []) - def test_tdf75509(self): # The sample file is an HSQLDB database with a single table. Aside from the primary key, the # table has two numeric type fields each with 2 decimal places. One of them is called @@ -74,7 +62,9 @@ class tdf75509(UITestCase): self.assertEqual(get_state_as_dict(xFormatText)["Text"], "2.72") # Save the table (ie, just the table, not the actual database file to disk) - self.execute_for_frame(self.ui_test.get_desktop().getCurrentFrame(), ".uno:Save") + self.xUITest.executeCommandForProvider( + ".uno:Save", + self.ui_test.get_desktop().getCurrentFrame()) self.xUITest.executeCommand(".uno:DBTableOpen") @@ -99,8 +89,9 @@ class tdf75509(UITestCase): # Modify the field so that the we can save the record xEdit.executeAction("SET", mkPropertyValues({"TEXT": "2.71"})) - self.execute_for_frame(self.ui_test.get_desktop().getCurrentFrame(), - ".uno:RecSave") + self.xUITest.executeCommandForProvider( + ".uno:RecSave", + self.ui_test.get_desktop().getCurrentFrame()) # Check that the default values actually entered the database xDbController = self.ui_test.get_desktop().getActiveFrame().getController() diff --git a/dbaccess/qa/uitest/query/insert_relation.py b/dbaccess/qa/uitest/query/insert_relation.py index 4f0c0e73567c..d6d291bea887 100644 --- a/dbaccess/qa/uitest/query/insert_relation.py +++ b/dbaccess/qa/uitest/query/insert_relation.py @@ -9,23 +9,12 @@ from uitest.framework import UITestCase from uitest.uihelper.common import get_state_as_dict, select_by_text from uitest.test import DEFAULT_SLEEP -from com.sun.star.util import URL from libreoffice.uno.propertyvalue import mkPropertyValues from libreoffice.uno.eventlistener import EventListener import time class InsertRelation(UITestCase): - def execute_for_provider(self, xProvider, command): - url = URL() - url.Complete = command - xUrlTransformer = self.xContext.ServiceManager.createInstanceWithContext( - "com.sun.star.util.URLTransformer", self.xContext) - _, url = xUrlTransformer.parseStrict(url) - - xDispatch = xProvider.queryDispatch(url, "", 0) - xDispatch.dispatch(url, []) - # Previously the Insert Relation dialog wouldn’t let you select a table in one box if the other # box already has it selected. This test checks the new behaviour where you can select any of # the three tables and the other table changes itself so that it’s not the same. @@ -49,8 +38,8 @@ class InsertRelation(UITestCase): # Close the window. This will open a dialog asking if we want to save with self.ui_test.execute_blocking_action( - self.execute_for_provider, - args=(xTableFrame, ".uno:CloseWin"), + self.xUITest.executeCommandForProvider, + args=(".uno:CloseWin", xTableFrame), close_button=None) as xSaveDialog: # Choose yes. This will open another dialog asking us to name the table with self.ui_test.execute_blocking_action( @@ -83,8 +72,8 @@ class InsertRelation(UITestCase): try: with self.ui_test.execute_blocking_action( - self.execute_for_provider, - args=(xQueryController, ".uno:DBAddRelation"), + self.xUITest.executeCommandForProvider, + args=(".uno:DBAddRelation", xQueryController), close_button="cancel") as xDialog: xTable1 = xDialog.getChild("table1") xTable2 = xDialog.getChild("table2") @@ -106,8 +95,8 @@ class InsertRelation(UITestCase): finally: # Close the query window and answer no when it asks if we want to save with self.ui_test.execute_blocking_action( - self.execute_for_provider, - args=(xQueryFrame, ".uno:CloseWin"), + self.xUITest.executeCommandForProvider, + args=(".uno:CloseWin", xQueryFrame), close_button="no"): pass diff --git a/dbaccess/qa/uitest/query/tdf99619_create_join_undo_redo.py b/dbaccess/qa/uitest/query/tdf99619_create_join_undo_redo.py index 1324f8771055..7484e4371a2f 100644 --- a/dbaccess/qa/uitest/query/tdf99619_create_join_undo_redo.py +++ b/dbaccess/qa/uitest/query/tdf99619_create_join_undo_redo.py @@ -10,23 +10,11 @@ from uitest.framework import UITestCase from uitest.uihelper.common import get_url_for_data_file, get_state_as_dict, select_by_text from uitest.test import DEFAULT_SLEEP -from com.sun.star.util import URL - import sys import time #Bug 99619 - query design segfault on redoing an undone table join creation class tdf99619(UITestCase): - def execute_for_provider(self, xProvider, command): - url = URL() - url.Complete = command - xUrlTransformer = self.xContext.ServiceManager.createInstanceWithContext( - "com.sun.star.util.URLTransformer", self.xContext) - _, url = xUrlTransformer.parseStrict(url) - - xDispatch = xProvider.queryDispatch(url, "", 0) - xDispatch.dispatch(url, []) - def test_tdf99619(self): # The sample file is an HSQLDB database with the two tables “person” and “object”. They both # have a text field and a primary key. The object table additionally has an person_id field @@ -58,8 +46,8 @@ class tdf99619(UITestCase): # Add a relation via the dialog with self.ui_test.execute_blocking_action( - self.execute_for_provider, - args=(xQueryController, ".uno:DBAddRelation")) as xDialog: + self.xUITest.executeCommandForProvider, + args=(".uno:DBAddRelation", xQueryController)) as xDialog: # Choose the two tables select_by_text(xDialog.getChild("table1"), "object") @@ -73,16 +61,17 @@ class tdf99619(UITestCase): xDialog.getChild("natural").executeAction("CLICK", tuple()) # Undo the join - self.execute_for_provider(xQueryFrame, ".uno:Undo") + self.xUITest.executeCommandForProvider(".uno:Undo", xQueryFrame) # Redo the join. This is where it crashes without any fixes to the bug - self.execute_for_provider(xQueryFrame, ".uno:Redo") + self.xUITest.executeCommandForProvider(".uno:Redo", xQueryFrame) # Save the query. This only saves the query in memory and doesn’t change the database # file on disk - self.execute_for_provider(xQueryFrame, ".uno:Save") + self.xUITest.executeCommandForProvider(".uno:Save", xQueryFrame) # Switch to SQL mode - self.execute_for_provider(xQueryController, ".uno:DBChangeDesignMode") + self.xUITest.executeCommandForProvider(".uno:DBChangeDesignMode", + xQueryController) # Get the SQL source for the query xSql = self.xUITest.getTopFocusWindow().getChild("sql") @@ -93,6 +82,6 @@ class tdf99619(UITestCase): print(f"Join missing from query: {query}", file=sys.stderr) self.assertTrue("NATURAL INNER JOIN" in query) - self.execute_for_provider(xQueryFrame, ".uno:CloseWin") + self.xUITest.executeCommandForProvider(".uno:CloseWin", xQueryFrame) # vim: set shiftwidth=4 softtabstop=4 expandtab: diff --git a/include/vcl/uitest/uitest.hxx b/include/vcl/uitest/uitest.hxx index 488cf4fc4b6f..5061320d68af 100644 --- a/include/vcl/uitest/uitest.hxx +++ b/include/vcl/uitest/uitest.hxx @@ -11,6 +11,7 @@ #define INCLUDED_VCL_UITEST_UITEST_HXX #include <rtl/ustring.hxx> +#include <com/sun/star/frame/XDispatchProvider.hpp> #include <memory> @@ -26,6 +27,10 @@ namespace UITest bool executeCommandWithParameters(const OUString& rCommand, const css::uno::Sequence< css::beans::PropertyValue >& rArgs); + bool executeCommandForProvider( + const OUString& rCommand, + const css::uno::Reference< css::frame::XDispatchProvider >& xProvider); + bool executeDialog(const OUString& rCommand); std::unique_ptr<UIObject> getFocusTopWindow(); diff --git a/offapi/com/sun/star/ui/test/XUITest.idl b/offapi/com/sun/star/ui/test/XUITest.idl index c551e8ebac89..3738983a610c 100644 --- a/offapi/com/sun/star/ui/test/XUITest.idl +++ b/offapi/com/sun/star/ui/test/XUITest.idl @@ -16,6 +16,9 @@ interface XUITest boolean executeCommandWithParameters([in] string command, [in] com::sun::star::beans::PropertyValues propValues); + boolean executeCommandForProvider([in] string command, + [in] ::com::sun::star::frame::XDispatchProvider xProvider); + boolean executeDialog([in] string command); XUIObject getTopFocusWindow(); diff --git a/vcl/source/uitest/uitest.cxx b/vcl/source/uitest/uitest.cxx index 67c8d93dd7db..5c6b03bbaaa9 100644 --- a/vcl/source/uitest/uitest.cxx +++ b/vcl/source/uitest/uitest.cxx @@ -44,6 +44,17 @@ bool UITest::executeCommandWithParameters(const OUString& rCommand, return comphelper::dispatchCommand(rCommand,lNewArgs); } +bool UITest::executeCommandForProvider( + const OUString& rCommand, + const css::uno::Reference< css::frame::XDispatchProvider >& xProvider) +{ + return comphelper::dispatchCommand( + rCommand, + xProvider, + {{u"SynchronMode"_ustr, -1, css::uno::Any(true), + css::beans::PropertyState_DIRECT_VALUE}}); +} + bool UITest::executeDialog(const OUString& rCommand) { return comphelper::dispatchCommand( diff --git a/vcl/source/uitest/uno/uitest_uno.cxx b/vcl/source/uitest/uno/uitest_uno.cxx index 1a3329a7ba1c..1bd960940c94 100644 --- a/vcl/source/uitest/uno/uitest_uno.cxx +++ b/vcl/source/uitest/uno/uitest_uno.cxx @@ -39,6 +39,10 @@ public: sal_Bool SAL_CALL executeCommandWithParameters(const OUString& rCommand, const css::uno::Sequence< css::beans::PropertyValue >& rArgs) override; + sal_Bool SAL_CALL executeCommandForProvider( + const OUString& rCommand, + const css::uno::Reference<css::frame::XDispatchProvider>& xProvider) override; + sal_Bool SAL_CALL executeDialog(const OUString& rCommand) override; css::uno::Reference<css::ui::test::XUIObject> SAL_CALL getTopFocusWindow() override; @@ -76,6 +80,14 @@ sal_Bool SAL_CALL UITestUnoObj::executeCommandWithParameters(const OUString& rCo return UITest::executeCommandWithParameters(rCommand,rArgs); } +sal_Bool SAL_CALL UITestUnoObj::executeCommandForProvider( + const OUString& rCommand, + const css::uno::Reference<css::frame::XDispatchProvider>& xProvider) +{ + SolarMutexGuard aGuard; + return UITest::executeCommandForProvider(rCommand, xProvider); +} + sal_Bool SAL_CALL UITestUnoObj::executeDialog(const OUString& rCommand) { SolarMutexGuard aGuard;
