kif-framework / KIF

Keep It Functional - An iOS Functional Testing Framework
Other
6.2k stars 909 forks source link

Use accessibility element to find correct tappable point #1259

Closed Tunous closed 2 years ago

Tunous commented 2 years ago

This pull request fixes tapping issue that happens when dealing with SwiftUI views and scroll views in tests.

Before this fix is applied, it's not possible to click on views in SwiftUI view hierarchy that are located outside scrolled bounds. This happens because SwiftUI applies some sort of flattening logic on the resulting view hierarchy, and the actual tappable view is only a small part of a bigger view.

For example, here is a debugger output from _scrollViewToTappablePointIfNeeded in a test where this issue happens:

(lldb) po view.frame
(origin = (x = 0, y = 0), size = (width = 390, height = 1362))

(lldb) po view
<_TtCC7SwiftUI17HostingScrollView22PlatformGroupContainer: 0x14b549a50; frame = (0 0; 390 1362); layer = <CALayer: 0x600000b4c8a0>>

(lldb) po element
<SwiftUI.AccessibilityNode: 0x600002590a00> Text of clickable button

(lldb) po elementFrame
(origin = (x = 24, y = 652.66666666666663), size = (width = 169.66666666666666, height = 19))

As you can see, the found view is a hosting scroll view and the view we want to click is actually a smaller AccessibilityNode which is not a view. This means that before the fix, scroll logic wouldn't work because the hosting container is already visible, but scroll bounds are incorrect. If we use accessibilityFrame of AccessibilityNode instead of view frame, the issue is resolved.

Potentially resolves #1137 as so far it's the only major issue that we have experienced when using KIF with SwiftUI.

dostrander commented 2 years ago

Thanks @Tunous