Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for swiping from the specified edge of the screen #1286

Merged
merged 5 commits into from
Jul 12, 2023

Conversation

Fitzmaz
Copy link
Contributor

@Fitzmaz Fitzmaz commented Jun 29, 2023

As discussed in issue #1281, I tried to address the problem by adding a new method to the tester. This method simulates a screen edge pan gesture by manually setting the _edgeType property. I wonder if there's any better solution, any feedback is greatly appreciated.

Copy link
Contributor

@justinseanmartin justinseanmartin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple of discussion points on the approach, but what you have here also seems reasonable. We appreciate the contribution and adding test coverage of the scenario.

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

- (void)swipeFromEdge:(UIRectEdge)edge atY:(CGFloat)y
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'd make this a % or the screen height to make it the API work more easily with different device screen sizes, like the dragFromPoint API.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have a use case where you care about the Y coordinate used for the edge swipe? If not, I think we should start by omitting the atY: parameter and default to using 50% of the screen height.

@@ -692,6 +701,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];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should alternatively come up with a heuristic here for what constitutes an edge swipe and do it implicitly. Being explicit seems reasonable as well though.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think with this we can make an API specifically for swiping at an edge, similarly to like tapping on a button or status bar instead of using x,y coordinatotes. As well as implicitly doing it from the edge if we can detect it being around where it should be. I think that'd be in line with other APIs of KIf

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about doing it implicitly like

if (startPoint.x < 1 || startPoint.x > screen.size.width - 1) {
    [touch setIsFromEdge:isFromEdge];
}

But this could be a breaking change for users who utilize the dragFromPoint method without intending to trigger a screen edge pan gesture.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried to implement an alternative way based on the suggestions, which one do you prefer?

Comment on lines +121 to +125
- (void)setIsFromEdge:(BOOL)isFromEdge
{
NSInteger edgeType = isFromEdge ? 4 : 0;
[self _setEdgeType:edgeType];
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would happen if we directly called _UITouchSetBasicTouchPropertiesFromEvent? Does Apple already have the appropriate heuristics to set this properly?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apple derives the value of the property from the HIDEvent. We would need to synthesize a different HIDEvent for edge pan before calling _UITouchSetBasicTouchPropertiesFromEvent. This introduces additional complexity and I lack the necessary knowledge to implement it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we could replace these magic numbers with Apple enums.

@@ -630,10 +630,15 @@ - (void)dragFromPoint:(CGPoint)startPoint toPoint:(CGPoint)endPoint steps:(NSUIn
}

- (void)dragFromPoint:(CGPoint)startPoint displacement:(KIFDisplacement)displacement steps:(NSUInteger)stepCount;
{
[self dragFromPoint:startPoint displacement:displacement steps:stepCount isFromEdge:NO];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is kind of a breaking change, in that it would require code changes in existing tests if they had working edge gestures. As you'd called out in the issue, this has been broken since iOS 11, so seems reasonable IMO.

KIF Tests/GestureTests.m Outdated Show resolved Hide resolved
Copy link
Contributor

@justinseanmartin justinseanmartin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for taking so long to get back here, and thanks for making the revisions! One other thing that we should do before landing this is add an equivalent API to KIFUIViewTestActor. That is the more flexible replacement of the KIFUITestActor API, though there is still a lot of documentation indicating to use the older API.

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

- (void)swipeFromEdge:(UIRectEdge)edge atY:(CGFloat)y
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have a use case where you care about the Y coordinate used for the edge swipe? If not, I think we should start by omitting the atY: parameter and default to using 50% of the screen height.

CGFloat height = self.bounds.size.height;
CGFloat edgeInset = 0.5;
NSDictionary *edgeToPoint = @{
@(UIRectEdgeTop): @(CGPointMake(width / 2, 0)),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also use edgeInset here for the top and height - edgeInset for the bottom?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'v made some revisions as suggested, please review again.

1. Omit the atY: parameter of swipeFromEdge
2. Add an equivalent API to KIFUIViewTestActor and add tests
3. dragFromEdge now uses edgeInset for the top and height - edgeInset for the bottom
@justinseanmartin
Copy link
Contributor

Thanks again for the iterations here and the contribution! I'll get this merged once CI reports green.

@justinseanmartin
Copy link
Contributor

The tests appear to be extremely flaky right now in AccessibilityIdentifierTests.testClearingAndEnteringTextIntoViewWithAccessibilityLabel. I'm rerunning them and it's making progress on ensuring they're all green before merging.

@dostrander dostrander merged commit 10352c9 into kif-framework:master Jul 12, 2023
5 checks passed
@dostrander
Copy link
Collaborator

The tests appear to be extremely flaky right now in AccessibilityIdentifierTests.testClearingAndEnteringTextIntoViewWithAccessibilityLabel. I'm rerunning them and it's making progress on ensuring they're all green before merging.

Merged as they all went green

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants