summaryrefslogtreecommitdiffstats
path: root/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm')
-rw-r--r--tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm260
1 files changed, 223 insertions, 37 deletions
diff --git a/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm b/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm
index b004e985bd..9573d26bd2 100644
--- a/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm
+++ b/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm
@@ -60,6 +60,43 @@ bool trusted()
return AXIsProcessTrusted();
}
+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)) { \
@@ -71,11 +108,6 @@ bool trusted()
@interface TestAXObject : NSObject
{
AXUIElementRef reference;
- NSString *_role;
- NSString *_title;
- NSString *_description;
- NSString *_value;
- CGRect _rect;
}
@property (readonly) NSString *role;
@property (readonly) NSString *title;
@@ -86,26 +118,10 @@ bool trusted()
@implementation TestAXObject
- @synthesize role = _role;
- @synthesize title = _title;
- @synthesize description = _description;
- @synthesize value = _value;
- @synthesize rect = _rect;
-
- (id) initWithAXUIElementRef: (AXUIElementRef) ref {
if ( self = [super init] ) {
reference = ref;
- AXUIElementCopyAttributeValue(ref, kAXRoleAttribute, (CFTypeRef*)&_role);
- AXUIElementCopyAttributeValue(ref, kAXTitleAttribute, (CFTypeRef*)&_title);
- AXUIElementCopyAttributeValue(ref, kAXDescriptionAttribute, (CFTypeRef*)&_description);
- AXUIElementCopyAttributeValue(ref, kAXValueAttribute, (CFTypeRef*)&_value);
- AXValueRef sizeValue;
- AXUIElementCopyAttributeValue(ref, kAXSizeAttribute, (CFTypeRef*)&sizeValue);
- AXValueGetValue(sizeValue, kAXValueCGSizeType, &_rect.size);
- AXValueRef positionValue;
- AXUIElementCopyAttributeValue(ref, kAXPositionAttribute, (CFTypeRef*)&positionValue);
- AXValueGetValue(positionValue, kAXValueCGPointType, &_rect.origin);
}
return self;
}
@@ -140,24 +156,18 @@ bool trusted()
- (AXUIElementRef) findDirectChildByRole: (CFStringRef) role
{
- AXUIElementRef result = nil;
+ TestAXObject *result = nil;
NSArray *childList = [self childList];
for (id child in childList) {
- CFStringRef typeString;
- AXUIElementCopyAttributeValue((AXUIElementRef)child, kAXRoleAttribute, (CFTypeRef*)&typeString);
- if (CFStringCompare(typeString, role, 0) == 0) {
- result = (AXUIElementRef) child;
+ TestAXObject *childObject = [[TestAXObject alloc] initWithAXUIElementRef:(AXUIElementRef)child];
+ if ([childObject.role isEqualToString:(NSString*)role]) {
+ result = childObject;
break;
}
}
- return result;
-}
-
-- (AXUIElementRef) parent
-{
- AXUIElementRef p = nil;
- AXUIElementCopyAttributeValue(reference, kAXParentAttribute, (CFTypeRef*)&p);
- return p;
+ AXUIElementRef ret = [result ref];
+ [result release];
+ return ret;
}
+ (TestAXObject *) getApplicationAXObject
@@ -168,6 +178,184 @@ bool trusted()
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, 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, 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, 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, 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(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(kAXValueCGPointType, &aPoint);
+ CFTypeRef value = [self _attributeValue:attribute forParameter:point];
+ CFRelease(point);
+ return value;
+}
+
+- (NSString*) role { return [self _stringAttributeValue:kAXRoleAttribute]; }
+- (NSString*) title { return [self _stringAttributeValue:kAXTitleAttribute]; }
+- (NSString*) description { return [self _stringAttributeValue:kAXDescriptionAttribute]; }
+- (NSString*) value { return [self _stringAttributeValue: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
@@ -225,9 +413,7 @@ bool testLineEdit()
// height of window includes title bar
EXPECT([window rect].size.height >= 400);
- NSString *windowTitle;
- AXUIElementCopyAttributeValue(windowRef, kAXTitleAttribute, (CFTypeRef*)&windowTitle);
- EXPECT([windowTitle isEqualToString:@"Test window"]);
+ EXPECT([window.title isEqualToString:@"Test window"]);
// children of window:
AXUIElementRef lineEdit = [window findDirectChildByRole: kAXTextFieldRole];