diff options
Diffstat (limited to 'tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm')
-rw-r--r-- | tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm | 600 |
1 files changed, 0 insertions, 600 deletions
diff --git a/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm b/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm deleted file mode 100644 index 4ebf7a37f9..0000000000 --- a/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm +++ /dev/null @@ -1,600 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// some versions of CALayer.h use 'slots' as an identifier -#define QT_NO_KEYWORDS - -#include "tst_qaccessibilitymac_helpers.h" -#include <QtWidgets/qapplication.h> -#include <QtWidgets/qlineedit.h> -#include <QtWidgets/qpushbutton.h> -#include <QtWidgets> -#include <QtTest> -#include <unistd.h> - -#import <AppKit/AppKit.h> -#import <ApplicationServices/ApplicationServices.h> - -QT_USE_NAMESPACE - -struct AXErrorTag { - AXError err; - explicit AXErrorTag(AXError theErr) : err(theErr) {} -}; - -QDebug operator<<(QDebug dbg, AXErrorTag err) -{ - QDebugStateSaver saver(dbg); - - const char *errDesc = 0; - const char *errName = 0; - switch (err.err) { -#define HANDLE_ERR(error, desc) case kAXError##error: errName = "kAXError" #error; errDesc = desc; break - HANDLE_ERR(Success, "Success"); - HANDLE_ERR(Failure, "A system error occurred, such as the failure to allocate an object."); - HANDLE_ERR(IllegalArgument, "An illegal argument was passed to the function."); - HANDLE_ERR(InvalidUIElement, "The AXUIElementRef passed to the function is invalid."); - HANDLE_ERR(InvalidUIElementObserver, "The AXObserverRef passed to the function is not a valid observer."); - HANDLE_ERR(CannotComplete, "The function cannot complete because messaging failed in some way or because the application with which the function is communicating is busy or unresponsive."); - HANDLE_ERR(AttributeUnsupported, "The attribute is not supported by the AXUIElementRef."); - HANDLE_ERR(ActionUnsupported, "The action is not supported by the AXUIElementRef."); - HANDLE_ERR(NotificationUnsupported, "The notification is not supported by the AXUIElementRef."); - HANDLE_ERR(NotImplemented, "Indicates that the function or method is not implemented (this can be returned if a process does not support the accessibility API)."); - HANDLE_ERR(NotificationAlreadyRegistered, "This notification has already been registered for."); - HANDLE_ERR(NotificationNotRegistered, "Indicates that a notification is not registered yet."); - HANDLE_ERR(APIDisabled, "The accessibility API is disabled (as when, for example, the user deselects \"Enable access for assistive devices\" in Universal Access Preferences)."); - HANDLE_ERR(NoValue, "The requested value or AXUIElementRef does not exist."); - HANDLE_ERR(ParameterizedAttributeUnsupported, "The parameterized attribute is not supported by the AXUIElementRef."); - HANDLE_ERR(NotEnoughPrecision, "Not enough precision."); - default: errName = "<unknown error>"; errDesc = "UNKNOWN ERROR"; break; - } -#undef HANDLE_ERR - - dbg.nospace() << "AXError(value=" << err.err << ", name=" << errName << ", description=\"" << errDesc << "\")"; - - return dbg; -} - -#define EXPECT(cond) \ - if (!(cond)) { \ - qWarning("Failure in %s, line: %d", __FILE__ , __LINE__); \ - return false; \ - } \ - - -@interface TestAXObject : NSObject -{ - AXUIElementRef reference; -} - @property (readonly) NSString *role; - @property (readonly) NSString *title; - @property (readonly) NSString *description; - @property (readonly) NSString *value; - @property (readonly) CGRect rect; - @property (readonly) NSArray *actions; -@end - -@implementation TestAXObject - -- (instancetype)initWithAXUIElementRef:(AXUIElementRef)ref { - - if ((self = [super init])) { - reference = ref; - } - return self; -} - -- (AXUIElementRef) ref { return reference; } -- (void) print { - NSLog(@"Accessible Object role: '%@', title: '%@', description: '%@', value: '%@', rect: '%@'", self.role, self.title, self.description, self.value, NSStringFromRect(NSRectFromCGRect(self.rect))); - NSLog(@" Children: %ld", [[self childList] count]); -} - -- (NSArray*) windowList -{ - NSArray *list; - AXUIElementCopyAttributeValues( - reference, - kAXWindowsAttribute, - 0, 100, /*min, max*/ - (CFArrayRef *) &list); - return list; -} - -- (NSArray*) childList -{ - NSArray *list; - AXUIElementCopyAttributeValues( - reference, - kAXChildrenAttribute, - 0, 100, /*min, max*/ - (CFArrayRef *) &list); - return list; -} - -- (AXUIElementRef) findDirectChildByRole: (CFStringRef) role -{ - TestAXObject *result = nil; - NSArray *childList = [self childList]; - for (id child in childList) { - TestAXObject *childObject = [[TestAXObject alloc] initWithAXUIElementRef:(AXUIElementRef)child]; - if ([childObject.role isEqualToString:(NSString*)role]) { - result = childObject; - break; - } - } - AXUIElementRef ret = [result ref]; - [result release]; - return ret; -} - -+ (TestAXObject *) getApplicationAXObject -{ - pid_t pid = getpid(); - AXUIElementRef appRef = AXUIElementCreateApplication(pid); - TestAXObject *appObject = [[TestAXObject alloc] initWithAXUIElementRef: appRef]; - return appObject; -} - -+ (NSInteger)_numberFromValue:(CFTypeRef)value -{ - NSInteger number = -1; - if (!CFNumberGetValue((CFNumberRef)value, kCFNumberNSIntegerType, &number)) - { - qDebug() << "Could not get NSInteger value out of CFNumberRef"; - } - return number; -} - -+ (BOOL)_boolFromValue:(CFTypeRef)value -{ - return CFBooleanGetValue((CFBooleanRef)value); -} - -+ (NSRange)_rangeFromValue:(CFTypeRef)value -{ - CFRange cfRange; - NSRange range = NSMakeRange(0, 0); - - if (!AXValueGetValue(AXValueRef(value), AXValueType(kAXValueCFRangeType), &cfRange)) - qDebug() << "Could not get CFRange value out of AXValueRef"; - else if (cfRange.location < 0 || cfRange.length < 0) - qDebug() << "Cannot convert CFRange with negative location or length to NSRange"; - else if (static_cast<uintmax_t>(cfRange.location) > NSUIntegerMax || static_cast<uintmax_t>(cfRange.length) > NSUIntegerMax) - qDebug() << "Cannot convert CFRange with location or length out of bounds for NSUInteger"; - else - { - range.length = static_cast<NSUInteger>(cfRange.length); - range.location = static_cast<NSUInteger>(cfRange.location); - } - - return range; -} - -+ (NSRect)_rectFromValue:(CFTypeRef)value -{ - NSRect rect = NSMakeRect(0, 0, 0, 0); - if (!AXValueGetValue(AXValueRef(value), AXValueType(kAXValueCGRectType), reinterpret_cast<CGRect*>(&rect))) - { - qDebug() << "Could not get CGRect value out of AXValueRef"; - } - return rect; -} - -+ (NSPoint)_pointFromValue:(CFTypeRef)value -{ - NSPoint point = NSMakePoint(0, 0); - if (!AXValueGetValue(AXValueRef(value), AXValueType(kAXValueCGPointType), reinterpret_cast<CGPoint*>(&point))) - { - qDebug() << "Could not get CGPoint value out of AXValueRef"; - } - return point; -} - -+ (NSSize)_sizeFromValue:(CFTypeRef)value -{ - NSSize size = NSMakeSize(0, 0); - if (!AXValueGetValue(AXValueRef(value), AXValueType(kAXValueCGSizeType), reinterpret_cast<CGSize*>(&size))) - { - qDebug() << "Could not get CGSize value out of AXValueRef"; - } - return size; -} - -- (CFTypeRef)_attributeValue:(CFStringRef)attribute -{ - CFTypeRef value = NULL; - AXError err; - - if (kAXErrorSuccess != (err = AXUIElementCopyAttributeValue(reference, attribute, &value))) - { - qDebug() << "AXUIElementCopyAttributeValue(" << QString::fromCFString(attribute) << ") returned error = " << AXErrorTag(err); - } - return value; -} - -- (NSString*)_stringAttributeValue:(CFStringRef)attribute -{ - return (NSString*)[self _attributeValue:attribute]; -} - -- (NSInteger)_numberAttributeValue:(CFStringRef)attribute -{ - return [[self class] _numberFromValue:[self _attributeValue:attribute]]; -} - -- (BOOL)_boolAttributeValue:(CFStringRef)attribute -{ - return [[self class] _boolFromValue:[self _attributeValue:attribute]]; -} - -- (NSRange)_rangeAttributeValue:(CFStringRef)attribute -{ - return [[self class] _rangeFromValue:[self _attributeValue:attribute]]; -} - -- (NSRect)_rectAttributeValue:(CFStringRef)attribute -{ - return [[self class] _rectFromValue:[self _attributeValue:attribute]]; -} - -- (NSPoint)_pointAttributeValue:(CFStringRef)attribute -{ - return [[self class] _pointFromValue:[self _attributeValue:attribute]]; -} - -- (NSSize)_sizeAttributeValue:(CFStringRef)attribute -{ - return [[self class] _sizeFromValue:[self _attributeValue:attribute]]; -} - -- (CFTypeRef)_attributeValue:(CFStringRef)attribute forParameter:(CFTypeRef)parameter -{ - CFTypeRef value = NULL; - AXError err; - - if (kAXErrorSuccess != (err = AXUIElementCopyParameterizedAttributeValue(reference, attribute, parameter, &value))) - { - CFStringRef description = CFCopyDescription(parameter); - qDebug() << "AXUIElementCopyParameterizedAttributeValue(" << QString::fromCFString(attribute) << ", parameter=" << QString::fromCFString(description) << ") returned error = " << AXErrorTag(err); - CFRelease(description); - } - return value; -} - -- (CFTypeRef)_attributeValue:(CFStringRef)attribute forRange:(NSRange)aRange -{ - CFRange cfRange = CFRangeMake(aRange.location, aRange.length); - AXValueRef range = AXValueCreate(AXValueType(kAXValueCFRangeType), &cfRange); - CFTypeRef value = [self _attributeValue:attribute forParameter:range]; - CFRelease(range); - return value; -} - -- (CFTypeRef)_attributeValue:(CFStringRef)attribute forNumber:(NSInteger)aNumber -{ - CFNumberRef number = CFNumberCreate(NULL, kCFNumberNSIntegerType, &aNumber); - CFTypeRef value = [self _attributeValue:attribute forParameter:number]; - CFRelease(number); - return value; -} - -- (CFTypeRef)_attributeValue:(CFStringRef)attribute forPoint:(CGPoint)aPoint -{ - AXValueRef point = AXValueCreate(AXValueType(kAXValueCGPointType), &aPoint); - CFTypeRef value = [self _attributeValue:attribute forParameter:point]; - CFRelease(point); - return value; -} - -- (NSArray*)actions -{ - AXError err; - CFArrayRef actions; - - if (kAXErrorSuccess != (err = AXUIElementCopyActionNames(reference, &actions))) - { - qDebug() << "AXUIElementCopyActionNames(...) returned error = " << AXErrorTag(err); - } - - return (NSArray*)actions; -} - -- (void)performAction:(CFStringRef)action -{ - AXError err; - - if (kAXErrorSuccess != (err = AXUIElementPerformAction(reference, action))) - { - qDebug() << "AXUIElementPerformAction(" << QString::fromCFString(action) << ") returned error = " << AXErrorTag(err); - } -} - -- (NSString*) role { return [self _stringAttributeValue:kAXRoleAttribute]; } -- (NSString*) title { return [self _stringAttributeValue:kAXTitleAttribute]; } -- (NSString*) description { return [self _stringAttributeValue:kAXDescriptionAttribute]; } -- (NSString*) value { return [self _stringAttributeValue:kAXValueAttribute]; } -- (NSInteger) valueNumber { return [self _numberAttributeValue:kAXValueAttribute]; } -- (NSRect) rect -{ - NSRect rect; - rect.origin = [self _pointAttributeValue:kAXPositionAttribute]; - rect.size = [self _sizeAttributeValue:kAXSizeAttribute]; - return rect; -} -- (AXUIElementRef) parent { return (AXUIElementRef)[self _attributeValue:kAXParentAttribute]; } -- (BOOL) focused { return [self _boolAttributeValue:kAXFocusedAttribute]; } -- (NSInteger) numberOfCharacters { return [self _numberAttributeValue:kAXNumberOfCharactersAttribute]; } -- (NSString*) selectedText { return [self _stringAttributeValue:kAXSelectedTextAttribute]; } -- (NSRange) selectedTextRange { return [self _rangeAttributeValue:kAXSelectedTextRangeAttribute]; } -- (NSRange) visibleCharacterRange { return [self _rangeAttributeValue:kAXVisibleCharacterRangeAttribute]; } -- (NSString*) help { return [self _stringAttributeValue:kAXHelpAttribute]; } -- (NSInteger) insertionPointLineNumber { return [self _numberAttributeValue:kAXInsertionPointLineNumberAttribute]; } - -- (NSInteger) lineForIndex:(NSInteger)index { return [[self class] _numberFromValue:[self _attributeValue:kAXLineForIndexParameterizedAttribute forNumber:index]]; } -- (NSRange) rangeForLine:(NSInteger)line { return [[self class] _rangeFromValue:[self _attributeValue:kAXRangeForLineParameterizedAttribute forNumber:line]]; } -- (NSString*) stringForRange:(NSRange)range { return (NSString*)[self _attributeValue:kAXStringForRangeParameterizedAttribute forRange:range]; } -- (NSAttributedString*) attributedStringForRange:(NSRange)range { return (NSAttributedString*)[self _attributeValue:kAXAttributedStringForRangeParameterizedAttribute forRange:range]; } -- (NSRect) boundsForRange:(NSRange)range { return [[self class] _rectFromValue:[self _attributeValue:kAXBoundsForRangeParameterizedAttribute forRange:range]]; } -- (NSRange) styleRangeForIndex:(NSInteger)index { return [[self class] _rangeFromValue:[self _attributeValue:kAXStyleRangeForIndexParameterizedAttribute forNumber:index]]; } - -@end - - -bool singleWidget() -{ - QLineEdit *le = new QLineEdit(); - le->setText("button"); - le->show(); - EXPECT(QTest::qWaitForWindowExposed(le)); - QCoreApplication::processEvents(); - - TestAXObject *appObject = [TestAXObject getApplicationAXObject]; - EXPECT(appObject); - - NSArray *windows = [appObject windowList]; - EXPECT([windows count] == 1); - - AXUIElementRef windowRef = (AXUIElementRef) [windows objectAtIndex: 0]; - EXPECT(windowRef != nil); - TestAXObject *window = [[TestAXObject alloc] initWithAXUIElementRef: windowRef]; - - AXUIElementRef lineEditRef = [window findDirectChildByRole: kAXTextFieldRole]; - EXPECT(lineEditRef != nil); - TestAXObject *lineEdit = [[TestAXObject alloc] initWithAXUIElementRef: lineEditRef]; - EXPECT([[lineEdit value] isEqualToString:@"button"]); - - // Access invalid reference, should return empty value - delete le; - QCoreApplication::processEvents(); - TestAXObject *lineEditInvalid = [[TestAXObject alloc] initWithAXUIElementRef: lineEditRef]; - EXPECT([[lineEditInvalid value] length] == 0); - - return true; -} - -bool testLineEdit() -{ - TestAXObject *appObject = [TestAXObject getApplicationAXObject]; - EXPECT(appObject); - - NSArray *windowList = [appObject windowList]; - // one window - EXPECT([windowList count] == 1); - AXUIElementRef windowRef = (AXUIElementRef) [windowList objectAtIndex: 0]; - EXPECT(windowRef != nil); - TestAXObject *window = [[TestAXObject alloc] initWithAXUIElementRef: windowRef]; - - EXPECT([window rect].size.width == 400); - // height of window includes title bar - EXPECT([window rect].size.height >= 400); - - EXPECT([window.title isEqualToString:@"Test window"]); - - // children of window: - AXUIElementRef lineEdit = [window findDirectChildByRole: kAXTextFieldRole]; - EXPECT(lineEdit != nil); - - TestAXObject *le = [[TestAXObject alloc] initWithAXUIElementRef: lineEdit]; - NSString *value = @"a11y test QLineEdit"; - EXPECT([le.value isEqualToString:value]); - EXPECT(value.length <= NSIntegerMax); - EXPECT(le.numberOfCharacters == static_cast<NSInteger>(value.length)); - const NSRange ranges[] = { - { 0, 0}, - { 0, 1}, - { 0, 5}, - { 5, 0}, - { 5, 1}, - { 0, value.length}, - { value.length, 0}, - }; - for (size_t i = 0; i < sizeof(ranges)/sizeof(ranges[0]); ++i) { - NSRange range = ranges[i]; - NSString *expectedSubstring = [value substringWithRange:range]; - NSString *actualSubstring = [le stringForRange:range]; - NSString *actualAttributedSubstring = [le attributedStringForRange:range].string; - EXPECT([actualSubstring isEqualTo:expectedSubstring]); - EXPECT([actualAttributedSubstring isEqualTo:expectedSubstring]); - } - return true; -} - -bool testHierarchy(QWidget *w) -{ - TestAXObject *appObject = [TestAXObject getApplicationAXObject]; - EXPECT(appObject); - - NSArray *windowList = [appObject windowList]; - // one window - EXPECT([windowList count] == 1); - AXUIElementRef windowRef = (AXUIElementRef) [windowList objectAtIndex: 0]; - EXPECT(windowRef != nil); - TestAXObject *window = [[TestAXObject alloc] initWithAXUIElementRef: windowRef]; - - // Because the plain widget is filtered out of the hierarchy, we expect the button - // to be a direct child of the window - AXUIElementRef buttonRef = [window findDirectChildByRole: kAXButtonRole]; - EXPECT(buttonRef != nil); - - TestAXObject *buttonObject = [[TestAXObject alloc] initWithAXUIElementRef: buttonRef]; - TestAXObject *parentObject = [[TestAXObject alloc] initWithAXUIElementRef: [buttonObject parent]]; - - // check that the parent is a window - EXPECT([[parentObject role] isEqualToString: NSAccessibilityWindowRole]); - - // test the focus - // child 0 is the layout, then button1 and 2 - QPushButton *button1 = qobject_cast<QPushButton*>(w->children().at(1)); - EXPECT(button1); - QPushButton *button2 = qobject_cast<QPushButton*>(w->children().at(2)); - EXPECT(button2); - button2->setFocus(); - - AXUIElementRef systemWideElement = AXUIElementCreateSystemWide(); - AXUIElementRef focussedElement = NULL; - AXError error = AXUIElementCopyAttributeValue(systemWideElement, - (CFStringRef)NSAccessibilityFocusedUIElementAttribute, (CFTypeRef*)&focussedElement); - EXPECT(!error); - EXPECT(focussedElement); - TestAXObject *focusButton2 = [[TestAXObject alloc] initWithAXUIElementRef: focussedElement]; - - EXPECT([[focusButton2 role] isEqualToString: NSAccessibilityButtonRole]); - EXPECT([[focusButton2 title] isEqualToString: @"Button 2"]); - - - button1->setFocus(); - error = AXUIElementCopyAttributeValue(systemWideElement, - (CFStringRef)NSAccessibilityFocusedUIElementAttribute, (CFTypeRef*)&focussedElement); - EXPECT(!error); - EXPECT(focussedElement); - TestAXObject *focusButton1 = [[TestAXObject alloc] initWithAXUIElementRef: focussedElement]; - EXPECT([[focusButton1 role] isEqualToString: NSAccessibilityButtonRole]); - EXPECT([[focusButton1 title] isEqualToString: @"I am a button"]); - - return true; -} - -QVector<int> notificationList; - -void observerCallback(AXObserverRef /*observer*/, AXUIElementRef /*element*/, CFStringRef notification, void *) -{ - if ([(NSString*)notification isEqualToString: NSAccessibilityFocusedUIElementChangedNotification]) - notificationList.append(QAccessible::Focus); - else if ([(NSString*)notification isEqualToString: NSAccessibilityValueChangedNotification]) - notificationList.append(QAccessible::ValueChanged); - else - notificationList.append(-1); -} - - -bool notifications(QWidget *w) -{ - QLineEdit *le1 = new QLineEdit(w); - QLineEdit *le2 = new QLineEdit(w); - w->layout()->addWidget(le1); - w->layout()->addWidget(le2); - - QCoreApplication::processEvents(); - QTest::qWait(100); - - TestAXObject *appObject = [TestAXObject getApplicationAXObject]; - EXPECT(appObject); - - NSArray *windowList = [appObject windowList]; - // one window - EXPECT([windowList count] == 1); - AXUIElementRef windowRef = (AXUIElementRef) [windowList objectAtIndex: 0]; - EXPECT(windowRef != nil); - TestAXObject *window = [[TestAXObject alloc] initWithAXUIElementRef: windowRef]; - - AXUIElementRef lineEdit1 = [window findDirectChildByRole: kAXTextFieldRole]; - EXPECT(lineEdit1 != nil); - - AXObserverRef observer = 0; - AXError err = AXObserverCreate(getpid(), observerCallback, &observer); - EXPECT(!err); - AXObserverAddNotification(observer, appObject.ref, kAXFocusedUIElementChangedNotification, 0); - AXObserverAddNotification(observer, lineEdit1, kAXValueChangedNotification, 0); - - CFRunLoopAddSource( [[NSRunLoop currentRunLoop] getCFRunLoop], AXObserverGetRunLoopSource(observer), kCFRunLoopDefaultMode); - - EXPECT(notificationList.length() == 0); - le2->setFocus(); - QCoreApplication::processEvents(); - EXPECT(notificationList.length() == 1); - EXPECT(notificationList.at(0) == QAccessible::Focus); - le1->setFocus(); - QCoreApplication::processEvents(); - EXPECT(notificationList.length() == 2); - EXPECT(notificationList.at(1) == QAccessible::Focus); - le1->setText("hello"); - QCoreApplication::processEvents(); - EXPECT(notificationList.length() == 3); - EXPECT(notificationList.at(2) == QAccessible::ValueChanged); - le1->setText("foo"); - QCoreApplication::processEvents(); - EXPECT(notificationList.length() == 4); - EXPECT(notificationList.at(3) == QAccessible::ValueChanged); - - return true; -} - -bool testCheckBox() -{ - TestAXObject *appObject = [TestAXObject getApplicationAXObject]; - EXPECT(appObject); - - NSArray *windowList = [appObject windowList]; - // one window - EXPECT([windowList count] == 1); - AXUIElementRef windowRef = (AXUIElementRef) [windowList objectAtIndex: 0]; - EXPECT(windowRef != nil); - TestAXObject *window = [[TestAXObject alloc] initWithAXUIElementRef: windowRef]; - - // children of window: - AXUIElementRef checkBox = [window findDirectChildByRole: kAXCheckBoxRole]; - EXPECT(checkBox != nil); - - TestAXObject *cb = [[TestAXObject alloc] initWithAXUIElementRef: checkBox]; - - // here start actual checkbox tests - EXPECT([cb valueNumber] == 0); - EXPECT([cb.title isEqualToString:@"Great option"]); - // EXPECT(cb.description == nil); // currently returns "" instead of nil - - EXPECT([cb.actions containsObject:(NSString*)kAXPressAction]); - - [cb performAction:kAXPressAction]; - EXPECT([cb valueNumber] == 1); - - [cb performAction:kAXPressAction]; - EXPECT([cb valueNumber] == 0); - - return true; -} |