summaryrefslogtreecommitdiffstats
path: root/tests/auto/other
diff options
context:
space:
mode:
authorJan Arve Sæther <jan-arve.saether@qt.io>2023-02-06 13:16:45 +0100
committerJan Arve Sæther <jan-arve.saether@qt.io>2023-02-28 17:53:10 +0100
commitafbfe30093d49eff0ec4c28c220d33c233b9f807 (patch)
treeaa2ff34af30b311646f7fea822c5891cf3796b2d /tests/auto/other
parent50057fec93a3acbd44080bc0c0f41d3dc1f41743 (diff)
a11y: Test and document relations better
The documentation for the RelationFlag enum was not very clear on what was the "first" and "second" object. And the fact that the AT-SPI backend (which these enum values originates from) inverses "first" and "second" makes it harder to understand what how it all fits together. So when (with this change) Qt documents 'QAccessible::Labelled' as "The returned object is labelled by the origin object" AT-SPI documents ATSPI_RELATION_LABELLED_BY as: "The origin object is labelled by the returned object" (Documentation for AT-SPI is rewritten so that it shares the same terminology) Notice that the two objects are exchanged, which means that even if they use the same 'Labelled' relation, the semantic gets 'inversed'. This is already the case today, so we cannot change it. Therefore, to be clear, the relation mapping will remain to be like this: Qt Relation | Maps to AT-SPI | Qt explanation ----------------+-------------------------------+-------------------------------------------------------------------------------- Label | ATSPI_RELATION_LABELLED_BY | The returned object is a Label for the origin object Labelled | ATSPI_RELATION_LABEL_FOR | The returned object is Labelled by the origin object Controller | ATSPI_RELATION_CONTROLLED_BY | The returned object is the Controller for the origin object Controlled | ATSPI_RELATION_CONTROLLER_FOR | The returned object is Controlled by the origin object This mapping can already be seen in qAccessibleRelationToAtSpiRelation() For the record, these future relations should then be mapped to like this: Qt Relation | Maps to AT-SPI | Qt explanation ----------------+-------------------------------+-------------------------------------------------------------------------------- Described | ATSPI_RELATION_DESCRIPTION_FOR| The returned object is described by the origin object DescriptionFor | ATSPI_RELATION_DESCRIBED_BY | The returned object provides a description for the origin object FlowsTo | ATSPI_RELATION_FLOWS_FROM | The returned object has content which flows logically to the origin object FlowsFrom | ATSPI_RELATION_FLOWS_TO | The returned object has content which flows logically from the origin object Change-Id: Ib245ec95564e4886dc6dbbb68abec2b23cd0e534 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Diffstat (limited to 'tests/auto/other')
-rw-r--r--tests/auto/other/qaccessibility/tst_qaccessibility.cpp88
1 files changed, 82 insertions, 6 deletions
diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
index 662d459af6..76d50b93e3 100644
--- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
+++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
@@ -222,6 +222,7 @@ private slots:
void accessibleName();
#if QT_CONFIG(shortcut)
void labelTest();
+ void relationTest();
void accelerators();
#endif
void bridgeTest();
@@ -3688,6 +3689,69 @@ void tst_QAccessibility::comboBoxTest()
QTestAccessibility::clearEvents();
}
+void tst_QAccessibility::relationTest()
+{
+ auto windowHolder = std::make_unique<QWidget>();
+ auto window = windowHolder.get();
+ QString text = "Hello World";
+ QLabel *label = new QLabel(text, window);
+ setFrameless(label);
+ QSpinBox *spinBox = new QSpinBox(window);
+ label->setBuddy(spinBox);
+ QProgressBar *pb = new QProgressBar(window);
+ pb->setRange(0, 99);
+ connect(spinBox, SIGNAL(valueChanged(int)), pb, SLOT(setValue(int)));
+
+ window->resize(320, 200);
+ window->show();
+
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+#if defined(Q_OS_UNIX)
+ QCoreApplication::processEvents();
+#endif
+ QTest::qWait(100);
+
+ QAccessibleInterface *acc_label = QAccessible::queryAccessibleInterface(label);
+ QVERIFY(acc_label);
+ QAccessibleInterface *acc_spinBox = QAccessible::queryAccessibleInterface(spinBox);
+ QVERIFY(acc_spinBox);
+ QAccessibleInterface *acc_pb = QAccessible::queryAccessibleInterface(pb);
+ QVERIFY(acc_pb);
+
+ typedef QPair<QAccessibleInterface*, QAccessible::Relation> RelationPair;
+ {
+ const QList<RelationPair> rels = acc_label->relations(QAccessible::Labelled);
+ QCOMPARE(rels.size(), 1);
+ const RelationPair relPair = rels.first();
+
+ // spinBox is Labelled by acc_label
+ QCOMPARE(relPair.first->object(), spinBox);
+ QCOMPARE(relPair.second, QAccessible::Labelled);
+ }
+
+ {
+ // Test multiple relations (spinBox have two)
+ const QList<RelationPair> rels = acc_spinBox->relations();
+ QCOMPARE(rels.size(), 2);
+ int visitCount = 0;
+ for (const auto &relPair : rels) {
+ if (relPair.second & QAccessible::Label) {
+ // label is the Label of spinBox
+ QCOMPARE(relPair.first->object(), label);
+ ++visitCount;
+ } else if (relPair.second & QAccessible::Controlled) {
+ // progressbar is Controlled by the spinBox
+ QCOMPARE(relPair.first->object(), pb);
+ ++visitCount;
+ }
+ }
+ QCOMPARE(visitCount, rels.size());
+ }
+
+ windowHolder.reset();
+ QTestAccessibility::clearEvents();
+}
+
#if QT_CONFIG(shortcut)
void tst_QAccessibility::labelTest()
@@ -3710,6 +3774,8 @@ void tst_QAccessibility::labelTest()
QAccessibleInterface *acc_label = QAccessible::queryAccessibleInterface(label);
QVERIFY(acc_label);
+ QAccessibleInterface *acc_lineEdit = QAccessible::queryAccessibleInterface(buddy);
+ QVERIFY(acc_lineEdit);
QCOMPARE(acc_label->text(QAccessible::Name), text);
QCOMPARE(acc_label->state().editable, false);
@@ -3719,13 +3785,23 @@ void tst_QAccessibility::labelTest()
QCOMPARE(acc_label->state().focusable, false);
QCOMPARE(acc_label->state().readOnly, true);
- QList<QPair<QAccessibleInterface *, QAccessible::Relation>> rels = acc_label->relations();
- QCOMPARE(rels.size(), 1);
- QAccessibleInterface *iface = rels.first().first;
- QAccessible::Relation rel = rels.first().second;
- QCOMPARE(rel, QAccessible::Labelled);
- QCOMPARE(iface->role(), QAccessible::EditableText);
+ typedef QPair<QAccessibleInterface*, QAccessible::Relation> RelationPair;
+ {
+ const QList<RelationPair> rels = acc_label->relations(QAccessible::Labelled);
+ QCOMPARE(rels.size(), 1);
+ const RelationPair relPair = rels.first();
+ QCOMPARE(relPair.first->object(), buddy);
+ QCOMPARE(relPair.second, QAccessible::Labelled);
+ }
+
+ {
+ const QList<RelationPair> rels = acc_lineEdit->relations(QAccessible::Label);
+ QCOMPARE(rels.size(), 1);
+ const RelationPair relPair = rels.first();
+ QCOMPARE(relPair.first->object(), label);
+ QCOMPARE(relPair.second, QAccessible::Label);
+ }
windowHolder.reset();
QTestAccessibility::clearEvents();