【问题标题】:How to click on a marker on the google map for Xamarin UITest如何在 Xamarin UITest 的谷歌地图上单击标记
【发布时间】:2020-04-08 00:08:54
【问题描述】:

我为 Android 应用程序编写 Xamarin UITest。在应用程序中使用谷歌地图。请帮帮我,如何点击地图上的标记?

【问题讨论】:

  • 您是否在询问如何以编程方式模拟标记点击、响应标记点击事件或其他?

标签: google-maps user-interface testing xamarin


【解决方案1】:

标记没有显示在视图树中,我猜它们是在地图框架布局内的屏幕上绘制的。

鉴于标记位于地图的中心,您可以使用以下方式点击它:

(带有 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)

但我认为这就是地图本身所能做的一切。

【讨论】:

  • 我只需点击地图即可到达中心。但是地图上有几个标记,我必须点击其中一个。如何找到标记的坐标?
  • 我认为不可能,因为标记不会作为地图的子视图出现,UITest 无法查询它们
  • iOS 地图似乎可行,而不是 Android。 forums.xamarin.com/discussion/38034/…
  • 谢谢。我也这么认为。但我曾希望。
【解决方案2】:

如果您自己构建应用程序,我建议您检查后门方法。这些方法可以构建到应用程序中,然后从测试中调用。

有很多关于 Obj-C 和 Java 应用程序的示例。这是 C# 后门方法的示例,您可以将其放入 MainActivity 或 AppDelegate 类中:http://danatxamarin.com/2015/05/07/configuring-backdoor-methods-in-c-for-xamarin-test-cloud/

我会创建一个后门来返回您需要的有关地图的任何数据,然后使用app.Invoke("myNewMethod"); 返回一个字符串(可能是 json)。该字符串可以包含屏幕坐标,然后您可以将其传递给app.TapCoordinates(x, y);

简短的回答是,Android 上的 Google 地图并没有真正以自动方式公开对象,因此第二好的选择是后门。

【讨论】:

    【解决方案3】:

    如果你有一个自定义的android渲染器,你可以在里面模拟点击,主要的技巧是访问渲染器内部的标记:

    var field = this.GetType().BaseType.GetField("_markers", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
    var markers = (List<Marker>)field.GetValue(this);
    

    现在对于markers 中的任何元素,因为您无法发送真正的点击,您可以模拟它。从我的实时项目中粘贴代码:

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

    【讨论】:

      猜你喜欢
      • 2020-06-18
      • 1970-01-01
      • 2012-09-27
      • 1970-01-01
      • 2020-07-19
      • 2019-11-30
      • 1970-01-01
      • 1970-01-01
      • 2012-01-10
      相关资源
      最近更新 更多