我正在Xamarin UI测试中为基于选项卡的Xamarin Forms应用程序编写测试。我想在每个选项卡项上设置自动化ID,以便UI测试可以单击特定的选项卡,而不必引用该选项卡的“文本”标签(已本地化)。
我想您需要使用自定义渲染器并设置ContentDescription(Android)和AccessibilityIdentifier(iOS),并且我一直在尝试这样做,但结果却不尽相同。正确的方法是什么?如果我在使用自定义渲染器方面步入正轨,那么我应该在IOS / Android中重写哪种渲染器方法来实现此目标?
更新:
iOS: 答案由@apineda提供。在问题下方查看他的解决方案。
Android :似乎需要自定义渲染器。这有点令人讨厌,但是可以。我们必须递归地在视图层次结构中搜索选项卡栏项,并为每个项设置“ ContentDescription”。由于我们使用的是底部导航栏,因此我们向后搜索以获得更好的性能。对于顶部导航栏,您需要搜索“ TabLayout”而不是“ BottomNavigationItemView”。
[assembly: ExportRenderer(typeof(MainPage), typeof(CustomTabbedPageRenderer))]
namespace Company.Project.Droid.CustomRenderers
{
public class CustomTabbedPageRenderer : TabbedRenderer
{
private bool tabsSet = false;
public CustomTabbedPageRenderer(Context context)
: base(context)
{
}
protected override void DispatchDraw(Canvas canvas)
{
if (!tabsSet)
{
SetTabsContentDescription(this);
}
base.DispatchDraw(canvas);
}
private void SetTabsContentDescription(Android.Views.ViewGroup viewGroup)
{
if (tabsSet)
{
return;
}
// loop through the view hierarchy backwards. this will work faster since the tab bar
// is at the bottom of the page
for (int i = viewGroup.ChildCount -1; i >= 0; i--)
{
var menuItem = viewGroup.GetChildAt(i) as BottomNavigationItemView;
if (menuItem != null)
{
menuItem.ContentDescription = "TabBarItem" + i.ToString();
// mark the tabs as set, so we don't do this loop again
tabsSet = true;
}
else
{
var viewGroupChild = viewGroup.GetChildAt(i) as Android.Views.ViewGroup;
if (viewGroupChild != null && viewGroupChild.ChildCount > 0)
{
SetTabsContentDescription(viewGroupChild);
}
}
}
}
}
}
答案 0 :(得分:2)
您不需要CustomRenderer
。您只需要将AutomationId
设置为TabPage的子项Pages
,并将其分配到条项。
假设您有以下TabPage
<?xml version="1.0" encoding="UTF-8"?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MyGreatNamespace"
x:Class="MyGreatNamespace.MyTabPage">
<TabbedPage.Children>
<local:MainPage AutomationId="MainTab" Title="Main Page" />
<local:PageOne AutomationId="TabOne" Title="Page One" />
<local:PageTwo AutomationId="TabTwo" Title="Page Two" />
</TabbedPage.Children>
</TabbedPage>
使用此配置,您将能够执行以下操作:
app.Tap("TabTwo");
您将不需要使用Text
属性。
希望这会有所帮助。-
更新:
只需确认以上内容不适用于Android(请注意,您最初的问题适用于Android),仅适用于iOS。由于某些原因,行为有所不同。
您仍然可以按照以下说明使用文本的本地化版本来“点击”。
处理本地化文本时可以使用的一个技巧是,设置正确的区域性,然后在XAML中使用相同的资源集作为测试的一部分。
即
app.Tap(AppResources.MyMainTabText)