Bring back Mac dependent code in QBoxLayout, QGridLayout
[profile/ivi/qtbase.git] / tests / auto / other / qaccessibility / tst_qaccessibility.cpp
index 68ad38d..9d61470 100644 (file)
@@ -1,38 +1,38 @@
 /****************************************************************************
 **
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
 **
 ** This file is part of the test suite of the Qt Toolkit.
 **
 ** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
 ** 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.
+** Alternatively, 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
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
-**
-**
-**
-**
+** 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.
 **
 **
 ** $QT_END_LICENSE$
 # include <oleacc.h>
 # include <servprov.h>
 # include <winuser.h>
-# ifndef Q_CC_MINGW
+# ifdef QT_SUPPORTS_IACCESSIBLE2
 #  include <Accessible2.h>
 #  include <AccessibleAction.h>
 #  include <AccessibleComponent.h>
+#  include <AccessibleEditableText.h>
+#  include <AccessibleText.h>
 # endif
 #endif
 #include <QtTest/QtTest>
 #include <QtGui>
 #include <QtWidgets>
 #include <math.h>
+#include <qpa/qplatformnativeinterface.h>
 
 #if defined(Q_OS_WIN) && defined(interface)
 #   undef interface
@@ -383,7 +386,8 @@ void tst_QAccessibility::eventTest()
 
     button->show();
     QAccessibleEvent showEvent(button, QAccessible::ObjectShow);
-    QVERIFY_EVENT(&showEvent);
+    // some platforms might send other events first, (such as state change event active=1)
+    QVERIFY(QTestAccessibility::containsEvent(&showEvent));
     button->setFocus(Qt::MouseFocusReason);
     QTestAccessibility::clearEvents();
     QTest::mouseClick(button, Qt::LeftButton, 0);
@@ -397,7 +401,8 @@ void tst_QAccessibility::eventTest()
 
     button->hide();
     QAccessibleEvent hideEvent(button, QAccessible::ObjectHide);
-    QVERIFY_EVENT(&hideEvent);
+    // some platforms might send other events first, (such as state change event active=1)
+    QVERIFY(QTestAccessibility::containsEvent(&hideEvent));
 
     delete button;
 }
@@ -751,7 +756,7 @@ void tst_QAccessibility::actionTest()
     {
     QPushButton *button = new QPushButton;
     button->show();
-    QTest::qWaitForWindowShown(button);
+    QVERIFY(QTest::qWaitForWindowExposed(button));
     button->clearFocus();
     QCOMPARE(button->hasFocus(), false);
     QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(button);
@@ -793,22 +798,25 @@ void tst_QAccessibility::mainWindowTest()
     QMainWindow *mw = new QMainWindow;
     mw->resize(300, 200);
     mw->show(); // triggers layout
+    qApp->setActiveWindow(mw);
 
     QLatin1String name = QLatin1String("I am the main window");
     mw->setWindowTitle(name);
-    QTest::qWaitForWindowShown(mw);
+    QVERIFY(QTest::qWaitForWindowActive(mw));
+
+    // The order of events is not really that important.
     QAccessibleEvent show(mw, QAccessible::ObjectShow);
-    QVERIFY_EVENT(&show);
+    QVERIFY(QTestAccessibility::containsEvent(&show));
+    QAccessible::State activeState;
+    activeState.active = true;
+    QAccessibleStateChangeEvent active(mw, activeState);
+    QVERIFY(QTestAccessibility::containsEvent(&active));
 
     QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(mw);
     QCOMPARE(iface->text(QAccessible::Name), name);
     QCOMPARE(iface->role(), QAccessible::Window);
     QVERIFY(iface->state().active);
 
-    QAccessible::State activeState;
-    activeState.active = true;
-    QAccessibleStateChangeEvent active(mw, activeState);
-    QVERIFY_EVENT(&active);
 
     delete iface;
     delete mw;
@@ -862,17 +870,6 @@ public Q_SLOTS:
     }
 };
 
-static QAccessibleInterface *relatedInterface(QAccessibleInterface *iface, QAccessible::RelationFlag flag)
-{
-    typedef QPair<QAccessibleInterface *, QAccessible::Relation> RelationPair;
-    QVector<RelationPair> rels = iface->relations(flag);
-
-    for (int i = 1; i < rels.count(); ++i)
-        delete rels.at(i).first;
-
-    return rels.value(0).first;
-}
-
 void tst_QAccessibility::buttonTest()
 {
     QWidget window;
@@ -906,30 +903,6 @@ void tst_QAccessibility::buttonTest()
     toggletool.setText("Toggle");
     toggletool.setMinimumSize(20,20);
 
-    // test Controller/Controlled relations
-    {
-    QCheckBox toggler("Toggle me!", &window);
-    bool ok = connect(&pushButton, SIGNAL(clicked()), &toggler, SLOT(toggle()));
-    QCOMPARE(ok, true);
-    QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&toggler);
-    QVERIFY(iface);
-    QCOMPARE(iface->role(), QAccessible::CheckBox);
-    QAccessibleInterface *buttonIFace = relatedInterface(iface, QAccessible::Controller);
-    QVERIFY(buttonIFace);
-    QCOMPARE(buttonIFace->role(), QAccessible::Button);
-    QCOMPARE(buttonIFace->object(), &pushButton);
-    delete buttonIFace;
-    delete iface;
-
-    buttonIFace = QAccessible::queryAccessibleInterface(&pushButton);
-    QVERIFY(buttonIFace);
-    QCOMPARE(buttonIFace->role(), QAccessible::Button);
-    iface = relatedInterface(buttonIFace, QAccessible::Controlled);
-    QVERIFY(iface);
-    QCOMPARE(iface->object(), &toggler);
-
-    }
-
     // test push button
     QAccessibleInterface* interface = QAccessible::queryAccessibleInterface(&pushButton);
     QAccessibleActionInterface* actionInterface = interface->actionInterface();
@@ -949,14 +922,14 @@ void tst_QAccessibility::buttonTest()
     interface = QAccessible::queryAccessibleInterface(&toggleButton);
     actionInterface = interface->actionInterface();
     QCOMPARE(interface->role(), QAccessible::CheckBox);
-    QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::checkAction() << QAccessibleActionInterface::setFocusAction());
-    QCOMPARE(actionInterface->localizedActionDescription(QAccessibleActionInterface::checkAction()), QString("Checks the checkbox"));
+    QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::toggleAction() << QAccessibleActionInterface::setFocusAction());
+    QCOMPARE(actionInterface->localizedActionDescription(QAccessibleActionInterface::toggleAction()), QString("Toggles the state"));
     QVERIFY(!toggleButton.isChecked());
     QVERIFY(!interface->state().checked);
-    actionInterface->doAction(QAccessibleActionInterface::checkAction());
+    actionInterface->doAction(QAccessibleActionInterface::toggleAction());
     QTest::qWait(500);
     QVERIFY(toggleButton.isChecked());
-    QCOMPARE(actionInterface->actionNames().at(0), QAccessibleActionInterface::uncheckAction());
+    QCOMPARE(actionInterface->actionNames().at(0), QAccessibleActionInterface::toggleAction());
     QVERIFY(interface->state().checked);
     delete interface;
 
@@ -987,12 +960,12 @@ void tst_QAccessibility::buttonTest()
     interface = QAccessible::queryAccessibleInterface(&checkBox);
     actionInterface = interface->actionInterface();
     QCOMPARE(interface->role(), QAccessible::CheckBox);
-    QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::checkAction() << QAccessibleActionInterface::setFocusAction());
+    QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::toggleAction() << QAccessibleActionInterface::setFocusAction());
     QVERIFY(!interface->state().checked);
-    actionInterface->doAction(QAccessibleActionInterface::checkAction());
+    actionInterface->doAction(QAccessibleActionInterface::toggleAction());
 
     QTest::qWait(500);
-    QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::uncheckAction() << QAccessibleActionInterface::setFocusAction());
+    QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::toggleAction() << QAccessibleActionInterface::setFocusAction());
     QVERIFY(interface->state().checked);
     QVERIFY(checkBox.isChecked());
     QAccessible::State st;
@@ -1009,11 +982,11 @@ void tst_QAccessibility::buttonTest()
     interface = QAccessible::queryAccessibleInterface(&radio);
     actionInterface = interface->actionInterface();
     QCOMPARE(interface->role(), QAccessible::RadioButton);
-    QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::checkAction() << QAccessibleActionInterface::setFocusAction());
+    QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::toggleAction() << QAccessibleActionInterface::setFocusAction());
     QVERIFY(!interface->state().checked);
-    actionInterface->doAction(QAccessibleActionInterface::checkAction());
+    actionInterface->doAction(QAccessibleActionInterface::toggleAction());
     QTest::qWait(500);
-    QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::checkAction() << QAccessibleActionInterface::setFocusAction());
+    QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::toggleAction() << QAccessibleActionInterface::setFocusAction());
     QVERIFY(interface->state().checked);
     QVERIFY(radio.isChecked());
     QAccessible::State st;
@@ -1505,6 +1478,8 @@ void tst_QAccessibility::spinBoxTest()
     QVERIFY(interface);
     QCOMPARE(interface->role(), QAccessible::SpinBox);
 
+    QVERIFY(QTest::qWaitForWindowExposed(spinBox));
+
     const QRect widgetRect = spinBox->geometry();
     const QRect accessibleRect = interface->rect();
     QCOMPARE(accessibleRect, widgetRect);
@@ -1543,6 +1518,8 @@ void tst_QAccessibility::doubleSpinBoxTest()
     QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(doubleSpinBox);
     QVERIFY(interface);
 
+    QVERIFY(QTest::qWaitForWindowExposed(doubleSpinBox));
+
     const QRect widgetRect = doubleSpinBox->geometry();
     const QRect accessibleRect = interface->rect();
     QCOMPARE(accessibleRect, widgetRect);
@@ -1560,53 +1537,89 @@ void tst_QAccessibility::doubleSpinBoxTest()
     QTestAccessibility::clearEvents();
 }
 
-void tst_QAccessibility::textEditTest()
+static QRect characterRect(const QTextEdit &edit, int offset)
 {
-    {
-    QTextEdit edit;
-    int startOffset;
-    int endOffset;
-    QString text = "hello world\nhow are you today?\n";
-    edit.setText(text);
-    edit.show();
-
-    QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&edit);
-    QCOMPARE(iface->text(QAccessible::Value), text);
-    QCOMPARE(iface->textInterface()->textAtOffset(8, QAccessible2::WordBoundary, &startOffset, &endOffset), QString("world"));
-    QCOMPARE(startOffset, 6);
-    QCOMPARE(endOffset, 11);
-    QCOMPARE(iface->textInterface()->textAtOffset(14, QAccessible2::LineBoundary, &startOffset, &endOffset), QString("how are you today?"));
-    QCOMPARE(startOffset, 12);
-    QCOMPARE(endOffset, 30);
-    QCOMPARE(iface->textInterface()->characterCount(), 31);
+    QTextBlock block = edit.document()->findBlock(offset);
+    QTextLayout *layout = block.layout();
+    QPointF layoutPosition = layout->position();
+    int relativeOffset = offset - block.position();
+    QTextLine line = layout->lineForTextPosition(relativeOffset);
     QFontMetrics fm(edit.font());
-    QCOMPARE(iface->textInterface()->characterRect(0).size(), QSize(fm.width("h"), fm.height()));
-    QCOMPARE(iface->textInterface()->characterRect(5).size(), QSize(fm.width(" "), fm.height()));
-    QCOMPARE(iface->textInterface()->characterRect(6).size(), QSize(fm.width("w"), fm.height()));
+    QChar ch = edit.document()->characterAt(offset);
+    int w = fm.width(ch);
+    int h = fm.height();
 
-    iface->editableTextInterface()->copyText(6, 11);
-    QCOMPARE(QApplication::clipboard()->text(), QLatin1String("world"));
-    iface->editableTextInterface()->cutText(12, 16);
-    QCOMPARE(QApplication::clipboard()->text(), QLatin1String("how "));
-    QCOMPARE(iface->textInterface()->text(12, 15), QLatin1String("are"));
+    qreal x = line.cursorToX(relativeOffset);
+    QRect r(layoutPosition.x() + x, layoutPosition.y() + line.y(), w, h);
+    r.moveTo(edit.viewport()->mapToGlobal(r.topLeft()));
 
-    QTestAccessibility::clearEvents();
+    return r;
+}
 
-    // select text
-    QTextCursor c = edit.textCursor();
-    c.setPosition(2);
-    c.setPosition(4, QTextCursor::KeepAnchor);
-    edit.setTextCursor(c);
-    QAccessibleTextSelectionEvent sel(&edit, 2, 4);
-    QVERIFY_EVENT(&sel);
+void tst_QAccessibility::textEditTest()
+{
+    for (int pass = 0; pass < 2; ++pass) {
+        {
+        QTextEdit edit;
+        int startOffset;
+        int endOffset;
+        // create two blocks of text. The first block has two lines.
+        QString text = "<p>hello world.<br/>How are you today?</p><p>I'm fine, thanks</p>";
+        edit.setHtml(text);
+        if (pass == 1) {
+            QFont font("Helvetica");
+            font.setPointSizeF(12.5);
+            font.setWordSpacing(1.1);
+            edit.setFont(font);
+        }
 
-    edit.selectAll();
-    int end = edit.textCursor().position();
-    sel.setCursorPosition(end);
-    sel.setSelection(0, end);
-    QVERIFY_EVENT(&sel);
+        edit.show();
+        QTest::qWaitForWindowShown(&edit);
+        QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&edit);
+        QCOMPARE(iface->text(QAccessible::Value), edit.toPlainText());
+        QCOMPARE(iface->textInterface()->textAtOffset(8, QAccessible2::WordBoundary, &startOffset, &endOffset), QString("world"));
+        QCOMPARE(startOffset, 6);
+        QCOMPARE(endOffset, 11);
+        QCOMPARE(iface->textInterface()->textAtOffset(15, QAccessible2::LineBoundary, &startOffset, &endOffset), QString("How are you today?"));
+        QCOMPARE(startOffset, 13);
+        QCOMPARE(endOffset, 31);
+        QCOMPARE(iface->textInterface()->characterCount(), 48);
+        QFontMetrics fm(edit.font());
+        QCOMPARE(iface->textInterface()->characterRect(0).size(), QSize(fm.width("h"), fm.height()));
+        QCOMPARE(iface->textInterface()->characterRect(5).size(), QSize(fm.width(" "), fm.height()));
+        QCOMPARE(iface->textInterface()->characterRect(6).size(), QSize(fm.width("w"), fm.height()));
+
+        int offset = 10;
+        QCOMPARE(iface->textInterface()->text(offset, offset + 1), QStringLiteral("d"));
+        QCOMPARE(iface->textInterface()->characterRect(offset), characterRect(edit, offset));
+        offset = 13;
+        QCOMPARE(iface->textInterface()->text(offset, offset + 1), QStringLiteral("H"));
+        QCOMPARE(iface->textInterface()->characterRect(offset), characterRect(edit, offset));
+        offset = 21;
+        QCOMPARE(iface->textInterface()->text(offset, offset + 1), QStringLiteral("y"));
+        QCOMPARE(iface->textInterface()->characterRect(offset), characterRect(edit, offset));
+        offset = 32;
+        QCOMPARE(iface->textInterface()->text(offset, offset + 1), QStringLiteral("I"));
+        QCOMPARE(iface->textInterface()->characterRect(offset), characterRect(edit, offset));
+
+        QTestAccessibility::clearEvents();
+
+        // select text
+        QTextCursor c = edit.textCursor();
+        c.setPosition(2);
+        c.setPosition(4, QTextCursor::KeepAnchor);
+        edit.setTextCursor(c);
+        QAccessibleTextSelectionEvent sel(&edit, 2, 4);
+        QVERIFY_EVENT(&sel);
+
+        edit.selectAll();
+        int end = edit.textCursor().position();
+        sel.setCursorPosition(end);
+        sel.setSelection(0, end);
+        QVERIFY_EVENT(&sel);
+        }
+        QTestAccessibility::clearEvents();
     }
-    QTestAccessibility::clearEvents();
 }
 
 void tst_QAccessibility::textBrowserTest()
@@ -1661,14 +1674,13 @@ void tst_QAccessibility::mdiSubWindowTest()
     QMdiArea mdiArea;
     mdiArea.show();
     qApp->setActiveWindow(&mdiArea);
-#if defined(Q_OS_UNIX)
-    QCoreApplication::processEvents();
-    QTest::qWait(150);
-#endif
+    QVERIFY(QTest::qWaitForWindowActive(&mdiArea));
+
 
     const int subWindowCount =  5;
     for (int i = 0; i < subWindowCount; ++i) {
         QMdiSubWindow *window = mdiArea.addSubWindow(new QPushButton("QAccessibilityTest"));
+        window->setAttribute(Qt::WA_LayoutUsesWidgetRect);
         window->show();
         // Parts of this test requires that the sub windows are placed next
         // to each other. In order to achieve that QMdiArea must have
@@ -1748,7 +1760,7 @@ void tst_QAccessibility::mdiSubWindowTest()
     const QPoint globalWidgetPos = QPoint(globalPos.x() + widgetGeometry.x(),
                                           globalPos.y() + widgetGeometry.y());
 #ifdef Q_OS_MAC
-    QEXPECT_FAIL("", "QTBUG-22812", Abort);
+    QSKIP("QTBUG-22812");
 #endif
     QCOMPARE(childRect(interface), QRect(globalWidgetPos, widgetGeometry.size()));
 
@@ -1874,6 +1886,7 @@ void tst_QAccessibility::lineEditTest()
     QCOMPARE(textIface->textAtOffset(8, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1(" "));
     QCOMPARE(textIface->textAtOffset(25, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1("advice"));
     QCOMPARE(textIface->textAtOffset(92, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1("oneself"));
+    QCOMPARE(textIface->textAtOffset(101, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1(". --"));
 
     QCOMPARE(textIface->textBeforeOffset(5, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1(" "));
     QCOMPARE(textIface->textAfterOffset(5, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1(" "));
@@ -2045,8 +2058,8 @@ void tst_QAccessibility::groupBoxTest()
     QAccessible::State state = iface->state();
     QVERIFY(state.checkable);
     QVERIFY(!state.checked);
-    QVERIFY(actionIface->actionNames().contains(QAccessibleActionInterface::checkAction()));
-    actionIface->doAction(QAccessibleActionInterface::checkAction());
+    QVERIFY(actionIface->actionNames().contains(QAccessibleActionInterface::toggleAction()));
+    actionIface->doAction(QAccessibleActionInterface::toggleAction());
     QVERIFY(groupBox->isChecked());
     state = iface->state();
     QVERIFY(state.checked);
@@ -2179,6 +2192,8 @@ void tst_QAccessibility::dialTest()
     QVERIFY(interface);
     QCOMPARE(interface->childCount(), 0);
 
+    QVERIFY(QTest::qWaitForWindowExposed(&dial));
+
     QCOMPARE(interface->text(QAccessible::Value), QString::number(dial.value()));
     QCOMPARE(interface->rect(), dial.geometry());
 
@@ -2808,7 +2823,11 @@ void tst_QAccessibility::comboBoxTest()
     { // not editable combobox
     QComboBox combo;
     combo.addItems(QStringList() << "one" << "two" << "three");
+    // Fully decorated windows have a minimum width of 160 on Windows.
+    combo.setMinimumWidth(200);
     combo.show();
+    QVERIFY(QTest::qWaitForWindowShown(&combo));
+
     QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&combo);
     QCOMPARE(verifyHierarchy(iface), 0);
 
@@ -2833,13 +2852,14 @@ void tst_QAccessibility::comboBoxTest()
     QVERIFY(iface->actionInterface());
     QCOMPARE(iface->actionInterface()->actionNames(), QStringList() << QAccessibleActionInterface::showMenuAction());
     iface->actionInterface()->doAction(QAccessibleActionInterface::showMenuAction());
-    QVERIFY(combo.view()->isVisible());
+    QTRY_VERIFY(combo.view()->isVisible());
 
     delete iface;
     }
 
     { // editable combobox
     QComboBox editableCombo;
+    editableCombo.setMinimumWidth(200);
     editableCombo.show();
     editableCombo.setEditable(true);
     editableCombo.addItems(QStringList() << "foo" << "bar" << "baz");
@@ -2946,6 +2966,28 @@ void tst_QAccessibility::accelerators()
     QTestAccessibility::clearEvents();
 }
 
+#ifdef QT_SUPPORTS_IACCESSIBLE2
+static IUnknown *queryIA2(IAccessible *acc, const IID &iid)
+{
+    IUnknown *resultInterface = 0;
+    IServiceProvider *pService = 0;
+    HRESULT hr = acc->QueryInterface(IID_IServiceProvider, (void **)&pService);
+    if (SUCCEEDED(hr)) {
+        IAccessible2 *pIA2 = 0;
+        hr = pService->QueryService(IID_IAccessible, IID_IAccessible2, (void**)&pIA2);
+        if (SUCCEEDED(hr) && pIA2) {
+            // The control supports IAccessible2.
+            // pIA2 is the reference to the accessible object's IAccessible2 interface.
+            hr = pIA2->QueryInterface(iid, (void**)&resultInterface);
+            pIA2->Release();
+        }
+        // The control supports IAccessible2.
+        pService->Release();
+    }
+    return resultInterface;
+}
+#endif
+
 void tst_QAccessibility::bridgeTest()
 {
     // For now this is a simple test to see if the bridge is working at all.
@@ -2955,27 +2997,31 @@ void tst_QAccessibility::bridgeTest()
     QWidget *window = new QWidget;
     QVBoxLayout *lay = new QVBoxLayout(window);
     QPushButton *button = new QPushButton(tr("Push me"), window);
-    QLineEdit *le = new QLineEdit(window);
+    QTextEdit *te = new QTextEdit(window);
+    te->setText(QLatin1String("hello world\nhow are you today?\n"));
     lay->addWidget(button);
-    lay->addWidget(le);
+    lay->addWidget(te);
 
     window->show();
-    QTest::qWaitForWindowShown(window);
+    QVERIFY(QTest::qWaitForWindowExposed(window));
+
 
+    /**************************************************
+     *   QPushButton
+     **************************************************/
     QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(button);
     QPoint buttonPos = button->mapToGlobal(QPoint(0,0));
     QRect buttonRect = iface->rect();
     QCOMPARE(buttonRect.topLeft(), buttonPos);
 
-
     // All set, now test the bridge.
     POINT pt;
     pt.x = buttonRect.center().x();
     pt.y = buttonRect.center().y();
-    IAccessible *iacc;
+    IAccessible *iaccButton;
 
     VARIANT varChild;
-    HRESULT hr = ::AccessibleObjectFromPoint(pt, &iacc, &varChild);
+    HRESULT hr = ::AccessibleObjectFromPoint(pt, &iaccButton, &varChild);
     QVERIFY(SUCCEEDED(hr));
     VARIANT varSELF;
     varSELF.vt = VT_I4;
@@ -2983,7 +3029,7 @@ void tst_QAccessibility::bridgeTest()
 
     // **** Test get_accRole ****
     VARIANT varRole;
-    hr = iacc->get_accRole(varSELF, &varRole);
+    hr = iaccButton->get_accRole(varSELF, &varRole);
     QVERIFY(SUCCEEDED(hr));
 
     QCOMPARE(varRole.vt, (VARTYPE)VT_I4);
@@ -2991,52 +3037,106 @@ void tst_QAccessibility::bridgeTest()
 
     // **** Test accLocation ****
     long x, y, w, h;
-    hr = iacc->accLocation(&x, &y, &w, &h, varSELF);
+    hr = iaccButton->accLocation(&x, &y, &w, &h, varSELF);
     QCOMPARE(buttonRect, QRect(x, y, w, h));
 
-#ifndef Q_CC_MINGW
+#ifdef QT_SUPPORTS_IACCESSIBLE2
     // Test IAccessible2 part of bridge
-    IServiceProvider *pService = 0;
-    hr = iacc->QueryInterface(IID_IServiceProvider, (void **)&pService);
-    if (SUCCEEDED(hr)) {
-        IAccessible2 *pIA2 = 0;
-        hr = pService->QueryService(IID_IAccessible, IID_IAccessible2, (void**)&pIA2);
-        if (SUCCEEDED(hr) && pIA2) {
-            // The control supports IAccessible2.
-            // pIA2 is the reference to the accessible object's IAccessible2 interface.
+    if (IAccessible2 *ia2Button = (IAccessible2*)queryIA2(iaccButton, IID_IAccessible2)) {
+        // The control supports IAccessible2.
+        // ia2Button is the reference to the accessible object's IAccessible2 interface.
+
+        /***** Test IAccessibleComponent *****/
+        IAccessibleComponent *ia2Component = 0;
+        hr = ia2Button->QueryInterface(IID_IAccessibleComponent, (void**)&ia2Component);
+        QVERIFY(SUCCEEDED(hr));
+        long x, y;
+        hr = ia2Component->get_locationInParent(&x, &y);
+        QVERIFY(SUCCEEDED(hr));
+        QCOMPARE(button->pos(), QPoint(x, y));
+        ia2Component->Release();
+
+        /***** Test IAccessibleAction *****/
+        IAccessibleAction *ia2Action = 0;
+        hr = ia2Button->QueryInterface(IID_IAccessibleAction, (void**)&ia2Action);
+        QVERIFY(SUCCEEDED(hr));
+        QVERIFY(ia2Action);
+        long nActions;
+        ia2Action->nActions(&nActions);
+        QVERIFY(nActions >= 1); // "Press" and "SetFocus"
+        BSTR actionName;
+        ia2Action->get_name(0, &actionName);
+        QString name((QChar*)actionName);
+        QCOMPARE(name, QAccessibleActionInterface::pressAction());
+        ia2Action->Release();
+
+
+        // Done testing
+        ia2Button->Release();
+    }
+#endif
+    iaccButton->Release();
 
-            /***** Test IAccessibleComponent *****/
-            IAccessibleComponent *ia2Component = 0;
-            hr = pIA2->QueryInterface(IID_IAccessibleComponent, (void**)&ia2Component);
-            QVERIFY(SUCCEEDED(hr));
-            long x, y;
-            hr = ia2Component->get_locationInParent(&x, &y);
-            QVERIFY(SUCCEEDED(hr));
-            QCOMPARE(button->pos(), QPoint(x, y));
-            ia2Component->Release();
-
-            /***** Test IAccessibleAction *****/
-            IAccessibleAction *ia2Action = 0;
-            hr = pIA2->QueryInterface(IID_IAccessibleAction, (void**)&ia2Action);
-            QVERIFY(SUCCEEDED(hr));
-            QVERIFY(ia2Action);
-            long nActions;
-            ia2Action->nActions(&nActions);
-            QVERIFY(nActions >= 1); // "Press" and "SetFocus"
-            BSTR actionName;
-            ia2Action->get_name(0, &actionName);
-            QString name((QChar*)actionName);
-            QCOMPARE(name, QAccessibleActionInterface::pressAction());
-            ia2Action->Release();
-
-            // Done testing
-            pIA2->Release();
-        }
-        pService->Release();
+    /**************************************************
+     *   QWidget
+     **************************************************/
+    QWindow *windowHandle = window->windowHandle();
+    QPlatformNativeInterface *platform = QGuiApplication::platformNativeInterface();
+    HWND hWnd = (HWND)platform->nativeResourceForWindow("handle", windowHandle);
+
+    IAccessible *iaccWindow;
+    hr = ::AccessibleObjectFromWindow(hWnd, OBJID_CLIENT, IID_IAccessible, (void**)&iaccWindow);
+    QVERIFY(SUCCEEDED(hr));
+    hr = iaccWindow->get_accRole(varSELF, &varRole);
+    QVERIFY(SUCCEEDED(hr));
+
+    QCOMPARE(varRole.vt, (VARTYPE)VT_I4);
+    QCOMPARE(varRole.lVal, (LONG)ROLE_SYSTEM_CLIENT);
+
+    long nChildren;
+    hr = iaccWindow->get_accChildCount(&nChildren);
+    QVERIFY(SUCCEEDED(hr));
+    QCOMPARE(nChildren, (long)2);
+
+    /**************************************************
+     *   QTextEdit
+     **************************************************/
+    // Get the second child (the accessible interface for the text edit)
+    varChild.vt = VT_I4;
+    varChild.lVal = 2;
+    QVERIFY(iaccWindow);
+    IAccessible *iaccTextEdit;
+    hr = iaccWindow->get_accChild(varChild, (IDispatch**)&iaccTextEdit);
+    QVERIFY(SUCCEEDED(hr));
+    QVERIFY(iaccTextEdit);
+    hr = iaccTextEdit->get_accRole(varSELF, &varRole);
+    QVERIFY(SUCCEEDED(hr));
+
+    QCOMPARE(varRole.vt, (VARTYPE)VT_I4);
+    QCOMPARE(varRole.lVal, (LONG)ROLE_SYSTEM_TEXT);
+
+
+
+#ifdef QT_SUPPORTS_IACCESSIBLE2
+    if (IAccessibleEditableText *ia2TextEdit = (IAccessibleEditableText*)queryIA2(iaccTextEdit, IID_IAccessibleEditableText)) {
+        ia2TextEdit->copyText(6, 11);
+        QCOMPARE(QApplication::clipboard()->text(), QLatin1String("world"));
+        ia2TextEdit->cutText(12, 16);
+        QCOMPARE(QApplication::clipboard()->text(), QLatin1String("how "));
+        ia2TextEdit->Release();
+    }
+    if (IAccessibleText *ia2Text = (IAccessibleText*)queryIA2(iaccTextEdit, IID_IAccessibleText)) {
+        BSTR txt;
+        hr = ia2Text->get_text(12, 15, &txt);
+        QVERIFY(SUCCEEDED(hr));
+        QCOMPARE(QString((QChar*)txt), QLatin1String("are"));
+        ia2Text->Release();
     }
 #endif
-    iacc->Release();
+    iaccTextEdit->Release();
+
 
+    iaccWindow->Release();
     QTestAccessibility::clearEvents();
 #endif
 }