iOS UI Automation元素不会找到子元素

时间:2013-02-11 22:02:11

标签: ios objective-c ios-ui-automation

我刚开始使用iOS自动化的iOS应用程序,我已经遇到了麻烦。我无法附加屏幕截图,所以我会尽力描述我的场景。

我正在为iOS 6.0构建并使用故事板。该应用程序启动到带有导航控制器的屏幕。根视图控制器包含一个主视图,该视图具有占据屏幕底部60%的1个UIView子视图和位于该子视图上方的分段控件。我能够为主视图配置辅助功能(标签“mainview”)。然后我能够在我的测试中找到这个元素没问题。但是,我现在无法找到分段控制器。所以我决定从我的“mainview”元素中注销“elements()”和“segementedControls()”的长度,每个数组的长度为0.所以当测试运行我的应用程序时,它说没有子 - 我的主要观点上的元素。

需要注意的另一件事是我在故事板编辑器的身份检查器中找不到分段控件的任何辅助功能部分。但是我暂时在主视图中添加了一个按钮,并使用辅助功能标签对其进行了配置,以便测试在运行我的测试时,elements()或者按钮()调用是否随后会显示主视图的元素,但是这些数组仍然是即使按下按钮也会返回为空。

这是我的剧本:

var target = UIATarget.localTarget();
var app = target.frontMostApp();

function selectListView() {
var testName = "selectListView";

UIALogger.logStart(testName);

var view = app.mainWindow().elements()["mainview"];
if (!view.isValid()) {
    UIALogger.logFail("Could not locate main view");    
}

UIALogger.logMessage("Number of elements for sub element: " + view.elements().length);

var segmentedControl = view.segmentedControls()[0];
if (!segmentedControl.isValid()) {
    UIALogger.logFail("Could not locate segmented control on physician collection parent view");
}

var listButton = segmentedControl.buttons()[1];
if (!listButton.isValid()) {
    UIALogger.logFail("Could not locate list button on segemented controller on physician collection parent view"); 
}

UIALogger.logMessage("Tapping List button on physician collection view's segmented control");
listButton.tap();

UIALogger.logPass(testName);
}

selectListView();

非常感谢任何帮助。

编辑:我将此添加到我的脚本中以从主窗口搜索整个视图层次结构,在initWithCoder中为我的分段控件设置辅助功能标签值(因为我似乎无法在故事板编辑器中为一个设置一个分段控制,正如我前面所说的那样)并且仍然无法找到元素 - 它就好像它不在视图层次结构中,尽管它在屏幕上并且运行正常:

function traverse(root, name) {
if (root.name() == name) {
    return root;
}

var elements = root.elements();

for (var i = 0; i < elements.length; i++) {
    var e = elements[i];

    var result = traverse(e, name);
    if(result != null) {
        return result;
    } 
}

return null;
}

function selectListView() {
var testName = "selectListView";

var segmentedControl = traverse(UIATarget.localTarget().frontMostApp().mainWindow(), "mysegementedcontrol");
if (segmentedControl == null) {
    UIALogger.logMessage("Still could not find it");
}

....
}

编辑:添加了对app.logElementTree()的调用,仍然没有看到分段控件(“PhysicianCollectionParentView”是我的“主视图” - 你可以看到,那里没有子元素):

enter image description here

编辑:这是一些屏幕截图。第一个显示我的“主”视图控制器。接下来显示除了分段控件之外,还有一个UIView子视图。第3部分显示了我的故事板中应用程序的基本入口点。

This shows the "master" view controller

This shows that in addition to the segmented control there is also an UIView subview

This shows the basic entry point part of my storyboard file

这里是我的“主”视图控制器的类扩展,显示了分段控件和其他UIView子视图的出口:

@interface PhysicianCollectionMasterViewController ()
@property (strong, nonatomic) IBOutlet UISegmentedControl *viewSelectionControl;
@property (strong, nonatomic) IBOutlet UIView *physicianCollectionView;
@end
编辑:这里有一些非常有趣的东西 - 我决定使用在乐器中创建的全新脚本并利用录制功能。当我点击我的分段控件时,这里是它创建的JavaScript,用于向我展示它如何访问我的分段控件上的一个按钮:

var target = UIATarget.localTarget();

target.frontMostApp().mainWindow().elements()["PhysicianCollectionParentView"].tapWithOptions({tapOffset:{x:0.45, y:0.04}});

所以,我猜最糟糕的情况我可以选择这样的东西,但是对我来说UI自动化只是不认为控件存在是没有意义的。这么奇怪。必须有一些我缺少的东西,但我的设置是如此基本,我无法想象它可能是什么。

2 个答案:

答案 0 :(得分:4)

为元素设置accessibilityLabel并将其标记为isAccessibilityElement = YES;时,隐藏该元素的子视图。对于自动化,您应该使用accessibilityIdentifier而不是accessibilityLabel并设置isAccessibilityElement = NO;

在呈现physicianCollectionView之后的目标C代码中,删除标签和辅助功能标志并执行此操作:

physicianCollectionView.accessibilityIdentifier = @"PhysicianCollectionParentView";
physicianCollectionView.isAccessibilityElement = NO;

对于元素树中没有子视图的最后一个元素,设置isAccessibilityElement = YES;

答案 1 :(得分:1)

如果您尚未尝试过,可以尝试在脚本开头添加延迟:

UIATarget.localTarget().delay(3);

我认为你的应用可能没有在你上面发布的logElementTree()之前完成呈现/动画。我们在自动测试脚本的开头和每个应用程序转换之间添加延迟,以确保屏幕已完成呈现。

编辑:在测试应用程序中搞砸了您的设置后,我认为您的问题是您在包含分段控件的UIView上启用了辅助功能。在UIView上禁用了辅助功能后,我能够在元素树中显示UISegmentedControl,但是一旦启用它,UIView就会开始显示为没有子节点的UIAElement。我的建议是禁用包含UIView的可访问性,并仅使用基本控件的可访问性(如按钮,表格视图单元格或分段按钮控件)。