Reputation: 13
I write Xamarin UITest for Android app. In the app uses google map. Help me please, how to click on a marker on the map?
Upvotes: 0
Views: 1343
Reputation: 6462
If you have a custom renderer for android you can simulate a click inside, the main trick is to access markers inside the renderer:
var field = this.GetType().BaseType.GetField("_markers", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
var markers = (List<Marker>)field.GetValue(this);
now for any element in markers
as you cannot send a real click you can just simulate it. Pasting the code from my live project:
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == "ExternalClickedPin")
{
if (FormsControl.ExternalClickedPin != null)
{
var pin = Map.Pins.FirstOrDefault(x => x.MarkerId == FormsControl.ExternalClickedPin.MarkerId);
if (pin != null)
{
var field = this.GetType().BaseType.GetField("_markers", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
var hiddenMarkers = (List<Marker>)field.GetValue(this);
var marker = hiddenMarkers.FirstOrDefault(x => x.Id == pin.MarkerId.ToString());
if (marker != null)
{
//simulating click
//1 invoke clicked event
// pin.SendMarkerClick(); // <- if needed for tests
//2 show info on map
marker.ShowInfoWindow(); //just what i was needing
//3 center pin on map
//Map.MoveToRegion(...); <- not here, im calling this from Forms subclassed control
}
}
FormsControl.ExternalClickedPin = null;
}
}
}
Upvotes: 0
Reputation: 16
If you're building the app yourself, I suggest checking out backdoor methods. These are methods that you can build into the app and then call from the test.
There are plenty of examples for Obj-C and Java apps. Here's an example for C# backdoor methods, which you'd put in either your MainActivity or AppDelegate classes: http://danatxamarin.com/2015/05/07/configuring-backdoor-methods-in-c-for-xamarin-test-cloud/
I'd create a backdoor to return whatever data you need about the map, and then use app.Invoke("myNewMethod");
which will return a string (which could be json). This string could contain screen coordinates, which you could then pass to app.TapCoordinates(x, y);
.
The short answer is, Google Maps on Android doesn't really expose objects in an automatable way, so the second best option is backdoors.
Upvotes: 0
Reputation: 1161
markers are not showing within the tree of views, my guess is that they're drawn on screen within the map framelayout.
given that the marker is at the center of the map, you could tap it using something like this :
(with a map fragment of id "map")
var map = app.Query("map")
var middleX = (map.First().Rect.Width + map.First().Rect.X) / 2
var middleY = (map.First().Rect.Height + map.First().Rect.Y) / 2
app.TapCoordinates(middleX, middleY)
but I think that's all you can do within the map itself.
Upvotes: 1