chart2/source/controller/inc/uiobject.hxx    |    2 ++
 chart2/source/controller/uitest/uiobject.cxx |    8 ++++++++
 include/vcl/uitest/uiobject.hxx              |    9 +++++++++
 offapi/com/sun/star/ui/test/XUIObject.idl    |    5 +++++
 sd/source/ui/uitest/uiobject.cxx             |   10 ++++++++++
 uitest/uitest/test.py                        |   17 +++++++++--------
 vcl/source/treelist/uiobject.cxx             |    9 +++++++++
 vcl/source/uitest/uiobject.cxx               |    8 ++++++++
 vcl/source/uitest/uno/uiobject_uno.cxx       |    5 +++++
 vcl/source/uitest/uno/uiobject_uno.hxx       |    2 ++
 10 files changed, 67 insertions(+), 8 deletions(-)

New commits:
commit 5ec7c4eecf955090cc3bdd7a283aa5a291d12385
Author:     Noel Grandin <[email protected]>
AuthorDate: Wed Mar 27 21:56:50 2024 +0200
Commit:     Noel Grandin <[email protected]>
CommitDate: Thu Mar 28 17:17:32 2024 +0100

    fix comparison of UIObject's inside UITests
    
    using == to compare them doesnt work, because we return
    a new one with every call to getTopFocusWindow and similar.
    So add a equals() method to the UNO interface to do the comparison.
    
    Change-Id: Ie909fe9b4e84fe07f4ca87bbebf65b56d3da8f78
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165436
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <[email protected]>

diff --git a/chart2/source/controller/inc/uiobject.hxx 
b/chart2/source/controller/inc/uiobject.hxx
index 917ba322bf5e..6de63f5d3fdf 100644
--- a/chart2/source/controller/inc/uiobject.hxx
+++ b/chart2/source/controller/inc/uiobject.hxx
@@ -32,6 +32,8 @@ public:
 
     virtual OUString get_type() const override;
 
+    virtual bool equals(const UIObject& rOther) const override;
+
 private:
 
     OUString maCID;
diff --git a/chart2/source/controller/uitest/uiobject.cxx 
b/chart2/source/controller/uitest/uiobject.cxx
index 783a91982f84..c75f15c3885c 100644
--- a/chart2/source/controller/uitest/uiobject.cxx
+++ b/chart2/source/controller/uitest/uiobject.cxx
@@ -95,6 +95,14 @@ OUString ChartUIObject::get_type() const
     return "ChartUIObject for type: ";
 }
 
+bool ChartUIObject::equals(const UIObject& rOther) const
+{
+    const ChartUIObject* pOther = dynamic_cast<const ChartUIObject*>(&rOther);
+    if (!pOther)
+        return false;
+    return mxChartWindow.get() == pOther->mxChartWindow.get();
+}
+
 ChartWindowUIObject::ChartWindowUIObject(const VclPtr<chart::ChartWindow>& 
xChartWindow):
     WindowUIObject(xChartWindow),
     mxChartWindow(xChartWindow)
diff --git a/include/vcl/uitest/uiobject.hxx b/include/vcl/uitest/uiobject.hxx
index d27140b2c21b..8f1624dc7f7a 100644
--- a/include/vcl/uitest/uiobject.hxx
+++ b/include/vcl/uitest/uiobject.hxx
@@ -113,6 +113,11 @@ public:
      * Gets the corresponding Action string for the event.
      */
     virtual OUString get_action(VclEventId nEvent) const;
+
+    /**
+     * Does this represent the same underlying UI widget as rOther?
+     */
+    virtual bool equals(const UIObject& rOther) const = 0;
 };
 
 class UITEST_DLLPUBLIC WindowUIObject : public UIObject
@@ -144,6 +149,8 @@ public:
 
     static std::unique_ptr<UIObject> create(vcl::Window* pWindow);
 
+    virtual bool equals(const UIObject& rOther) const override;
+
 protected:
 
     virtual OUString get_name() const;
@@ -505,6 +512,8 @@ public:
 
     virtual OUString get_type() const override;
 
+    virtual bool equals(const UIObject& rOther) const override;
+
 private:
 
     SvTreeListEntry* getEntry() const;
diff --git a/offapi/com/sun/star/ui/test/XUIObject.idl 
b/offapi/com/sun/star/ui/test/XUIObject.idl
index 8f5febffb17e..4f37b11568e1 100644
--- a/offapi/com/sun/star/ui/test/XUIObject.idl
+++ b/offapi/com/sun/star/ui/test/XUIObject.idl
@@ -22,6 +22,11 @@ interface XUIObject
     sequence<string> getChildren();
 
     string getHierarchy();
+
+    /** Return true if the other XUIObject represents the same underlying vcl 
widget.
+        This is necessary because we return a new XUIObject every time we call 
getChild.
+    */
+    boolean equals([in] XUIObject other);
 };
 
 }; }; }; }; };
diff --git a/sd/source/ui/uitest/uiobject.cxx b/sd/source/ui/uitest/uiobject.cxx
index 00884fc90d6f..2c96b9495b14 100644
--- a/sd/source/ui/uitest/uiobject.cxx
+++ b/sd/source/ui/uitest/uiobject.cxx
@@ -29,6 +29,8 @@ public:
 
     SdrObject* get_object() override;
 
+    virtual bool equals(const UIObject& rOther) const override;
+
 private:
     VclPtr<sd::Window> mxWindow;
 
@@ -74,6 +76,14 @@ ImpressSdrObject::ImpressSdrObject(const VclPtr<sd::Window>& 
xImpressWin, OUStri
 
 SdrObject* ImpressSdrObject::get_object() { return getObject(mxWindow, 
maName); }
 
+bool ImpressSdrObject::equals(const UIObject& rOther) const
+{
+    const ImpressSdrObject* pOther = dynamic_cast<const 
ImpressSdrObject*>(&rOther);
+    if (!pOther)
+        return false;
+    return mxWindow.get() == pOther->mxWindow.get();
+}
+
 ImpressWindowUIObject::ImpressWindowUIObject(const VclPtr<sd::Window>& xWindow)
     : WindowUIObject(xWindow)
     , mxWindow(xWindow)
diff --git a/uitest/uitest/test.py b/uitest/uitest/test.py
index fbe5d2a87c99..e6491af3f67f 100644
--- a/uitest/uitest/test.py
+++ b/uitest/uitest/test.py
@@ -128,18 +128,18 @@ class UITest(object):
         while not event.executed:
             time.sleep(DEFAULT_SLEEP)
         dialog = self._xUITest.getTopFocusWindow()
-        if parent == dialog:
+        if parent.equals(dialog):
             raise Exception("executing the action did not open the dialog")
         try:
             yield dialog
         except:
             if not close_button:
                 if 'cancel' in dialog.getChildren():
-                    self.close_dialog_through_button(dialog.getChild("cancel"))
+                    
self.close_dialog_through_button(dialog.getChild("cancel"), dialog)
             raise
         finally:
             if close_button:
-                self.close_dialog_through_button(dialog.getChild(close_button))
+                
self.close_dialog_through_button(dialog.getChild(close_button), dialog)
 
     # Calls UITest.close_dialog_through_button at exit
     @contextmanager
@@ -189,8 +189,9 @@ class UITest(object):
                     return
                 time.sleep(DEFAULT_SLEEP)
 
-    def close_dialog_through_button(self, button):
-        dialog = self._xUITest.getTopFocusWindow()
+    def close_dialog_through_button(self, button, dialog=None):
+        if dialog is None:
+            dialog = self._xUITest.getTopFocusWindow()
         with EventListener(self._xContext, "DialogClosed" ) as event:
             button.executeAction("CLICK", tuple())
             while True:
@@ -199,7 +200,7 @@ class UITest(object):
                     break
                 time.sleep(DEFAULT_SLEEP)
         parent = self._xUITest.getTopFocusWindow()
-        if parent == dialog:
+        if parent.equals(dialog):
             raise Exception("executing the action did not close the dialog")
 
     def close_doc(self):
@@ -252,11 +253,11 @@ class UITest(object):
                     except:
                         if not close_button:
                             if 'cancel' in xDialog.getChildren():
-                                
self.close_dialog_through_button(xDialog.getChild("cancel"))
+                                
self.close_dialog_through_button(xDialog.getChild("cancel"), xDialog)
                         raise
                     finally:
                         if close_button:
-                            
self.close_dialog_through_button(xDialog.getChild(close_button))
+                            
self.close_dialog_through_button(xDialog.getChild(close_button), xDialog)
                         thread.join()
                     return
                 time.sleep(DEFAULT_SLEEP)
diff --git a/vcl/source/treelist/uiobject.cxx b/vcl/source/treelist/uiobject.cxx
index ca45d76fa9e6..e9999e2ae119 100644
--- a/vcl/source/treelist/uiobject.cxx
+++ b/vcl/source/treelist/uiobject.cxx
@@ -217,4 +217,13 @@ OUString TreeListEntryUIObject::get_type() const
     return "TreeListEntry";
 }
 
+bool TreeListEntryUIObject::equals(const UIObject& rOther) const
+{
+    const TreeListEntryUIObject* pOther = dynamic_cast<const 
TreeListEntryUIObject*>(&rOther);
+    if (!pOther)
+        return false;
+    return mxTreeList.get() == pOther->mxTreeList.get()
+            && maTreePath == pOther->maTreePath;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/uitest/uiobject.cxx b/vcl/source/uitest/uiobject.cxx
index 2671a9145436..d209edd6a5c4 100644
--- a/vcl/source/uitest/uiobject.cxx
+++ b/vcl/source/uitest/uiobject.cxx
@@ -396,6 +396,14 @@ OUString WindowUIObject::get_type() const
     return get_name();
 }
 
+bool WindowUIObject::equals(const UIObject& rOther) const
+{
+    const WindowUIObject* pOther = dynamic_cast<const 
WindowUIObject*>(&rOther);
+    if (!pOther)
+        return false;
+    return mxWindow.get() == pOther->mxWindow.get();
+}
+
 namespace {
 
 vcl::Window* findChild(vcl::Window* pParent, const OUString& rID, bool 
bRequireVisible = false, OUStringBuffer* debug = nullptr)
diff --git a/vcl/source/uitest/uno/uiobject_uno.cxx 
b/vcl/source/uitest/uno/uiobject_uno.cxx
index 1a59520f1943..a17c744c0331 100644
--- a/vcl/source/uitest/uno/uiobject_uno.cxx
+++ b/vcl/source/uitest/uno/uiobject_uno.cxx
@@ -206,4 +206,9 @@ OUString SAL_CALL UIObjectUnoObj::getHierarchy()
     return mpObj->dumpHierarchy();
 }
 
+sal_Bool SAL_CALL UIObjectUnoObj::equals(const 
css::uno::Reference<css::ui::test::XUIObject>& rOther)
+{
+    return mpObj->equals(*static_cast<UIObjectUnoObj&>(*rOther).mpObj);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/uitest/uno/uiobject_uno.hxx 
b/vcl/source/uitest/uno/uiobject_uno.hxx
index e86ce1bfd289..85158fe76b8d 100644
--- a/vcl/source/uitest/uno/uiobject_uno.hxx
+++ b/vcl/source/uitest/uno/uiobject_uno.hxx
@@ -48,6 +48,8 @@ public:
     css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
 
     OUString SAL_CALL getHierarchy() override;
+
+    sal_Bool SAL_CALL equals(const 
css::uno::Reference<css::ui::test::XUIObject>& rOther) override;
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Reply via email to