Baseline tests: improve focus setting and clearing

Set focus on the test window so that the tested widget doesn't have it.
Remove the "PublicWidget" hack, we have public QWidget APIs to find the
next widget in the focus chain that we can use to transfer focus
reliably. Use TabFocusReason to maintain existing behavior, and to
test that widgets that handle that specifically appear correctly. Clear
the focus on the test widget by setting it back to the window after
taking the "focused" snapshot.

Add QCOMPARE and QVERIFY to assert that the test is in the right state
before taking screenshots.

Change-Id: Icef6ce1bb1c63c9f6cde7d0ddca82e693cace420
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit bf2ed624091d0239bce91a84df59b7afc843298a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Volker Hilsheimer 2024-04-17 10:25:32 +02:00 committed by Qt Cherry-pick Bot
parent 76807bdfb7
commit 5519bf0cf9

View File

@ -80,6 +80,7 @@ void QWidgetBaselineTest::init()
background = new QWidget(nullptr, Qt::FramelessWindowHint);
window = new QWidget(background, Qt::Window);
window->setWindowTitle(QTest::currentDataTag());
window->setFocusPolicy(Qt::StrongFocus);
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
background->setScreen(QGuiApplication::primaryScreen());
window->setScreen(QGuiApplication::primaryScreen());
@ -106,9 +107,9 @@ void QWidgetBaselineTest::makeVisible()
window->show();
QApplicationPrivate::setActiveWindow(window);
QVERIFY(QTest::qWaitForWindowActive(window));
// explicitly unset focus, the test needs to control when focus is shown
if (window->focusWidget())
window->focusWidget()->clearFocus();
// explicitly set focus on the window so that the test widget doesn't have it
window->setFocus(Qt::OtherFocusReason);
QTRY_COMPARE(window->focusWidget(), window);
}
/*
@ -146,23 +147,25 @@ QImage QWidgetBaselineTest::takeScreenSnapshot(const QRect& windowRect)
void QWidgetBaselineTest::takeStandardSnapshots()
{
makeVisible();
struct PublicWidget : QWidget {
bool focusNextPrevChild(bool next) override { return QWidget::focusNextPrevChild(next); }
};
QWidget *oldFocusWidget = testWindow()->focusWidget();
QCOMPARE(oldFocusWidget, testWindow());
QBASELINE_CHECK_DEFERRED(takeSnapshot(), "default");
// try hard to set focus
static_cast<PublicWidget*>(window)->focusNextPrevChild(true);
if (!window->focusWidget()) {
QWidget *firstChild = window->findChild<QWidget*>();
if (firstChild)
firstChild->setFocus();
}
QWidget *testWidget = window->nextInFocusChain();
if (!testWidget)
testWidget = window->findChild<QWidget*>();
QVERIFY(testWidget);
// use TabFocusReason, some widgets handle that specifically to e.g. select
testWidget->setFocus(Qt::TabFocusReason);
if (testWindow()->focusWidget()) {
if (testWindow()->focusWidget() != oldFocusWidget) {
QBASELINE_CHECK_DEFERRED(takeSnapshot(), "focused");
testWindow()->focusWidget()->clearFocus();
// set focus back
oldFocusWidget->setFocus(Qt::OtherFocusReason);
} else {
qWarning() << "Couldn't set focus on tested widget" << testWidget;
}
// this disables all children