iOS/UI Automation: UIAActionSheet does not have possibilities to manipulate with buttons

戏子无情 提交于 2019-12-02 03:22:14

As you can see there is method to return default button for each action sheet, which is Cancel button. As there is no other 'default' buttons for action sheet you need to implement those on your own.
One thing to notice woorth apple reference is that it skips methods for given class which are inherited from parent. UIAActionSheet (like most UIA elements) inherits all methods from UIAElement class. Check this reference. You should be able to get array of all buttons from actionsheet by calling

var arrButtons = objActionSheet.buttons();

Then you can check by name property which one you need (again method from UIAElement name() ).

Alliteratively, if you check which element in array you are interested in you could call that button directly (assuming, that you won't change ActionSheet) by using UIAElement method elements().
For example if you want to tap second button in ActionSheet tree, you just call

UIATarget.localTarget().frontMostApp().actionSheet().elements()[1].tap();

Maybe you can skip localTarget(), not sure, but code above should work.

I have found a solution for the problem using direct tapping simulation. It is not an excellent solution but at least it works. I have asked the same question in the Apple Developer Forum but did not get any response.

So, the function below is my solution. I have tested it and it performs well. I will still continue to search for better approach.

function tapActionSheetButton(target, actionSheet, buttonIndex)
{
    var headerHeight = 28;
    var buttonHeight = 50;

    if (buttonIndex >= 0) 
    {
        var actionSheetRect = actionSheet.rect();
        UIALogger.logMessage("actionSheet:{rect:{origin:{x:" + actionSheetRect.origin.x.toString() 
                             + ", y:" + actionSheetRect.origin.y.toString()
                             + "}, size:{width:" + actionSheetRect.size.width.toString()
                             + ", height:" + actionSheetRect.size.height.toString()
                             + "}}}");
        var xOffset = actionSheetRect.size.width / 2;
        var yOffset = headerHeight + buttonIndex * buttonHeight + buttonHeight / 2;
        if (yOffset < actionSheetRect.size.height) {
            var tap_x = actionSheetRect.origin.x + xOffset;
            var tap_y = actionSheetRect.origin.y + yOffset;
            target.tap({x:tap_x, y:tap_y});
        }
    }
    else
    {
        var message = "Cannot tap button " + buttonIndex.toString() + ". It does not exist";
        throw message;
    }
}

Since my action sheet was in a popover this returns a nil element:

UIATarget.localTarget().frontMostApp().actionSheet();

This does return the action sheet:

UIATarget.localTarget().frontMostApp().mainWindow().popover().actionSheet();

But it has nil elements() and buttons().

So I used MikhailV's function to tap the buttons.

var target = UIATarget.localTarget();
var actionSheet = UIATarget.localTarget().frontMostApp().mainWindow().popover().actionSheet();
var buttonIndex = 1;

tapActionSheetButton(target, actionSheet, buttonIndex);

If you like to keep it organized like me:

function getTarget() {
    return UIATarget.localTarget();
}

function getApp() {
    return getTarget().frontMostApp();
}

function getWindow() {
    return getApp().mainWindow();
}

function tapActionSheetButtonInIndex(index) {
    var actionSheet = getApp().actionSheet() || getWindow().popover().actionSheet();
    actionSheet.buttons()[index].tap(); 
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!