Skip to content

Commit cdeab2e

Browse files
committed
Future iOS SDK compatibility.
Makes app work with SDK's that do not contain UITouch->_gestureView. Work around defect in current betas where accessibilityValue may return an NSAttributedString. Address issues where an application's keyWindow may not be a member of the windows array. Increase the timeout between scrolling to a cell and looking it up. Note that the latest simulator release has issues with accessibility and the tests will need to be run on device or with an earlier simulator.
1 parent 1e4b0e8 commit cdeab2e

6 files changed

Lines changed: 35 additions & 14 deletions

File tree

Additions/UIApplication-KIFAdditions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@
1919

2020
- (UIWindow *)keyboardWindow;
2121
- (UIWindow *)pickerViewWindow;
22+
- (NSArray *)windowsWithKeyWindow;
2223

2324
@end

Additions/UIApplication-KIFAdditions.m

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ - (UIAccessibilityElement *)accessibilityElementWithLabel:(NSString *)label acce
3131
{
3232
// Go through the array of windows in reverse order to process the frontmost window first.
3333
// When several elements with the same accessibilitylabel are present the one in front will be picked.
34-
for (UIWindow *window in [self.windows reverseObjectEnumerator]) {
34+
for (UIWindow *window in [self.windowsWithKeyWindow reverseObjectEnumerator]) {
3535
UIAccessibilityElement *element = [window accessibilityElementWithLabel:label accessibilityValue:value traits:traits];
3636
if (element) {
3737
return element;
@@ -43,7 +43,7 @@ - (UIAccessibilityElement *)accessibilityElementWithLabel:(NSString *)label acce
4343

4444
- (UIAccessibilityElement *)accessibilityElementMatchingBlock:(BOOL(^)(UIAccessibilityElement *))matchBlock;
4545
{
46-
for (UIWindow *window in [self.windows reverseObjectEnumerator]) {
46+
for (UIWindow *window in [self.windowsWithKeyWindow reverseObjectEnumerator]) {
4747
UIAccessibilityElement *element = [window accessibilityElementMatchingBlock:matchBlock];
4848
if (element) {
4949
return element;
@@ -55,7 +55,7 @@ - (UIAccessibilityElement *)accessibilityElementMatchingBlock:(BOOL(^)(UIAccessi
5555

5656
- (UIWindow *)keyboardWindow;
5757
{
58-
for (UIWindow *window in self.windows) {
58+
for (UIWindow *window in self.windowsWithKeyWindow) {
5959
if ([NSStringFromClass([window class]) isEqual:@"UITextEffectsWindow"]) {
6060
return window;
6161
}
@@ -66,7 +66,7 @@ - (UIWindow *)keyboardWindow;
6666

6767
- (UIWindow *)pickerViewWindow;
6868
{
69-
for (UIWindow *window in [self windows]) {
69+
for (UIWindow *window in self.windowsWithKeyWindow) {
7070
NSArray *pickerViews = [window subviewsWithClassNameOrSuperClassNamePrefix:@"UIPickerView"];
7171
if (pickerViews.count > 0) {
7272
return window;
@@ -76,4 +76,14 @@ - (UIWindow *)pickerViewWindow;
7676
return nil;
7777
}
7878

79+
- (NSArray *)windowsWithKeyWindow
80+
{
81+
NSMutableArray *windows = self.windows.mutableCopy;
82+
UIWindow *keyWindow = self.keyWindow;
83+
if (![windows containsObject:keyWindow]) {
84+
[windows addObject:keyWindow];
85+
}
86+
return [windows autorelease];
87+
}
88+
7989
@end

Additions/UITouch-KIFAdditions.m

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ @interface UITouch () {
2424

2525
UIWindow *_window;
2626
UIView *_view;
27-
UIView *_gestureView;
2827
UIView *_warpedIntoView;
2928
NSMutableArray *_gestureRecognizers;
3029
NSMutableArray *_forwardingRecord;
@@ -43,6 +42,7 @@ @interface UITouch () {
4342
} _touchFlags;
4443
#endif
4544
}
45+
- (void)setGestureView:(UIView *)view;
4646
@end
4747

4848
@implementation UITouch (KIFAdditions)
@@ -70,7 +70,9 @@ - (id)initAtPoint:(CGPoint)point inWindow:(UIWindow *)window;
7070

7171
_window = [window retain];
7272
_view = [hitTestView retain];
73-
_gestureView = [hitTestView retain];
73+
if ([self respondsToSelector:@selector(setGestureView:)]) {
74+
[self setGestureView:hitTestView];
75+
}
7476
_phase = UITouchPhaseBegan;
7577
_touchFlags._firstTouchForView = 1;
7678
_touchFlags._isTap = 1;

Additions/UIView-KIFAdditions.m

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,16 @@ - (UIAccessibilityElement *)accessibilityElementWithLabel:(NSString *)label trai
8181
- (UIAccessibilityElement *)accessibilityElementWithLabel:(NSString *)label accessibilityValue:(NSString *)value traits:(UIAccessibilityTraits)traits;
8282
{
8383
return [self accessibilityElementMatchingBlock:^(UIAccessibilityElement *element) {
84+
85+
// TODO: This is a temporary fix for an SDK defect.
86+
NSString *accessibilityValue = element.accessibilityValue;
87+
if ([accessibilityValue isKindOfClass:[NSAttributedString class]]) {
88+
accessibilityValue = [(NSAttributedString *)accessibilityValue string];
89+
}
90+
8491
BOOL labelsMatch = [element.accessibilityLabel isEqual:label];
8592
BOOL traitsMatch = ((element.accessibilityTraits) & traits) == traits;
86-
BOOL valuesMatch = !value || [value isEqual:element.accessibilityValue];
93+
BOOL valuesMatch = !value || [value isEqual:accessibilityValue];
8794

8895
return (BOOL)(labelsMatch && traitsMatch && valuesMatch);
8996
}];

Classes/KIFTestController.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111
#import "KIFTestScenario.h"
1212
#import "KIFTestStep.h"
1313
#import "NSFileManager-KIFAdditions.h"
14+
#import "UIApplication-KIFAdditions.h"
1415
#import <QuartzCore/QuartzCore.h>
1516
#import <dlfcn.h>
1617
#import <objc/runtime.h>
1718

18-
1919
extern id objc_msgSend(id theReceiver, SEL theSelector, ...);
2020

2121

@@ -442,7 +442,7 @@ - (void)_writeScreenshotForStep:(KIFTestStep *)step;
442442
return;
443443
}
444444

445-
NSArray *windows = [[UIApplication sharedApplication] windows];
445+
NSArray *windows = [[UIApplication sharedApplication] windowsWithKeyWindow];
446446
if (windows.count == 0) {
447447
return;
448448
}

Classes/KIFTestStep.m

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ + (id)stepToTapScreenAtPoint:(CGPoint)screenPoint;
334334

335335
// Try all the windows until we get one back that actually has something in it at the given point
336336
UIView *view = nil;
337-
for (UIWindow *window in [[[UIApplication sharedApplication] windows] reverseObjectEnumerator]) {
337+
for (UIWindow *window in [[[UIApplication sharedApplication] windowsWithKeyWindow] reverseObjectEnumerator]) {
338338
CGPoint windowPoint = [window convertPoint:screenPoint fromView:nil];
339339
view = [window hitTest:windowPoint withEvent:nil];
340340

@@ -585,7 +585,7 @@ + (id)stepToDismissPopover;
585585
{
586586
return [self stepWithDescription:@"Dismiss the popover" executionBlock:^(KIFTestStep *step, NSError **error) {
587587
const NSTimeInterval tapDelay = 0.05;
588-
NSArray *windows = [[UIApplication sharedApplication] windows];
588+
NSArray *windows = [[UIApplication sharedApplication] windowsWithKeyWindow];
589589
KIFTestCondition(windows.count, error, @"Failed to find any windows in the application");
590590
UIView *dimmingView = [[[windows objectAtIndex:0] subviewsWithClassNamePrefix:@"UIDimmingView"] lastObject];
591591
[dimmingView tapAtPoint:CGPointMake(50.0f, 50.0f)];
@@ -619,7 +619,7 @@ + (id)stepToTapRowInTableViewWithAccessibilityLabel:(NSString*)tableViewLabel at
619619
KIFTestCondition([indexPath section] < [tableView numberOfSections], error, @"Section %d is not found in '%@' table view", [indexPath section], tableViewLabel);
620620
KIFTestCondition([indexPath row] < [tableView numberOfRowsInSection:[indexPath section]], error, @"Row %d is not found in section %d of '%@' table view", [indexPath row], [indexPath section], tableViewLabel);
621621
[tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
622-
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.25]];
622+
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]];
623623
cell = [tableView cellForRowAtIndexPath:indexPath];
624624
}
625625
KIFTestCondition(cell, error, @"Table view cell at index path %@ not found", indexPath);
@@ -915,9 +915,10 @@ + (UIAccessibilityElement *)_accessibilityElementWithLabel:(NSString *)label acc
915915
UIAccessibilityElement *element = [[UIApplication sharedApplication] accessibilityElementWithLabel:label accessibilityValue:value traits:traits];
916916
if (!element) {
917917
if (error) {
918+
element = [[UIApplication sharedApplication] accessibilityElementWithLabel:label accessibilityValue:nil traits:traits];
918919
// For purposes of a better error message, see if we can find the view, just not a view with the specified value.
919-
if (value && [[UIApplication sharedApplication] accessibilityElementWithLabel:label accessibilityValue:nil traits:traits]) {
920-
*error = [[[NSError alloc] initWithDomain:@"KIFTest" code:KIFTestStepResultFailure userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Found an accessibility element with the label \"%@\", but not with the value \"%@\"", label, value], NSLocalizedDescriptionKey, nil]] autorelease];
920+
if (value && element) {
921+
*error = [[[NSError alloc] initWithDomain:@"KIFTest" code:KIFTestStepResultFailure userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Found an accessibility element with the label \"%@\", but with the value \"%@\", not \"%@\"", label, element.accessibilityValue, value], NSLocalizedDescriptionKey, nil]] autorelease];
921922

922923
// Check the traits, too.
923924
} else if (traits != UIAccessibilityTraitNone && [[UIApplication sharedApplication] accessibilityElementWithLabel:label accessibilityValue:nil traits:UIAccessibilityTraitNone]) {

0 commit comments

Comments
 (0)