package net.northking.cctp.element.mobile.ios.keywords;

import net.northking.cctp.element.core.DeviceDriver;
import net.northking.cctp.element.core.IExecuteContext;
import net.northking.cctp.element.core.IStepTarget;
import net.northking.cctp.element.core.annotation.Argument;
import net.northking.cctp.element.core.annotation.Keyword;
import net.northking.cctp.element.core.annotation.Keywords;
import net.northking.cctp.element.core.annotation.Return;
import net.northking.cctp.element.core.exception.AssertException;
import net.northking.cctp.element.core.exception.ExecuteException;
import net.northking.cctp.element.core.type.DataType;
import net.northking.cctp.element.core.type.InputType;
import net.northking.cctp.element.core.type.ParamScope;
import net.northking.cctp.element.mobile.ios.entity.ElementHandleParam;
import net.northking.cctp.element.mobile.ios.enums.AppEnum;
import net.northking.cctp.element.mobile.ios.enums.SwipeDirection;
import net.northking.cctp.element.mobile.ios.enums.WhetherOrNotEnum;
import net.northking.cctp.element.mobile.ios.utils.AutomationHandleUtil;
import net.northking.cctp.element.mobile.ios.utils.CommonUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.concurrent.CancellationException;

/**
 * ios新版的组件
 */
@Keywords
public class IOSNewTools {

    private Logger logger = LoggerFactory.getLogger(IOSNewTools.class);

    /**
     * <p>点击控件（ios新）</p>
     *
     * @param deviceDriver   设备驱动链接
     * @param targets        定位控件的信息
     * @param waitTimeout    默认超时时间
     * @param waitStatusStr  是否等待界面稳定
     * @param swipe          滑动方向
     * @param swipeCount     滑动次数
     * @param preExecuteWait 执行前等待
     * @param sufExecuteWait 执行后等待
     * @return
     */
    @Keyword(alias = "点击控件(ios新)", category = "0", attributes = "9", commonlyUse = true)
    @Return(name = "result", comment = "点击结果", type = DataType.BOOLEAN)
    public boolean clickElement(IExecuteContext context,
                                @Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
                                @Argument(name = "targets", scope = ParamScope.STEP, comment = "控件位置", type = DataType.LIST, defaultDisplay = false) List<IStepTarget> targets,
                                @Argument(name = "timeout", scope = ParamScope.ARGS, comment = "默认超时时间", type = DataType.INTEGER, required = false, defaultValue = "30", defaultDisplay = false) Integer waitTimeout,
                                @Argument(name = "waitStatus", scope = ParamScope.ARGS, comment = "等待界面稳定", type = DataType.ENUM, enumValues = WhetherOrNotEnum.class, inputType = InputType.select, defaultValue = "1", defaultDisplay = false) String waitStatusStr,
                                @Argument(name = "swipe", scope = ParamScope.ARGS, comment = "滑动方向", type = DataType.ENUM, enumValues = SwipeDirection.class, required = false, defaultValue = "0", inputType = InputType.select, defaultDisplay = false) String swipe,
                                @Argument(name = "swipeCount", scope = ParamScope.ARGS, comment = "滑动次数", type = DataType.INTEGER, required = false, defaultValue = "0", defaultDisplay = false) Integer swipeCount,
//                                   @Argument(name = "xMove", scope = ParamScope.ARGS, comment = "水平偏移量", type = DataType.INTEGER, required = false, defaultValue = "0", defaultDisplay = false) Integer xMove,
//                                   @Argument(name = "yMove", scope = ParamScope.ARGS, comment = "垂直偏移量", type = DataType.INTEGER, required = false, defaultValue = "0", defaultDisplay = false) Integer yMove,
                                @Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float preExecuteWait,
                                @Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float sufExecuteWait
    ) {
        CommonUtils.handlePreExecuteWait(preExecuteWait);  //执行前等待
        boolean waitStatus = "1".equals(waitStatusStr);   //是否等待界面稳定
        ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
                .useContext(context)
                .withTargets(targets)
                .waitTimeout(waitTimeout)
                .searchSwipeDirection(swipe)
                .withSwipeCount(swipeCount)
                .waitStatus(waitStatus);
        boolean success = false;
        try {
            success = AutomationHandleUtil.clickElement(param);
        } catch (InterruptedException ie) {
            logger.warn("用户取消查询元素");
            throw new ExecuteException("取消操作");
        } catch (Exception e) {
            logger.error("出现了其他的问题。。。。", e);
            throw new ExecuteException(e.getMessage());
        }
        CommonUtils.handleSufExecuteWait(sufExecuteWait);  //执行后等待
        return success;
    }

    /**
     * <p>判断是否界面上存在某一个元素（ios新）</p>
     *
     * @param deviceDriver   设备驱动
     * @param targets        元素的信息
     * @param waitTimeout    默认超时时间
     * @param waitStatusStr  是否等待界面稳定
     * @param swipe          滑动方向
     * @param swipeCount     滑动次数
     * @param value          返回结果接受的值
     * @param preExecuteWait 执行前等待
     * @param sufExecuteWait 执行后等待
     * @return
     */
    @Keyword(alias = "是否存在元素（ios新）", category = "0", attributes = "9")
    @Return(name = "result", comment = "是否存在元素的结果", type = DataType.BOOLEAN)
    public boolean ifElement(IExecuteContext context,
                             @Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
                             @Argument(name = "targets", scope = ParamScope.STEP, comment = "控件位置", type = DataType.LIST, defaultDisplay = false) List<IStepTarget> targets,
                             @Argument(name = "timeout", scope = ParamScope.ARGS, comment = "默认超时时间", type = DataType.INTEGER, required = false, defaultValue = "30", defaultDisplay = false) Integer waitTimeout,
                             @Argument(name = "waitStatus", scope = ParamScope.ARGS, comment = "等待界面稳定", type = DataType.ENUM, enumValues = WhetherOrNotEnum.class, inputType = InputType.select, defaultValue = "1", defaultDisplay = false) String waitStatusStr,
                             @Argument(name = "swipe", scope = ParamScope.ARGS, comment = "滑动方向", type = DataType.ENUM, enumValues = SwipeDirection.class, inputType = InputType.select, defaultValue = "0", required = false, defaultDisplay = false) String swipe,
                             @Argument(name = "swipeCount", scope = ParamScope.ARGS, comment = "滑动次数", type = DataType.INTEGER, defaultValue = "0", required = false, defaultDisplay = false) Integer swipeCount,
                             @Argument(name = "value", scope = ParamScope.OUTPUT, comment = "组件返回值", type = DataType.STRING, defaultValue = "") String value,
                             @Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float preExecuteWait,
                             @Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float sufExecuteWait) {
        CommonUtils.handlePreExecuteWait(preExecuteWait);  //执行前等待
        boolean waitStatus = "1".equals(waitStatusStr);   //是否等待界面稳定
        ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
                .useContext(context)
                .withTargets(targets)
                .waitTimeout(waitTimeout)
                .searchSwipeDirection(swipe)
                .withSwipeCount(swipeCount)
                .waitStatus(waitStatus);
        Boolean success = false;
        try {
            success = AutomationHandleUtil.ifElement(param);
        } catch (InterruptedException ie) {
            logger.warn("用户取消查询元素");
            throw new ExecuteException("取消操作");
        } catch (Exception e) {
            logger.error("出现了其他的问题。。。。", e);
            success = false;
        }
        CommonUtils.handleSufExecuteWait(sufExecuteWait);  //执行后等待
        CommonUtils.setParamValue(context, value, success.toString());
        return success;
    }

    /**
     * <p>标准滑动屏幕(ios)</p>
     *
     * @param direction      滑动方向
     * @param deviceDriver   设备连接
     * @param size           滑动距离
     * @param preExecuteWait 执行前等待
     * @param sufExecuteWait 执行后等待
     * @return
     */
    @Keyword(alias = "标准滑动（ios新）", category = "0", attributes = "9", commonlyUse = true)
    @Return(name = "result", comment = "滑动结果", type = DataType.BOOLEAN)
    public boolean standardSwipe(
            @Argument(name = "direction", scope = ParamScope.ARGS, comment = "滑动方向", type = DataType.ENUM, enumValues = SwipeDirection.class, inputType = InputType.select, defaultValue = "up") String direction,
            @Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
            @Argument(name = "timeout", scope = ParamScope.ARGS, comment = "默认超时时间", type = DataType.INTEGER, required = false, defaultValue = "30", defaultDisplay = false) Integer waitTimeout,
            @Argument(name = "size", scope = ParamScope.ARGS, comment = "滑动距离", type = DataType.INTEGER, required = false, notNull = false, defaultValue = "500") Integer size,
            @Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float preExecuteWait,
            @Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float sufExecuteWait
    ) {
        CommonUtils.handlePreExecuteWait(preExecuteWait);  //执行前等待
        ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
                .waitTimeout(waitTimeout)
                .swipeDirection(direction)
                .withSwipeSize(size);
        Boolean success = false;
        try {
            success = AutomationHandleUtil.standardSwipe(param);
        } catch (InterruptedException ie) {
            logger.warn("用户取消查询元素");
            throw new ExecuteException("取消操作");
        } catch (Exception e) {
            logger.error("出现了其他的问题。。。。", e);
            throw new ExecuteException(e.getMessage());
        }
        CommonUtils.handleSufExecuteWait(sufExecuteWait);  //执行后等待
        return success;
    }

    /**
     * <p>控件滑动，以控件的中心坐标点为起点滑动</p>
     *
     * @param direction      滑动方向
     * @param deviceDriver   设备驱动
     * @param size           滑动距离
     * @param targets        控件信息
     * @param waitTimeout    默认超时时间
     * @param waitStatusStr  是否等待界面稳定
     * @param swipe          滑动方向
     * @param swipeCount     滑动次数
     * @param preExecuteWait 执行前等待
     * @param sufExecuteWait 执行后等待
     * @return
     */
    @Keyword(alias = "控件滑动（ios新）", category = "0", attributes = "9", commonlyUse = true)
    @Return(name = "result", comment = "滑动的结果", type = DataType.BOOLEAN)
    public boolean elementSwipe(IExecuteContext context,
                                @Argument(name = "direction", scope = ParamScope.ARGS, comment = "控件滑动方向", type = DataType.ENUM, enumValues = SwipeDirection.class, defaultDisplay = false, inputType = InputType.select, defaultValue = "up") String direction,
                                @Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
                                @Argument(name = "size", scope = ParamScope.ARGS, comment = "滑动距离", type = DataType.INTEGER, required = false, notNull = false, defaultValue = "500") Integer size,
                                @Argument(name = "targets", scope = ParamScope.STEP, comment = "控件位置", type = DataType.LIST, defaultDisplay = false) List<IStepTarget> targets,
                                @Argument(name = "timeout", scope = ParamScope.ARGS, comment = "默认超时时间", type = DataType.INTEGER, required = false, defaultValue = "30", defaultDisplay = false) Integer waitTimeout,
                                @Argument(name = "waitStatus", scope = ParamScope.ARGS, comment = "等待界面稳定", type = DataType.ENUM, enumValues = WhetherOrNotEnum.class, inputType = InputType.select, defaultValue = "1", defaultDisplay = false) String waitStatusStr,
                                @Argument(name = "swipe", scope = ParamScope.ARGS, comment = "查找控件滑动方向", type = DataType.ENUM, enumValues = SwipeDirection.class, inputType = InputType.select, defaultValue = "0", required = false, defaultDisplay = false) String swipe,
                                @Argument(name = "swipeCount", scope = ParamScope.ARGS, comment = "滑动次数", type = DataType.INTEGER, defaultValue = "0", required = false, defaultDisplay = false) Integer swipeCount,
                                @Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float preExecuteWait,
                                @Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float sufExecuteWait) {
        CommonUtils.handlePreExecuteWait(preExecuteWait);  //执行前等待
        boolean waitStatus = "1".equals(waitStatusStr);   //是否等待界面稳定
        ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
                .useContext(context)
                .withTargets(targets)
                .waitTimeout(waitTimeout)
                .searchSwipeDirection(swipe)
                .withSwipeCount(swipeCount)
                .swipeDirection(direction)
                .withSwipeSize(size)
                .waitStatus(waitStatus);
        Boolean success = false;
        try {
            success = AutomationHandleUtil.elementSwipe(param);
        } catch (InterruptedException ie) {
            logger.warn("用户取消查询元素");
            throw new ExecuteException("取消操作");
        } catch (Exception e) {
            logger.error("出现了其他的问题。。。。", e);
            throw new ExecuteException(e.getMessage());
        }
        CommonUtils.handleSufExecuteWait(sufExecuteWait);  //执行后等待
        return success;
    }

    /**
     * <p>在控件中输入文本（ios新）</p>
     *
     * @param text           输入的文本
     * @param cleanStr       是否清空文本框0-否，1-是
     * @param deviceDriver   设备连接驱动
     * @param targets        定位控件参数
     * @param waitTimeout    超时时间
     * @param waitStatusStr  是否等待屏幕稳定
     * @param swipe          是否滑屏查找控件0-否，up-上滑，down-下滑，left-左滑,right-右滑
     * @param swipeCount     滑屏次数
     * @param preExecuteWait 执行前等待
     * @param sufExecuteWait 执行后等待
     * @return
     */
    @Keyword(alias = "控件输入文本（ios新）", category = "0", attributes = "9", commonlyUse = true)
    @Return(name = "result", comment = "输入的结果", type = DataType.BOOLEAN)
    public boolean inputText(IExecuteContext context,
                             @Argument(name = "text", scope = ParamScope.VARIABLES, comment = "输入的文本", type = DataType.STRING) String text,
                             @Argument(name = "clean", scope = ParamScope.ARGS, comment = "是否清空输入框", type = DataType.ENUM, enumValues = WhetherOrNotEnum.class, inputType = InputType.select, defaultValue = "1", defaultDisplay = false) String cleanStr,
                             @Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
                             @Argument(name = "targets", scope = ParamScope.STEP, comment = "控件位置", type = DataType.LIST, defaultDisplay = false) List<IStepTarget> targets,
                             @Argument(name = "timeout", scope = ParamScope.ARGS, comment = "默认超时时间", type = DataType.INTEGER, required = false, defaultValue = "30", defaultDisplay = false) Integer waitTimeout,
                             @Argument(name = "waitStatus", scope = ParamScope.ARGS, comment = "等待界面稳定", type = DataType.ENUM, enumValues = WhetherOrNotEnum.class, inputType = InputType.select, defaultValue = "1", defaultDisplay = false) String waitStatusStr,
                             @Argument(name = "swipe", scope = ParamScope.ARGS, comment = "滑动方向", type = DataType.ENUM, enumValues = SwipeDirection.class, inputType = InputType.select, defaultValue = "0", required = false, defaultDisplay = false) String swipe,
                             @Argument(name = "swipeCount", scope = ParamScope.ARGS, comment = "滑动次数", type = DataType.INTEGER, required = false, defaultValue = "0", defaultDisplay = false) Integer swipeCount,
                             @Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float preExecuteWait,
                             @Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float sufExecuteWait
    ) {
        CommonUtils.handlePreExecuteWait(preExecuteWait);  //执行前等待
        boolean waitStatus = "1".equals(waitStatusStr);   //是否等待界面稳定
        boolean clear = "1".equals(cleanStr);   //是否清除文本框
        ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
                .useContext(context)
                .withTargets(targets)
                .waitTimeout(waitTimeout)
                .searchSwipeDirection(swipe)
                .withSwipeCount(swipeCount)
                .clear(clear)
                .withInputTextValue(text)
                .waitStatus(waitStatus);
        Boolean success = false;
        try {
            success = AutomationHandleUtil.elementInput(param);
        } catch (InterruptedException ie) {
            logger.warn("用户取消查询元素");
            throw new ExecuteException("取消操作");
        } catch (Exception e) {
            logger.error("出现了其他的问题。。。。", e);
            throw new ExecuteException(e.getMessage());
        }
        CommonUtils.handleSufExecuteWait(sufExecuteWait);  //执行后等待
        return success;
    }

    /**
     * <p>获取控件的值</p>
     *
     * @param deviceDriver   设备连接驱动
     * @param targets        定位控件参数
     * @param waitTimeout    超时时间
     * @param waitStatusStr  是否等待屏幕稳定
     * @param swipe          是否滑屏查找控件0-否，up-上滑，down-下滑，left-左滑,right-右滑
     * @param swipeCount     滑屏次数
     * @param preExecuteWait 执行前等待
     * @param sufExecuteWait 执行后等待
     * @param value          输出值
     * @return
     */
    @Keyword(alias = "获取控件的值（ios新）", category = "0", attributes = "9")
    @Return(name = "result", comment = "获取控件值的结果", type = DataType.OBJECT)
    public String getElementText(IExecuteContext context,
                                 @Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
                                 @Argument(name = "targets", scope = ParamScope.STEP, comment = "控件位置", type = DataType.LIST, defaultDisplay = false) List<IStepTarget> targets,
                                 @Argument(name = "timeout", scope = ParamScope.ARGS, comment = "默认超时时间", type = DataType.INTEGER, required = false, defaultValue = "30", defaultDisplay = false) Integer waitTimeout,
                                 @Argument(name = "waitStatus", scope = ParamScope.ARGS, comment = "等待界面稳定", type = DataType.ENUM, enumValues = WhetherOrNotEnum.class, inputType = InputType.select, defaultValue = "1", defaultDisplay = false) String waitStatusStr,
                                 @Argument(name = "swipe", scope = ParamScope.ARGS, comment = "滑动方向", type = DataType.ENUM, enumValues = SwipeDirection.class, inputType = InputType.select, defaultValue = "0", required = false, defaultDisplay = false) String swipe,
                                 @Argument(name = "swipeCount", scope = ParamScope.ARGS, comment = "滑动次数", type = DataType.INTEGER, required = false, defaultValue = "0", defaultDisplay = false) Integer swipeCount,
                                 @Argument(name = "value", scope = ParamScope.OUTPUT, comment = "组件返回值", type = DataType.STRING, defaultValue = "") String value,
                                 @Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float preExecuteWait,
                                 @Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float sufExecuteWait) {
        CommonUtils.handlePreExecuteWait(preExecuteWait);  //执行前等待
        boolean waitStatus = "1".equals(waitStatusStr);   //是否等待界面稳定
        ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
                .useContext(context)
                .withTargets(targets)
                .waitTimeout(waitTimeout)
                .searchSwipeDirection(swipe)
                .withSwipeCount(swipeCount)
                .waitStatus(waitStatus);
        String result = "";
        try {
            result = AutomationHandleUtil.getElementValue(param);
        } catch (InterruptedException ie) {
            logger.warn("用户取消查询元素");
            throw new ExecuteException("取消操作");
        } catch (Exception e) {
            logger.error("出现了其他的问题。。。。", e);
            throw new ExecuteException(e.getMessage());
        }
        CommonUtils.handleSufExecuteWait(sufExecuteWait);  //执行后等待
        CommonUtils.setParamValue(context, value, result);
        return result;
    }

    /**
     * <p>长按控件</p>
     *
     * @param deviceDriver   设备连接驱动
     * @param targets        定位控件参数
     * @param waitTimeout    超时时间
     * @param waitStatusStr  是否等待屏幕稳定
     * @param swipe          是否滑屏查找控件0-否，up-上滑，down-下滑，left-左滑,right-右滑
     * @param swipeCount     滑屏次数
     * @param preExecuteWait 执行前等待
     * @param sufExecuteWait 执行后等待
     * @return
     */
    @Keyword(alias = "长按控件(ios新)", category = "0", attributes = "9", commonlyUse = true)
    @Return(name = "result", comment = "长按结果", type = DataType.BOOLEAN)
    public boolean longPress(IExecuteContext context,
                             @Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
                             @Argument(name = "targets", scope = ParamScope.STEP, comment = "控件位置", type = DataType.LIST, defaultDisplay = false) List<IStepTarget> targets,
                             @Argument(name = "timeout", scope = ParamScope.ARGS, comment = "默认超时时间", type = DataType.INTEGER, required = false, defaultValue = "30", defaultDisplay = false) Integer waitTimeout,
                             @Argument(name = "waitStatus", scope = ParamScope.ARGS, comment = "等待界面稳定", type = DataType.ENUM, enumValues = WhetherOrNotEnum.class, inputType = InputType.select, defaultValue = "1", defaultDisplay = false) String waitStatusStr,
                             @Argument(name = "swipe", scope = ParamScope.ARGS, comment = "滑动方向", type = DataType.ENUM, enumValues = SwipeDirection.class, inputType = InputType.select, defaultValue = "0", required = false, defaultDisplay = false) String swipe,
                             @Argument(name = "swipeCount", scope = ParamScope.ARGS, comment = "滑动次数", type = DataType.INTEGER, defaultValue = "0", required = false, defaultDisplay = false) Integer swipeCount,
                             @Argument(name = "xMove", scope = ParamScope.ARGS, comment = "水平偏移量", type = DataType.INTEGER, required = false, defaultValue = "0", defaultDisplay = false) Integer xMove,
                             @Argument(name = "yMove", scope = ParamScope.ARGS, comment = "垂直偏移量", type = DataType.INTEGER, required = false, defaultValue = "0", defaultDisplay = false) Integer yMove,
                             @Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float preExecuteWait,
                             @Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float sufExecuteWait
    ) {
        CommonUtils.handlePreExecuteWait(preExecuteWait);  //执行前等待
        boolean waitStatus = "1".equals(waitStatusStr);   //是否等待界面稳定
        ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
                .useContext(context)
                .withTargets(targets)
                .waitTimeout(waitTimeout)
                .searchSwipeDirection(swipe)
                .withSwipeCount(swipeCount)
                .waitStatus(waitStatus)
                .withXMove(xMove)
                .withYMove(yMove);
        boolean success = false;
        try {
            success = AutomationHandleUtil.longPressElement(param);
        } catch (InterruptedException ie) {
            logger.warn("用户取消查询元素");
            throw new ExecuteException("取消操作");
        } catch (Exception e) {
            logger.error("出现了其他的问题。。。。", e);
            throw new ExecuteException(e.getMessage());
        }
        CommonUtils.handleSufExecuteWait(sufExecuteWait);  //执行后等待
        return success;
    }

    /**
     * <p>断言元素</p>
     *
     * @param deviceDriver   设备连接驱动
     * @param targets        定位控件参数
     * @param waitTimeout    超时时间
     * @param waitStatusStr  是否等待屏幕稳定
     * @param swipe          是否滑屏查找控件0-否，up-上滑，down-下滑，left-左滑,right-右滑
     * @param swipeCount     滑屏次数
     * @param preExecuteWait 执行前等待
     * @param sufExecuteWait 执行后等待
     * @return
     */
    @Keyword(alias = "断言元素（ios新）", category = "0", attributes = "9", commonlyUse = true)
    @Return(name = "result", comment = "断言结果", type = DataType.BOOLEAN)
    public boolean assertElement(IExecuteContext context,
                                 @Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
                                 @Argument(name = "timeout", scope = ParamScope.ARGS, comment = "默认超时时间", type = DataType.INTEGER, required = false, defaultValue = "30", defaultDisplay = false) Integer waitTimeout,
                                 @Argument(name = "waitStatus", scope = ParamScope.ARGS, comment = "等待界面稳定", type = DataType.ENUM, enumValues = WhetherOrNotEnum.class, inputType = InputType.select, defaultValue = "1", defaultDisplay = false) String waitStatusStr,
                                 @Argument(name = "swipe", scope = ParamScope.ARGS, comment = "滑动方向", type = DataType.ENUM, enumValues = SwipeDirection.class, inputType = InputType.select, defaultValue = "0", required = false, defaultDisplay = false) String swipe,
                                 @Argument(name = "swipeCount", scope = ParamScope.ARGS, comment = "滑动次数", type = DataType.INTEGER, defaultValue = "0", required = false, defaultDisplay = false) Integer swipeCount,
                                 @Argument(name = "targets", scope = ParamScope.STEP, comment = "图片参数", type = DataType.LIST, defaultDisplay = false) List<IStepTarget> targets,
                                 @Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float preExecuteWait,
                                 @Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float sufExecuteWait
    ) {

        CommonUtils.handlePreExecuteWait(preExecuteWait);  //执行前等待
        boolean waitStatus = "1".equals(waitStatusStr);   //是否等待界面稳定
        ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
                .useContext(context)
                .withTargets(targets)
                .waitTimeout(waitTimeout)
                .searchSwipeDirection(swipe)
                .withSwipeCount(swipeCount)
                .waitStatus(waitStatus);
        Boolean success = false;
        try {
            success = AutomationHandleUtil.ifElement(param);
        } catch (InterruptedException ie) {
            logger.warn("用户取消查询元素");
            throw new ExecuteException("取消操作");
        } catch (Exception e) {
            logger.error("出现了其他的问题。。。。", e);
            throw new ExecuteException(e.getMessage());
        }
        CommonUtils.handleSufExecuteWait(sufExecuteWait);  //执行后等待
        if (success != null && success) {
            return success;
        }
        throw new AssertException("断言失败，找不到目标元素");
    }

    /**
     * <p>验证码识别</p>
     *
     * @param deviceDriver   设备连接驱动
     * @param targets        定位元素参数
     * @param waitTimeout    等待超时时间
     * @param value          赋值变量
     * @param preExecuteWait 执行前等待
     * @param sufExecuteWait 执行后等待
     * @return
     */
    @Keyword(alias = "识别验证码（ios新）", category = "0", attributes = "9")
    @Return(name = "result", comment = "验证码识别", type = DataType.STRING)
    public String getCodeByOcr(
            IExecuteContext context,
            @Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
            @Argument(name = "targets", scope = ParamScope.STEP, comment = "控件位置", type = DataType.LIST, defaultDisplay = false) List<IStepTarget> targets,
            @Argument(name = "timeout", scope = ParamScope.ARGS, comment = "默认超时时间", type = DataType.INTEGER, required = false, defaultValue = "30", defaultDisplay = false) Integer waitTimeout,
            @Argument(name = "value", scope = ParamScope.OUTPUT, comment = "组件返回值", type = DataType.STRING, defaultValue = "") String value,
            @Argument(name = "waitStatus", scope = ParamScope.ARGS, comment = "等待界面稳定", type = DataType.ENUM, enumValues = WhetherOrNotEnum.class, inputType = InputType.select, defaultValue = "1", defaultDisplay = false) String waitStatusStr,
            @Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float preExecuteWait,
            @Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float sufExecuteWait

    ) {
        CommonUtils.handlePreExecuteWait(preExecuteWait);  //执行前等待
        boolean waitStatus = "1".equals(waitStatusStr);   //是否等待界面稳定
        ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
                .useContext(context)
                .withTargets(targets)
                .waitTimeout(waitTimeout)
                .searchSwipeDirection("0")     //不滑动
                .withSwipeCount(1)
                .waitStatus(waitStatus);
        String result = "";
        try {
            result = AutomationHandleUtil.getVerificationCode(param);
        } catch (InterruptedException ie) {
            logger.warn("用户取消查询元素");
            throw new ExecuteException("取消操作");
        } catch (Exception e) {
            logger.error("出现了其他的问题。。。。", e);
            throw new ExecuteException(e.getMessage());
        }
        CommonUtils.handleSufExecuteWait(sufExecuteWait);  //执行后等待
        CommonUtils.setParamValue(context, value, result);
        return result;
    }

    /**
     * <p>点击文本</p>
     *
     * @param deviceDriver   设备连接驱动
     * @param waitTimeout    默认超时时间
     * @param text           点击的文本
     * @param index          选择第几个
     * @param preExecuteWait 执行前等待
     * @param sufExecuteWait 执行后等待
     * @return
     */
    @Keyword(alias = "点击文本(ios新)", category = "0", attributes = "9", commonlyUse = true)
    @Return(name = "result", comment = "是否点击成功", type = DataType.BOOLEAN)
    public Boolean clickText(
            IExecuteContext context,
            @Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
            @Argument(name = "timeout", scope = ParamScope.ARGS, comment = "默认超时时间", type = DataType.INTEGER, required = false, defaultValue = "30", defaultDisplay = false) Integer waitTimeout,
            @Argument(name = "text", comment = "点击文本", scope = ParamScope.ARGS, type = DataType.STRING) String text,
            @Argument(name = "index", comment = "第几个", scope = ParamScope.ARGS, type = DataType.INTEGER, required = true, defaultValue = "1", defaultDisplay = false) Integer index,
            @Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "0.0", defaultDisplay = false) Float preExecuteWait,
            @Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "0.0", defaultDisplay = false) Float sufExecuteWait

    ) {
        CommonUtils.handlePreExecuteWait(preExecuteWait);  //执行前等待
        ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
                .useContext(context)
                .waitTimeout(waitTimeout)
                .searchSwipeDirection("0")   //不滑动
                .withSwipeCount(1)
                .withText(text)
                .withIndex(index);
        boolean success = false;
        try {
            success = AutomationHandleUtil.clickText(param);
        } catch (InterruptedException ie) {
            logger.warn("用户取消查询元素");
            throw new ExecuteException("取消操作");
        } catch (Exception e) {
            logger.error("出现了其他的问题。。。。", e);
            throw new ExecuteException(e.getMessage());
        }
        CommonUtils.handleSufExecuteWait(sufExecuteWait);  //执行后等待
        return success;
    }

    /**
     * <p>点击文本(新)</p>
     *
     * @param deviceDriver   设备连接驱动
     * @param waitTimeout    默认超时时间
     * @param text           点击的文本
     * @param index          选择第几个
     * @param preExecuteWait 执行前等待
     * @param sufExecuteWait 执行后等待
     * @return
     */
    @Keyword(alias = "点击文本(新)(ios新)", category = "0", attributes = "9", commonlyUse = true)
    @Return(name = "result", comment = "是否点击成功", type = DataType.BOOLEAN)
    public Boolean clickTextNew(
            IExecuteContext context,
            @Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
            @Argument(name = "timeout", scope = ParamScope.ARGS, comment = "默认超时时间", type = DataType.INTEGER, required = false, defaultValue = "30", defaultDisplay = false) Integer waitTimeout,
            @Argument(name = "text", comment = "点击文本", scope = ParamScope.ARGS, type = DataType.STRING) String text,
            @Argument(name = "index", comment = "第几个", scope = ParamScope.ARGS, type = DataType.INTEGER, required = true, defaultValue = "1", defaultDisplay = false) Integer index,
            @Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "0.0", defaultDisplay = false) Float preExecuteWait,
            @Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "0.0", defaultDisplay = false) Float sufExecuteWait

    ) {
        CommonUtils.handlePreExecuteWait(preExecuteWait);  //执行前等待
        ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
                .useContext(context)
                .waitTimeout(waitTimeout)
                .searchSwipeDirection("0")   //不滑动
                .withSwipeCount(1)
                .withText(text)
                .withIndex(index);
        boolean success = false;
        try {
            success = AutomationHandleUtil.clickTextNew(param);
        } catch (InterruptedException ie) {
            logger.warn("用户取消查询元素");
            throw new ExecuteException("取消操作");
        } catch (Exception e) {
            logger.error("出现了其他的问题。。。。", e);
            throw new ExecuteException(e.getMessage());
        }
        CommonUtils.handleSufExecuteWait(sufExecuteWait);  //执行后等待
        return success;
    }

    /**
     * <p>判断当前页面是否存在文本</p>
     *
     * @param deviceDriver   设备连接驱动
     * @param waitTimeout    默认等待时长
     * @param text           判断的文本
     * @param value          接受返回结果
     * @param preExecuteWait 执行前等待
     * @param sufExecuteWait 执行后等待
     * @return 返回判断的结果
     */
    @Keyword(alias = "是否存在文本(ios新)", category = "0", attributes = "9")
    @Return(name = "result", comment = "文本存在与不存在的结果", type = DataType.BOOLEAN)
    public Boolean ifText(
            IExecuteContext context,
            @Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
            @Argument(name = "timeout", scope = ParamScope.ARGS, comment = "默认超时时间", type = DataType.INTEGER, required = false, defaultValue = "30", defaultDisplay = false) Integer waitTimeout,
            @Argument(name = "text", comment = "文本", scope = ParamScope.ARGS, type = DataType.STRING) String text,
            @Argument(name = "swipe", scope = ParamScope.ARGS, comment = "滑动方向", type = DataType.ENUM, enumValues = SwipeDirection.class, inputType = InputType.select, defaultValue = "0", required = false, defaultDisplay = false) String swipe,
            @Argument(name = "swipeCount", scope = ParamScope.ARGS, comment = "滑动次数", type = DataType.INTEGER, defaultValue = "0", required = false, defaultDisplay = false) Integer swipeCount,
            @Argument(name = "value", scope = ParamScope.OUTPUT, comment = "组件返回值", type = DataType.STRING, defaultValue = "") String value,
            @Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "0.0", defaultDisplay = false) Float preExecuteWait,
            @Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "0.0", defaultDisplay = false) Float sufExecuteWait
    ) {
        CommonUtils.handlePreExecuteWait(preExecuteWait);  //执行前等待
        ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
                .useContext(context)
                .waitTimeout(waitTimeout)
                .searchSwipeDirection(swipe)
                .withSwipeCount(swipeCount)
                .withText(text);
        boolean success = false;
        try {
            success = AutomationHandleUtil.ifText(param);
        } catch (InterruptedException ie) {
            logger.warn("用户取消查询元素");
            throw new ExecuteException("取消操作");
        } catch (Exception e) {
            logger.error("出现了其他的问题。。。。", e);
            throw new ExecuteException(e.getMessage());
        }
        CommonUtils.handleSufExecuteWait(sufExecuteWait);  //执行后等待
        CommonUtils.setParamValue(context, value, String.valueOf(success));
        return success;
    }

    /**
     * <p>app处理</p>
     *
     * @param deviceDriver   设备连接驱动
     * @param appPackage     启动包名
     * @param waitTimeout    等待超时时间
     * @param type           操作应用的类型0-关闭，1-启动
     * @param preExecuteWait 执行前等待
     * @param sufExecuteWait 执行后等待
     * @return
     */
    @Keyword(alias = "app处理(ios新)", category = "0", attributes = "9", commonlyUse = true)
    @Return(name = "result", comment = "app处理", type = DataType.BOOLEAN)
    public boolean handleApp(IExecuteContext context,
                             @Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
                             @Argument(name = "appPackage", scope = ParamScope.ARGS, comment = "应用包名", type = DataType.STRING) String appPackage,
                             @Argument(name = "timeout", scope = ParamScope.ARGS, comment = "默认超时时间", type = DataType.INTEGER, required = false, defaultValue = "30", defaultDisplay = false) Integer waitTimeout,
                             @Argument(name = "type", scope = ParamScope.ARGS, comment = "应用操作类型", type = DataType.ENUM, enumValues = AppEnum.class, inputType = InputType.select, defaultValue = "1") String type,
                             @Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "0.0", defaultDisplay = false) Float preExecuteWait,
                             @Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "0.0", defaultDisplay = false) Float sufExecuteWait) {
        CommonUtils.handlePreExecuteWait(preExecuteWait);  //执行前等待
        ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
                .withAppPackage(appPackage)
                .withType(type)
                .useContext(context)
                .waitTimeout(waitTimeout);
        boolean success = false;
        try {
            success = AutomationHandleUtil.handleApp(param);
        } catch (InterruptedException ie) {
            logger.warn("用户取消查询元素");
            throw new ExecuteException("取消操作");
        } catch (Exception e) {
            logger.error("出现了其他的问题。。。。", e);
            throw new ExecuteException(e.getMessage());
        }
        CommonUtils.handleSufExecuteWait(sufExecuteWait);  //执行后等待
        return success;
    }

    /**
     * <p>点击home键</p>
     *
     * @param deviceDriver   设备连接驱动
     * @param preExecuteWait 执行前等待
     * @param sufExecuteWait 执行后等待
     * @return
     */
    @Keyword(alias = "点击home键(ios新)", category = "0", attributes = "9", commonlyUse = true)
    @Return(name = "result", comment = "点击home键", type = DataType.BOOLEAN)
    public boolean pressKeyHome(IExecuteContext context,
                                @Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
                                @Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "0.0", defaultDisplay = false) Float preExecuteWait,
                                @Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "0.0", defaultDisplay = false) Float sufExecuteWait) {
        CommonUtils.handlePreExecuteWait(preExecuteWait);  //执行前等待
        ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
                .useContext(context)
                .waitTimeout(30);
        boolean success = false;
        try {
            success = AutomationHandleUtil.pressKeyHome(param);
        } catch (InterruptedException ie) {
            logger.warn("用户取消查询元素");
            throw new ExecuteException("取消操作");
        } catch (Exception e) {
            logger.error("出现了其他的问题。。。。", e);
            throw new ExecuteException(e.getMessage());
        }
        CommonUtils.handleSufExecuteWait(sufExecuteWait);  //执行后等待
        return success;
    }

    /**
     * <p>等待</p>
     *
     * @param waitTime 等待时间（单位s）
     * @return
     */
    @Keyword(alias = "等待(ios新)", category = "0", attributes = "9")
    @Return(name = "result", comment = "验证码识别", type = DataType.BOOLEAN)
    public boolean wait(
            @Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
            @Argument(name = "waitTime", scope = ParamScope.ARGS, comment = "等待时间(单位s)", type = DataType.INTEGER, defaultValue = "3") Integer waitTime
    ) {
        try {
            long time = waitTime * 1000L;
            Thread.sleep(time);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            logger.error("等待失败", e);
        } catch (CancellationException e) {
            logger.warn("该操作被取消了");
            throw new ExecuteException("用户取消，执行失败");
        }
        return true;
    }

//    /**
//     * <p>接口方式获取验证码（临时）</p>
//     *
//     * @return
//     */
//    @Keyword(alias = "接口方式获取验证码(ios新)", category = "0", attributes = "5")
//    @Return(name = "result", comment = "接口方式获取验证码", type = DataType.BOOLEAN)
//    public String getCodeByHttp(
//            IExecuteContext context,
//            @Argument(name = "url", scope = ParamScope.ARGS, comment = "验证码获取地址", type = DataType.STRING) String url,
//            @Argument(name = "header", scope = ParamScope.ARGS, comment = "请求头", type = DataType.STRING) String header,
//            @Argument(name = "body", scope = ParamScope.ARGS, comment = "请求体", type = DataType.STRING) String body,
//            @Argument(name = "value", scope = ParamScope.OUTPUT, comment = "组件返回值", type = DataType.STRING, defaultValue = "") String value,
//            @Argument(name = "waitTime", scope = ParamScope.ARGS, comment = "等待时间(单位s)", type = DataType.INTEGER, defaultValue = "30") Integer waitTime
//    ) {
//        HttpHeaders headers = new HttpHeaders();
//        headers.setContentType(MediaType.APPLICATION_JSON);
//        if (StringUtils.hasText(header)) {
//            Map map = JSON.parseObject(header, Map.class);
//            for (Object o : map.keySet()) {
//                headers.add((String) o, (String) map.get(o));
//            }
//        }
//        String result = null;
//        Map map = JSON.parseObject(body, Map.class);
//        HttpEntity<Map> entity = new HttpEntity<>(map, headers);
//        JSONObject data = HttpUtils.doPost(url, entity, JSONObject.class);
//        JSONArray gridData = data.getJSONArray("gridData");
//        if (gridData.size() > 0) {
//            Object o = gridData.get(0);
//            logger.info("获取验证码的数据：{}", JSON.toJSONString(o));
//            JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(o), JSONObject.class);
//            String psend = jsonObject.getString("psend");
//            int index = psend.indexOf("</retdesc><responsecode>");
//            result = psend.substring(index + 24, psend.lastIndexOf("</responsecode>"));
//            logger.info("获取的验证码：{}", result);
//        }
//        CommonUtils.setParamValue(context,value,result);
//        return result;
//    }

    /**
     * <p>密码输入(ocr)</p>
     *
     * @param deviceDriver   设备驱动链接
     * @param targets        定位控件的信息
     * @param waitTimeout    默认超时时间
     * @param preExecuteWait 执行前等待
     * @param sufExecuteWait 执行后等待
     * @return
     */
    @Keyword(alias = "密码输入(ocr)(ios新)", category = "0", attributes = "9", commonlyUse = true)
    @Return(name = "result", comment = "输入结果", type = DataType.BOOLEAN)
    public boolean inputPasswordByOcr(IExecuteContext context,
                                      @Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
                                      @Argument(name = "text", scope = ParamScope.VARIABLES, comment = "输入的密码", type = DataType.STRING) String text,
                                      @Argument(name = "targets", scope = ParamScope.STEP, comment = "控件位置", type = DataType.LIST, defaultDisplay = false) List<IStepTarget> targets,
                                      @Argument(name = "timeout", scope = ParamScope.ARGS, comment = "默认超时时间", type = DataType.INTEGER, required = false, defaultValue = "30", defaultDisplay = false) Integer waitTimeout,
                                      @Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float preExecuteWait,
                                      @Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float sufExecuteWait
    ) {
        CommonUtils.handlePreExecuteWait(preExecuteWait);  //执行前等待
        ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
                .useContext(context)
                .withTargets(targets)
                .waitTimeout(waitTimeout)
                .searchSwipeDirection("0")     //不滑动
                .withSwipeCount(1)
                .withText(text);
        boolean success = false;
        try {
            success = AutomationHandleUtil.inputPasswordByOcr(param);
        } catch (InterruptedException ie) {
            logger.warn("用户取消查询元素");
            throw new ExecuteException("取消操作");
        } catch (Exception e) {
            logger.error("出现了其他的问题。。。。", e);
            throw new ExecuteException(e.getMessage());
        }
        CommonUtils.handleSufExecuteWait(sufExecuteWait);  //执行后等待
        return success;
    }

    /**
     * <p>识别金额</p>
     *
     * @param deviceDriver   设备连接驱动
     * @param targets        定位控件参数
     * @param waitTimeout    超时时间
     * @param waitStatusStr  是否等待屏幕稳定
     * @param swipe          是否滑屏查找控件0-否，up-上滑，down-下滑，left-左滑,right-右滑
     * @param swipeCount     滑屏次数
     * @param preExecuteWait 执行前等待
     * @param sufExecuteWait 执行后等待
     * @param value          输出值
     * @return
     */
    @Keyword(alias = "识别金额(ios新)", category = "0", attributes = "9")
    @Return(name = "result", comment = "输入的结果", type = DataType.OBJECT)
    public String getElementMoneyText(IExecuteContext context,
                                      @Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
                                      @Argument(name = "targets", scope = ParamScope.STEP, comment = "控件位置", type = DataType.LIST, defaultDisplay = false) List<IStepTarget> targets,
                                      @Argument(name = "timeout", scope = ParamScope.ARGS, comment = "默认超时时间", type = DataType.INTEGER, required = false, defaultValue = "30", defaultDisplay = false) Integer waitTimeout,
                                      @Argument(name = "waitStatus", scope = ParamScope.ARGS, comment = "等待界面稳定", type = DataType.ENUM, enumValues = WhetherOrNotEnum.class, inputType = InputType.select, defaultValue = "1", defaultDisplay = false) String waitStatusStr,
                                      @Argument(name = "swipe", scope = ParamScope.ARGS, comment = "滑动方向", type = DataType.ENUM, enumValues = SwipeDirection.class, inputType = InputType.select, defaultValue = "0", required = false, defaultDisplay = false) String swipe,
                                      @Argument(name = "swipeCount", scope = ParamScope.ARGS, comment = "滑动次数", type = DataType.INTEGER, required = false, defaultValue = "0", defaultDisplay = false) Integer swipeCount,
                                      @Argument(name = "value", scope = ParamScope.OUTPUT, comment = "组件返回值", type = DataType.STRING, defaultValue = "") String value,
                                      @Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float preExecuteWait,
                                      @Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float sufExecuteWait) {
        CommonUtils.handlePreExecuteWait(preExecuteWait);  //执行前等待
        boolean waitStatus = "1".equals(waitStatusStr);   //是否等待界面稳定
        ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
                .useContext(context)
                .withTargets(targets)
                .waitTimeout(waitTimeout)
                .searchSwipeDirection("0")     //不滑动
                .withSwipeCount(1)
                .waitStatus(waitStatus);
        String result = "";
        try {
            result = AutomationHandleUtil.getElementMoneyText(param);
        } catch (InterruptedException ie) {
            logger.warn("用户取消查询元素");
            throw new ExecuteException("取消操作");
        } catch (Exception e) {
            logger.error("出现了其他的问题。。。。", e);
            throw new ExecuteException(e.getMessage());
        }
        CommonUtils.handleSufExecuteWait(sufExecuteWait);  //执行后等待
        CommonUtils.setParamValue(context, value, result);
        return result;
    }

}
