Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Fix tapping of media picker photo #71

Merged
merged 2 commits into from

2 participants

@nickpaulson

Fix a bug where the choose button in the media picker would never be pressed. This was due to a runloop issue triggered by CFRunLoopRunInMode. As a work around, we use KIF's built-in wait functionality.

We saw this on Xcode 4.1 with the iOS 4.3 simulator.

Nick Paulson... added some commits
Nick Paulson + Eric Firestone Fix a bug where the choose button in the media picker would never be …
…pressed. This was due to a runloop issue triggered by CFRunLoopRunInMode. As a work around, we use KIF's built-in wait functionality.
8c17419
Nick Paulson + Eric Firestone Fix ordering of wait to happen after the check for first responder-ness e52fd75
@mthole

LGTM.

@mthole mthole merged commit 72a412d into master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 22, 2011
  1. Fix a bug where the choose button in the media picker would never be …

    Nick Paulson + Eric Firestone authored
    …pressed. This was due to a runloop issue triggered by CFRunLoopRunInMode. As a work around, we use KIF's built-in wait functionality.
  2. Fix ordering of wait to happen after the check for first responder-ness

    Nick Paulson + Eric Firestone authored
This page is out of date. Refresh to see the latest.
Showing with 33 additions and 19 deletions.
  1. +33 −19 Classes/KIFTestStep.m
View
52 Classes/KIFTestStep.m
@@ -195,10 +195,18 @@ + (id)stepToWaitForTappableViewWithAccessibilityLabel:(NSString *)label value:(N
+ (id)stepToWaitForTimeInterval:(NSTimeInterval)interval description:(NSString *)description;
{
// In general, we should discourage use of a step like this. It's pragmatic to include it though.
+ __block NSTimeInterval startTime = 0;
KIFTestStep *step = [self stepWithDescription:description executionBlock:^(KIFTestStep *step, NSError **error) {
- NSLog(@"Wait run loop exited with %d", CFRunLoopRunInMode(kCFRunLoopDefaultMode, interval, false));
+ if (startTime == 0) {
+ startTime = [NSDate timeIntervalSinceReferenceDate];
+ }
+
+ KIFTestWaitCondition((([NSDate timeIntervalSinceReferenceDate] - startTime) >= interval), error, @"Waiting for time interval to expire.");
+
return KIFTestStepResultSuccess;
}];
+
+ // Make sure that the timeout is set so that it doesn't timeout prematurely.
step.timeout = interval + 1.0;
return step;
@@ -240,15 +248,27 @@ + (id)stepToTapViewWithAccessibilityLabel:(NSString *)label value:(NSString *)va
} else {
description = [NSString stringWithFormat:@"Tap view with accessibility label \"%@\"", label];
}
+
+ // After tapping the view we want to wait a short period to allow things to settle (animations and such). We can't do this using CFRunLoopRunInMode() because certain things, such as the built-in media picker, do things with the run loop that are not compatible with this kind of wait. Instead we leverage the way KIF hooks into the existing run loop by returning "wait" results for the desired period.
+ const NSTimeInterval quiesceWaitInterval = 0.5;
+ __block NSTimeInterval quiesceStartTime = 0.0;
+
+ __block UIView *view = nil;
return [self stepWithDescription:description executionBlock:^(KIFTestStep *step, NSError **error) {
-
+
+ // If we've already tapped the view and stored it to a variable, and we've waited for the quiesce time to elapse, then we're done.
+ if (view) {
+ KIFTestWaitCondition(([NSDate timeIntervalSinceReferenceDate] - quiesceStartTime) >= quiesceWaitInterval, error, @"Waiting for view to become the first responder.");
+ return KIFTestStepResultSuccess;
+ }
+
UIAccessibilityElement *element = [self _accessibilityElementWithLabel:label accessibilityValue:value tappable:YES traits:traits error:error];
if (!element) {
return KIFTestStepResultWait;
}
-
- UIView *view = [UIAccessibilityElement viewContainingAccessibilityElement:element];
+
+ view = [UIAccessibilityElement viewContainingAccessibilityElement:element];
KIFTestWaitCondition(view, error, @"Failed to find view for accessibility element with label \"%@\"", label);
if (![self _isUserInteractionEnabledForView:view]) {
@@ -257,25 +277,19 @@ + (id)stepToTapViewWithAccessibilityLabel:(NSString *)label value:(NSString *)va
}
return KIFTestStepResultWait;
}
-
+
CGRect elementFrame = [view.window convertRect:element.accessibilityFrame toView:view];
CGPoint tappablePointInElement = [view tappablePointInRect:elementFrame];
-
+
// This is mostly redundant of the test in _accessibilityElementWithLabel:
KIFTestWaitCondition(!isnan(tappablePointInElement.x), error, @"The element with accessibility label %@ is not tappable", label);
[view tapAtPoint:tappablePointInElement];
- // Verify that we successfully selected the view
- if (![view canBecomeFirstResponder]) {
- CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.5, false);
- return KIFTestStepResultSuccess;
- }
-
- KIFTestCondition([view isDescendantOfFirstResponder], error, @"Failed to make the view %@ which contains the accessibility element \"%@\" into the first responder", view, label);
-
- CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.5, false);
-
- return KIFTestStepResultSuccess;
+ KIFTestCondition(![view canBecomeFirstResponder] || [view isDescendantOfFirstResponder], error, @"Failed to make the view %@ which contains the accessibility element \"%@\" into the first responder", view, label);
+
+ quiesceStartTime = [NSDate timeIntervalSinceReferenceDate];
+
+ KIFTestWaitCondition(NO, error, @"Waiting for the view to settle.");
}];
}
@@ -523,11 +537,11 @@ + (NSArray *)stepsToChoosePhotoInAlbum:(NSString *)albumName atRow:(NSInteger)ro
[view tapAtPoint:tappablePointInElement];
- CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.5, false);
-
return KIFTestStepResultSuccess;
}]];
+ [steps addObject:[KIFTestStep stepToWaitForTimeInterval:0.5 description:@"Wait for media picker view controller to be pushed."]];
+
// Tap the desired photo in the grid
// TODO: This currently only works for the first page of photos. It should scroll appropriately at some point.
const CGFloat headerHeight = 64.0;
Something went wrong with that request. Please try again.