How to do UITests with Google Maps on iOS

Issue #374

Interact with GMSMapView

Add accessibilityIdentifier to the parent view of GMSMapView. Setting directly onto GMSMapView has no effect

1
accessibilityIdentifier = "MapView"
1
2
3
4
5
6
7
let map = app.otherElements.matching(identifier: "MapView").element(boundBy: 0)
map.pinch(withScale: 2, velocity: 1)
map.rotate(CGFloat.pi/3, withVelocity: 1.0)
map.swipeLeft()
map.swipeRight()
map.swipeDown()
map.swipeDown()

Interact with GMSMarker (1st try)

Need to enable accessibility

1
mapView.accessibilityElementsHidden = false

Can’t use pinch to zoom out with UITests, so need to mock location !!!

1
map().pinch(withScale: 0.05, velocity: -1)

Need to use gpx to mock to preferred location

1
2
3
4
let map = app.otherElements[Constant.AccessibilityId.mapView.rawValue]
let pin = app.otherElements
.matching(identifier: Constant.AccessibilityId.pin.rawValue)
.element(boundBy: 0)

Try isAccessibilityElement = true for PinView, can’t touch!!
Use coordinate, can’t touch !!

1
2
let coordinate = pin.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.5))
coordinate.tap()

Try traversing all the pins, can’t touch

1
2
3
4
5
6
Array(0..<pins.count).forEach {
let pin = pins.element(boundBy: $0)
if pin.isHittable {
pin.tap()
}
}

When po app.otherElements, coordinates are outside screen

1
Other, {{1624.0, 1624.0}, {30.0, 30.0}}, identifier: 'pin', label: 'Hello world'

Interact with GMSMarker (works)

My PinView has isHittable being false, no matter how I use coordinate or enable it. It can’t be touched.

Go to Xcode -> Open Developer Tool -> Accessibility Inspector to inspect our app in iOS simulator

inspector

It turns out that if I do

1
po app.buttons

It shows all the GMSMarker, but with identifier having class name MyApp.MyStopMarker, so just need to use buttons

1
2
3
4
5
6
7
8
9
10
11
extension NSPredicate {
static func contains(identifier: String) -> NSPredicate {
return NSPredicate(format: "identifier CONTAINS[c] '\(text)'")
}
}

let pin = map()
.buttons.matching(NSPredicate.contains("MyStopMarker"))
.element(boundBy: 0)

pin.tap()

Updated at 2021-01-26 09:47:41

Comments