Skip to content

Commit

Permalink
Merge pull request #1286 from Fitzmaz/add-swipeFromEdge
Browse files Browse the repository at this point in the history
Add support for swiping from the specified edge of the screen
  • Loading branch information
dostrander committed Jul 12, 2023
2 parents 6c3ff27 + d07657e commit 10352c9
Show file tree
Hide file tree
Showing 12 changed files with 259 additions and 54 deletions.
28 changes: 28 additions & 0 deletions KIF Tests/GestureTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,34 @@ - (void)testSwipingDownWithIdentifier
[tester waitForViewWithAccessibilityLabel:@"Down"];
}

- (void)testSwipingFromScreenEdgeLeft
{
UIView *view = [tester waitForViewWithAccessibilityIdentifier:@"gestures.swipeMe"];
CGSize windowSize = view.window.bounds.size;
CGPoint point = CGPointMake(0.5, 200);
point = [view convertPoint:point fromView:view.window];
KIFDisplacement displacement = CGPointMake(windowSize.width * 0.5, 5);
[view dragFromPoint:point displacement:displacement steps:20];
[tester waitForAbsenceOfViewWithAccessibilityLabel:@"LeftEdge"];

[tester swipeFromEdge:UIRectEdgeLeft];
[tester waitForViewWithAccessibilityLabel:@"LeftEdge"];
}

- (void)testSwipingFromScreenEdgeRight
{
UIView *view = [tester waitForViewWithAccessibilityIdentifier:@"gestures.swipeMe"];
CGSize windowSize = view.window.bounds.size;
CGPoint point = CGPointMake(windowSize.width - 0.5, 200);
point = [view convertPoint:point fromView:view.window];
KIFDisplacement displacement = CGPointMake(-windowSize.width * 0.5, 5);
[view dragFromPoint:point displacement:displacement steps:20];
[tester waitForAbsenceOfViewWithAccessibilityLabel:@"RightEdge"];

[tester swipeFromEdge:UIRectEdgeRight];
[tester waitForViewWithAccessibilityLabel:@"RightEdge"];
}

- (void)testScrolling
{
// Needs to be offset from the edge to prevent the navigation controller's interactivePopGestureRecognizer from triggering
Expand Down
12 changes: 12 additions & 0 deletions KIF Tests/GestureTests_ViewTestActor.m
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,16 @@ - (void)testMissingScrollableElement
KIFExpectFailure([[[viewTester usingTimeout:0.25] usingIdentifier:@"Unknown"] scrollByFractionOfSizeHorizontal:0.5 vertical:0.5]);
}

- (void)testSwipingFromScreenEdgeLeft
{
[viewTester swipeFromEdge:UIRectEdgeLeft];
[[viewTester usingLabel:@"LeftEdge"] waitForView];
}

- (void)testSwipingFromScreenEdgeRight
{
[viewTester swipeFromEdge:UIRectEdgeRight];
[[viewTester usingLabel:@"RightEdge"] waitForView];
}

@end
1 change: 1 addition & 0 deletions Sources/KIF/Additions/UITouch-KIFAdditions.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@

- (void)setLocationInWindow:(CGPoint)location;
- (void)setPhaseAndUpdateTimestamp:(UITouchPhase)phase;
- (void)setIsFromEdge:(BOOL)isFromEdge;

@end
7 changes: 7 additions & 0 deletions Sources/KIF/Additions/UITouch-KIFAdditions.m
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ - (void)_setIsFirstTouchForView:(BOOL)firstTouchForView;
- (void)_setIsTapToClick:(BOOL)tapToClick;

- (void)_setHidEvent:(IOHIDEventRef)event;
- (void)_setEdgeType:(NSInteger)edgeType;

@end

Expand Down Expand Up @@ -117,6 +118,12 @@ - (void)setPhaseAndUpdateTimestamp:(UITouchPhase)phase
[self setPhase:phase];
}

- (void)setIsFromEdge:(BOOL)isFromEdge
{
NSInteger edgeType = isFromEdge ? 4 : 0;
[self _setEdgeType:edgeType];
}

- (void)kif_setHidEvent {
IOHIDEventRef event = kif_IOHIDEventWithTouches(@[self]);
[self _setHidEvent:event];
Expand Down
1 change: 1 addition & 0 deletions Sources/KIF/Additions/UIView-KIFAdditions.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ typedef CGPoint KIFDisplacement;
- (void)dragFromPoint:(CGPoint)startPoint toPoint:(CGPoint)endPoint;
- (void)dragFromPoint:(CGPoint)startPoint toPoint:(CGPoint)endPoint steps:(NSUInteger)stepCount;
- (void)dragFromPoint:(CGPoint)startPoint displacement:(KIFDisplacement)displacement steps:(NSUInteger)stepCount;
- (void)dragFromEdge:(UIRectEdge)startEdge toEdge:(UIRectEdge)endEdge;
- (void)dragAlongPathWithPoints:(CGPoint *)points count:(NSInteger)count;
- (void)twoFingerPanFromPoint:(CGPoint)startPoint toPoint:(CGPoint)toPoint steps:(NSUInteger)stepCount;
- (void)pinchAtPoint:(CGPoint)centerPoint distance:(CGFloat)distance steps:(NSUInteger)stepCount;
Expand Down
26 changes: 26 additions & 0 deletions Sources/KIF/Additions/UIView-KIFAdditions.m
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,27 @@ - (void)dragFromPoint:(CGPoint)startPoint displacement:(KIFDisplacement)displace
[self dragPointsAlongPaths:@[path]];
}

- (void)dragFromEdge:(UIRectEdge)startEdge toEdge:(UIRectEdge)endEdge
{
CGFloat width = self.bounds.size.width;
CGFloat height = self.bounds.size.height;
CGFloat edgeInset = 0.5;
NSDictionary *edgeToPoint = @{
@(UIRectEdgeTop): @(CGPointMake(width / 2, edgeInset)),
@(UIRectEdgeLeft): @(CGPointMake(edgeInset, height / 2)),
@(UIRectEdgeBottom): @(CGPointMake(width / 2, height - edgeInset)),
@(UIRectEdgeRight): @(CGPointMake(width - edgeInset, height / 2)),
};
CGPoint startPoint = [edgeToPoint[@(startEdge)] CGPointValue];
CGPoint endPoint = [edgeToPoint[@(endEdge)] CGPointValue];

CGPoint screenPoint = [self convertPoint:startPoint toView:self.window];
BOOL isFromScreenEdge = (screenPoint.x < 1 || screenPoint.x > self.window.bounds.size.width - 1);

NSArray<NSValue *> *path = [self pointsFromStartPoint:startPoint toPoint:endPoint steps:20];
[self dragPointsAlongPaths:@[path] isFromEdge:isFromScreenEdge];
}

- (void)dragAlongPathWithPoints:(CGPoint *)points count:(NSInteger)count;
{
// convert point array into NSArray with NSValue
Expand All @@ -648,6 +669,10 @@ - (void)dragAlongPathWithPoints:(CGPoint *)points count:(NSInteger)count;
}

- (void)dragPointsAlongPaths:(NSArray<NSArray<NSValue *> *> *)arrayOfPaths {
[self dragPointsAlongPaths:arrayOfPaths isFromEdge:NO];
}

- (void)dragPointsAlongPaths:(NSArray<NSArray<NSValue *> *> *)arrayOfPaths isFromEdge:(BOOL)isFromEdge {
// There must be at least one path with at least one point
if (arrayOfPaths.count == 0 || arrayOfPaths.firstObject.count == 0)
{
Expand Down Expand Up @@ -692,6 +717,7 @@ - (void)dragPointsAlongPaths:(NSArray<NSArray<NSValue *> *> *)arrayOfPaths {
point = [self convertPoint:point fromView:self.window];
UITouch *touch = [[UITouch alloc] initAtPoint:point inView:self];
[touch setPhaseAndUpdateTimestamp:UITouchPhaseBegan];
[touch setIsFromEdge:isFromEdge];
[touches addObject:touch];
}
UIEvent *eventDown = [self eventWithTouches:[NSArray arrayWithArray:touches]];
Expand Down
6 changes: 6 additions & 0 deletions Sources/KIF/Classes/KIFUITestActor.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,12 @@ typedef NS_ENUM(NSUInteger, KIFPullToRefreshTiming) {
*/
- (void)tapScreenAtPoint:(CGPoint)screenPoint;

/*!
@abstract Performs a swipe gesture starting from the specified edge of the screen.
@param edge The edge from which the swipe gesture should start.
*/
- (void)swipeFromEdge:(UIRectEdge)edge;

/*!
@abstract Performs a long press on a particular view in the view hierarchy.
@discussion The view or accessibility element with the given label is searched for in the view hierarchy. If the element isn't found or isn't currently tappable, then the step will attempt to wait until it is. Once the view is present and tappable, touch events are simulated in the center of the view or element.
Expand Down
52 changes: 40 additions & 12 deletions Sources/KIF/Classes/KIFUITestActor.m
Original file line number Diff line number Diff line change
Expand Up @@ -366,18 +366,7 @@ - (void)tapAccessibilityElement:(UIAccessibilityElement *)element inView:(UIView
- (void)tapScreenAtPoint:(CGPoint)screenPoint
{
[self runBlock:^KIFTestStepResult(NSError **error) {

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

// If we hit the window itself, then skip it.
if (view != window && view != nil) {
break;
}
}
UIView *view = [self viewAtPoint:screenPoint];

KIFTestWaitCondition(view, error, @"No view was found at the point %@", NSStringFromCGPoint(screenPoint));

Expand All @@ -389,6 +378,45 @@ - (void)tapScreenAtPoint:(CGPoint)screenPoint
}];
}

- (void)swipeFromEdge:(UIRectEdge)edge
{
CGSize screenSize = UIScreen.mainScreen.bounds.size;
CGPoint screenPoint;
if (edge == UIRectEdgeLeft) {
screenPoint = CGPointMake(0.3, screenSize.height / 2);
} else if (edge == UIRectEdgeRight) {
screenPoint = CGPointMake(screenSize.width - 0.3, screenSize.height / 2);
} else {
return;
}
[self runBlock:^KIFTestStepResult(NSError **error) {
UIView *view = [self viewAtPoint:screenPoint];

KIFTestWaitCondition(view, error, @"No view was found at the point %@", NSStringFromCGPoint(screenPoint));

UIRectEdge endEdge = (UIRectEdgeLeft | UIRectEdgeRight) - edge;
[view dragFromEdge:edge toEdge:endEdge];

return KIFTestStepResultSuccess;
}];
}

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

// If we hit the window itself, then skip it.
if (view != window && view != nil) {
break;
}
}
return view;
}

- (void)longPressViewWithAccessibilityLabel:(NSString *)label duration:(NSTimeInterval)duration;
{
[self longPressViewWithAccessibilityLabel:label value:nil traits:UIAccessibilityTraitNone duration:duration];
Expand Down
6 changes: 6 additions & 0 deletions Sources/KIF/Classes/KIFUIViewTestActor.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,12 @@ extern NSString *const inputFieldTestString;
*/
- (void)swipeInDirection:(KIFSwipeDirection)direction;

/*!
@abstract Performs a swipe gesture starting from the specified edge of the screen.
@param edge The edge from which the swipe gesture should start.
*/
- (void)swipeFromEdge:(UIRectEdge)edge;

#pragma mark Waiting & Finding

/*!
Expand Down
5 changes: 5 additions & 0 deletions Sources/KIF/Classes/KIFUIViewTestActor.m
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,11 @@ - (void)swipeInDirection:(KIFSwipeDirection)direction;
}
}

- (void)swipeFromEdge:(UIRectEdge)edge
{
[self.actor swipeFromEdge:edge];
}

#pragma mark - Scroll/Table/CollectionView Actions

- (void)scrollByFractionOfSizeHorizontal:(CGFloat)horizontalFraction vertical:(CGFloat)verticalFraction;
Expand Down
Loading

0 comments on commit 10352c9

Please sign in to comment.