From 9acec431c360379a21cdbe36d8e342083f344c3c Mon Sep 17 00:00:00 2001 From: Jo Asplin Date: Fri, 25 Nov 2011 09:30:03 +0100 Subject: Moved integrationtests/* into other/ Currently there seems to be no precise definition of what an integrationtest is in the context of Qt testing. To avoid confusion, the tests under integrationtests/ are moved into other/ (which is effectively where we keep tests that don't clearly fit into any other category). Tests can be moved back into an integrationtests/ directory at a later point, should an unambiguous definition be established. Change-Id: I3bb289be2dc2aca11b51a8ce8fcc5942f06d6c5c Reviewed-by: Jason McDonald --- tests/auto/other/macgui/.gitignore | 1 + tests/auto/other/macgui/guitest.cpp | 343 +++++++++++++++++++++++++++++++++ tests/auto/other/macgui/guitest.h | 172 +++++++++++++++++ tests/auto/other/macgui/macgui.pro | 15 ++ tests/auto/other/macgui/tst_macgui.cpp | 242 +++++++++++++++++++++++ 5 files changed, 773 insertions(+) create mode 100644 tests/auto/other/macgui/.gitignore create mode 100644 tests/auto/other/macgui/guitest.cpp create mode 100644 tests/auto/other/macgui/guitest.h create mode 100644 tests/auto/other/macgui/macgui.pro create mode 100644 tests/auto/other/macgui/tst_macgui.cpp (limited to 'tests/auto/other/macgui') diff --git a/tests/auto/other/macgui/.gitignore b/tests/auto/other/macgui/.gitignore new file mode 100644 index 0000000000..2b13357fac --- /dev/null +++ b/tests/auto/other/macgui/.gitignore @@ -0,0 +1 @@ +tst_macgui diff --git a/tests/auto/other/macgui/guitest.cpp b/tests/auto/other/macgui/guitest.cpp new file mode 100644 index 0000000000..e5245528cb --- /dev/null +++ b/tests/auto/other/macgui/guitest.cpp @@ -0,0 +1,343 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "guitest.h" +#include +#include +#include +#include +#include + +#ifdef Q_OS_MAC +# include +#endif + + +/* + Not really a test, just prints interface info. +*/ +class PrintTest : public TestBase +{ +public: + bool operator()(QAccessibleInterface *candidate) + { + qDebug() << ""; + qDebug() << "Name" << candidate->text(QAccessible::Name); + qDebug() << "Pos" << candidate->rect(); + qDebug() << "Number of children" << candidate->childCount(); + return false; + } +}; + +class NameTest : public TestBase +{ +public: + NameTest(const QString &text, QAccessible::Text textType) : text(text), textType(textType) {} + QString text; + QAccessible::Text textType; + + bool operator()(QAccessibleInterface *candidate) + { + return (candidate->text(textType) == text); + } +}; + +void WidgetNavigator::printAll(QWidget *widget) +{ + QAccessibleInterface * const iface = QAccessible::queryAccessibleInterface(widget); + deleteInDestructor(iface); + printAll(iface); +} + +void WidgetNavigator::printAll(QAccessibleInterface *interface) +{ + PrintTest printTest; + recursiveSearch(&printTest, interface); +} + +QAccessibleInterface *WidgetNavigator::find(QAccessible::Text textType, const QString &text, QWidget *start) +{ + QAccessibleInterface *const iface = QAccessible::queryAccessibleInterface(start); + deleteInDestructor(iface); + return find(textType, text, iface); +} + +QAccessibleInterface *WidgetNavigator::find(QAccessible::Text textType, const QString &text, QAccessibleInterface *start) +{ + NameTest nameTest(text, textType); + return recursiveSearch(&nameTest, start); +} + +/* + Recursiveley navigates the accessible hiearchy looking for an interface that + passsed the Test (meaning it returns true). +*/ +QAccessibleInterface *WidgetNavigator::recursiveSearch(TestBase *test, QAccessibleInterface *iface) +{ + QStack todoInterfaces; + todoInterfaces.push(iface); + + while (todoInterfaces.isEmpty() == false) { + QAccessibleInterface *testInterface = todoInterfaces.pop(); + + if ((*test)(testInterface)) + return testInterface; + + const int numChildren = testInterface->childCount(); + for (int i = 0; i < numChildren; ++i) { + QAccessibleInterface *childInterface = testInterface->child(i); + if (childInterface) { + todoInterfaces.push(childInterface); + deleteInDestructor(childInterface); + } + } + } + return 0; +} + +void WidgetNavigator::deleteInDestructor(QAccessibleInterface *interface) +{ + interfaces.insert(interface); +} + +QWidget *WidgetNavigator::getWidget(QAccessibleInterface *interface) +{ + return qobject_cast(interface->object()); +} + +WidgetNavigator::~WidgetNavigator() +{ + foreach(QAccessibleInterface *interface, interfaces) { + delete interface; + } +} + +/////////////////////////////////////////////////////////////////////////////// + +namespace NativeEvents { +#ifdef Q_OS_MAC + void mouseClick(const QPoint &globalPos, Qt::MouseButtons buttons, MousePosition updateMouse) + { + CGPoint position; + position.x = globalPos.x(); + position.y = globalPos.y(); + + const bool updateMousePosition = (updateMouse == UpdatePosition); + + // Mouse down. + CGPostMouseEvent(position, updateMousePosition, 3, + (buttons & Qt::LeftButton) ? true : false, + (buttons & Qt::MidButton/* Middlebutton! */) ? true : false, + (buttons & Qt::RightButton) ? true : false); + + // Mouse up. + CGPostMouseEvent(position, updateMousePosition, 3, false, false, false); + } +#else +# error Oops, NativeEvents::mouseClick() is not implemented on this platform. +#endif +}; + +/////////////////////////////////////////////////////////////////////////////// + +GuiTester::GuiTester() +{ + clearSequence(); +} + +GuiTester::~GuiTester() +{ + foreach(DelayedAction *action, actions) + delete action; +} + +bool checkPixel(QColor pixel, QColor expected) +{ + const int allowedDiff = 20; + + return !(qAbs(pixel.red() - expected.red()) > allowedDiff || + qAbs(pixel.green() - expected.green()) > allowedDiff || + qAbs(pixel.blue() - expected.blue()) > allowedDiff); +} + +/* + Tests that the pixels inside rect in image all have the given color. +*/ +bool GuiTester::isFilled(const QImage image, const QRect &rect, const QColor &color) +{ + for (int y = rect.top(); y <= rect.bottom(); ++y) + for (int x = rect.left(); x <= rect.right(); ++x) { + const QColor pixel = image.pixel(x, y); + if (checkPixel(pixel, color) == false) { +// qDebug()<< "Wrong pixel value at" << x << y << pixel.red() << pixel.green() << pixel.blue(); + return false; + } + } + return true; +} + + +/* + Tests that stuff is painted to the pixels inside rect. + This test fails if any lines in the given direction have pixels + of only one color. +*/ +bool GuiTester::isContent(const QImage image, const QRect &rect, Directions directions) +{ + if (directions & Horizontal) { + for (int y = rect.top(); y <= rect.bottom(); ++y) { + QColor currentColor = image.pixel(rect.left(), y); + bool fullRun = true; + for (int x = rect.left() + 1; x <= rect.right(); ++x) { + if (checkPixel(image.pixel(x, y), currentColor) == false) { + fullRun = false; + break; + } + } + if (fullRun) { +// qDebug() << "Single-color line at horizontal line " << y << currentColor; + return false; + } + } + return true; + } + + if (directions & Vertical) { + for (int x = rect.left(); x <= rect.right(); ++x) { + QRgb currentColor = image.pixel(x, rect.top()); + bool fullRun = true; + for (int y = rect.top() + 1; y <= rect.bottom(); ++y) { + if (checkPixel(image.pixel(x, y), currentColor) == false) { + fullRun = false; + break; + } + } + if (fullRun) { +// qDebug() << "Single-color line at vertical line" << x << currentColor; + return false; + } + } + return true; + } + return false; // shut the compiler up. +} + +void DelayedAction::run() +{ + if (next) + QTimer::singleShot(next->delay, next, SLOT(run())); +}; + +/* + Schedules a mouse click at an interface using a singleShot timer. + Only one click can be scheduled at a time. +*/ +ClickLaterAction::ClickLaterAction(QAccessibleInterface *interface, Qt::MouseButtons buttons) +{ + this->useInterface = true; + this->interface = interface; + this->buttons = buttons; +} + +/* + Schedules a mouse click at a widget using a singleShot timer. + Only one click can be scheduled at a time. +*/ +ClickLaterAction::ClickLaterAction(QWidget *widget, Qt::MouseButtons buttons) +{ + this->useInterface = false; + this->widget = widget; + this->buttons = buttons; +} + +void ClickLaterAction::run() +{ + if (useInterface) { + const QPoint globalCenter = interface->rect().center(); + NativeEvents::mouseClick(globalCenter, buttons); + } else { // use widget + const QSize halfSize = widget->size() / 2; + const QPoint globalCenter = widget->mapToGlobal(QPoint(halfSize.width(), halfSize.height())); + NativeEvents::mouseClick(globalCenter, buttons); + } + DelayedAction::run(); +} + +void GuiTester::clickLater(QAccessibleInterface *interface, Qt::MouseButtons buttons, int delay) +{ + clearSequence(); + addToSequence(new ClickLaterAction(interface, buttons), delay); + runSequence(); +} + +void GuiTester::clickLater(QWidget *widget, Qt::MouseButtons buttons, int delay) +{ + clearSequence(); + addToSequence(new ClickLaterAction(widget, buttons), delay); + runSequence(); +} + +void GuiTester::clearSequence() +{ + startAction = new DelayedAction(); + actions.insert(startAction); + lastAction = startAction; +} + +void GuiTester::addToSequence(DelayedAction *action, int delay) +{ + actions.insert(action); + action->delay = delay; + lastAction->next = action; + lastAction = action; +} + +void GuiTester::runSequence() +{ + QTimer::singleShot(0, startAction, SLOT(run())); +} + +void GuiTester::exitLoopSlot() +{ + QTestEventLoop::instance().exitLoop(); +} + diff --git a/tests/auto/other/macgui/guitest.h b/tests/auto/other/macgui/guitest.h new file mode 100644 index 0000000000..170fc5c19c --- /dev/null +++ b/tests/auto/other/macgui/guitest.h @@ -0,0 +1,172 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef GUITEST_H +#define GUITEST_H + +#include +#include +#include +#include + +QT_USE_NAMESPACE + +/* + GuiTest provides tools for: + - navigating the Qt Widget hiearchy using the accessibilty APIs. + - Simulating platform mouse and keybord events. +*/ + +class TestBase { +public: + virtual bool operator()(QAccessibleInterface *candidate) = 0; + virtual ~TestBase() {} +}; + +/* + WidgetNavigator navigates a Qt GUI hierarchy using the QAccessibility APIs. +*/ +class WidgetNavigator { +public: + WidgetNavigator() {}; + ~WidgetNavigator(); + + void printAll(QWidget *widget); + void printAll(QAccessibleInterface *interface); + + QAccessibleInterface *find(QAccessible::Text textType, const QString &text, QWidget *start); + QAccessibleInterface *find(QAccessible::Text textType, const QString &text, QAccessibleInterface *start); + + QAccessibleInterface *recursiveSearch(TestBase *test, QAccessibleInterface *iface); + + void deleteInDestructor(QAccessibleInterface * interface); + static QWidget *getWidget(QAccessibleInterface *interface); +private: + QSet interfaces; +}; + +/* + NativeEvents contains platform-specific code for simulating mouse and keybord events. + (Implemented so far: mouseClick on Mac) +*/ +namespace NativeEvents { + enum MousePosition { UpdatePosition, DontUpdatePosition }; + /* + Simulates a mouse click with button at globalPos. + */ + void mouseClick(const QPoint &globalPos, Qt::MouseButtons buttons, MousePosition updateMouse = DontUpdatePosition); +}; + +class ColorWidget : public QWidget +{ +public: + ColorWidget(QWidget *parent = 0, QColor color = QColor(Qt::red)) + : QWidget(parent), color(color) {} + + QColor color; + +protected: + void paintEvent(QPaintEvent *) + { + QPainter p(this); + p.fillRect(this->rect(), color); + } +}; + +class DelayedAction : public QObject +{ +Q_OBJECT +public: + DelayedAction() : delay(0), next(0) {} + virtual ~DelayedAction(){} +public slots: + virtual void run(); +public: + int delay; + DelayedAction *next; +}; + +class ClickLaterAction : public DelayedAction +{ +Q_OBJECT +public: + ClickLaterAction(QAccessibleInterface *interface, Qt::MouseButtons buttons = Qt::LeftButton); + ClickLaterAction(QWidget *widget, Qt::MouseButtons buttons = Qt::LeftButton); +protected slots: + void run(); +private: + bool useInterface; + QAccessibleInterface *interface; + QWidget *widget; + Qt::MouseButtons buttons; +}; + +/* + +*/ +class GuiTester : public QObject +{ +Q_OBJECT +public: + GuiTester(); + ~GuiTester(); + enum Direction {Horizontal = 1, Vertical = 2, HorizontalAndVertical = 3}; + Q_DECLARE_FLAGS(Directions, Direction) + bool isFilled(const QImage image, const QRect &rect, const QColor &color); + bool isContent(const QImage image, const QRect &rect, Directions directions = HorizontalAndVertical); +protected slots: + void exitLoopSlot(); +protected: + void clickLater(QAccessibleInterface *interface, Qt::MouseButtons buttons = Qt::LeftButton, int delay = 300); + void clickLater(QWidget *widget, Qt::MouseButtons buttons = Qt::LeftButton, int delay = 300); + + void clearSequence(); + void addToSequence(DelayedAction *action, int delay = 0); + void runSequence(); + WidgetNavigator wn; +private: + QSet actions; + DelayedAction *startAction; + DelayedAction *lastAction; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(GuiTester::Directions) + +#endif diff --git a/tests/auto/other/macgui/macgui.pro b/tests/auto/other/macgui/macgui.pro new file mode 100644 index 0000000000..5632450a3a --- /dev/null +++ b/tests/auto/other/macgui/macgui.pro @@ -0,0 +1,15 @@ +CONFIG += testcase +TARGET = tst_macgui +TEMPLATE = app +DEPENDPATH += . +INCLUDEPATH += . + +# Input +SOURCES += tst_macgui.cpp guitest.cpp +HEADERS += guitest.h + +QT = core-private widgets-private testlib + +requires(mac) + +CONFIG+=insignificant_test # QTBUG-20984, fails unstably diff --git a/tests/auto/other/macgui/tst_macgui.cpp b/tests/auto/other/macgui/tst_macgui.cpp new file mode 100644 index 0000000000..9ff2897aa8 --- /dev/null +++ b/tests/auto/other/macgui/tst_macgui.cpp @@ -0,0 +1,242 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include +#include +#include +#include +#include +#include +#include + +#include + +class tst_MacGui : public GuiTester +{ +Q_OBJECT +private slots: + void scrollbarPainting(); + + void dummy(); + void splashScreenModality(); + void nonModalOrder(); + + void spinBoxArrowButtons(); +}; + + +QPixmap grabWindowContents(QWidget * widget) +{ + return QPixmap::grabWindow(widget->winId()); +} + +/* + Test that vertical and horizontal mac-style scrollbars paint their + entire area. +*/ +void tst_MacGui::scrollbarPainting() +{ + ColorWidget colorWidget; + colorWidget.resize(400, 400); + + QSize scrollBarSize; + + QScrollBar verticalScrollbar(&colorWidget); + verticalScrollbar.move(10, 10); + scrollBarSize = verticalScrollbar.sizeHint(); + scrollBarSize.setHeight(200); + verticalScrollbar.resize(scrollBarSize); + + QScrollBar horizontalScrollbar(&colorWidget); + horizontalScrollbar.move(30, 10); + horizontalScrollbar.setOrientation(Qt::Horizontal); + scrollBarSize = horizontalScrollbar.sizeHint(); + scrollBarSize.setWidth(200); + horizontalScrollbar.resize(scrollBarSize); + + colorWidget.show(); + colorWidget.raise(); + QTest::qWait(100); + + QPixmap pixmap = grabWindowContents(&colorWidget); + + QVERIFY(isContent(pixmap.toImage(), verticalScrollbar.geometry(), GuiTester::Horizontal)); + QVERIFY(isContent(pixmap.toImage(), horizontalScrollbar.geometry(), GuiTester::Vertical)); +} + +// When running the auto-tests on scruffy, the first enter-the-event-loop-and-wait-for-a-click +// test that runs always times out, so we have this dummy test. +void tst_MacGui::dummy() +{ + QPixmap pix(100, 100); + QSplashScreen splash(pix); + splash.show(); + + QMessageBox *box = new QMessageBox(); + box->setText("accessible?"); + box->show(); + + // Find the "OK" button and schedule a press. + QAccessibleInterface *interface = wn.find(QAccessible::Name, "OK", box); + QVERIFY(interface); + const int delay = 1000; + clickLater(interface, Qt::LeftButton, delay); + + // Show dialog and and enter event loop. + connect(wn.getWidget(interface), SIGNAL(clicked()), SLOT(exitLoopSlot())); + const int timeout = 4; + QTestEventLoop::instance().enterLoop(timeout); +} + +/* + Test that a message box pops up in front of a QSplashScreen. +*/ +void tst_MacGui::splashScreenModality() +{ + QPixmap pix(300, 300); + QSplashScreen splash(pix); + splash.show(); + + QMessageBox box; + //box.setWindowFlags(box.windowFlags() | Qt::WindowStaysOnTopHint); + box.setText("accessible?"); + box.show(); + + // Find the "OK" button and schedule a press. + QAccessibleInterface *interface = wn.find(QAccessible::Name, "OK", &box); + QVERIFY(interface); + const int delay = 1000; + clickLater(interface, Qt::LeftButton, delay); + + // Show dialog and and enter event loop. + connect(wn.getWidget(interface), SIGNAL(clicked()), SLOT(exitLoopSlot())); + const int timeout = 4; + QTestEventLoop::instance().enterLoop(timeout); + QVERIFY(QTestEventLoop::instance().timeout() == false); +} + +class PrimaryWindowDialog : public QDialog +{ +Q_OBJECT +public: + PrimaryWindowDialog(); + QWidget *secondaryWindow; + QWidget *frontWidget; +public slots: + void showSecondaryWindow(); + void test(); +}; + +PrimaryWindowDialog::PrimaryWindowDialog() : QDialog(0) +{ + frontWidget = 0; + secondaryWindow = new ColorWidget(this); + secondaryWindow->setWindowFlags(Qt::Window); + secondaryWindow->resize(400, 400); + secondaryWindow->move(100, 100); + QTimer::singleShot(1000, this, SLOT(showSecondaryWindow())); + QTimer::singleShot(2000, this, SLOT(test())); + QTimer::singleShot(3000, this, SLOT(close())); +} + +void PrimaryWindowDialog::showSecondaryWindow() +{ + secondaryWindow->show(); +} + +void PrimaryWindowDialog::test() +{ + frontWidget = QApplication::widgetAt(secondaryWindow->mapToGlobal(QPoint(100, 100))); +} + +/* + Test that a non-modal child window of a modal dialog is shown in front + of the dialog even if the dialog becomes modal after the child window + is created. +*/ +void tst_MacGui::nonModalOrder() +{ + clearSequence(); + PrimaryWindowDialog primary; + primary.resize(400, 400); + primary.move(100, 100); + primary.exec(); + QCOMPARE(primary.frontWidget, primary.secondaryWindow); +} + +/* + Test that the QSpinBox buttons are correctly positioned with the Mac style. +*/ +void tst_MacGui::spinBoxArrowButtons() +{ + ColorWidget colorWidget; + colorWidget.resize(200, 200); + QSpinBox spinBox(&colorWidget); + QSpinBox spinBox2(&colorWidget); + spinBox2.move(0, 100); + colorWidget.show(); + QTest::qWait(100); + + // Grab an unfocused spin box. + const QImage noFocus = grabWindowContents(&colorWidget).toImage(); + + // Set focus by clicking the less button. + QAccessibleInterface *lessInterface = wn.find(QAccessible::Name, "Less", &spinBox); + QVERIFY(lessInterface); + const int delay = 500; + clickLater(lessInterface, Qt::LeftButton, delay); + const int timeout = 1; + QTestEventLoop::instance().enterLoop(timeout); + + // Grab a focused spin box. + const QImage focus = grabWindowContents(&colorWidget).toImage(); + + // Compare the arrow area of the less button to see if it moved. + const QRect lessRect = lessInterface->rect(); + const QRect lessLocalRect(colorWidget.mapFromGlobal(lessRect.topLeft()), colorWidget.mapFromGlobal(lessRect.bottomRight())); + const QRect compareRect = lessLocalRect.adjusted(5, 3, -5, -7); + QVERIFY(noFocus.copy(compareRect) == focus.copy(compareRect)); +} + +QTEST_MAIN(tst_MacGui) +#include "tst_macgui.moc" + -- cgit v1.2.3