简体   繁体   中英

How to click on a marker on the google map for Xamarin UITest

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?

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.

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.

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;
            }



        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM