0

(Xcode 7.3.1, iOS9.3, Swift)

I'm struggling with setting up an UI Test in my assignment for what would seem to be a fairly standard and common use case.

I have a sub-classed UITableViewCell which contains a textField that does not fill the entire cell and has the Disclosure Indicator set. The user is able to type the data into textField by tapping on it, but if they tap outside the textField, but still in the cell, my app segues to another view. The project works fine and the child view receives the correct data from the cell's textField.

My Master-Detail app has UITableViews on both the Master and Detail views. My UI Test selects the first cell in the Master View, waits a little for the DV and then selects the second cell in the detail view, which is configured in accordance to my earlier description.

I am simulating a tap on the second cell using

tablesQuery.cells.elementBoundByIndex(1).tap()

However, the simulator interprets it as a tap in the textField, so no segue occurs. I have read SwiftyCruz's question and the given answers but his use case is a little different, as I'm not using a Detail Disclosure, also the accepted answer doesn't translate to my situation. In following ferunandu explanation, I have tried setting the Accessibility Label and Identifier on the Cell as well as a different string for the accessoryView?.accessibilityIdentifier. Though UI Test still doesn't work, ferunandu's snippet does change the disclosure indicator from > to a blue box.

Using a breakpoint, I've been querying the app object in the debug window trying to find the right control, but to no avail. I am able to find the textField using indices as well as the identifier, but nothing I've tried has returned .exists true for the accessoryView.

Am I trying to access the cell incorrectly? Or, is it actually not possible to do what I'm attempting?

The code for my test is:

    XCUIDevice.sharedDevice().orientation = .Portrait
    let app = XCUIApplication()
    wait()
    let tablesQuery = app.tables
    tablesQuery.cells.elementBoundByIndex(0).tap()
    wait()
    tablesQuery.cells.elementBoundByIndex(1).tap()

What am I not understanding properly here? Any advice would be greatly appreciated.

(I know I could have used a standard UITableViewCell with the data entry done on the child view, but I prefer not to change the design of my app to accommodate XCTest's, seems a bit backwards.)

Community
  • 1
  • 1
gone
  • 1,079
  • 5
  • 13
  • 31

1 Answers1

0

I have a sub-classed UITableViewCell which contains a textField that does not fill the entire cell...

I am simulating a tap on the second cell using

tablesQuery.cells.elementBoundByIndex(1).tap()

However, the simulator interprets it as a tap in the textField, so no segue occurs.

It sounds like your tap on the table view cell is being intercepted by the text field. When UI tests tap on a table view cell, the tap will be at the centre of the UI element's frame.

To offset the tap location from the centre of the cell, use coordinate(withNormalizedOffset:) and tap the coordinate instead of the element directly.

let cell = app.tables.cells.elementBoundByIndex(0)
// Retrieves coordinate that is 50% of the way along the cell
// and 20% of the way down the cell - adjust these values to
// find the right values to avoid tapping the text field area
// of the cell
let cellCoordinateForTap = cell.coordinateWithNormalizedOffset(CGVector(dx: 0.5, dy: 0.2))
cellCoordinateForTap.tap()
Community
  • 1
  • 1
Oletha
  • 7,324
  • 1
  • 26
  • 46