testlib: make it possible to test double-clicks with discrete events
The timestamp will no longer be incremented by 500ms after a mouse
release if the delay has been explicitly specified.
The default delay is 1 ms since f5010c49a3
but the running timestamp was unconditionally post-incremented by 500ms
after every mouse release, to prevent double-clicks, which were always
deemed as unintended (because we have a mouseDClick function for that).
Now, we do that 500ms increment only if the user has not provided a
delay value in the function argument at all. We have often found it
useful in our own tests to generate double-clicks "the hard way", by
sending indivdual events, so as to be able to check state in some target
object at each step, as shown in the new snippet.
[ChangeLog][QtTest] QTest::mouseRelease() and mouseClick() can now be
used to test double-clicks, by specifying a realistic timestamp delay.
Fixes: QTBUG-102441
Change-Id: I8e8d242061f79efb4c6e02638645e03661a9cd92
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
bb10
parent
5caf808750
commit
0f94430a0f
|
|
@ -119,3 +119,16 @@ char *toString(const MyType &t)
|
|||
return repr;
|
||||
}
|
||||
//! [34]
|
||||
|
||||
//! [35]
|
||||
QSignalSpy doubleClickSpy(target, &TargetClass::doubleClicked);
|
||||
const QPoint p(1, 2);
|
||||
QTest::mousePress(&myWindow, Qt::LeftButton, Qt::NoModifier, p);
|
||||
QVERIFY(target.isPressed());
|
||||
QTest::mouseRelease(&myWindow, Qt::LeftButton, Qt::NoModifier, p, 10);
|
||||
QCOMPARE(target.isPressed(), false);
|
||||
QTest::mousePress(&myWindow, Qt::LeftButton, Qt::NoModifier, p, 10);
|
||||
QCOMPARE(target.pressCount(), 2);
|
||||
QTest::mouseRelease(&myWindow, Qt::LeftButton, Qt::NoModifier, p, 10);
|
||||
QCOMPARE(doubleClickSpy.count(), 1);
|
||||
//! [35]
|
||||
|
|
|
|||
|
|
@ -1260,7 +1260,16 @@
|
|||
on a \a widget. The position of the release is defined by \a pos;
|
||||
the default position is the center of the widget. If \a delay is
|
||||
specified, the test will wait for the specified amount of
|
||||
milliseconds before releasing the button.
|
||||
milliseconds before releasing the button; otherwise, it will wait for a
|
||||
default amount of time (1 ms), which can be overridden via
|
||||
\l {Testing Options}{command-line arguments}.
|
||||
|
||||
\note If you wish to test a double-click by sending events individually,
|
||||
specify a short delay, greater than the default, on both mouse release events.
|
||||
The total of the delays for the press, release, press and release must be
|
||||
less than QStyleHints::mouseDoubleClickInterval(). But if you don't need
|
||||
to check state between events, it's better to use QTest::mouseDClick().
|
||||
\snippet code/src_qtestlib_qtestcase_snippet.cpp 35
|
||||
|
||||
\sa QTest::mousePress(), QTest::mouseClick()
|
||||
*/
|
||||
|
|
@ -1273,7 +1282,16 @@
|
|||
on a \a window. The position of the release is defined by \a pos;
|
||||
the default position is the center of the window. If \a delay is
|
||||
specified, the test will wait for the specified amount of
|
||||
milliseconds before releasing the button.
|
||||
milliseconds before releasing the button; otherwise, it will wait for a
|
||||
default amount of time (1 ms), which can be overridden via
|
||||
\l {Testing Options}{command-line arguments}.
|
||||
|
||||
\note If you wish to test a double-click by sending events individually,
|
||||
specify a short delay, greater than the default, on both mouse release events.
|
||||
The total of the delays for the press, release, press and release must be
|
||||
less than QStyleHints::mouseDoubleClickInterval(). But if you don't need
|
||||
to check state between events, it's better to use QTest::mouseDClick().
|
||||
\snippet code/src_qtestlib_qtestcase_snippet.cpp 35
|
||||
|
||||
\sa QTest::mousePress(), QTest::mouseClick()
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -57,6 +57,12 @@ namespace QTest
|
|||
event. We expect all event-handling code to rely on the event
|
||||
timestamps, not the system clock; therefore tests can be run faster
|
||||
than real-time.
|
||||
|
||||
If \a delay is not given, a default minimum mouse delay is used, and
|
||||
unintended double-click events are prevented by incrementing the
|
||||
timestamp by 500ms after each mouse release. Therefore, to test
|
||||
double-clicks, it's necessary to give a realistic \a delay value (for
|
||||
example, 10ms).
|
||||
*/
|
||||
static void mouseEvent(MouseAction action, QWindow *window, Qt::MouseButton button,
|
||||
Qt::KeyboardModifiers stateKey, QPoint pos, int delay=-1)
|
||||
|
|
@ -71,9 +77,8 @@ namespace QTest
|
|||
pos.x(), pos.y(), windowSize.width(), windowSize.height());
|
||||
}
|
||||
|
||||
if (delay == -1 || delay < defaultMouseDelay())
|
||||
delay = defaultMouseDelay();
|
||||
lastMouseTimestamp += qMax(1, delay);
|
||||
int actualDelay = (delay == -1 || delay < defaultMouseDelay()) ? defaultMouseDelay() : delay;
|
||||
lastMouseTimestamp += qMax(1, actualDelay);
|
||||
|
||||
if (pos.isNull())
|
||||
pos = QPoint(window->width() / 2, window->height() / 2);
|
||||
|
|
@ -108,7 +113,8 @@ namespace QTest
|
|||
qtestMouseButtons.setFlag(button, false);
|
||||
qt_handleMouseEvent(w, pos, global, qtestMouseButtons, button, QEvent::MouseButtonRelease,
|
||||
stateKey, lastMouseTimestamp);
|
||||
lastMouseTimestamp += mouseDoubleClickInterval; // avoid double clicks being generated
|
||||
if (delay == -1)
|
||||
lastMouseTimestamp += mouseDoubleClickInterval; // avoid double clicks being generated
|
||||
break;
|
||||
case MouseMove:
|
||||
qt_handleMouseEvent(w, pos, global, qtestMouseButtons, Qt::NoButton, QEvent::MouseMove,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<testsuite name="tst_Mouse" timestamp="@TEST_START_TIME@" hostname="@HOSTNAME@" tests="13" failures="0" errors="0" skipped="3" time="@TEST_DURATION@">
|
||||
<testsuite name="tst_Mouse" timestamp="@TEST_START_TIME@" hostname="@HOSTNAME@" tests="14" failures="0" errors="0" skipped="3" time="@TEST_DURATION@">
|
||||
<properties>
|
||||
<property name="QTestVersion" value="@INSERT_QT_VERSION_HERE@"/>
|
||||
<property name="QtVersion" value="@INSERT_QT_VERSION_HERE@"/>
|
||||
|
|
@ -23,5 +23,6 @@
|
|||
<testcase name="deterministicEvents(first-run-false)" classname="tst_Mouse" time="@TEST_DURATION@">
|
||||
<skipped message="Not implemented!"/>
|
||||
</testcase>
|
||||
<testcase name="doubleClick" classname="tst_Mouse" time="@TEST_DURATION@"/>
|
||||
<testcase name="cleanupTestCase" classname="tst_Mouse" time="@TEST_DURATION@"/>
|
||||
</testsuite>
|
||||
|
|
|
|||
|
|
@ -54,6 +54,10 @@
|
|||
</Incident>
|
||||
<Duration msecs="0"/>
|
||||
</TestFunction>
|
||||
<TestFunction name="doubleClick">
|
||||
<Incident type="pass" file="" line="0" />
|
||||
<Duration msecs="0"/>
|
||||
</TestFunction>
|
||||
<TestFunction name="cleanupTestCase">
|
||||
<Incident type="pass" file="" line="0" />
|
||||
<Duration msecs="0"/>
|
||||
|
|
|
|||
|
|
@ -12,8 +12,9 @@ ok 9 - stateHandlingPart1(dummy-2)
|
|||
ok 10 - stateHandlingPart2() # SKIP Not implemented beyond this point!
|
||||
ok 11 - deterministicEvents(first-run-true) # SKIP Not implemented!
|
||||
ok 12 - deterministicEvents(first-run-false) # SKIP Not implemented!
|
||||
ok 13 - cleanupTestCase()
|
||||
1..13
|
||||
# tests 13
|
||||
# pass 10
|
||||
ok 13 - doubleClick()
|
||||
ok 14 - cleanupTestCase()
|
||||
1..14
|
||||
# tests 14
|
||||
# pass 11
|
||||
# fail 0
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
##teamcity[testStarted name='deterministicEvents(first-run-false)' flowId='tst_Mouse']
|
||||
##teamcity[testIgnored name='deterministicEvents(first-run-false)' message='Not implemented! |[Loc: qtbase/tests/auto/testlib/selftests/mouse/tst_mouse.cpp(0)|]' flowId='tst_Mouse']
|
||||
##teamcity[testFinished name='deterministicEvents(first-run-false)' flowId='tst_Mouse']
|
||||
##teamcity[testStarted name='doubleClick()' flowId='tst_Mouse']
|
||||
##teamcity[testFinished name='doubleClick()' flowId='tst_Mouse']
|
||||
##teamcity[testStarted name='cleanupTestCase()' flowId='tst_Mouse']
|
||||
##teamcity[testFinished name='cleanupTestCase()' flowId='tst_Mouse']
|
||||
##teamcity[testSuiteFinished name='tst_Mouse' flowId='tst_Mouse']
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ SKIP : tst_Mouse::deterministicEvents(first-run-true) Not implemented!
|
|||
Loc: [qtbase/tests/auto/testlib/selftests/mouse/tst_mouse.cpp(0)]
|
||||
SKIP : tst_Mouse::deterministicEvents(first-run-false) Not implemented!
|
||||
Loc: [qtbase/tests/auto/testlib/selftests/mouse/tst_mouse.cpp(0)]
|
||||
PASS : tst_Mouse::doubleClick()
|
||||
PASS : tst_Mouse::cleanupTestCase()
|
||||
Totals: 10 passed, 0 failed, 3 skipped, 0 blacklisted, 0ms
|
||||
Totals: 11 passed, 0 failed, 3 skipped, 0 blacklisted, 0ms
|
||||
********* Finished testing of tst_Mouse *********
|
||||
|
|
|
|||
|
|
@ -56,6 +56,10 @@
|
|||
</Incident>
|
||||
<Duration msecs="0"/>
|
||||
</TestFunction>
|
||||
<TestFunction name="doubleClick">
|
||||
<Incident type="pass" file="" line="0" />
|
||||
<Duration msecs="0"/>
|
||||
</TestFunction>
|
||||
<TestFunction name="cleanupTestCase">
|
||||
<Incident type="pass" file="" line="0" />
|
||||
<Duration msecs="0"/>
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ private slots:
|
|||
void stateHandlingPart2();
|
||||
void deterministicEvents_data();
|
||||
void deterministicEvents();
|
||||
void doubleClick();
|
||||
};
|
||||
|
||||
class MouseWindow : public QWindow
|
||||
|
|
@ -251,5 +252,53 @@ void tst_Mouse::deterministicEvents()
|
|||
QCOMPARE(w.moveCount, 1);
|
||||
}
|
||||
|
||||
void tst_Mouse::doubleClick()
|
||||
{
|
||||
MouseWindow w;
|
||||
w.show();
|
||||
w.setGeometry(100, 100, 200, 200);
|
||||
QVERIFY(QTest::qWaitForWindowActive(&w));
|
||||
|
||||
// click
|
||||
QPoint point(10, 10);
|
||||
QCOMPARE(w.pressCount, 0);
|
||||
QTest::mousePress(&w, Qt::LeftButton, { }, point);
|
||||
QCOMPARE(w.pressCount, 1);
|
||||
// give a delay of 10ms
|
||||
auto ts = w.lastTimeStamp;
|
||||
QTest::mouseRelease(&w, Qt::LeftButton, { }, point, 10);
|
||||
QCOMPARE(w.lastTimeStamp, ts + 10);
|
||||
QCOMPARE(w.doubleClickCount, 0);
|
||||
|
||||
// click again within a short time to generate double-click
|
||||
QTest::mousePress(&w, Qt::LeftButton, { }, point, 10);
|
||||
QCOMPARE(w.pressCount, 2);
|
||||
QCOMPARE(w.lastTimeStamp, ts + 20);
|
||||
// this time, let some virtual time elapse, because we're going to test double-click again afterwards
|
||||
QTest::mouseRelease(&w, Qt::LeftButton, { }, point);
|
||||
QCOMPARE_GT(w.lastTimeStamp, ts + 20);
|
||||
QCOMPARE(w.doubleClickCount, 1);
|
||||
|
||||
// use the mouseClick function to generate another double-click
|
||||
ts = w.lastTimeStamp;
|
||||
QTest::mouseClick(&w, Qt::LeftButton, {}, point, 10);
|
||||
QCOMPARE_GE(w.lastTimeStamp, ts + 500); // because the last release had a default delay
|
||||
QTest::mouseClick(&w, Qt::LeftButton, {}, point);
|
||||
QCOMPARE(w.doubleClickCount, 2);
|
||||
|
||||
// use the mouseDClick function to generate another double-click
|
||||
ts = w.lastTimeStamp;
|
||||
QTest::mouseDClick(&w, Qt::LeftButton, {}, point);
|
||||
QCOMPARE_GE(w.lastTimeStamp, ts + 500); // because the last release had a default delay
|
||||
QCOMPARE(w.doubleClickCount, 3);
|
||||
|
||||
// use the mouseClick function with default delay to avoid double-click
|
||||
ts = w.lastTimeStamp;
|
||||
QTest::mouseClick(&w, Qt::LeftButton, {}, point);
|
||||
QCOMPARE_GE(w.lastTimeStamp, ts + 500); // because the last release had a default delay
|
||||
QTest::mouseClick(&w, Qt::LeftButton, {}, point);
|
||||
QCOMPARE(w.doubleClickCount, 3);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_Mouse)
|
||||
#include "tst_mouse.moc"
|
||||
|
|
|
|||
Loading…
Reference in New Issue