How to Tap on a Specific Point Using Xcode Uitests

How to tap on a specific point using Xcode UITests

You can tap a specific point with the XCUICoordinate API. Unfortunately you can't just say "tap 10,10" referencing a pixel coordinate. You will need to create the coordinate with a relative offset to an actual view.

We can use the mentioned web view to interact with the relative coordinate.

let app = XCUIApplication()
let webView = app.webViews.element
let coordinate = webView.coordinateWithNormalizedOffset(CGVector(dx: 10, dy: 10))
coordinate.tap()

Side note, but have you tried interacting with the web view directly? I've had a lot of success using app.links["Link title"].tap() or app.staticTexts["A different link title"].tap(). Here's a demo app I put together demonstrating interacting with a web view.


Update: As Michal W. pointed out in the comments, you can now tap a coordinate directly, without worrying about normalizing the offset.

let normalized = webView.coordinate(withNormalizedOffset: CGVector(dx: 0, dy: 0))
let coordinate = normalized.withOffset(CGVector(dx: 10, dy: 10))
coordinate.tap()

Notice that I pass 0,0 to the normalized vector and then the actual point, 10,10, to the second call.

Xcodes UI Testing - Tapping an x y location

The dx and dy are not pixel offsets but normalized vectors. For example, 0.5 is actually the middle of the element. Your code is trying to tap an element outside of the screens bounds (by ~50x!).

I suggest trying to solve the problem with a different approach. First off, why can't the button be identified? What have you tried? Are you using a custom UIButton subclass?

I ask because you can (usually) expose any control or UI element to UI testing with the right accessibility attributes. For example, you can set accessibilityLabel and accessibilityIdentifier to the button's text. Then you can use that value to access the button under test.

// Production Code
let button = UIButton()
button.setTitle("Save", forState: .Normal)
button.accessibilityIdentifier = "Save"

// UI Test Code
```
let app = XCUIApplication()
app.buttons["Save"].tap()

Touch specific coordinate (UI tests)

You can only tap specific coordinate referenced off of a known element. Meaning, you can't tap the pixel at coordinates (20, 400). Instead, you need to find an element and then tap something with an offset.

XCUIApplication *app = [[XCUIApplication alloc] init];
XCUIElement *label = app.labels[@"Label Name"];
XCUICoordinate *coordinate = [label coordinateWithNormalizedOffset(CGVectorMake(0.5, 1.2));
[coordinate tap];

I documented more information on how to figure out the right offset in my UI Testing Cheat Sheet post.


If you are just trying to tap the Action button you can access it directly (instead of drilling down with all of those queries).

XCUIApplication *app = [[XCUIApplication alloc] init];
[[[app.navigationBars element].staticTexts[@"Action"] tap];

How do I perform a tap and drag in Xcode UI Test scripts?

You can use XCUICoordinate to tap and drag elements in UI Testing. Here is an example of how to pull to refresh via table cell coordinates.

let firstCell = app.staticTexts["Adrienne"]
let start = firstCell.coordinateWithNormalizedOffset(CGVectorMake(0, 0))
let finish = firstCell.coordinateWithNormalizedOffset(CGVectorMake(0, 6))
start.pressForDuration(0, thenDragToCoordinate: finish)

If you don't have elements to reference you should be able to create arbitrary coordinates based off of XCUIApplication.

let app = XCUIApplication()
let fromCoordinate = app.coordinateWithNormalizedOffset(CGVector(dx: 0, dy: 10))
let toCoordinate = app.coordinateWithNormalizedOffset(CGVector(dx: 0, dy: 20))
fromCoordinate.pressForDuration(0, thenDragToCoordinate: toCoordinate)

UI Testing doesn't have official documentation, but I've scraped the headers and put together an XCTest Reference if you are interested in more details.

ui testing xcode, how to tap on a table view cell button with cellquery

If the button is present in the 3rd cell then it should be:

let cellQuery = self.app.tables.cells.element(boundBy: 2)
cellQuery.buttons["signup button"].tap()

If button is 3rd in the cell then add accessibility for the cells and then:

app.cells["AccessibilityIdentifier"].buttons.element(boundBy: 2).tap()


Related Topics



Leave a reply



Submit