我为Android应用程序编写Xamarin UITest。在应用程序中使用谷歌地图。请帮帮我,如何点击地图上的标记?
标记没有显示在视图树中,我猜测它们是在地图框架布局的屏幕上绘制的。
假设标记在地图的中心,你可以使用这样的东西点击它:
(带有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)
但我认为这就是地图本身所能做的。
如果你自己构建应用程序,我建议你查看后门方法。这些方法可以构建到应用程序中,然后从测试中调用。
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的自定义渲染器,你可以在里面模拟点击,主要的技巧是访问渲染器里面的标记:
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;
}
}
}