1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
43 #include <QtTest/QtTest>
44 #include "QtTest/qtestaccessible.h"
46 #include <QtGui/qaccessible.h>
48 #include <QtQuick/qquickview.h>
49 #include <QtQuick/qquickitem.h>
51 #include <QtDeclarative/qdeclarativeengine.h>
52 #include <QtDeclarative/qdeclarativeproperty.h>
53 #include <QtQuick/private/qquickaccessibleattached_p.h>
55 #include "../../shared/util.h"
58 typedef QSharedPointer<QAccessibleInterface> QAI;
60 #define EXPECT(cond) \
62 if (!errorAt && !(cond)) { \
64 qWarning("level: %d, middle: %d, role: %d (%s)", treelevel, middle, iface->role(), #cond); \
68 static int verifyHierarchy(QAccessibleInterface *iface)
71 static int treelevel = 0; // for error diagnostics
72 QAccessibleInterface *middleChild, *if2;
75 int middle = iface->childCount()/2 + 1;
76 if (iface->childCount() >= 2) {
77 middleChild = iface->child(middle - 1);
79 for (int i = 0; i < iface->childCount() && !errorAt; ++i) {
80 if2 = iface->child(i);
82 // navigate Ancestor...
83 QAccessibleInterface *parent = if2->parent();
84 EXPECT(iface->object() == parent->object());
89 errorAt = verifyHierarchy(if2);
101 class tst_QQuickAccessible : public QDeclarativeDataTest
105 tst_QQuickAccessible();
106 virtual ~tst_QQuickAccessible();
109 void commonTests_data();
112 void declarativeAttachedProperties();
113 void basicPropertiesTest();
115 void checkableTest();
118 tst_QQuickAccessible::tst_QQuickAccessible()
123 tst_QQuickAccessible::~tst_QQuickAccessible()
128 void tst_QQuickAccessible::commonTests_data()
130 QTest::addColumn<QString>("accessibleRoleFileName");
132 QTest::newRow("StaticText") << SRCDIR "/data/statictext.qml";
133 QTest::newRow("PushButton") << SRCDIR "/data/pushbutton.qml";
136 void tst_QQuickAccessible::commonTests()
138 QFETCH(QString, accessibleRoleFileName);
140 qDebug() << "testing" << accessibleRoleFileName;
142 QQuickView *view = new QQuickView();
143 // view->setFixedSize(240,320);
144 view->setSource(QUrl::fromLocalFile(accessibleRoleFileName));
147 QVERIFY(view->rootObject() != 0);
149 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(view);
158 QString eventName(const int ev)
161 case 0x0001: return "SoundPlayed";
162 case 0x0002: return "Alert";
163 case 0x0003: return "ForegroundChanged";
164 case 0x0004: return "MenuStart";
165 case 0x0005: return "MenuEnd";
166 case 0x0006: return "PopupMenuStart";
167 case 0x0007: return "PopupMenuEnd";
168 case 0x000C: return "ContextHelpStart";
169 case 0x000D: return "ContextHelpEnd";
170 case 0x000E: return "DragDropStart";
171 case 0x000F: return "DragDropEnd";
172 case 0x0010: return "DialogStart";
173 case 0x0011: return "DialogEnd";
174 case 0x0012: return "ScrollingStart";
175 case 0x0013: return "ScrollingEnd";
176 case 0x0018: return "MenuCommand";
177 case 0x8000: return "ObjectCreated";
178 case 0x8001: return "ObjectDestroyed";
179 case 0x8002: return "ObjectShow";
180 case 0x8003: return "ObjectHide";
181 case 0x8004: return "ObjectReorder";
182 case 0x8005: return "Focus";
183 case 0x8006: return "Selection";
184 case 0x8007: return "SelectionAdd";
185 case 0x8008: return "SelectionRemove";
186 case 0x8009: return "SelectionWithin";
187 case 0x800A: return "StateChanged";
188 case 0x800B: return "LocationChanged";
189 case 0x800C: return "NameChanged";
190 case 0x800D: return "DescriptionChanged";
191 case 0x800E: return "ValueChanged";
192 case 0x800F: return "ParentChanged";
193 case 0x80A0: return "HelpChanged";
194 case 0x80B0: return "DefaultActionChanged";
195 case 0x80C0: return "AcceleratorChanged";
196 default: return "Unknown Event";
200 void tst_QQuickAccessible::declarativeAttachedProperties()
203 QDeclarativeEngine engine;
204 QDeclarativeComponent component(&engine);
205 component.setData("import QtQuick 2.0\nItem {\n"
207 QObject *object = component.create();
208 QVERIFY(object != 0);
210 QObject *attachedObject = QQuickAccessibleAttached::attachedProperties(object);
211 QCOMPARE(attachedObject, static_cast<QObject*>(0));
218 QQuickAccessibleAttached *attachedObj = new QQuickAccessibleAttached(&parent);
222 QVariant pp = attachedObj->property("name");
223 QDeclarativeEngine engine;
224 QDeclarativeComponent component(&engine);
225 component.setData("import QtQuick 2.0\nItem {\n"
226 "Accessible.role: Accessible.Button\n"
228 QObject *object = component.create();
229 QVERIFY(object != 0);
231 QObject *attachedObject = QQuickAccessibleAttached::attachedProperties(object);
232 QVERIFY(attachedObject);
233 if (attachedObject) {
234 QVariant p = attachedObject->property("role");
235 QCOMPARE(p.isNull(), false);
236 QCOMPARE(p.toInt(), int(QAccessible::PushButton));
237 p = attachedObject->property("name");
238 QCOMPARE(p.isNull(), true);
239 p = attachedObject->property("description");
240 QCOMPARE(p.isNull(), true);
247 QDeclarativeEngine engine;
248 QDeclarativeComponent component(&engine);
249 component.setData("import QtQuick 2.0\nItem {\n"
250 "Accessible.role: Accessible.Button\n"
251 "Accessible.name: \"Donald\"\n"
252 "Accessible.description: \"Duck\"\n"
254 QObject *object = component.create();
255 QVERIFY(object != 0);
257 QObject *attachedObject = QQuickAccessibleAttached::attachedProperties(object);
258 QVERIFY(attachedObject);
259 if (attachedObject) {
260 QVariant p = attachedObject->property("role");
261 QCOMPARE(p.isNull(), false);
262 QCOMPARE(p.toInt(), int(QAccessible::PushButton));
263 p = attachedObject->property("name");
264 QCOMPARE(p.isNull(), false);
265 QCOMPARE(p.toString(), QLatin1String("Donald"));
266 p = attachedObject->property("description");
267 QCOMPARE(p.isNull(), false);
268 QCOMPARE(p.toString(), QLatin1String("Duck"));
275 void tst_QQuickAccessible::basicPropertiesTest()
277 QAI app = QAI(QAccessible::queryAccessibleInterface(qApp));
278 QCOMPARE(app->childCount(), 0);
280 QQuickView *canvas = new QQuickView();
281 canvas->setSource(testFileUrl("statictext.qml"));
283 QCOMPARE(app->childCount(), 1);
285 QAI iface = QAI(QAccessible::queryAccessibleInterface(canvas));
286 QVERIFY(iface.data());
287 QCOMPARE(iface->childCount(), 1);
289 QAI item = QAI(iface->child(0));
290 QVERIFY(item.data());
291 QCOMPARE(item->childCount(), 2);
292 QCOMPARE(item->rect().size(), QSize(400, 400));
293 QCOMPARE(item->role(), QAccessible::Pane);
294 QCOMPARE(iface->indexOfChild(item.data()), 0);
296 QAI text = QAI(item->child(0));
297 QVERIFY(text.data());
298 QCOMPARE(text->childCount(), 0);
300 QCOMPARE(text->text(QAccessible::Name), QLatin1String("Hello Accessibility"));
301 QCOMPARE(text->rect().size(), QSize(200, 50));
302 QCOMPARE(text->rect().x(), item->rect().x() + 100);
303 QCOMPARE(text->rect().y(), item->rect().y() + 20);
304 QCOMPARE(text->role(), QAccessible::StaticText);
305 QCOMPARE(item->indexOfChild(text.data()), 0);
307 QAI text2 = QAI(item->child(1));
308 QVERIFY(text2.data());
309 QCOMPARE(text2->childCount(), 0);
311 QCOMPARE(text2->text(QAccessible::Name), QLatin1String("The Hello 2 accessible text"));
312 QCOMPARE(text2->rect().size(), QSize(100, 40));
313 QCOMPARE(text2->rect().x(), item->rect().x() + 100);
314 QCOMPARE(text2->rect().y(), item->rect().y() + 40);
315 QCOMPARE(text2->role(), QAccessible::StaticText);
316 QCOMPARE(item->indexOfChild(text2.data()), 1);
318 QCOMPARE(iface->indexOfChild(text2.data()), -1);
319 QCOMPARE(text2->indexOfChild(item.data()), -1);
324 QAI topLevelChildAt(QAccessibleInterface *iface, int x, int y)
326 QAI child = QAI(iface->childAt(x, y));
331 while (childOfChild = QAI(child->childAt(x, y))) {
332 child = childOfChild;
337 void tst_QQuickAccessible::hitTest()
339 QQuickView *canvas = new QQuickView;
340 canvas->setSource(testFileUrl("hittest.qml"));
343 QAI iface = QAI(QAccessible::queryAccessibleInterface(canvas));
344 QVERIFY(iface.data());
345 QAI rootItem = QAI(iface->child(0));
346 QRect rootRect = rootItem->rect();
349 QAI itemHit(iface->childAt(rootRect.x() + 200, rootRect.y() + 50));
351 QCOMPARE(rootRect, itemHit->rect());
354 QAI rect1(rootItem->child(1));
355 QRect rect1Rect = rect1->rect();
356 itemHit = QAI(rootItem->childAt(rect1Rect.x() + 10, rect1Rect.y() + 10));
358 QCOMPARE(rect1Rect, itemHit->rect());
359 QCOMPARE(itemHit->text(QAccessible::Name), QLatin1String("rect1"));
361 // should also work from top level (app)
362 QAI app(QAccessible::queryAccessibleInterface(qApp));
363 QAI itemHit2(topLevelChildAt(app.data(), rect1Rect.x() + 10, rect1Rect.y() + 10));
365 QCOMPARE(itemHit2->rect(), rect1Rect);
366 QCOMPARE(itemHit2->text(QAccessible::Name), QLatin1String("rect1"));
369 QAI rect2(rootItem->child(2));
370 QAI rect20(rect2->child(1));
371 QAI rect201(rect20->child(2));
374 QRect rect201Rect = rect201->rect();
375 itemHit = QAI(iface->childAt(rect201Rect.x() + 20, rect201Rect.y() + 20));
377 QCOMPARE(itemHit->rect(), rect201Rect);
378 QCOMPARE(itemHit->text(QAccessible::Name), QLatin1String("rect201"));
383 void tst_QQuickAccessible::checkableTest()
385 QQuickView *canvas = new QQuickView();
386 canvas->setSource(testFileUrl("checkbuttons.qml"));
389 QAI iface = QAI(QAccessible::queryAccessibleInterface(canvas));
390 QVERIFY(iface.data());
391 QAI root = QAI(iface->child(0));
393 QAI button1 = QAI(root->child(0));
394 QCOMPARE(button1->role(), QAccessible::Button);
395 QVERIFY(!(button1->state().checked));
396 QAI button2 = QAI(root->child(1));
397 QVERIFY(!(button2->state().checked));
398 QAI button3 = QAI(root->child(2));
399 QVERIFY(button3->state().checked);
401 QAI checkBox1 = QAI(root->child(3));
402 QCOMPARE(checkBox1->role(), QAccessible::CheckBox);
403 QVERIFY((checkBox1->state().checked));
404 QAI checkBox2 = QAI(root->child(4));
405 QVERIFY(!(checkBox2->state().checked));
408 QTEST_MAIN(tst_QQuickAccessible)
410 #include "tst_qquickaccessible.moc"