diff --git a/tests/controls/bitmaptogglebuttontest.cpp b/tests/controls/bitmaptogglebuttontest.cpp index 2f91dc29f3..e3843f8fa4 100644 --- a/tests/controls/bitmaptogglebuttontest.cpp +++ b/tests/controls/bitmaptogglebuttontest.cpp @@ -74,8 +74,10 @@ void BitmapToggleButtonTestCase::Click() wxUIActionSimulator sim; + const wxPoint pos = m_button->GetScreenPosition(); + //We move in slightly to account for window decorations - sim.MouseMove(m_button->GetScreenPosition() + wxPoint(10, 10)); + sim.MouseMove(pos + wxPoint(10, 10)); wxYield(); sim.MouseClick(); @@ -86,9 +88,10 @@ void BitmapToggleButtonTestCase::Click() clicked.Clear(); -#ifdef __WXMSW__ - wxMilliSleep(1000); -#endif + // Change the mouse position to prevent the second click from being + // recognized as double click. + sim.MouseMove(pos + wxPoint(20, 20)); + wxYield(); sim.MouseClick(); wxYield(); diff --git a/tests/controls/buttontest.cpp b/tests/controls/buttontest.cpp index ce958bc5e9..2a5570b354 100644 --- a/tests/controls/buttontest.cpp +++ b/tests/controls/buttontest.cpp @@ -23,6 +23,7 @@ // Get operator<<(wxSize) so that wxSize values are shown correctly in case of // a failure of a CHECK() involving them. #include "asserthelper.h" +#include "waitfor.h" class ButtonTestCase { @@ -64,7 +65,10 @@ TEST_CASE_METHOD(ButtonTestCase, "Button::Click", "[button]") wxYield(); sim.MouseClick(); - wxYield(); + + // At least under wxMSW calling wxYield() just once doesn't always work, so + // try for a while. + WaitFor("button to be clicked", [&]() { return clicked.GetCount() != 0; }); CHECK( clicked.GetCount() == 1 ); } diff --git a/tests/controls/dataviewctrltest.cpp b/tests/controls/dataviewctrltest.cpp index b460195a43..bfb849b14d 100644 --- a/tests/controls/dataviewctrltest.cpp +++ b/tests/controls/dataviewctrltest.cpp @@ -20,7 +20,7 @@ #include "wx/uiaction.h" #ifdef __WXGTK__ - #include "wx/stopwatch.h" + #include "waitfor.h" #endif // __WXGTK__ #include "testableframe.h" @@ -366,31 +366,23 @@ protected: #ifdef __WXGTK__ // Unfortunately it's not enough to call wxYield() once, so wait up to // 0.5 sec. - wxStopWatch sw; - while ( true ) - { - wxYield(); - + WaitFor("wxDataViewCtrl upder", [this, item, existence]() { const bool isItemRectEmpty = m_dvc->GetItemRect(item).IsEmpty(); switch ( existence ) { case wxITEM_APPEAR: if ( !isItemRectEmpty ) - return; + return true; break; case wxITEM_DISAPPEAR: if ( isItemRectEmpty ) - return; + return true; break; } - if ( sw.Time() > 500 ) - { - WARN("Timed out waiting for wxDataViewCtrl"); - break; - } - } + return false; + }); #else // !__WXGTK__ wxUnusedVar(item); wxUnusedVar(existence); @@ -810,16 +802,9 @@ TEST_CASE_METHOD(SingleSelectDataViewCtrlTestCase, #ifdef __WXGTK__ // Wait for the list control to be relaid out. - wxStopWatch sw; - while ( m_dvc->GetTopItem() == m_root ) - { - if ( sw.Time() > 500 ) - { - WARN("Timed out waiting for wxDataViewCtrl layout"); - break; - } - wxYield(); - } + WaitFor("wxDataViewCtrl layout", [this]() { + return m_dvc->GetTopItem() != m_root; + }); #endif // __WXGTK__ // Check that this was indeed the case. @@ -858,16 +843,9 @@ TEST_CASE_METHOD(MultiColumnsDataViewCtrlTestCase, { #ifdef __WXGTK__ // Wait for the list control to be realized. - wxStopWatch sw; - while ( m_firstColumn->GetWidth() == 0 ) - { - if ( sw.Time() > 500 ) - { - WARN("Timed out waiting for wxDataViewListCtrl to be realized"); - break; - } - wxYield(); - } + WaitFor("wxDataViewCtrl to be realized", [this]() { + return m_firstColumn->GetWidth() != 0; + }); #endif // Check the width of the first column. diff --git a/tests/controls/gridtest.cpp b/tests/controls/gridtest.cpp index 9077e02726..5921793b82 100644 --- a/tests/controls/gridtest.cpp +++ b/tests/controls/gridtest.cpp @@ -26,7 +26,7 @@ #include "wx/stopwatch.h" #endif // __WXGTK__ -#include "waitforpaint.h" +#include "waitfor.h" // To disable tests which work locally, but not when run on GitHub CI. #if defined(__WXGTK__) && !defined(__WXGTK3__) diff --git a/tests/controls/propgridtest.cpp b/tests/controls/propgridtest.cpp index 675a8524e7..0c21b04751 100644 --- a/tests/controls/propgridtest.cpp +++ b/tests/controls/propgridtest.cpp @@ -16,12 +16,13 @@ #if wxUSE_DATEPICKCTRL #include "wx/datectrl.h" #endif -#include "wx/stopwatch.h" #include "wx/propgrid/propgrid.h" #include "wx/propgrid/manager.h" #include "wx/propgrid/advprops.h" +#include "waitfor.h" + #include #include @@ -450,11 +451,7 @@ static wxPropertyGridManager* CreateGrid(int style, int extraStyle) pgManager->Refresh(); pgManager->Update(); // Wait for update to be done - wxStopWatch sw; - while ( sw.Time() < 100 ) - { - wxYield(); - } + YieldForAWhile(100); return pgManager; } @@ -722,11 +719,7 @@ TEST_CASE("PropertyGridTestCase", "[propgrid]") pgManager->Refresh(); pgManager->Update(); // Wait for update to be done - wxStopWatch sw; - while ( sw.Time() < 100 ) - { - wxYield(); - } + YieldForAWhile(100); } SECTION("Default_Values") diff --git a/tests/controls/textctrltest.cpp b/tests/controls/textctrltest.cpp index 4137487d48..a0c9991d0c 100644 --- a/tests/controls/textctrltest.cpp +++ b/tests/controls/textctrltest.cpp @@ -29,7 +29,7 @@ #endif // wxUSE_CLIPBOARD #ifdef __WXGTK__ - #include "wx/stopwatch.h" + #include "waitfor.h" #endif #include "wx/private/localeset.h" @@ -397,8 +397,7 @@ void TextCtrlTestCase::HitTestSingleLine() #ifdef __WXGTK__ // wxGTK must be given an opportunity to lay the text out. - for ( wxStopWatch sw; sw.Time() < 50; ) - wxYield(); + YieldForAWhile(); #endif REQUIRE( m_text->HitTest(wxPoint(2*sizeChar.x, yMid), &pos) == wxTE_HT_ON_TEXT ); @@ -757,18 +756,10 @@ void TextCtrlTestCase::DoPositionToCoordsTestWithStyle(long style) // wxGTK needs to yield here to update the text control. #ifdef __WXGTK__ - wxStopWatch sw; - while ( m_text->PositionToCoords(0).y == 0 || - m_text->PositionToCoords(pos).y > TEXT_HEIGHT ) - { - if ( sw.Time() > 1000 ) - { - FAIL("Timed out waiting for wxTextCtrl update."); - break; - } - - wxYield(); - } + WaitFor("wxTextCtrl update", [this, pos]() { + return m_text->PositionToCoords(0).y != 0 && + m_text->PositionToCoords(pos).y <= TEXT_HEIGHT; + }, 1000); #endif // __WXGTK__ wxPoint coords = m_text->PositionToCoords(0); diff --git a/tests/controls/webtest.cpp b/tests/controls/webtest.cpp index 98a817c997..c7055d895f 100644 --- a/tests/controls/webtest.cpp +++ b/tests/controls/webtest.cpp @@ -22,7 +22,7 @@ #include "wx/msw/webview_ie.h" #endif #if wxUSE_WEBVIEW_WEBKIT2 - #include "wx/stopwatch.h" + #include "waitfor.h" #endif //Convenience macro @@ -235,8 +235,7 @@ TEST_CASE_METHOD(WebViewTestCase, "WebView", "[wxWebView]") // bit before giving up. Avoid calling HasSelection() right away // without wxYielding a bit because this seems to cause the extension // to hang with webkit 2.40.0+. - for ( wxStopWatch sw; sw.Time() < 50; ) - wxYield(); + YieldForAWhile(); #endif // wxUSE_WEBVIEW_WEBKIT2 CHECK(m_browser->HasSelection()); diff --git a/tests/controls/windowtest.cpp b/tests/controls/windowtest.cpp index 6041bcb2fa..648fb6eacb 100644 --- a/tests/controls/windowtest.cpp +++ b/tests/controls/windowtest.cpp @@ -19,12 +19,12 @@ #include "asserthelper.h" #include "testableframe.h" #include "testwindow.h" +#include "waitfor.h" #include "wx/uiaction.h" #include "wx/caret.h" #include "wx/cshelp.h" #include "wx/dcclient.h" -#include "wx/stopwatch.h" #include "wx/tooltip.h" #include "wx/wupdlock.h" @@ -40,8 +40,7 @@ public: // Without this, when running this test suite solo it succeeds, // but not when running it together with the other tests !! // Not needed when run under Xvfb display. - for ( wxStopWatch sw; sw.Time() < 50; ) - wxYield(); + YieldForAWhile(); #endif } @@ -510,13 +509,7 @@ TEST_CASE_METHOD(WindowTestCase, "Window::Refresh", "[window]") parent->RefreshRect(wxRect(150, 10, 300, 80)); - for ( wxStopWatch sw; sw.Time() < 100; ) - { - if ( isParentPainted ) - break; - - wxYield(); - } + WaitFor("parent repaint", [&]() { return isParentPainted; }, 100); // child1 should be the only window not to receive the wxEVT_PAINT event // because it does not intersect with the refreshed rectangle. diff --git a/tests/events/keyboard.cpp b/tests/events/keyboard.cpp index 0b66a58bfb..9bf8f3a261 100644 --- a/tests/events/keyboard.cpp +++ b/tests/events/keyboard.cpp @@ -24,9 +24,7 @@ #include "wx/uiaction.h" #include "wx/vector.h" -#ifdef __WXGTK__ -#include "wx/stopwatch.h" -#endif +#include "waitfor.h" namespace { @@ -229,10 +227,7 @@ void KeyboardEventTestCase::setUp() wxYield(); m_win->SetFocus(); -#ifdef __WXGTK__ - for ( wxStopWatch sw; sw.Time() < 10; ) -#endif - wxYield(); // needed to show the new window + YieldForAWhile(10); // needed to show the new window // The window might get some key up events when it's being shown if the key // was pressed when the program was started and released after the window diff --git a/tests/events/propagation.cpp b/tests/events/propagation.cpp index 771e0e5bb2..37f2fc90aa 100644 --- a/tests/events/propagation.cpp +++ b/tests/events/propagation.cpp @@ -26,10 +26,13 @@ #include "wx/scopeguard.h" #include "wx/toolbar.h" #include "wx/uiaction.h" -#include "wx/stopwatch.h" #include +#ifdef __WXGTK__ + #include "waitfor.h" +#endif + // FIXME: Currently under OS X testing paint event doesn't work because neither // calling Refresh()+Update() nor even sending wxPaintEvent directly to // the window doesn't result in calls to its event handlers, so disable @@ -174,8 +177,7 @@ public: #ifdef __WXGTK__ // We need to map the window, otherwise we're not going to get any // paint events for it. - for ( wxStopWatch sw; sw.Time() < 50; ) - wxYield(); + YieldForAWhile(); // Ignore events generated during the initial mapping. g_str.clear(); diff --git a/tests/graphics/clipper.cpp b/tests/graphics/clipper.cpp index 0ab95b3f19..676a2e1270 100644 --- a/tests/graphics/clipper.cpp +++ b/tests/graphics/clipper.cpp @@ -23,7 +23,7 @@ #include "wx/window.h" #include "testfile.h" -#include "waitforpaint.h" +#include "waitfor.h" static const wxSize s_dcSize(260, 300); @@ -751,11 +751,7 @@ TEST_CASE("ClipperTestCase::wxPaintDC", "[clipper][dc][paintdc]") testWin->Refresh(); testWin->Update(); // Wait for update to be done - wxStopWatch sw; - while( sw.Time() < 50 ) - { - wxYield(); - } + YieldForAWhile(); CHECK(paintExecuted == true); } diff --git a/tests/graphics/clippingbox.cpp b/tests/graphics/clippingbox.cpp index d5da29af1a..cf0f409468 100644 --- a/tests/graphics/clippingbox.cpp +++ b/tests/graphics/clippingbox.cpp @@ -22,7 +22,7 @@ #include "wx/dcclient.h" #include "testfile.h" -#include "waitforpaint.h" +#include "waitfor.h" #include @@ -4322,11 +4322,7 @@ TEST_CASE("ClippingBoxTestCase::wxPaintDC", "[clip][dc][paintdc]") testWin->Refresh(); testWin->Update(); // Wait for update to be done - wxStopWatch sw; - while( sw.Time() < 50 ) - { - wxYield(); - } + YieldForAWhile(); CHECK(paintExecuted == true); } diff --git a/tests/persistence/dataview.cpp b/tests/persistence/dataview.cpp index 686cbec6a6..0cfa99c527 100644 --- a/tests/persistence/dataview.cpp +++ b/tests/persistence/dataview.cpp @@ -19,14 +19,14 @@ #ifndef WX_PRECOMP #include "wx/dataview.h" - - #ifdef __WXGTK__ - #include "wx/stopwatch.h" - #endif // __WXGTK__ #endif // WX_PRECOMP #include "wx/persist/dataview.h" +#ifdef __WXGTK__ + #include "waitfor.h" +#endif // __WXGTK__ + // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- @@ -90,17 +90,9 @@ static wxDataViewCtrl* CreatePersistenceTestDVC() void GTKWaitRealized(wxDataViewCtrl* list) { #ifdef __WXGTK__ - wxStopWatch sw; - while ( list->GetColumn(0)->GetWidth() == 0 ) - { - if ( sw.Time() > 500 ) - { - WARN("Timed out waiting for wxDataViewCtrl to be realized"); - break; - } - - wxYield(); - } + WaitFor("wxDataViewCtrl to be realized", [list]() { + return list->GetColumn(0)->GetWidth() != 0; + }); #else // !__WXGTK__ wxUnusedVar(list); #endif // __WXGTK__/!__WXGTK__ diff --git a/tests/persistence/tlw.cpp b/tests/persistence/tlw.cpp index 1de89b5756..34b43cc1fd 100644 --- a/tests/persistence/tlw.cpp +++ b/tests/persistence/tlw.cpp @@ -17,14 +17,14 @@ #ifndef WX_PRECOMP #include "wx/frame.h" - - #ifdef __WXGTK__ - #include "wx/stopwatch.h" - #endif // __WXGTK__ #endif // WX_PRECOMP #include "wx/persist/toplevel.h" +#ifdef __WXGTK__ + #include "waitfor.h" +#endif // __WXGTK__ + // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- @@ -117,17 +117,11 @@ TEST_CASE_METHOD(PersistenceTests, "wxPersistTLW", "[persist][tlw]") } else { - wxStopWatch sw; - while ( !frame->IsIconized() ) + if ( !WaitFor("frame to be iconized", [frame]() { + return frame->IsIconized(); + }) ) { - wxYield(); - if ( sw.Time() > 500 ) - { - // 500ms should be enough for the window to end up iconized. - WARN("Frame wasn't iconized as expected"); - checkIconized = false; - break; - } + checkIconized = false; } } #endif // __WXGTK__ @@ -148,16 +142,9 @@ TEST_CASE_METHOD(PersistenceTests, "wxPersistTLW", "[persist][tlw]") if ( checkIconized ) { #ifdef __WXGTK__ - wxStopWatch sw; - while ( !frame->IsIconized() ) - { - wxYield(); - if ( sw.Time() > 500 ) - { - INFO("Abandoning wait after " << sw.Time() << "ms"); - break; - } - } + WaitFor("frame to be iconized", [frame]() { + return frame->IsIconized(); + }); #endif // __WXGTK__ CHECK(frame->IsIconized()); diff --git a/tests/waitforpaint.h b/tests/waitfor.h similarity index 65% rename from tests/waitforpaint.h rename to tests/waitfor.h index 0a1891901b..b3d0f6cc33 100644 --- a/tests/waitforpaint.h +++ b/tests/waitfor.h @@ -1,17 +1,57 @@ /////////////////////////////////////////////////////////////////////////////// -// Name: tests/waitforpaint.h +// Name: tests/waitfor.h // Purpose: Helper WaitForPaint class // Author: Vadim Zeitlin // Created: 2019-10-17 (extracted from tests/window/setsize.cpp) // Copyright: (c) 2019 Vadim Zeitlin /////////////////////////////////////////////////////////////////////////////// -#ifndef _WX_TESTS_WAITFORPAINT_H_ -#define _WX_TESTS_WAITFORPAINT_H_ +#ifndef _WX_TESTS_WAITFOR_H_ +#define _WX_TESTS_WAITFOR_H_ #include "wx/stopwatch.h" #include "wx/window.h" +#include + +// Function used to wait until the given predicate becomes true or timeout +// expires. +inline bool +WaitFor(const char* what, const std::function& pred, int timeout = 500) +{ + wxStopWatch sw; + for ( ;; ) + { + wxYield(); + + if ( pred() ) + break; + + if ( sw.Time() > timeout ) + { + WARN("Timed out waiting for " << what); + return false; + } + } + + return true; +} + +// An even simpler version which doesn't wait for anything but just calls +// wxYield() until the given timeout expires. +inline void +YieldForAWhile(int timeout = 50) +{ + wxStopWatch sw; + for ( ;; ) + { + wxYield(); + + if ( sw.Time() > timeout ) + break; + } +} + // Class used to check if we received the (first) paint event: this is // currently used under GTK only, as MSW doesn't seem to need to wait for the // things to work, while under Mac nothing works anyhow. @@ -32,23 +72,10 @@ public: // event to come and logs a warning if we didn't get it. void YieldUntilPainted(int timeoutInMS = 250) { - wxStopWatch sw; - for ( ;; ) + if ( WaitFor("repaint", [this]() { return m_painted; }, timeoutInMS) ) { - wxYield(); - - if ( m_painted ) - { - // Reset it in case YieldUntilPainted() is called again. - m_painted = false; - break; - } - - if ( sw.Time() > timeoutInMS ) - { - WARN("Didn't get a paint event until timeout expiration"); - break; - } + // Reset it in case YieldUntilPainted() is called again. + m_painted = false; } } @@ -99,4 +126,4 @@ public: #endif // __WXGTK__/!__WXGTK__ -#endif // _WX_TESTS_WAITFORPAINT_H_ +#endif // _WX_TESTS_WAITFOR_H_ diff --git a/tests/window/clientsize.cpp b/tests/window/clientsize.cpp index 61f2b87cec..9d2da0380d 100644 --- a/tests/window/clientsize.cpp +++ b/tests/window/clientsize.cpp @@ -21,7 +21,7 @@ #include #include "asserthelper.h" -#include "waitforpaint.h" +#include "waitfor.h" // ---------------------------------------------------------------------------- // tests themselves diff --git a/tests/window/setsize.cpp b/tests/window/setsize.cpp index d30fb22fdb..e89516fa05 100644 --- a/tests/window/setsize.cpp +++ b/tests/window/setsize.cpp @@ -22,7 +22,7 @@ #include #include "asserthelper.h" -#include "waitforpaint.h" +#include "waitfor.h" // ---------------------------------------------------------------------------- // tests helpers