-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
fix(scrollTo): raise if scroll view element is not hittable. #3115
Conversation
@@ -0,0 +1,46 @@ | |||
const { expectToThrow } = require('./utils/custom-expects'); | |||
|
|||
describe(':ios: Overlay', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll run tomorrow, thanks!
@asafkorem maybe I'll mention the obvious, but this change should pass pre-release lifecycle on our Wix internal projects, I guess. Nightly RCs for all the projects. |
3124c1a
to
3ebd8cf
Compare
3ebd8cf
to
6a5fc38
Compare
[self dtx_assertVisibleWithPercent:@1]; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like this.
However, I don't like the current approach also (>=75% visible), what we use in other views actions (see for example), since the view can be half visible and still accessible..
Also, the normalizedStartingPoint
is undefined in many cases and then we use some almost-arbitrary point (from one of the edges). Theoretically I could use this point to check whether it's hittable on that point, but then it might result in breakage of tests (where this points are hidden but the view is partially visible, like in 03.actions-scroll.test.js
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be the best we can offer for this fix, without breaking the current API much. Of course, I'd like to hear more thoughts..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that adding the ≥75 assertion offhand would be reckless, and also will not make sense as long as the percentage cannot be specified by the user.
As for the idea you suggested - checking hittability, I wouldn't get it off the table altogether. But in any case, on Android we essentially do something quite similar to your change with respect to visibility -- asserting the view is non-empty (which means it may actually make sense).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done ✔️ we will now check hittability instead of visibility.
There's a lot of changes in the new implementation, so this may be effective to review them face to face.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
of course, we should also test it with the latest changes as broadly as possible using the internal wix projects. especially when it adds more assertions to touch actions.
@wix/detox-team I'll appreciate if one of you can review this change :) |
it('should be intractable when overlay is not shown', async () => { | ||
await verticalScrollView.scrollTo('bottom'); | ||
await expect(showOverlayButton).not.toBeVisible(); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think is not necessary because it is tested in the actions suite
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Basically you are right but not really, since I'm testing the whole screen, in this test I made sure that we start from the desired initial state (where the button disappears after scrolling). This covers the case where the scroll view might be not-scrollable (for example, too few items on some screen).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still kind of sounds like this:
it('should scroll to edge', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree, I'm not testing the functionality of a scroll view, but the expectation from the initial state of this screen. Let's discuss about this f2f?
overlayWindow = [[UIWindow alloc] initWithFrame:screenBounds]; | ||
|
||
[overlayWindow setWindowLevel:UIWindowLevelStatusBar]; | ||
[overlayWindow setBackgroundColor:[UIColor.grayColor colorWithAlphaComponent:0.5]]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to challenge further and use a 0 alpha?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Holy s**t, that's an excellent question!
If the overlying view has a transparent background (or, clearColor
), we consider the underlying view as visible. So in this case the views are considered as "visible" but they are not tappable / scrollable.
So it makes a lot of sense, but the tests will break, but we need to cover these cases also since they shouldn't (touch gestures should not pass).
We must have some better mechanism here than just asserting on visibility.
6a5fc38
to
0f2652e
Compare
@d4vidi fixed and squashed. I rewrote the mechanism of is-hittable check on iOS. The guiding logic is:
The problems that were in the previous check (of is-hittable, which also weren't even in use in some actions):
Some tests are still failing: I'm investigating the reasons. Pushed the current changes for visibility, in case you want to start looking. As a side note, XCUITest already provide API for isHittable, so when we'll use XCUIT we'll get a much more accurate check. |
6af218c
to
9ce9eae
Compare
// Copyright © 2021 Wix. All rights reserved. | ||
// | ||
|
||
#import "UIResponder+First.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ref stackoverflow
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
v
|
Changes pushed
Done ✔️
Done ✔️
Done ✔️ |
8d4c744
to
e6c4341
Compare
Replaces this error message: `View “<RCTView: 0x7fa3020598b0>” is not visible: View is clipped by one or more of its superviews' bounds and does not pass visibility percent threshold (7,500)`, With this error message: `View “<RCTView: 0x7fa3020598b0>” is not visible: View is clipped by one or more of its superviews' bounds and does not pass visibility percent threshold (75)`.
Failed tests: - `scroll view -> should not be scrollable when overlay is shown`. - `button -> should not be hittable when overlay is shown`.
Rewrite the logic: - Finds a visible point of the view (otherwise the view is not hittable). - Finds the topmost window, tries to tap on the visible point using `hitTest`. - Checks whether the hitted view is the view itself / descendent of the tested view.
e6c4341
to
ac6ccdb
Compare
ac6ccdb
to
1d67fe5
Compare
detox/test/e2e/03.actions.test.js
Outdated
if (device.getPlatform() === 'ios') { | ||
// TODO: investigate why this assertion fails on Android | ||
await expect(element(by.text('Text1'))).not.toBeVisible(1); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was already TODOed here:
Detox/detox/test/e2e/03.actions.test.js
Lines 147 to 150 in d95b5e7
if (device.getPlatform() === 'ios') { | |
// TODO: investigate why this assertion fails on Android | |
await expect(element(by.text('Text1'))).not.toBeVisible(); | |
} |
@jonathanmos / @d4vidi FYI
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, it's related to an issue that was reported very recently 😄 , and Amit has reported on that long ago in a RN issue: #3105 (comment), facebook/react-native#23870
…3115)" This reverts commit b146425, reversing changes made to d95b5e7. # Conflicts: # detox/package.json # detox/test/package.json # examples/demo-native-android/package.json # examples/demo-native-ios/package.json # examples/demo-react-native-detox-instruments/package.json # examples/demo-react-native-jest/package.json # examples/demo-react-native/package.json # lerna.json # package.json (Resolved by using the current files)
Description
This pull request addresses the issue described here: #2834.
In this pull request, I have reproduced the bug from the issue, by adding more tests to the test-app. Apparently, only the
scrollTo
didn't work as expected because we don't assert if the called element is hidden by another view or window.This fixes the bug as we did in all other UI interaction actions (taps, long-presses, date-picking), by raising an assertion when the view is not hittable.
Similar failed tests could be achieved by hiding the scroll view with another view, but I still decided to implement them with
UIWindow
("overlay") since it is not tested anywhere in our test suite, and that's an iOS-specific behaviour (in Android we touch the visible screen, and not the window behind the element).Also, in addition to this fix, I rewrote the mechanism of assertions before interacting with a view (for any UI gesture).