2011-04-27 10:05:43 +00:00
/****************************************************************************
* *
* * 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
2011-05-24 09:34:08 +00:00
* * 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.
2011-04-27 10:05:43 +00:00
* *
* * In addition , as a special exception , Nokia gives you certain additional
2011-05-24 09:34:08 +00:00
* * rights . These rights are described in the Nokia Qt LGPL Exception
2011-04-27 10:05:43 +00:00
* * version 1.1 , included in the file LGPL_EXCEPTION . txt in this package .
* *
2011-05-24 09:34:08 +00:00
* * 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 .
2011-04-27 10:05:43 +00:00
* *
* *
* *
* *
* *
* * $ QT_END_LICENSE $
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include <QtTest/QtTest>
# if defined(Q_WS_MAC) && !defined (QT_MAC_USE_COCOA)
# include <private/qt_mac_p.h>
# undef verify // yes, lets reserve the word "verify"
# include <QApplication>
# include <QDebug>
# include <QTimer>
# include <QString>
# include <QFile>
# include <QVariant>
# include <QPushButton>
# include <QToolBar>
# include <QSlider>
# include <QListWidget>
# include <QTableWidget>
# include <QScrollArea>
# include <QLabel>
# include <QScrollBar>
# include <QTextEdit>
# include <QAccessibleInterface>
# include <QAccessible>
# include <QPluginLoader>
# include <private/qaccessible_mac_p.h>
# include <quiloader.h>
# include <sys/types.h> // for getpid()
# include <unistd.h>
Q_DECLARE_METATYPE ( AXUIElementRef ) ;
typedef QCFType < CFArrayRef > QCFArrayRef ;
class tst_qaccessibility_mac : public QObject
{
Q_OBJECT
public slots :
void printInfo ( ) ;
void testForm ( ) ;
void testButtons ( ) ;
void testLineEdit ( ) ;
void testLabel ( ) ;
void testGroups ( ) ;
void testTabWidget ( ) ;
void testTabBar ( ) ;
void testComboBox ( ) ;
void testDeleteWidget ( ) ;
void testDeleteWidgets ( ) ;
void testMultipleWindows ( ) ;
void testHiddenWidgets ( ) ;
void testActions ( ) ;
void testChangeState ( ) ;
void testSlider ( ) ;
void testScrollArea ( ) ;
void testListView ( ) ;
void testTableView ( ) ;
void testScrollBar ( ) ;
void testSplitter ( ) ;
void testTextEdit ( ) ;
void testItemViewsWithoutModel ( ) ;
private slots :
void testQAElement ( ) ;
void testQAInterface ( ) ;
// ui tests load an .ui file.
void uitests_data ( ) ;
void uitests ( ) ;
void tests_data ( ) ;
void tests ( ) ;
private :
void runTest ( const QString & testSlot ) ;
} ;
/*
VERIFYs that there is no error and prints an error message if there is .
*/
void testError ( AXError error , const QString & text )
{
if ( error )
qDebug ( ) < < " Error " < < error < < text ;
QVERIFY ( error = = 0 ) ;
}
/*
Prints an CFArray holding CFStrings .
*/
void printCFStringArray ( CFArrayRef array , const QString & title )
{
const int numElements = CFArrayGetCount ( array ) ;
qDebug ( ) < < " num " < < title < < " " < < numElements ;
for ( int i = 0 ; i < numElements ; + + i ) {
CFStringRef str = ( CFStringRef ) CFArrayGetValueAtIndex ( array , i ) ;
qDebug ( ) < < QCFString : : toQString ( str ) ;
}
}
QStringList toQStringList ( const CFArrayRef array )
{
const int numElements = CFArrayGetCount ( array ) ;
QStringList qtStrings ;
for ( int i = 0 ; i < numElements ; + + i ) {
CFStringRef str = ( CFStringRef ) CFArrayGetValueAtIndex ( array , i ) ;
qtStrings . append ( QCFString : : toQString ( str ) ) ;
}
return qtStrings ;
}
QVariant AXValueToQVariant ( AXValueRef value )
{
QVariant var ;
const AXValueType type = AXValueGetType ( value ) ;
switch ( type ) {
case kAXValueCGPointType : {
CGPoint point ;
if ( AXValueGetValue ( value , type , & point ) )
var = QPointF ( point . x , point . y ) ;
} break ;
case kAXValueCGSizeType : {
CGSize size ;
if ( AXValueGetValue ( value , type , & size ) )
var = QSizeF ( size . width , size . height ) ;
} break ;
case kAXValueCGRectType : {
CGRect rect ;
if ( AXValueGetValue ( value , type , & rect ) )
var = QRectF ( rect . origin . x , rect . origin . y , rect . size . width , rect . size . height ) ;
} break ;
case kAXValueCFRangeType :
# if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
case kAXValueAXErrorType :
# endif
case kAXValueIllegalType :
default :
qDebug ( ) < < " Illegal/Unsuported AXValue: " < < type ;
break ;
} ;
return var ;
}
/*
Converts a CFTypeRef to a QVariant , for certain selected types . Prints
an error message and returns QVariant ( ) if the type is not supported .
*/
QVariant CFTypeToQVariant ( CFTypeRef value )
{
QVariant var ;
if ( value = = 0 )
return var ;
const uint typeID = CFGetTypeID ( value ) ;
if ( typeID = = CFStringGetTypeID ( ) ) {
var . setValue ( QCFString : : toQString ( ( CFStringRef ) value ) ) ;
} else if ( typeID = = CFBooleanGetTypeID ( ) ) {
var . setValue ( ( bool ) CFBooleanGetValue ( ( CFBooleanRef ) value ) ) ;
} else if ( typeID = = AXUIElementGetTypeID ( ) ) {
var . setValue ( ( AXUIElementRef ) value ) ;
} else if ( typeID = = AXValueGetTypeID ( ) ) {
var = AXValueToQVariant ( ( AXValueRef ) value ) ;
} else if ( typeID = = CFNumberGetTypeID ( ) ) {
CFNumberRef number = ( CFNumberRef ) value ;
if ( CFNumberGetType ( number ) ! = kCFNumberSInt32Type )
qDebug ( ) < < " unsupported number type " < < CFNumberGetType ( number ) ;
int theNumber ;
CFNumberGetValue ( number , kCFNumberSInt32Type , & theNumber ) ;
var . setValue ( theNumber ) ;
} else if ( typeID = = CFArrayGetTypeID ( ) ) {
CFArrayRef cfarray = static_cast < CFArrayRef > ( value ) ;
QVariantList list ;
CFIndex size = CFArrayGetCount ( cfarray ) ;
for ( CFIndex i = 0 ; i < size ; + + i )
list < < CFTypeToQVariant ( CFArrayGetValueAtIndex ( cfarray , i ) ) ;
var . setValue ( list ) ;
} else {
QCFString str = CFCopyTypeIDDescription ( typeID ) ;
qDebug ( ) < < " Unknown CFType: " < < typeID < < ( QString ) str ;
}
return var ;
}
/*
Tests if a given attribute is supported by an element . Expects either
no error or error - 25205 ( Not supported ) . Causes a test failure
on other error values .
*/
bool supportsAttribute ( AXUIElementRef element , CFStringRef attribute )
{
CFArrayRef array ;
AXError err = AXUIElementCopyAttributeNames ( element , & array ) ;
if ( err ) {
testError ( err , QLatin1String ( " unexpected error when testing for supported attribute " ) + QCFString : : toQString ( attribute ) ) ;
return false ;
}
CFRange range ;
range . location = 0 ;
range . length = CFArrayGetCount ( array ) ;
return CFArrayContainsValue ( array , range , attribute ) ;
}
/*
Returns the accessibility attribute specified with attribute in a QVariant
*/
QVariant attribute ( AXUIElementRef element , CFStringRef attribute )
{
CFTypeRef value = 0 ;
AXError err = AXUIElementCopyAttributeValue ( element , attribute , & value ) ;
testError ( err , QString ( " Error getting element attribute " ) + QCFString : : toQString ( attribute ) ) ;
if ( err )
return QVariant ( ) ;
return CFTypeToQVariant ( value ) ;
}
/*
Returns the title for an element .
*/
QString title ( AXUIElementRef element )
{
return attribute ( element , kAXTitleAttribute ) . toString ( ) ;
}
/*
Returns the role for an element .
*/
QString role ( AXUIElementRef element )
{
return attribute ( element , kAXRoleAttribute ) . toString ( ) ;
}
/*
Returns the subrole for an element .
*/
QString subrole ( AXUIElementRef element )
{
return attribute ( element , kAXSubroleAttribute ) . toString ( ) ;
}
/*
Returns the role description for an element .
*/
QString roleDescription ( AXUIElementRef element )
{
return attribute ( element , kAXRoleDescriptionAttribute ) . toString ( ) ;
}
/*
Returns the enabled attribute for an element .
*/
bool enabled ( AXUIElementRef element )
{
return attribute ( element , kAXEnabledAttribute ) . toBool ( ) ;
}
/*
Returns the value attribute for an element as an QVariant .
*/
QVariant value ( AXUIElementRef element )
{
return attribute ( element , kAXValueAttribute ) ;
}
QVariant value ( QAElement element )
{
return value ( element . element ( ) ) ;
}
/*
Returns the description attribute for an element as an QVariant .
*/
QVariant description ( AXUIElementRef element )
{
return attribute ( element , kAXDescriptionAttribute ) ;
}
/*
Returns the value attribute for an element as an bool .
*/
bool boolValue ( AXUIElementRef element )
{
return attribute ( element , kAXValueAttribute ) . toBool ( ) ;
}
/*
Returns the parent for an element
*/
AXUIElementRef parent ( AXUIElementRef element )
{
return attribute ( element , kAXParentAttribute ) . value < AXUIElementRef > ( ) ;
}
/*
Returns the ( top - level ) window ( not a sheet or a drawer ) for an element
*/
AXUIElementRef window ( AXUIElementRef element )
{
return attribute ( element , kAXWindowAttribute ) . value < AXUIElementRef > ( ) ;
}
/*
Returns the ( top - level ) UI element ( can also be a sheet or drawer ) for an element
*/
# if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
AXUIElementRef topLevelUIElement ( AXUIElementRef element )
{
return attribute ( element , kAXTopLevelUIElementAttribute ) . value < AXUIElementRef > ( ) ;
}
# endif
/*
Returns thie size of the element .
*/
QSizeF size ( AXUIElementRef element )
{
return attribute ( element , kAXSizeAttribute ) . value < QSizeF > ( ) ;
}
/*
Returns the position of the element .
*/
QPointF position ( AXUIElementRef element )
{
return attribute ( element , kAXPositionAttribute ) . value < QPointF > ( ) ;
}
/*
Returns the rect of the element .
*/
QRectF rect ( AXUIElementRef element )
{
return QRectF ( position ( element ) , size ( element ) ) ;
}
bool above ( AXUIElementRef a , AXUIElementRef b )
{
return ( position ( a ) . y ( ) + size ( a ) . height ( ) < = position ( b ) . y ( ) ) ;
}
bool contains ( AXUIElementRef a , AXUIElementRef b )
{
return rect ( a ) . contains ( rect ( b ) ) ;
}
QList < AXUIElementRef > tabs ( AXUIElementRef element )
{
CFTypeRef value ;
AXError err = AXUIElementCopyAttributeValue ( element , kAXTabsAttribute , & value ) ;
if ( err )
return QList < AXUIElementRef > ( ) ;
CFArrayRef array = ( CFArrayRef ) value ;
QList < AXUIElementRef > elements ;
const int count = CFArrayGetCount ( array ) ;
for ( int i = 0 ; i < count ; + + i )
elements . append ( ( AXUIElementRef ) CFArrayGetValueAtIndex ( array , i ) ) ;
return elements ;
}
QList < AXUIElementRef > elementListAttribute ( AXUIElementRef element , CFStringRef attributeName )
{
QList < AXUIElementRef > elementList ;
QVariantList variants = attribute ( element , attributeName ) . value < QVariantList > ( ) ;
foreach ( QVariant variant , variants )
elementList . append ( variant . value < AXUIElementRef > ( ) ) ;
return elementList ;
}
AXUIElementRef elementAttribute ( AXUIElementRef element , CFStringRef attributeName )
{
return attribute ( element , attributeName ) . value < AXUIElementRef > ( ) ;
}
QString stringAttribute ( AXUIElementRef element , CFStringRef attributeName )
{
return attribute ( element , attributeName ) . value < QString > ( ) ;
}
/*
Returns the UIElement at the given position .
*/
AXUIElementRef childAtPoint ( QPointF position )
{
AXUIElementRef element = 0 ;
const AXError err = AXUIElementCopyElementAtPosition ( AXUIElementCreateApplication ( getpid ( ) ) , position . x ( ) , position . y ( ) , & element ) ;
if ( err ) {
qDebug ( ) < < " Error getting element at " < < position ;
return 0 ;
}
return element ;
}
/*
Returns a QStringList containing the names of the actions the ui element supports
*/
QStringList actionNames ( AXUIElementRef element )
{
CFArrayRef cfStrings ;
const AXError err = AXUIElementCopyActionNames ( element , & cfStrings ) ;
testError ( err , " Unable to get action names " ) ;
return toQStringList ( cfStrings ) ;
}
bool supportsAction ( const AXUIElementRef element , const QString & actionName )
{
const QStringList actions = actionNames ( element ) ;
return actions . contains ( actionName ) ;
}
bool performAction ( const AXUIElementRef element , const QString & actionName )
{
const AXError err = AXUIElementPerformAction ( element , QCFString ( actionName ) ) ;
return ( err = = 0 ) ;
}
/*
Om 10.4 and up , verifyes the AXRoleDescription attribute for an element ,
on 10.3 and below this test always passes .
The reason for this is that the HICopyAccessibilityRoleDescription call
used to implement this functionality was introduced in 10.4 .
*/
# if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
# define VERIFY_ROLE_DESCRIPTION(ELEMENT, TEXT) \
QCOMPARE ( roleDescription ( ELEMENT ) , QString ( TEXT ) )
# else
# define VERIFY_ROLE_DESCRIPTION(ELEMENT, TEXT) QVERIFY(true)
# endif
CFArrayRef childrenArray ( AXUIElementRef element )
{
CFTypeRef value = 0 ;
AXError err = AXUIElementCopyAttributeValue ( element , kAXChildrenAttribute , & value ) ;
if ( ! err & & CFGetTypeID ( value ) = = CFArrayGetTypeID ( ) ) {
return ( CFArrayRef ) value ;
}
return CFArrayCreate ( 0 , 0 , 0 , 0 ) ;
}
/*
Gest the child count from an element .
*/
int numChildren ( AXUIElementRef element )
{
return CFArrayGetCount ( childrenArray ( element ) ) ;
}
/*
Gets the child with index childIndex from element . Returns 0 if not found .
*/
AXUIElementRef child ( AXUIElementRef element , int childIndex )
{
CFArrayRef children = childrenArray ( element ) ;
if ( childIndex > = CFArrayGetCount ( children ) )
return 0 ;
const void * data = CFArrayGetValueAtIndex ( children , childIndex ) ;
return ( AXUIElementRef ) data ;
}
/*
Gets the child titled childTitle from element . Returns 0 if not found .
*/
AXUIElementRef childByTitle ( AXUIElementRef element , const QString & childTitle )
{
CFArrayRef children = childrenArray ( element ) ;
const int numChildren = CFArrayGetCount ( children ) ;
for ( int i = 0 ; i < numChildren ; + + i ) {
const AXUIElementRef childElement = ( AXUIElementRef ) CFArrayGetValueAtIndex ( children , i ) ;
// Test for support for title attribute before getting it to avoid test fail.
if ( supportsAttribute ( childElement , kAXTitleAttribute ) & & title ( childElement ) = = childTitle )
return childElement ;
}
return 0 ;
}
/*
Gets the child with the given value from element . Returns 0 if not found .
*/
AXUIElementRef childByValue ( AXUIElementRef element , const QVariant & testValue )
{
CFArrayRef children = childrenArray ( element ) ;
const int numChildren = CFArrayGetCount ( children ) ;
for ( int i = 0 ; i < numChildren ; + + i ) {
const AXUIElementRef childElement = ( AXUIElementRef ) CFArrayGetValueAtIndex ( children , i ) ;
// Test for support for value attribute before getting it to avoid test fail.
if ( supportsAttribute ( childElement , kAXValueAttribute ) & & value ( childElement ) = = testValue )
return childElement ;
}
return 0 ;
}
/*
Gets the child by role from element . Returns 0 if not found .
*/
AXUIElementRef childByRole ( AXUIElementRef element , const QString & macRole )
{
CFArrayRef children = childrenArray ( element ) ;
const int numChildren = CFArrayGetCount ( children ) ;
for ( int i = 0 ; i < numChildren ; + + i ) {
const AXUIElementRef childElement = ( AXUIElementRef ) CFArrayGetValueAtIndex ( children , i ) ;
if ( role ( childElement ) = = macRole )
return childElement ;
}
return 0 ;
}
void printTypeForAttribute ( AXUIElementRef element , CFStringRef attribute )
{
CFTypeRef value = 0 ;
AXError err = AXUIElementCopyAttributeValue ( element , attribute , & value ) ;
if ( ! err ) {
qDebug ( ) < < " type id " < < CFGetTypeID ( value ) ;
QCFString str = CFCopyTypeIDDescription ( CFGetTypeID ( value ) ) ;
qDebug ( ) < < ( QString ) str ;
} else {
qDebug ( ) < < " Attribute Get error " < < endl ;
}
}
int indent = 0 ;
QString space ( )
{
QString space ;
for ( int i = 0 ; i < indent ; + + i ) {
space + = " " ;
}
return space ;
}
/*
Recursively prints acccesibility info for currentElement and all its children .
*/
void printElementInfo ( AXUIElementRef currentElement )
{
if ( HIObjectIsAccessibilityIgnored ( AXUIElementGetHIObject ( currentElement ) ) ) {
qDebug ( ) < < space ( ) < < " Ignoring element with role " < < role ( currentElement ) ;
return ;
}
qDebug ( ) < < space ( ) < < " Role " < < role ( currentElement ) ;
if ( supportsAttribute ( currentElement , kAXTitleAttribute ) )
qDebug ( ) < < space ( ) < < " Title " < < title ( currentElement ) ;
else
qDebug ( ) < < space ( ) < < " Title not supported " ;
if ( supportsAttribute ( currentElement , kAXValueAttribute ) )
qDebug ( ) < < space ( ) < < " Value " < < attribute ( currentElement , kAXValueAttribute ) ;
else
qDebug ( ) < < space ( ) < < " Value not supported " ;
qDebug ( ) < < space ( ) < < " Number of children " < < numChildren ( currentElement ) ;
for ( int i = 0 ; i < numChildren ( currentElement ) ; + + i ) {
AXUIElementRef childElement = child ( currentElement , i ) ;
// Skip the menu bar.
if ( role ( childElement ) ! = " AXMenuBar " ) {
indent + = 4 ;
printElementInfo ( childElement ) ;
indent - = 4 ;
}
}
qDebug ( ) < < " " ;
}
/*
Recursively prints the child interfaces belonging to interface .
*/
void printChildren ( const QAInterface & interface )
{
if ( interface . isValid ( ) = = false )
return ;
QList < QAInterface > children = interface . children ( ) ;
if ( children . isEmpty ( ) )
return ;
qDebug ( ) < < " ## Children for " < < interface ;
foreach ( const QAInterface & child , children ) {
qDebug ( ) < < child < < " index in parent " < < interface . indexOfChild ( child ) ;
}
foreach ( const QAInterface & child , children ) {
printChildren ( child ) ;
}
}
bool isIgnored ( AXUIElementRef currentElement )
{
return HIObjectIsAccessibilityIgnored ( AXUIElementGetHIObject ( currentElement ) ) ;
}
bool equal ( CFTypeRef o1 , CFTypeRef o2 )
{
if ( o1 = = 0 | | o2 = = 0 )
return false ;
return CFEqual ( o1 , o2 ) ;
}
/*
Verifies basic element info .
*/
# define VERIFY_ELEMENT(element, _parent, _role) \
QVERIFY ( element ! = 0 ) ; \
QVERIFY ( role ( element ) = = _role ) ; \
QVERIFY ( equal ( : : parent ( element ) , _parent ) ) ;
/*
Verifies that the application and the main form is there has the right info .
*/
void testAppAndForm ( AXUIElementRef application )
{
QVERIFY ( title ( application ) = = " tst_qaccessibility_mac " ) ;
QVERIFY ( role ( application ) = = " AXApplication " ) ;
AXUIElementRef form = childByTitle ( application , " Form " ) ;
VERIFY_ELEMENT ( form , application , " AXWindow " ) ;
}
void tst_qaccessibility_mac : : printInfo ( )
{
AXUIElementRef currentApplication = AXUIElementCreateApplication ( getpid ( ) ) ;
printElementInfo ( currentApplication ) ;
}
/*
Tests for form . ui
*/
void tst_qaccessibility_mac : : testForm ( )
{
// Get reference to the current application.
AXUIElementRef currentApplication = AXUIElementCreateApplication ( getpid ( ) ) ;
testAppAndForm ( currentApplication ) ;
childByTitle ( currentApplication , " Form " ) ;
}
/*
Tests for buttons . ui
*/
void tst_qaccessibility_mac : : testButtons ( )
{
// Get reference to the current application.
AXUIElementRef currentApplication = AXUIElementCreateApplication ( getpid ( ) ) ;
testAppAndForm ( currentApplication ) ;
AXUIElementRef form = childByTitle ( currentApplication , " Form " ) ;
AXUIElementRef ren = childByTitle ( form , " Ren " ) ;
VERIFY_ELEMENT ( ren , form , " AXButton " ) ;
QVERIFY ( enabled ( ren ) = = true ) ;
VERIFY_ROLE_DESCRIPTION ( ren , " button " ) ;
AXUIElementRef stimpy = childByTitle ( form , " Stimpy " ) ;
VERIFY_ELEMENT ( stimpy , form , " AXRadioButton " ) ;
QVERIFY ( enabled ( stimpy ) = = true ) ;
QVERIFY ( value ( stimpy ) . toInt ( ) = = 1 ) ; // checked;
VERIFY_ROLE_DESCRIPTION ( stimpy , " radio button " ) ;
AXUIElementRef pinky = childByTitle ( form , " Pinky " ) ;
VERIFY_ELEMENT ( pinky , form , " AXCheckBox " ) ;
QVERIFY ( enabled ( pinky ) = = false ) ;
QVERIFY ( value ( pinky ) . toInt ( ) = = 0 ) ; // unchecked;
VERIFY_ROLE_DESCRIPTION ( pinky , " check box " ) ;
AXUIElementRef brain = childByTitle ( form , " Brain " ) ;
VERIFY_ELEMENT ( brain , form , " AXButton " ) ;
VERIFY_ROLE_DESCRIPTION ( brain , " button " ) ;
}
void tst_qaccessibility_mac : : testLabel ( )
{
// Get reference to the current application.
AXUIElementRef currentApplication = AXUIElementCreateApplication ( getpid ( ) ) ;
testAppAndForm ( currentApplication ) ;
AXUIElementRef form = childByTitle ( currentApplication , " Form " ) ;
AXUIElementRef label = childByValue ( form , " This is a Text Label " ) ;
QVERIFY ( label ) ;
VERIFY_ELEMENT ( label , form , " AXStaticText " ) ;
VERIFY_ROLE_DESCRIPTION ( label , " text " ) ;
QCOMPARE ( supportsAttribute ( label , kAXDescriptionAttribute ) , false ) ;
}
/*
Tests for lineedit . ui
*/
void tst_qaccessibility_mac : : testLineEdit ( )
{
// Get reference to the current application.
AXUIElementRef currentApplication = AXUIElementCreateApplication ( getpid ( ) ) ;
testAppAndForm ( currentApplication ) ;
AXUIElementRef form = childByTitle ( currentApplication , " Form " ) ;
AXUIElementRef lineEdit = childByValue ( form , " Line edit " ) ;
VERIFY_ELEMENT ( lineEdit , form , " AXTextField " ) ;
VERIFY_ROLE_DESCRIPTION ( lineEdit , " text field " ) ;
}
/*
Tests for groups . ui
*/
void tst_qaccessibility_mac : : testGroups ( )
{
// Get reference to the current application.
AXUIElementRef currentApplication = AXUIElementCreateApplication ( getpid ( ) ) ;
testAppAndForm ( currentApplication ) ;
AXUIElementRef form = childByTitle ( currentApplication , " Form " ) ;
AXUIElementRef groupA = childByTitle ( form , " Group A " ) ;
VERIFY_ELEMENT ( groupA , form , " AXGroup " ) ;
AXUIElementRef button1 = childByTitle ( groupA , " PushButton 1 " ) ;
VERIFY_ELEMENT ( button1 , groupA , " AXButton " ) ;
VERIFY_ROLE_DESCRIPTION ( groupA , " group " ) ;
AXUIElementRef groupB = childByTitle ( form , " Group B " ) ;
VERIFY_ELEMENT ( groupB , form , " AXGroup " ) ;
AXUIElementRef button3 = childByTitle ( groupB , " PushButton 3 " ) ;
VERIFY_ELEMENT ( button3 , groupB , " AXButton " ) ;
}
/*
Tests for tabs . ui
*/
void tst_qaccessibility_mac : : testTabWidget ( )
{
{ // Test that the QTabWidget hierarchy is what we expect it to be.
QTabWidget tabWidget ;
tabWidget . show ( ) ;
QAInterface interface = QAccessible : : queryAccessibleInterface ( & tabWidget ) ;
tabWidget . addTab ( new QPushButton ( " Foo " ) , " FooTab " ) ;
tabWidget . addTab ( new QPushButton ( " Bar " ) , " BarTab " ) ;
QCOMPARE ( interface . childCount ( ) , 2 ) ;
const QList < QAInterface > children = interface . children ( ) ;
QVERIFY ( children . at ( 0 ) . object ( ) - > inherits ( " QStackedWidget " ) ) ;
QVERIFY ( children . at ( 1 ) . object ( ) - > inherits ( " QTabBar " ) ) ;
const QList < QAInterface > tabBarChildren = children . at ( 1 ) . children ( ) ;
QCOMPARE ( tabBarChildren . count ( ) , 4 ) ;
QCOMPARE ( tabBarChildren . at ( 0 ) . text ( QAccessible : : Name ) , QLatin1String ( " FooTab " ) ) ;
QCOMPARE ( tabBarChildren . at ( 1 ) . text ( QAccessible : : Name ) , QLatin1String ( " BarTab " ) ) ;
QCOMPARE ( tabBarChildren . at ( 0 ) . role ( ) , QAccessible : : PageTab ) ;
QCOMPARE ( tabBarChildren . at ( 1 ) . role ( ) , QAccessible : : PageTab ) ;
// Check that the hierarchy manager is able to register the tab bar children.
QAccessibleHierarchyManager * manager = QAccessibleHierarchyManager : : instance ( ) ;
QAInterface tabBarInterface = children . at ( 1 ) ;
QAElement tabBarElement = manager - > registerInterface ( tabBarInterface ) ;
QCOMPARE ( manager - > lookup ( tabBarElement ) . childCount ( ) , 4 ) ;
manager - > registerChildren ( tabBarInterface ) ;
QAElement tabButtonElement = manager - > lookup ( tabBarChildren . at ( 1 ) ) ;
QAInterface tabButtonInterface = manager - > lookup ( tabButtonElement ) ;
QCOMPARE ( tabButtonInterface . text ( QAccessible : : Name ) , QLatin1String ( " BarTab " ) ) ;
QVERIFY ( isItInteresting ( tabButtonInterface ) = = true ) ;
}
// Get reference to the current application.
AXUIElementRef currentApplication = AXUIElementCreateApplication ( getpid ( ) ) ;
testAppAndForm ( currentApplication ) ;
const QString formTitle = " Form " ;
AXUIElementRef form = childByTitle ( currentApplication , formTitle ) ;
QVERIFY ( form ) ;
const QString tabRole = " AXTabGroup " ;
AXUIElementRef tabGroup = childByRole ( form , tabRole ) ;
QVERIFY ( tabGroup ) ;
// Test that we have three child buttons (the tab buttons + plus the contents of the first tab)
const int numChildren = : : numChildren ( tabGroup ) ;
QCOMPARE ( numChildren , 3 ) ;
const QString tab1Title = " Tab 1 " ;
AXUIElementRef tabButton1 = childByTitle ( tabGroup , tab1Title ) ;
QVERIFY ( tabButton1 ) ;
VERIFY_ELEMENT ( tabButton1 , tabGroup , " AXRadioButton " ) ;
QCOMPARE ( title ( tabButton1 ) , tab1Title ) ;
const QString tab2Title = " Tab 2 " ;
const AXUIElementRef tabButton2 = childByTitle ( tabGroup , tab2Title ) ;
QVERIFY ( tabButton2 ) ;
VERIFY_ELEMENT ( tabButton2 , tabGroup , " AXRadioButton " ) ;
QCOMPARE ( title ( tabButton2 ) , tab2Title ) ;
// Test that the window and top-level-ui-elment is the form.
// Window is not reported properly on 10.5
if ( QSysInfo : : MacintoshVersion < QSysInfo : : MV_10_5 ) {
QVERIFY ( equal ( window ( tabGroup ) , form ) ) ;
// ### hangs on 10.4
# if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
QVERIFY ( equal ( window ( tabButton1 ) , form ) ) ;
# endif
}
// ### hangs on 10.4
# if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
QVERIFY ( equal ( topLevelUIElement ( tabGroup ) , form ) ) ;
QVERIFY ( equal ( topLevelUIElement ( tabButton1 ) , form ) ) ;
# endif
// Test the bounding rectangles for the tab group and buttons.
const QRectF groupRect ( position ( tabGroup ) , size ( tabGroup ) ) ;
const QRectF tabButton1Rect ( position ( tabButton1 ) , size ( tabButton1 ) ) ;
const QRectF tabButton2Rect ( position ( tabButton2 ) , size ( tabButton2 ) ) ;
QVERIFY ( groupRect . isNull ( ) = = false ) ;
QVERIFY ( tabButton1Rect . isNull ( ) = = false ) ;
QVERIFY ( tabButton1Rect . isNull ( ) = = false ) ;
QVERIFY ( groupRect . contains ( tabButton1Rect ) ) ;
QVERIFY ( groupRect . contains ( tabButton2Rect ) ) ;
QVERIFY ( tabButton2Rect . contains ( tabButton1Rect ) = = false ) ;
// Test the childAtPoint event.
const AXUIElementRef childAtTab1Position = childAtPoint ( position ( tabButton1 ) + QPointF ( 5 , 5 ) ) ;
QVERIFY ( equal ( childAtTab1Position , tabButton1 ) ) ;
const AXUIElementRef childAtOtherPosition = childAtPoint ( position ( tabButton1 ) - QPointF ( 5 , 5 ) ) ;
QVERIFY ( equal ( childAtOtherPosition , tabButton1 ) = = false ) ;
// Test AXTabs attribute
QVERIFY ( supportsAttribute ( tabGroup , kAXTabsAttribute ) ) ;
QList < AXUIElementRef > tabElements = tabs ( tabGroup ) ;
QCOMPARE ( tabElements . count ( ) , 2 ) ;
QVERIFY ( equal ( tabElements . at ( 0 ) , tabButton1 ) ) ;
QVERIFY ( equal ( tabElements . at ( 1 ) , tabButton2 ) ) ;
// Perform the press action on each child.
for ( int i = 0 ; i < numChildren ; + + i ) {
const AXUIElementRef child = : : child ( tabGroup , i ) ;
QVERIFY ( supportsAction ( child , " AXPress " ) ) ;
QVERIFY ( performAction ( child , " AXPress " ) ) ;
}
}
void tst_qaccessibility_mac : : testTabBar ( )
{
QTabBar tabBar ;
tabBar . addTab ( " Tab A " ) ;
tabBar . addTab ( " Tab B " ) ;
tabBar . show ( ) ;
AXUIElementRef currentApplication = AXUIElementCreateApplication ( getpid ( ) ) ;
AXUIElementRef window = childByRole ( currentApplication , " AXWindow " ) ;
QVERIFY ( window ) ;
const QString tabRole = " AXTabGroup " ;
AXUIElementRef tabGroup = childByRole ( window , tabRole ) ;
QVERIFY ( tabGroup ) ;
const int numChildren = : : numChildren ( tabGroup ) ;
QCOMPARE ( numChildren , 2 ) ;
const QString tab1Title = " Tab A " ;
AXUIElementRef tabButton1 = childByTitle ( tabGroup , tab1Title ) ;
QVERIFY ( tabButton1 ) ;
VERIFY_ELEMENT ( tabButton1 , tabGroup , " AXRadioButton " ) ;
QCOMPARE ( title ( tabButton1 ) , tab1Title ) ;
const QString tab2Title = " Tab B " ;
const AXUIElementRef tabButton2 = childByTitle ( tabGroup , tab2Title ) ;
QVERIFY ( tabButton2 ) ;
VERIFY_ELEMENT ( tabButton2 , tabGroup , " AXRadioButton " ) ;
QCOMPARE ( title ( tabButton2 ) , tab2Title ) ;
// Test the childAtPoint event.
const AXUIElementRef childAtTab1Position = childAtPoint ( position ( tabButton1 ) + QPointF ( 5 , 5 ) ) ;
QVERIFY ( equal ( childAtTab1Position , tabButton1 ) ) ;
const AXUIElementRef childAtOtherPosition = childAtPoint ( position ( tabButton1 ) - QPointF ( 5 , 5 ) ) ;
QVERIFY ( equal ( childAtOtherPosition , tabButton1 ) = = false ) ;
// Test AXTabs attribute
QVERIFY ( supportsAttribute ( tabGroup , kAXTabsAttribute ) ) ;
QList < AXUIElementRef > tabElements = tabs ( tabGroup ) ;
QCOMPARE ( tabElements . count ( ) , 2 ) ;
QVERIFY ( equal ( tabElements . at ( 0 ) , tabButton1 ) ) ;
QVERIFY ( equal ( tabElements . at ( 1 ) , tabButton2 ) ) ;
// Perform the press action on each child.
for ( int i = 0 ; i < numChildren ; + + i ) {
const AXUIElementRef child = : : child ( tabGroup , i ) ;
QVERIFY ( supportsAction ( child , " AXPress " ) ) ;
QVERIFY ( performAction ( child , " AXPress " ) ) ;
}
}
void tst_qaccessibility_mac : : testComboBox ( )
{
// Get reference to the current application.
AXUIElementRef currentApplication = AXUIElementCreateApplication ( getpid ( ) ) ;
testAppAndForm ( currentApplication ) ;
const QString formTitle = " Form " ;
AXUIElementRef form = childByTitle ( currentApplication , formTitle ) ;
const QString comboBoxRole = " AXPopUpButton " ;
AXUIElementRef comboBox = childByRole ( form , comboBoxRole ) ;
QVERIFY ( comboBox ! = 0 ) ;
QVERIFY ( supportsAction ( comboBox , " AXPress " ) ) ;
QVERIFY ( performAction ( comboBox , " AXPress " ) ) ;
}
void tst_qaccessibility_mac : : testDeleteWidget ( )
{
const QString buttonTitle = " Hi there " ;
QWidget * form = new QWidget ( 0 , Qt : : Window ) ;
form - > setWindowTitle ( " Form " ) ;
form - > show ( ) ;
QPushButton * button = new QPushButton ( buttonTitle , form ) ;
button - > show ( ) ;
AXUIElementRef currentApplication = AXUIElementCreateApplication ( getpid ( ) ) ;
testAppAndForm ( currentApplication ) ;
AXUIElementRef formElement = childByTitle ( currentApplication , " Form " ) ;
AXUIElementRef buttonElement = childByTitle ( formElement , buttonTitle ) ;
QVERIFY ( buttonElement ) ;
button - > hide ( ) ;
delete button ;
buttonElement = childByTitle ( formElement , buttonTitle ) ;
QVERIFY ( ! buttonElement ) ;
delete form ;
}
void tst_qaccessibility_mac : : testDeleteWidgets ( )
{
const QString buttonTitle = " Hi there " ;
const int repeats = 10 ;
for ( int i = 0 ; i < repeats ; + + i ) {
QWidget * form = new QWidget ( 0 , Qt : : Window ) ;
form - > setWindowTitle ( " Form " ) ;
form - > show ( ) ;
QPushButton * button = new QPushButton ( buttonTitle , form ) ;
button - > show ( ) ;
AXUIElementRef currentApplication = AXUIElementCreateApplication ( getpid ( ) ) ;
testAppAndForm ( currentApplication ) ;
AXUIElementRef formElement = childByTitle ( currentApplication , " Form " ) ;
AXUIElementRef buttonElement = childByTitle ( formElement , buttonTitle ) ;
QVERIFY ( buttonElement ) ;
delete form ;
{
AXUIElementRef currentApplication = AXUIElementCreateApplication ( getpid ( ) ) ;
QVERIFY ( currentApplication ) ;
AXUIElementRef formElement = childByTitle ( currentApplication , " Form " ) ;
QVERIFY ( ! formElement ) ;
}
}
for ( int i = 0 ; i < repeats ; + + i ) {
QWidget * form = new QWidget ( 0 , Qt : : Window ) ;
form - > setWindowTitle ( " Form " ) ;
new QScrollBar ( form ) ;
form - > show ( ) ;
AXUIElementRef currentApplication = AXUIElementCreateApplication ( getpid ( ) ) ;
testAppAndForm ( currentApplication ) ;
AXUIElementRef formElement = childByTitle ( currentApplication , " Form " ) ;
const AXUIElementRef scrollBarElement = childByRole ( formElement , " AXScrollBar " ) ;
QVERIFY ( scrollBarElement ) ;
delete form ;
{
AXUIElementRef currentApplication = AXUIElementCreateApplication ( getpid ( ) ) ;
QVERIFY ( currentApplication ) ;
AXUIElementRef formElement = childByTitle ( currentApplication , " Form " ) ;
QVERIFY ( ! formElement ) ;
}
}
for ( int i = 0 ; i < repeats ; + + i ) {
QWidget * form = new QWidget ( 0 , Qt : : Window ) ;
form - > setWindowTitle ( " Form " ) ;
QListWidget * listWidget = new QListWidget ( form ) ;
listWidget - > addItem ( " Foo " ) ;
listWidget - > addItem ( " Bar " ) ;
form - > show ( ) ;
AXUIElementRef currentApplication = AXUIElementCreateApplication ( getpid ( ) ) ;
testAppAndForm ( currentApplication ) ;
AXUIElementRef formElement = childByTitle ( currentApplication , " Form " ) ;
const AXUIElementRef scrollAreaElement = childByRole ( formElement , " AXScrollArea " ) ;
QVERIFY ( scrollAreaElement ) ;
const AXUIElementRef listElement = childByRole ( scrollAreaElement , " AXList " ) ;
QVERIFY ( listElement ) ;
delete form ;
{
AXUIElementRef currentApplication = AXUIElementCreateApplication ( getpid ( ) ) ;
QVERIFY ( currentApplication ) ;
AXUIElementRef formElement = childByTitle ( currentApplication , " Form " ) ;
QVERIFY ( ! formElement ) ;
}
}
}
void tst_qaccessibility_mac : : testMultipleWindows ( )
{
const QString formATitle ( " FormA " ) ;
const QString formBTitle ( " FormB " ) ;
// Create a window
QWidget * formA = new QWidget ( 0 , Qt : : Window ) ;
formA - > setWindowTitle ( formATitle ) ;
formA - > show ( ) ;
// Test if we can access the window
AXUIElementRef currentApplication = AXUIElementCreateApplication ( getpid ( ) ) ;
AXUIElementRef formAElement = childByTitle ( currentApplication , formATitle ) ;
QVERIFY ( formAElement ) ;
// Create another window
QWidget * formB = new QWidget ( 0 , Qt : : Window ) ;
formB - > setWindowTitle ( formBTitle ) ;
formB - > show ( ) ;
// Test if we can access both windows
formAElement = childByTitle ( currentApplication , formATitle ) ;
QVERIFY ( formAElement ) ;
AXUIElementRef formBElement = childByTitle ( currentApplication , formBTitle ) ;
QVERIFY ( formBElement ) ;
delete formA ;
}
void tst_qaccessibility_mac : : testHiddenWidgets ( )
{
const QString windowTitle = " a widget " ;
QWidget * const window = new QWidget ( 0 ) ;
window - > setWindowTitle ( windowTitle ) ;
window - > show ( ) ;
const AXUIElementRef currentApplication = AXUIElementCreateApplication ( getpid ( ) ) ;
const AXUIElementRef windowElement = childByTitle ( currentApplication , windowTitle ) ;
QVERIFY ( windowElement ) ;
QCOMPARE ( isIgnored ( windowElement ) , false ) ;
const QString buttonTitle = " a button " ;
QPushButton * const button = new QPushButton ( window ) ;
button - > setText ( buttonTitle ) ;
button - > show ( ) ;
const AXUIElementRef buttonElement = childByTitle ( windowElement , buttonTitle ) ;
QVERIFY ( buttonElement ) ;
QCOMPARE ( isIgnored ( buttonElement ) , false ) ;
const QString toolbarTitle = " a toolbar " ;
QToolBar * const toolbar = new QToolBar ( toolbarTitle , window ) ;
toolbar - > show ( ) ;
const AXUIElementRef toolBarElement = childByTitle ( windowElement , toolbarTitle ) ;
QVERIFY ( toolBarElement = = 0 ) ;
delete window ;
} ;
void tst_qaccessibility_mac : : testActions ( )
{
// create a window with a push button
const QString windowTitle = " a widget " ;
QWidget * const window = new QWidget ( ) ;
window - > setWindowTitle ( windowTitle ) ;
window - > show ( ) ;
const AXUIElementRef currentApplication = AXUIElementCreateApplication ( getpid ( ) ) ;
const AXUIElementRef windowElement = childByTitle ( currentApplication , windowTitle ) ;
QVERIFY ( windowElement ) ;
const QString buttonTitle = " a button " ;
QPushButton * const button = new QPushButton ( window ) ;
button - > setText ( buttonTitle ) ;
button - > show ( ) ;
const AXUIElementRef buttonElement = childByTitle ( windowElement , buttonTitle ) ;
QVERIFY ( buttonElement ) ;
// Verify that the button has the Press action.
const QStringList actions = actionNames ( buttonElement ) ;
const QString pressActionName ( " AXPress " ) ;
QVERIFY ( actions . contains ( pressActionName ) ) ;
// Press button and check the pressed signal
QSignalSpy pressed ( button , SIGNAL ( pressed ( ) ) ) ;
QVERIFY ( performAction ( buttonElement , pressActionName ) ) ;
QCOMPARE ( pressed . count ( ) , 1 ) ;
pressed . clear ( ) ;
QVERIFY ( performAction ( buttonElement , QString ( " does not exist " ) ) ) ;
QCOMPARE ( pressed . count ( ) , 0 ) ;
delete window ;
} ;
void tst_qaccessibility_mac : : testChangeState ( )
{
const QString windowTitle = " a widget " ;
QWidget * const window = new QWidget ( ) ;
window - > setWindowTitle ( windowTitle ) ;
window - > show ( ) ;
const AXUIElementRef applicationElement = AXUIElementCreateApplication ( getpid ( ) ) ;
const AXUIElementRef windowElement = childByTitle ( applicationElement , windowTitle ) ;
QVERIFY ( windowElement ) ;
const int otherChildren = numChildren ( windowElement ) ;
const QString buttonTitle = " Button " ;
QPushButton * const button = new QPushButton ( buttonTitle , window ) ;
button - > setText ( buttonTitle ) ;
// Test that show/hide adds/removes the button from the hierachy.
QVERIFY ( childByTitle ( windowElement , buttonTitle ) = = 0 ) ;
QCOMPARE ( numChildren ( windowElement ) , otherChildren ) ;
button - > show ( ) ;
QVERIFY ( childByTitle ( windowElement , buttonTitle ) ! = 0 ) ;
QCOMPARE ( numChildren ( windowElement ) , otherChildren + 1 ) ;
button - > hide ( ) ;
QVERIFY ( childByTitle ( windowElement , buttonTitle ) = = 0 ) ;
QCOMPARE ( numChildren ( windowElement ) , otherChildren ) ;
button - > show ( ) ;
QVERIFY ( childByTitle ( windowElement , buttonTitle ) ! = 0 ) ;
QCOMPARE ( numChildren ( windowElement ) , otherChildren + 1 ) ;
// Test that hiding and showing a widget also removes and adds all its children.
{
QWidget * const parent = new QWidget ( window ) ;
const int otherChildren = numChildren ( windowElement ) ;
QPushButton * const child = new QPushButton ( parent ) ;
const QString childButtonTitle = " child button " ;
child - > setText ( childButtonTitle ) ;
parent - > show ( ) ;
QVERIFY ( childByTitle ( windowElement , childButtonTitle ) ! = 0 ) ;
QCOMPARE ( numChildren ( windowElement ) , otherChildren + 1 ) ;
parent - > hide ( ) ;
QVERIFY ( childByTitle ( windowElement , childButtonTitle ) = = 0 ) ;
QCOMPARE ( numChildren ( windowElement ) , otherChildren ) ;
parent - > show ( ) ;
QVERIFY ( childByTitle ( windowElement , childButtonTitle ) ! = 0 ) ;
QCOMPARE ( numChildren ( windowElement ) , otherChildren + 1 ) ;
delete parent ;
}
// Test that the enabled attribute is updated after a call to setEnabled.
const AXUIElementRef buttonElement = childByTitle ( windowElement , buttonTitle ) ;
QVERIFY ( enabled ( buttonElement ) ) ;
button - > setEnabled ( false ) ;
QVERIFY ( enabled ( buttonElement ) = = false ) ;
button - > setEnabled ( true ) ;
QVERIFY ( enabled ( buttonElement ) ) ;
// Test that changing the title updates the accessibility information.
const QString buttonTitle2 = " Button 2 " ;
button - > setText ( buttonTitle2 ) ;
QVERIFY ( childByTitle ( windowElement , buttonTitle2 ) ! = 0 ) ;
QVERIFY ( childByTitle ( windowElement , buttonTitle ) = = 0 ) ;
delete window ;
}
void tst_qaccessibility_mac : : testSlider ( )
{
const QString windowTitle = " a widget " ;
QWidget * const window = new QWidget ( ) ;
window - > setWindowTitle ( windowTitle ) ;
window - > show ( ) ;
const AXUIElementRef applicationElement = AXUIElementCreateApplication ( getpid ( ) ) ;
QVERIFY ( applicationElement ) ;
const AXUIElementRef windowElement = childByTitle ( applicationElement , windowTitle ) ;
QVERIFY ( windowElement ) ;
const int windowChildren = numChildren ( windowElement ) ;
QSlider * const slider = new QSlider ( window ) ;
slider - > show ( ) ;
const AXUIElementRef sliderElement = childByRole ( windowElement , " AXSlider " ) ;
QVERIFY ( sliderElement ) ;
// Test that the slider and its children are removed from the hierachy when we call hide().
QCOMPARE ( numChildren ( windowElement ) , windowChildren + 1 ) ;
slider - > hide ( ) ;
QCOMPARE ( numChildren ( windowElement ) , windowChildren ) ;
delete slider ;
}
void tst_qaccessibility_mac : : testScrollArea ( )
{
QWidget window ;
const QString windowTitle = " window " ;
window . setWindowTitle ( windowTitle ) ;
window . resize ( 300 , 300 ) ;
QScrollArea scrollArea ( & window ) ;
scrollArea . resize ( 300 , 300 ) ;
scrollArea . setVerticalScrollBarPolicy ( Qt : : ScrollBarAlwaysOn ) ;
scrollArea . setHorizontalScrollBarPolicy ( Qt : : ScrollBarAlwaysOn ) ;
QLabel label ;
label . setText ( " Foo " ) ;
scrollArea . setWidget ( & label ) ;
window . show ( ) ;
// Verify that the QAinterface returns the correct children
QAInterface interface = QAccessible : : queryAccessibleInterface ( & scrollArea ) ;
QCOMPARE ( interface . childCount ( ) , 3 ) ;
QAInterface viewport = interface . navigate ( QAccessible : : Child , 1 ) ;
QVERIFY ( viewport . isValid ( ) ) ;
QAInterface scrollBarContainer1 = interface . navigate ( QAccessible : : Child , 2 ) ;
QVERIFY ( scrollBarContainer1 . isValid ( ) ) ;
QAInterface scrollBar1 = scrollBarContainer1 . navigate ( QAccessible : : Child , 1 ) ;
QVERIFY ( scrollBar1 . isValid ( ) ) ;
QVERIFY ( scrollBar1 . role ( ) = = QAccessible : : ScrollBar ) ;
QAInterface scrollBarContainer2 = interface . navigate ( QAccessible : : Child , 3 ) ;
QVERIFY ( scrollBarContainer1 . isValid ( ) ) ;
QAInterface scrollBar2 = scrollBarContainer2 . navigate ( QAccessible : : Child , 1 ) ;
QVERIFY ( scrollBar2 . isValid ( ) ) ;
QVERIFY ( scrollBar2 . role ( ) = = QAccessible : : ScrollBar ) ;
// Navigate to the scroll area from the application
const AXUIElementRef applicationElement = AXUIElementCreateApplication ( getpid ( ) ) ;
QVERIFY ( applicationElement ) ;
const AXUIElementRef windowElement = childByTitle ( applicationElement , windowTitle ) ;
QVERIFY ( windowElement ) ;
const AXUIElementRef scrollAreaElement = childByRole ( windowElement , " AXScrollArea " ) ;
QVERIFY ( scrollAreaElement ) ;
// Get the scroll bars
QVERIFY ( supportsAttribute ( scrollAreaElement , kAXHorizontalScrollBarAttribute ) ) ;
const AXUIElementRef horizontalScrollBar = elementAttribute ( scrollAreaElement , kAXHorizontalScrollBarAttribute ) ;
QVERIFY ( horizontalScrollBar ) ;
QVERIFY ( role ( horizontalScrollBar ) = = " AXScrollBar " ) ;
QVERIFY ( stringAttribute ( horizontalScrollBar , kAXOrientationAttribute ) = = " AXHorizontalOrientation " ) ;
QVERIFY ( supportsAttribute ( scrollAreaElement , kAXVerticalScrollBarAttribute ) ) ;
const AXUIElementRef verticalScrollBar = elementAttribute ( scrollAreaElement , kAXVerticalScrollBarAttribute ) ;
QVERIFY ( verticalScrollBar ) ;
QVERIFY ( role ( verticalScrollBar ) = = " AXScrollBar " ) ;
QVERIFY ( stringAttribute ( verticalScrollBar , kAXOrientationAttribute ) = = " AXVerticalOrientation " ) ;
// Get the contents and verify that we get the label.
QVERIFY ( supportsAttribute ( scrollAreaElement , kAXContentsAttribute ) ) ;
const QList < AXUIElementRef > contents = elementListAttribute ( scrollAreaElement , kAXContentsAttribute ) ;
QCOMPARE ( contents . count ( ) , 1 ) ;
AXUIElementRef content = contents . at ( 0 ) ;
QVERIFY ( role ( content ) = = " AXStaticText " ) ;
QVERIFY ( title ( content ) = = " Foo " ) ;
// Turn scroll bars off
{
scrollArea . setVerticalScrollBarPolicy ( Qt : : ScrollBarAlwaysOff ) ;
scrollArea . setHorizontalScrollBarPolicy ( Qt : : ScrollBarAlwaysOff ) ;
QVERIFY ( supportsAttribute ( scrollAreaElement , kAXHorizontalScrollBarAttribute ) = = false ) ;
QVERIFY ( supportsAttribute ( scrollAreaElement , kAXVerticalScrollBarAttribute ) = = false ) ;
QVERIFY ( supportsAttribute ( scrollAreaElement , kAXContentsAttribute ) ) ;
const QList < AXUIElementRef > contents = elementListAttribute ( scrollAreaElement , kAXContentsAttribute ) ;
QCOMPARE ( contents . count ( ) , 1 ) ;
AXUIElementRef content = contents . at ( 0 ) ;
QVERIFY ( role ( content ) = = " AXStaticText " ) ;
QVERIFY ( title ( content ) = = " Foo " ) ;
}
// Turn the horizontal scrollbar on.
{
scrollArea . setHorizontalScrollBarPolicy ( Qt : : ScrollBarAlwaysOn ) ;
scrollArea . setVerticalScrollBarPolicy ( Qt : : ScrollBarAlwaysOff ) ;
QVERIFY ( supportsAttribute ( scrollAreaElement , kAXHorizontalScrollBarAttribute ) = = true ) ;
QVERIFY ( supportsAttribute ( scrollAreaElement , kAXVerticalScrollBarAttribute ) = = false ) ;
const AXUIElementRef horizontalScrollBar = elementAttribute ( scrollAreaElement , kAXHorizontalScrollBarAttribute ) ;
QVERIFY ( horizontalScrollBar ) ;
QVERIFY ( role ( horizontalScrollBar ) = = " AXScrollBar " ) ;
QVERIFY ( stringAttribute ( horizontalScrollBar , kAXOrientationAttribute ) = = " AXHorizontalOrientation " ) ;
QVERIFY ( supportsAttribute ( scrollAreaElement , kAXContentsAttribute ) ) ;
const QList < AXUIElementRef > contents = elementListAttribute ( scrollAreaElement , kAXContentsAttribute ) ;
QCOMPARE ( contents . count ( ) , 1 ) ;
AXUIElementRef content = contents . at ( 0 ) ;
QVERIFY ( role ( content ) = = " AXStaticText " ) ;
QVERIFY ( title ( content ) = = " Foo " ) ;
}
// Turn the vertical scrollbar on.
{
scrollArea . setHorizontalScrollBarPolicy ( Qt : : ScrollBarAlwaysOff ) ;
scrollArea . setVerticalScrollBarPolicy ( Qt : : ScrollBarAlwaysOn ) ;
QVERIFY ( supportsAttribute ( scrollAreaElement , kAXHorizontalScrollBarAttribute ) = = false ) ;
QVERIFY ( supportsAttribute ( scrollAreaElement , kAXVerticalScrollBarAttribute ) = = true ) ;
QVERIFY ( supportsAttribute ( scrollAreaElement , kAXVerticalScrollBarAttribute ) ) ;
const AXUIElementRef verticalScrollBar = elementAttribute ( scrollAreaElement , kAXVerticalScrollBarAttribute ) ;
QVERIFY ( verticalScrollBar ) ;
QVERIFY ( role ( verticalScrollBar ) = = " AXScrollBar " ) ;
QVERIFY ( stringAttribute ( verticalScrollBar , kAXOrientationAttribute ) = = " AXVerticalOrientation " ) ;
QVERIFY ( supportsAttribute ( scrollAreaElement , kAXContentsAttribute ) ) ;
const QList < AXUIElementRef > contents = elementListAttribute ( scrollAreaElement , kAXContentsAttribute ) ;
QCOMPARE ( contents . count ( ) , 1 ) ;
AXUIElementRef content = contents . at ( 0 ) ;
QVERIFY ( role ( content ) = = " AXStaticText " ) ;
QVERIFY ( title ( content ) = = " Foo " ) ;
}
}
void tst_qaccessibility_mac : : testListView ( )
{
QWidget window ;
const QString windowTitle ( " window " ) ;
window . setWindowTitle ( windowTitle ) ;
window . resize ( 300 , 300 ) ;
QListWidget * listWidget = new QListWidget ( & window ) ;
listWidget - > setObjectName ( " listwidget " ) ;
listWidget - > addItem ( " A " ) ;
listWidget - > addItem ( " B " ) ;
listWidget - > addItem ( " C " ) ;
window . show ( ) ;
QTest : : qWait ( 1 ) ;
{
// Verify that QAInterface works as expected for list views
QAInterface listWidgetInterface = QAccessible : : queryAccessibleInterface ( listWidget ) ;
QCOMPARE ( listWidgetInterface . role ( ) , QAccessible : : Client ) ;
QCOMPARE ( listWidgetInterface . childCount ( ) , 1 ) ;
QAInterface viewPort = listWidgetInterface . childAt ( 1 ) ;
QCOMPARE ( viewPort . role ( ) , QAccessible : : List ) ;
QVERIFY ( viewPort . object ( ) ! = 0 ) ;
QCOMPARE ( viewPort . childCount ( ) , 3 ) ;
const QList < QAInterface > rows = viewPort . children ( ) ;
QCOMPARE ( rows . count ( ) , 3 ) ;
QVERIFY ( rows . at ( 0 ) . object ( ) = = 0 ) ;
QCOMPARE ( rows . at ( 0 ) . parent ( ) . indexOfChild ( rows . at ( 0 ) ) , 1 ) ;
QCOMPARE ( rows . at ( 1 ) . parent ( ) . indexOfChild ( rows . at ( 1 ) ) , 2 ) ;
QCOMPARE ( rows . at ( 2 ) . parent ( ) . indexOfChild ( rows . at ( 2 ) ) , 3 ) ;
// test the QAInterface comparison operator
QVERIFY ( rows . at ( 0 ) = = rows . at ( 0 ) ) ;
QVERIFY ( rows . at ( 0 ) ! = rows . at ( 1 ) ) ;
QVERIFY ( rows . at ( 0 ) ! = viewPort ) ;
QVERIFY ( viewPort = = viewPort ) ;
QVERIFY ( listWidgetInterface ! = viewPort ) ;
QVERIFY ( listWidgetInterface = = listWidgetInterface ) ;
// test QAInterface::isHIView()
QVERIFY ( viewPort . isHIView ( ) ) ;
QVERIFY ( listWidgetInterface . isHIView ( ) ) ;
QVERIFY ( rows . at ( 0 ) . isHIView ( ) = = false ) ;
}
const AXUIElementRef applicationElement = AXUIElementCreateApplication ( getpid ( ) ) ;
QVERIFY ( applicationElement ) ;
const AXUIElementRef windowElement = childByTitle ( applicationElement , windowTitle ) ;
QVERIFY ( windowElement ) ;
const AXUIElementRef scrollAreaElement = childByRole ( windowElement , " AXScrollArea " ) ;
QVERIFY ( scrollAreaElement ) ;
const AXUIElementRef listElement = childByRole ( scrollAreaElement , " AXList " ) ;
QVERIFY ( listElement ) ;
QVERIFY ( equal ( : : parent ( listElement ) , scrollAreaElement ) ) ;
// Window is not reported properly on 10.5
if ( QSysInfo : : MacintoshVersion < QSysInfo : : MV_10_5 )
QVERIFY ( equal ( : : window ( listElement ) , windowElement ) ) ;
const AXUIElementRef A = childByTitle ( listElement , " A " ) ;
QVERIFY ( A ) ;
const AXUIElementRef B = childByTitle ( listElement , " B " ) ;
QVERIFY ( B ) ;
const AXUIElementRef C = childByTitle ( listElement , " C " ) ;
QVERIFY ( C ) ;
QVERIFY ( value ( A ) = = " A " ) ;
QVERIFY ( equal ( : : parent ( A ) , listElement ) ) ;
QVERIFY ( enabled ( A ) ) ;
// Window is not reported properly on 10.5, this test
// hangs on 10.4. Disable it for now.
// if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_5)
// QVERIFY(equal(::window(A), windowElement));
QVERIFY ( above ( A , B ) ) ;
QVERIFY ( ! above ( B , A ) ) ;
QVERIFY ( above ( B , C ) ) ;
QVERIFY ( contains ( listElement , A ) ) ;
QVERIFY ( ! contains ( A , listElement ) ) ;
QVERIFY ( contains ( listElement , B ) ) ;
QVERIFY ( contains ( listElement , C ) ) ;
}
void tst_qaccessibility_mac : : testTableView ( )
{
QWidget window ;
const QString windowTitle ( " window " ) ;
window . setWindowTitle ( windowTitle ) ;
window . resize ( 300 , 300 ) ;
QTableWidget * tableWidget = new QTableWidget ( & window ) ;
tableWidget - > setObjectName ( " tablewidget " ) ;
tableWidget - > setRowCount ( 3 ) ;
tableWidget - > setColumnCount ( 2 ) ;
tableWidget - > setItem ( 0 , 0 , new QTableWidgetItem ( " A1 " ) ) ;
tableWidget - > setItem ( 0 , 1 , new QTableWidgetItem ( " A2 " ) ) ;
tableWidget - > setItem ( 1 , 0 , new QTableWidgetItem ( " B1 " ) ) ;
tableWidget - > setItem ( 1 , 1 , new QTableWidgetItem ( " B2 " ) ) ;
tableWidget - > setItem ( 2 , 0 , new QTableWidgetItem ( " C1 " ) ) ;
tableWidget - > setItem ( 2 , 1 , new QTableWidgetItem ( " C2 " ) ) ;
window . show ( ) ;
{
// Verify that QAInterface works as expected for table view children.
QAInterface tableWidgetInterface = QAccessible : : queryAccessibleInterface ( tableWidget ) ;
QCOMPARE ( tableWidgetInterface . role ( ) , QAccessible : : Client ) ;
QCOMPARE ( tableWidgetInterface . childCount ( ) , 1 ) ;
QAInterface viewPort = tableWidgetInterface . childAt ( 1 ) ;
QCOMPARE ( viewPort . childCount ( ) , 4 ) ;
QCOMPARE ( viewPort . role ( ) , QAccessible : : Table ) ;
QVERIFY ( viewPort . object ( ) ! = 0 ) ;
const QList < QAInterface > rows = viewPort . children ( ) ;
QCOMPARE ( rows . count ( ) , 4 ) ;
QVERIFY ( rows . at ( 0 ) . object ( ) = = 0 ) ;
QCOMPARE ( rows . at ( 0 ) . parent ( ) . indexOfChild ( rows . at ( 0 ) ) , 1 ) ;
QCOMPARE ( rows . at ( 1 ) . parent ( ) . indexOfChild ( rows . at ( 1 ) ) , 2 ) ;
QCOMPARE ( rows . at ( 2 ) . parent ( ) . indexOfChild ( rows . at ( 2 ) ) , 3 ) ;
QAInterface Arow = rows . at ( 1 ) ;
QCOMPARE ( Arow . role ( ) , QAccessible : : Row ) ;
QAInterface Brow = rows . at ( 2 ) ;
QVERIFY ( Arow . name ( ) = = " 1 " ) ;
QVERIFY ( Brow . name ( ) = = " 2 " ) ;
QVERIFY ( Arow = = Arow ) ;
QVERIFY ( Brow ! = Arow ) ;
QVERIFY ( Arow . isHIView ( ) = = false ) ;
QCOMPARE ( Arow . childCount ( ) , 3 ) ;
QList < QAInterface > Achildren = Arow . children ( ) ;
QCOMPARE ( Achildren . count ( ) , 3 ) ;
QAInterface A1 = Achildren . at ( 1 ) ;
QAInterface A2 = Achildren . at ( 2 ) ;
QCOMPARE ( Arow . indexOfChild ( A1 ) , 2 ) ;
QCOMPARE ( Arow . indexOfChild ( A2 ) , 3 ) ;
QCOMPARE ( A1 . role ( ) , QAccessible : : Cell ) ;
QList < QAInterface > Bchildren = Brow . children ( ) ;
QCOMPARE ( Bchildren . count ( ) , 3 ) ;
QAInterface B1 = Bchildren . at ( 1 ) ;
QAInterface B2 = Bchildren . at ( 2 ) ;
QVERIFY ( B1 . parent ( ) = = Brow ) ;
QVERIFY ( B1 . parent ( ) ! = Arow ) ;
QCOMPARE ( Arow . indexOfChild ( B1 ) , - 1 ) ;
QVERIFY ( A1 = = A1 ) ;
QVERIFY ( A1 ! = A2 ) ;
QVERIFY ( B1 ! = A1 ) ;
QVERIFY ( B1 ! = A2 ) ;
QVERIFY ( A1 ! = Arow ) ;
QVERIFY ( A1 ! = Brow ) ;
QVERIFY ( A1 ! = viewPort ) ;
QVERIFY ( A1 . isHIView ( ) = = false ) ;
QVERIFY ( B1 . parent ( ) = = Brow ) ;
QVERIFY ( A1 . parent ( ) = = Arow ) ;
B1 = A1 ;
QVERIFY ( B1 . parent ( ) = = Arow ) ;
}
const AXUIElementRef applicationElement = AXUIElementCreateApplication ( getpid ( ) ) ;
QVERIFY ( applicationElement ) ;
const AXUIElementRef windowElement = childByTitle ( applicationElement , windowTitle ) ;
QVERIFY ( windowElement ) ;
const AXUIElementRef scrollAreaElement = childByRole ( windowElement , " AXScrollArea " ) ;
QVERIFY ( scrollAreaElement ) ;
const AXUIElementRef tableElement = childByRole ( scrollAreaElement , " AXTable " ) ;
QVERIFY ( tableElement ) ;
{
// Verify that QAccessibleHierarchyManager can look up table view children correctly
QAccessibleHierarchyManager * manager = QAccessibleHierarchyManager : : instance ( ) ;
QAInterface tableInterface = manager - > lookup ( tableElement ) ;
QVERIFY ( tableInterface . isValid ( ) ) ;
QVERIFY ( tableInterface . role ( ) = = QAccessible : : Table ) ;
QAInterface ArowInterface = tableInterface . childAt ( 2 ) ;
QVERIFY ( ArowInterface . name ( ) = = " 1 " ) ;
QVERIFY ( manager - > lookup ( manager - > lookup ( ArowInterface ) ) . name ( ) = = " 1 " ) ;
QCOMPARE ( ArowInterface . childCount ( ) , 3 ) ;
QAInterface A1Interface = ArowInterface . childAt ( 2 ) ;
QCOMPARE ( A1Interface . value ( ) , QString ( " A1 " ) ) ;
QVERIFY ( value ( manager - > lookup ( A1Interface ) ) . toString ( ) = = " A1 " ) ;
QAInterface A2Interface = ArowInterface . childAt ( 3 ) ;
QAElement A2Element = manager - > lookup ( A2Interface ) ;
QVERIFY ( manager - > lookup ( A2Element ) . value ( ) = = " A2 " ) ;
QVERIFY ( value ( A2Element ) . toString ( ) = = " A2 " ) ;
QAInterface BrowInterface = tableInterface . childAt ( 3 ) ;
QVERIFY ( BrowInterface . value ( ) = = " 2 " ) ;
QVERIFY ( manager - > lookup ( manager - > lookup ( BrowInterface ) ) . value ( ) = = " 2 " ) ;
QCOMPARE ( BrowInterface . childCount ( ) , 3 ) ;
QAInterface B1Interface = BrowInterface . childAt ( 2 ) ;
QVERIFY ( value ( manager - > lookup ( B1Interface ) ) . toString ( ) = = " B1 " ) ;
QAInterface B2Interface = BrowInterface . childAt ( 3 ) ;
QAElement B2Element = manager - > lookup ( B2Interface ) ;
QVERIFY ( manager - > lookup ( B2Element ) . value ( ) = = " B2 " ) ;
QVERIFY ( value ( B2Element ) . toString ( ) = = " B2 " ) ;
}
const AXUIElementRef Arow = childByTitle ( tableElement , " 1 " ) ;
QVERIFY ( Arow ) ;
const AXUIElementRef Brow = childByTitle ( tableElement , " 2 " ) ;
QVERIFY ( Brow ) ;
const AXUIElementRef Crow = childByTitle ( tableElement , " 3 " ) ;
QVERIFY ( Crow ) ;
QCOMPARE ( numChildren ( Arow ) , 3 ) ;
const AXUIElementRef A1cell = childByTitle ( Arow , " A1 " ) ;
QVERIFY ( A1cell ) ;
QVERIFY ( role ( A1cell ) = = " AXTextField " ) ;
const AXUIElementRef A2cell = childByTitle ( Arow , " A2 " ) ;
QVERIFY ( A2cell ) ;
QVERIFY ( equal ( : : parent ( A2cell ) , Arow ) ) ;
const AXUIElementRef B2cell = childByTitle ( Brow , " B2 " ) ;
QVERIFY ( B2cell ) ;
QVERIFY ( equal ( : : parent ( B2cell ) , Brow ) ) ;
{
QVERIFY ( supportsAttribute ( tableElement , kAXRowsAttribute ) ) ;
const QList < AXUIElementRef > rows = elementListAttribute ( tableElement , kAXRowsAttribute ) ;
QCOMPARE ( rows . count ( ) , 3 ) ; // the header is not a row
QVERIFY ( value ( rows . at ( 1 ) ) = = " 2 " ) ;
QVERIFY ( value ( rows . at ( 2 ) ) = = " 3 " ) ;
}
{
QVERIFY ( supportsAttribute ( tableElement , kAXVisibleRowsAttribute ) ) ;
const QList < AXUIElementRef > rows = elementListAttribute ( tableElement , kAXVisibleRowsAttribute ) ;
QCOMPARE ( rows . count ( ) , 3 ) ;
QVERIFY ( value ( rows . at ( 1 ) ) = = " 2 " ) ;
}
{
QVERIFY ( supportsAttribute ( tableElement , kAXSelectedRowsAttribute ) ) ;
const QList < AXUIElementRef > rows = elementListAttribute ( tableElement , kAXSelectedRowsAttribute ) ;
QCOMPARE ( rows . count ( ) , 0 ) ;
}
// test row visibility
{
QTableWidget tableWidget ;
tableWidget . setObjectName ( " tablewidget " ) ;
tableWidget . setRowCount ( 1000 ) ;
tableWidget . setColumnCount ( 1 ) ;
for ( int i = 0 ; i < 1000 ; + + i ) {
tableWidget . setItem ( i , 0 , new QTableWidgetItem ( " item " ) ) ;
}
tableWidget . show ( ) ;
QAInterface tableWidgetInterface = QAccessible : : queryAccessibleInterface ( & tableWidget ) ;
QAInterface viewPortInterface = tableWidgetInterface . childAt ( 1 ) ;
QCOMPARE ( viewPortInterface . childCount ( ) , 1001 ) ;
QVERIFY ( ( viewPortInterface . childAt ( 2 ) . state ( ) & QAccessible : : Invisible ) = = false ) ;
QVERIFY ( ( viewPortInterface . childAt ( 2 ) . state ( ) & QAccessible : : Offscreen ) = = false ) ;
QVERIFY ( viewPortInterface . childAt ( 500 ) . state ( ) & QAccessible : : Invisible ) ;
// QVERIFY(viewPortInterface.childAt(500).state() & QAccessible::Offscreen);
tableWidget . hide ( ) ;
}
// printElementInfo(tableElement);
// QTest::qWait(1000000);
}
void tst_qaccessibility_mac : : testScrollBar ( )
{
{
QScrollBar scrollBar ;
scrollBar . show ( ) ;
QAInterface scrollBarInterface = QAccessible : : queryAccessibleInterface ( & scrollBar ) ;
QVERIFY ( scrollBarInterface . isValid ( ) ) ;
QCOMPARE ( scrollBarInterface . childCount ( ) , 5 ) ;
QCOMPARE ( scrollBarInterface . indexOfChild ( scrollBarInterface . childAt ( 1 ) ) , 1 ) ;
QCOMPARE ( scrollBarInterface . indexOfChild ( scrollBarInterface . childAt ( 2 ) ) , 2 ) ;
QCOMPARE ( scrollBarInterface . indexOfChild ( scrollBarInterface . childAt ( 5 ) ) , 5 ) ;
QCOMPARE ( scrollBarInterface . indexOfChild ( scrollBarInterface ) , - 1 ) ;
}
const AXUIElementRef currentApplication = AXUIElementCreateApplication ( getpid ( ) ) ;
testAppAndForm ( currentApplication ) ;
const AXUIElementRef form = childByTitle ( currentApplication , " Form " ) ;
QVERIFY ( form ) ;
const AXUIElementRef scrollBarElement = childByRole ( form , " AXScrollBar " ) ;
QVERIFY ( scrollBarElement ) ;
QCOMPARE ( attribute ( scrollBarElement , kAXOrientationAttribute ) . toString ( ) , QLatin1String ( " AXVerticalOrientation " ) ) ;
{
const AXUIElementRef lineUpElement = childByTitle ( scrollBarElement , " Line up " ) ;
QVERIFY ( lineUpElement ) ;
QCOMPARE ( subrole ( lineUpElement ) , QLatin1String ( " AXDecrementArrow " ) ) ;
} {
const AXUIElementRef lineDownElement = childByTitle ( scrollBarElement , " Line down " ) ;
QVERIFY ( lineDownElement ) ;
QCOMPARE ( subrole ( lineDownElement ) , QLatin1String ( " AXIncrementArrow " ) ) ;
} {
const AXUIElementRef pageUpElement = childByTitle ( scrollBarElement , " Page up " ) ;
QVERIFY ( pageUpElement ) ;
QCOMPARE ( subrole ( pageUpElement ) , QLatin1String ( " AXDecrementPage " ) ) ;
} {
const AXUIElementRef pageDownElement = childByTitle ( scrollBarElement , " Page down " ) ;
QVERIFY ( pageDownElement ) ;
QCOMPARE ( subrole ( pageDownElement ) , QLatin1String ( " AXIncrementPage " ) ) ;
} {
const AXUIElementRef valueIndicatorElement = childByTitle ( scrollBarElement , " Position " ) ;
QVERIFY ( valueIndicatorElement ) ;
QCOMPARE ( value ( valueIndicatorElement ) . toInt ( ) , 50 ) ;
}
}
void tst_qaccessibility_mac : : testSplitter ( )
{
const AXUIElementRef currentApplication = AXUIElementCreateApplication ( getpid ( ) ) ;
testAppAndForm ( currentApplication ) ;
const AXUIElementRef form = childByTitle ( currentApplication , " Form " ) ;
QVERIFY ( form ) ;
const AXUIElementRef splitGroupElement = childByRole ( form , " AXSplitGroup " ) ;
QVERIFY ( splitGroupElement ) ;
for ( int i = 0 ; i < numChildren ( splitGroupElement ) ; + + i )
QVERIFY ( child ( splitGroupElement , 3 ) ) ;
// Visual Order: Foo splitter Bar splitter Baz
QList < AXUIElementRef > splitterList = elementListAttribute ( splitGroupElement , kAXSplittersAttribute ) ;
QCOMPARE ( splitterList . count ( ) , 2 ) ;
foreach ( AXUIElementRef splitter , splitterList ) {
QCOMPARE ( role ( splitter ) , QLatin1String ( " AXSplitter " ) ) ;
QVERIFY ( supportsAttribute ( splitter , kAXPreviousContentsAttribute ) ) ;
QVERIFY ( supportsAttribute ( splitter , kAXNextContentsAttribute ) ) ;
QCOMPARE ( attribute ( splitter , kAXOrientationAttribute ) . toString ( ) , QLatin1String ( " AXVerticalOrientation " ) ) ;
QList < AXUIElementRef > prevList = elementListAttribute ( splitter , kAXPreviousContentsAttribute ) ;
QCOMPARE ( prevList . count ( ) , 1 ) ;
QList < AXUIElementRef > nextList = elementListAttribute ( splitter , kAXNextContentsAttribute ) ;
QCOMPARE ( nextList . count ( ) , 1 ) ;
// verify order
if ( title ( prevList . at ( 0 ) ) = = QLatin1String ( " Foo " ) )
QCOMPARE ( title ( nextList . at ( 0 ) ) , QLatin1String ( " Bar " ) ) ;
else if ( title ( prevList . at ( 0 ) ) = = QLatin1String ( " Bar " ) )
QCOMPARE ( title ( nextList . at ( 0 ) ) , QLatin1String ( " Baz " ) ) ;
else {
QFAIL ( " Splitter contents and handles are out of order " ) ;
}
}
}
void tst_qaccessibility_mac : : testTextEdit ( )
{
QWidget window ;
const QString windowTitle ( " window " ) ;
window . setWindowTitle ( windowTitle ) ;
window . resize ( 300 , 300 ) ;
QTextEdit * textEdit = new QTextEdit ( & window ) ;
textEdit - > resize ( 300 , 300 ) ;
const QString textLine ( " this is a line " ) ;
textEdit - > setText ( textLine ) ;
window . show ( ) ;
const AXUIElementRef applicationElement = AXUIElementCreateApplication ( getpid ( ) ) ;
QVERIFY ( applicationElement ) ;
const AXUIElementRef windowElement = childByTitle ( applicationElement , windowTitle ) ;
QVERIFY ( windowElement ) ;
const AXUIElementRef scrollAreaElement = childByRole ( windowElement , " AXScrollArea " ) ;
QVERIFY ( scrollAreaElement ) ;
const AXUIElementRef textElement = childByRole ( scrollAreaElement , " AXTextField " ) ;
QVERIFY ( textElement ) ;
QVERIFY ( value ( textElement ) = = textLine ) ;
}
void testModelLessItemView ( QAbstractItemView * itemView , const QByteArray & role )
{
const QString windowTitle ( " window " ) ;
itemView - > setWindowTitle ( windowTitle ) ;
itemView - > show ( ) ;
QTest : : qWait ( 100 ) ;
# if defined(Q_WS_X11)
qt_x11_wait_for_window_manager ( w ) ;
# endif
QAccessibleInterface * acc = QAccessible : : queryAccessibleInterface ( itemView ) ;
QVERIFY ( acc - > isValid ( ) ) ;
QCOMPARE ( acc - > childCount ( ) , 1 ) ;
acc - > role ( 0 ) ;
acc - > rect ( 0 ) ;
QAccessibleInterface * accViewport = 0 ;
int entry = acc - > navigate ( QAccessible : : Child , 1 , & accViewport ) ;
QVERIFY ( accViewport ) ;
QCOMPARE ( entry , 0 ) ;
QVERIFY ( accViewport - > isValid ( ) ) ;
QCOMPARE ( accViewport - > childCount ( ) , 0 ) ;
accViewport - > role ( 0 ) ;
accViewport - > rect ( 0 ) ;
delete acc ;
delete accViewport ;
const AXUIElementRef applicationElement = AXUIElementCreateApplication ( getpid ( ) ) ;
QVERIFY ( applicationElement ) ;
const AXUIElementRef windowElement = childByTitle ( applicationElement , windowTitle ) ;
QVERIFY ( windowElement ) ;
const AXUIElementRef scrollAreaElement = childByRole ( windowElement , " AXScrollArea " ) ;
QVERIFY ( scrollAreaElement ) ;
const AXUIElementRef tableElement = childByRole ( scrollAreaElement , role ) ;
QVERIFY ( tableElement ) ;
delete itemView ;
}
void tst_qaccessibility_mac : : testItemViewsWithoutModel ( )
{
testModelLessItemView ( new QListView ( ) , " AXList " ) ;
testModelLessItemView ( new QTableView ( ) , " AXTable " ) ;
}
void tst_qaccessibility_mac : : testQAElement ( )
{
{
QAElement element ;
QVERIFY ( element . isValid ( ) = = false ) ;
}
{
QAElement element ( 0 , 0 ) ;
QVERIFY ( element . isValid ( ) = = false ) ;
}
{
int argc = 0 ;
char * * argv = 0 ;
QApplication app ( argc , argv ) ;
QWidget w ;
QAElement element ( reinterpret_cast < HIObjectRef > ( w . winId ( ) ) , 0 ) ;
QVERIFY ( element . isValid ( ) = = true ) ;
}
}
void tst_qaccessibility_mac : : testQAInterface ( )
{
{
QAInterface interface ;
QVERIFY ( interface . isValid ( ) = = false ) ;
}
{
QAInterface interface ( 0 , 0 ) ;
QVERIFY ( interface . isValid ( ) = = false ) ;
}
{
int argc = 0 ;
char * * argv = 0 ;
QApplication app ( argc , argv ) ;
{
QWidget w ;
QAInterface element ( QAccessible : : queryAccessibleInterface ( & w ) , 0 ) ;
QVERIFY ( element . isValid ( ) = = true ) ;
}
{
QWidget w ;
QAInterface element ( QAccessible : : queryAccessibleInterface ( & w ) , 100 ) ;
QVERIFY ( element . isValid ( ) = = false ) ;
}
}
}
void tst_qaccessibility_mac : : uitests_data ( )
{
QTest : : addColumn < QString > ( " uiFilename " ) ;
QTest : : addColumn < QString > ( " testSlot " ) ;
QTest : : newRow ( " form " ) < < " form.ui " < < SLOT ( testForm ( ) ) ;
QTest : : newRow ( " buttons " ) < < " buttons.ui " < < SLOT ( testButtons ( ) ) ;
QTest : : newRow ( " label " ) < < " label.ui " < < SLOT ( testLabel ( ) ) ;
QTest : : newRow ( " line edit " ) < < " lineedit.ui " < < SLOT ( testLineEdit ( ) ) ;
QTest : : newRow ( " groups " ) < < " groups.ui " < < SLOT ( testGroups ( ) ) ;
QTest : : newRow ( " tabs " ) < < " tabs.ui " < < SLOT ( testTabWidget ( ) ) ;
QTest : : newRow ( " combobox " ) < < " combobox.ui " < < SLOT ( testComboBox ( ) ) ;
QTest : : newRow ( " scrollbar " ) < < " scrollbar.ui " < < SLOT ( testScrollBar ( ) ) ;
QTest : : newRow ( " splitters " ) < < " splitters.ui " < < SLOT ( testSplitter ( ) ) ;
}
void tst_qaccessibility_mac : : uitests ( )
{
QFETCH ( QString , uiFilename ) ;
QFETCH ( QString , testSlot ) ;
// The Accessibility interface must be enabled to run this test.
if ( ! AXAPIEnabled ( ) )
QSKIP ( " Accessibility not enabled. Check \" Enable access for assistive devices \" in the system preferences -> universal access to run this test. " , SkipAll ) ;
int argc = 0 ;
char * * argv = 0 ;
QApplication app ( argc , argv ) ;
// Create and display form.
QUiLoader loader ;
QFile file ( " : " + uiFilename ) ;
QVERIFY ( file . exists ( ) ) ;
file . open ( QFile : : ReadOnly ) ;
QWidget * window = loader . load ( & file , 0 ) ;
QVERIFY ( window ) ;
file . close ( ) ;
window - > show ( ) ;
QTimer : : singleShot ( 50 , this , qPrintable ( testSlot ) ) ;
// Quit when returning to the main event loop after running tests.
QTimer : : singleShot ( 200 , & app , SLOT ( quit ( ) ) ) ;
app . exec ( ) ;
delete window ;
}
void tst_qaccessibility_mac : : tests_data ( )
{
QTest : : addColumn < QString > ( " testSlot " ) ;
QTest : : newRow ( " deleteWidget " ) < < SLOT ( testDeleteWidget ( ) ) ;
QTest : : newRow ( " deleteWidgets " ) < < SLOT ( testDeleteWidgets ( ) ) ;
QTest : : newRow ( " multipleWindows " ) < < SLOT ( testMultipleWindows ( ) ) ;
QTest : : newRow ( " hiddenWidgets " ) < < SLOT ( testHiddenWidgets ( ) ) ;
QTest : : newRow ( " actions " ) < < SLOT ( testActions ( ) ) ;
QTest : : newRow ( " changeState " ) < < SLOT ( testChangeState ( ) ) ;
QTest : : newRow ( " slider " ) < < SLOT ( testSlider ( ) ) ;
QTest : : newRow ( " scrollArea " ) < < SLOT ( testScrollArea ( ) ) ;
QTest : : newRow ( " listView " ) < < SLOT ( testListView ( ) ) ;
QTest : : newRow ( " tableView " ) < < SLOT ( testTableView ( ) ) ;
QTest : : newRow ( " textEdit " ) < < SLOT ( testTextEdit ( ) ) ;
QTest : : newRow ( " ItemViews without model " ) < < SLOT ( testItemViewsWithoutModel ( ) ) ;
QTest : : newRow ( " tabbar " ) < < SLOT ( testTabBar ( ) ) ;
}
void tst_qaccessibility_mac : : tests ( )
{
QFETCH ( QString , testSlot ) ;
runTest ( testSlot ) ;
}
/*
Tests show that querying the accessibility interface directly does not work . ( I get a
kAXErrorAPIDisabled error , indicating that the accessible API is disabled , which it isn ' t . )
To work around this , we run the tests in a callback slot called from the main event loop .
*/
void tst_qaccessibility_mac : : runTest ( const QString & testSlot )
{
// The Accessibility interface must be enabled to run this test.
if ( ! AXAPIEnabled ( ) )
QSKIP ( " Accessibility not enabled. Check \" Enable access for assistive devices \" in the system preferences -> universal access to run this test. " , SkipAll ) ;
int argc = 0 ;
char * * argv = 0 ;
QApplication app ( argc , argv ) ;
QTimer : : singleShot ( 50 , this , qPrintable ( testSlot ) ) ;
// Quit when returning to the main event loop after running tests.
QTimer : : singleShot ( 200 , & app , SLOT ( quit ( ) ) ) ;
app . exec ( ) ;
}
QTEST_APPLESS_MAIN ( tst_qaccessibility_mac )
# else // defined(Q_WS_MAC) && !defined (QT_MAC_USE_COCOA)
QTEST_NOOP_MAIN
# endif
# include "tst_qaccessibility_mac.moc"