问题
I'm just starting out with UI Automation for my iOS app and am already having trouble. I'm unable to attach screen shots so I'll do my best to describe my scenario.
I'm building for iOS 6.0 and am using a storyboard. The app launches to a screen with a navigation controller. The root view controller contains a main view that has 1 UIView subview that takes up the bottom 60% of the screen and a segmented control that sits above that subview. I was able to configure accessibility for the main view (label "mainview"). I am then able to locate this element in my test no problem. However, I am now having trouble finding the segmented controller. So I decided to log out the length of "elements()" and "segementedControls()" from my "mainview" element and the length of each array is 0. So somehow when the test is running my app it's saying there are no sub-elements on my main view.
Another thing to note is that I could not find any accessibility section in the identity inspector of the storyboard editor for the segmented control. However I temporarily added a button to my main view and configured that with an accessibility label, just to test if the elements() or buttons() calls would subsequently show an element for the main view when running my test, but these arrays were still returning as empty, even with the button.
Here's my script:
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();
Any help greatly appreciated.
EDIT: I added this to my script to search the entire view hierarchy from the main window, set an accessibility label value for my segmented control in initWithCoder (since I don't seem able to set one in the storyboard editor for a segmented control, as I stated earlier) and still could not find the element - it's as though it's just not in the view hierarchy, though it's on the screen and functions just fine:
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");
}
....
}
EDIT: Added call to app.logElementTree() and still no segmented control in sight ("PhysicianCollectionParentView" is my "mainview" - you can see, no sub-elements there):
EDIT: Here are some screen shots. The first shows my "master" view controller. The next shows that in addition to the segmented control there is also a UIView subview. The 3rd shows the basic entry point for the app in my storyboard.
Here is the class extension for my "master" view controller here, showing the outlets for the segmented control and the other UIView subview:
@interface PhysicianCollectionMasterViewController ()
@property (strong, nonatomic) IBOutlet UISegmentedControl *viewSelectionControl;
@property (strong, nonatomic) IBOutlet UIView *physicianCollectionView;
@end
EDIT: Here's something very interesting - I decided to go with a brand new script created within instruments and take advantage of the record feature. When I clicked on my segmented control, here's the JavaScript it created to show me how it had accessed one of the buttons on my segmented control:
var target = UIATarget.localTarget();
target.frontMostApp().mainWindow().elements()["PhysicianCollectionParentView"].tapWithOptions({tapOffset:{x:0.45, y:0.04}});
So, I guess worst-case I could go with something like this, but it just makes no sense to me that UI Automation just does not think that the control exists. So strange. There must be something I'm missing but my setup is so basic I can't imagine what it could be.
回答1:
When you set accessibilityLabel for an element and flag it isAccessibilityElement = YES;
the subviews of that element are hidden. For automation, you should use accessibilityIdentifier instead of accessibilityLabel and set isAccessibilityElement = NO;
In your objective C code after physicianCollectionView is rendered, remove the label and accessibility flag and do this instead:
physicianCollectionView.accessibilityIdentifier = @"PhysicianCollectionParentView";
physicianCollectionView.isAccessibilityElement = NO;
For last elements in element tree, which do not have sub views, set isAccessibilityElement = YES;
回答2:
If you haven't tried it already, you might try adding a delay at the beginning of your script:
UIATarget.localTarget().delay(3);
I think that it is possible that your app isn't done rendering/animating before the logElementTree() that you have posted above. We add delays at the beginning and between each application transition in our automated testing scripts to ensure that the screen has finished rendering.
EDIT: After messing around with your setup in a test app, I believe that your issue is that you are enabling Accessibility on the UIView that contains your segmented control. With accessibility disabled on the UIView, I am able to get the UISegmentedControl to show in the element tree, but once I enable it, the UIView then begins displaying as a UIAElement with no children. My suggestion is to disable accessibility for the containing UIView, and only use accessibility for base controls (like buttons, table view cells, or your segmented button control).
来源:https://stackoverflow.com/questions/14821713/ios-ui-automation-element-finds-no-sub-elements