skip to Main Content

Sample Project

This is a sample project that showing the issue. It’s storyboard based, but method of building interface doesn’t matter. It’s UIViewController with UIScrollView for entire screen and 128 pts height view that is on top of this UIScrollView.
Inside scroll view there is an UIView that has 2000 pts height and UIButton in the center.

Initial State After light scroll At the bottom of UIScrollView
Initial State After light scroll At the bottom of UIScrollView

Link here: https://github.com/JakubMazur/UITestsDemo

Problem

  1. I’m trying to tap this green button with XCUITest using app.buttons["Tap Me!"].tap()
  2. XCUITest get identifiers from elements on screen for entire scroll view that works fine.
  3. According to this reply on a thread on Apple Developer Forum written by Apple Framework Engineer I shouldn’t scroll manually to get to the button and yes, this is partially true.

screenshot of accepted replay from link pasted above

  1. What is happening when code from (1) is executed is that button is scrolled just enough to be visible on screen but it’s still not hittable, because other (purple view) is on top of UIScrollView

image that shows the issue

What is working

If I run a test written like this:

    func testThatDoWorkButItsSlow() {
        app.scrollViews.firstMatch.swipeUp()
        app.buttons[buttonLabel].tap()
    }

that is scrolling up and then looks for a button this will work, but it’s slow and so inaccurate that is hardly usable.

What I cannot do

Disabling userInteractions on purple view. In real example I still need touches for this (purple) view.

Questions

  1. Is there a way to use precise scrolling in XCTest for this case?
  2. Or is there a way to set contentOffset scrollview to other value that will make this button more centered on a screen compared to action of tap()?
  3. Or there is a way to fast scroll to the bottom (without animations) and maybe moving only up for each element?

2

Answers


  1. My recommendation here would be to use the XCUICoordinate.press(forDuration:thenDragTo:) method to scroll.

    https://developer.apple.com/documentation/xctest/xcuicoordinate/1615003-press

    You can create a XCUICoordinate for the yellow view, then drag it slightly upwards to expose the button and make it hittable.

    In most cases, the automatic scroll should work, but it seems like in this case a manual scroll/drag is necessary.

    Login or Signup to reply.
  2. The UI Testing should replicate human interactions. You cannot expect from a human being to scroll "153px", you can just expect to "scroll until".

    You can try something like :

        while (!app.buttons["Tap Me!"].isHittable) {
            app.swipeUp()
        } 
    

    NB: You may also want to add a condition to leave the while loop if you can’t find the button after a reasonable amount of attempts

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search