手机自动化测试:appium源码分析之bootstrap十一

手机自动化测试:appium源码分析之bootstrap十一

 

poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标。如果对课程感兴趣,请大家咨询qq:908821478。

GetName

package io.appium.android.bootstrap.handler;

import com.android.uiautomator.core.UiObjectNotFoundException;

import io.appium.android.bootstrap.*;

import org.json.JSONException;

/**

 * This handler is used to get the text of elements that support it.

 */

public class GetName extends CommandHandler {

  /*

   * @param command The {@link AndroidCommand} used for this handler.

   *

   * @return {@link AndroidCommandResult}

   *

   * @throws JSONException

   *

   * @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android.

   * bootstrap.AndroidCommand)

   */

  @Override

  public AndroidCommandResult execute(final AndroidCommand command)

      throws JSONException {

    if (!command.isElementCommand()) {

      return getErrorResult("Unable to get name without an element.");

    }

    try {

      final AndroidElement el = command.getElement();

      return getSuccessResult(el.getContentDesc());

    } catch (final UiObjectNotFoundException e) {

      return new AndroidCommandResult(WDStatus.NO_SUCH_ELEMENT, e.getMessage());

    } catch (final Exception e) { // handle NullPointerException

      return getErrorResult("Unknown error");

    }

  }

}

最终会调用UiObject.getContentDescription()方法获得控件当描述信息

GetAttribute

package io.appium.android.bootstrap.handler;

import com.android.uiautomator.core.UiObjectNotFoundException;

import io.appium.android.bootstrap.*;

import io.appium.android.bootstrap.exceptions.NoAttributeFoundException;

import org.json.JSONException;

import java.util.Hashtable;

/**

 * This handler is used to get an attribute of an element.

 *

 */

public class GetAttribute extends CommandHandler {

  /*

   * @param command The {@link AndroidCommand} used for this handler.

   *

   * @return {@link AndroidCommandResult}

   *

   * @throws JSONException

   *

   * @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android.

   * bootstrap.AndroidCommand)

   */

  @Override

  public AndroidCommandResult execute(final AndroidCommand command)

      throws JSONException {

    if (command.isElementCommand()) {

      // only makes sense on an element

      final Hashtable<String, Object> params = command.params();

      try {

        final AndroidElement el = command.getElement();

        final String attr = params.get("attribute").toString();

        if (attr.equals("name") || attr.equals("text")

            || attr.equals("className")) {

          return getSuccessResult(el.getStringAttribute(attr));

        } else {

          return getSuccessResult(String.valueOf(el.getBoolAttribute(attr)));

        }

      } catch (final NoAttributeFoundException e) {

        return new AndroidCommandResult(WDStatus.NO_SUCH_ELEMENT,

            e.getMessage());

      } catch (final UiObjectNotFoundException e) {

        return new AndroidCommandResult(WDStatus.NO_SUCH_ELEMENT,

            e.getMessage());

      } catch (final Exception e) { // el is null

        return new AndroidCommandResult(WDStatus.NO_SUCH_ELEMENT,

            e.getMessage());

      }

    } else {

      return getErrorResult("Unable to get attribute without an element.");

    }

  }

}

该事件是为获取控件相关信息设置的,来看看可以获取哪些信息,其实就是uiautomatorviewer里的信息。

public String getStringAttribute(final String attr)

      throws UiObjectNotFoundException, NoAttributeFoundException {

    String res;

    if (attr.equals("name")) {

      res = getContentDesc();

      if (res.equals("")) {

        res = getText();

      }

    } else if (attr.equals("text")) {

      res = getText();

    } else if (attr.equals("className")) {

      res = getClassName();

    } else {

      throw new NoAttributeFoundException(attr);

    }

    return res;

  }

文本值:content-desc、text、className.

public boolean getBoolAttribute(final String attr)

      throws UiObjectNotFoundException, NoAttributeFoundException {

    boolean res;

    if (attr.equals("enabled")) {

      res = el.isEnabled();

    } else if (attr.equals("checkable")) {

      res = el.isCheckable();

    } else if (attr.equals("checked")) {

      res = el.isChecked();

    } else if (attr.equals("clickable")) {

      res = el.isClickable();

    } else if (attr.equals("focusable")) {

      res = el.isFocusable();

    } else if (attr.equals("focused")) {

      res = el.isFocused();

    } else if (attr.equals("longClickable")) {

      res = el.isLongClickable();

    } else if (attr.equals("scrollable")) {

      res = el.isScrollable();

    } else if (attr.equals("selected")) {

      res = el.isSelected();

    } else if (attr.equals("displayed")) {

      res = el.exists();

    } else {

      throw new NoAttributeFoundException(attr);

    }

    return res;

  }

boolean类型的值:如上等等。

GetDeviceSize

package io.appium.android.bootstrap.handler;

import com.android.uiautomator.core.UiDevice;

import io.appium.android.bootstrap.AndroidCommand;

import io.appium.android.bootstrap.AndroidCommandResult;

import io.appium.android.bootstrap.CommandHandler;

import org.json.JSONException;

import org.json.JSONObject;

/**

 * This handler is used to get the size of the screen.

 *

 */

public class GetDeviceSize extends CommandHandler {

  /*

   * @param command The {@link AndroidCommand} used for this handler.

   *

   * @return {@link AndroidCommandResult}

   *

   * @throws JSONException

   *

   * @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android.

   * bootstrap.AndroidCommand)

   */

  @Override

  public AndroidCommandResult execute(final AndroidCommand command) {

    if (!command.isElementCommand()) {

      // only makes sense on a device

      final UiDevice d = UiDevice.getInstance();

      final JSONObject res = new JSONObject();

      try {

        res.put("height", d.getDisplayHeight());

        res.put("width", d.getDisplayWidth());

      } catch (final JSONException e) {

        getErrorResult("Error serializing height/width data into JSON");

      }

      return getSuccessResult(res);

    } else {

      return getErrorResult("Unable to get device size on an element.");

    }

  }

}

获取屏幕的长和宽,调用的是UiDevice的方法:getDisplayHeight()和getDisplayWidth()

GetSize

package io.appium.android.bootstrap.handler;

import android.graphics.Rect;

import com.android.uiautomator.core.UiObjectNotFoundException;

import io.appium.android.bootstrap.*;

import org.json.JSONException;

import org.json.JSONObject;

/**

 * This handler is used to get the size of elements that support it.

 *

 */

public class GetSize extends CommandHandler {

  /*

   * @param command The {@link AndroidCommand} used for this handler.

   *

   * @return {@link AndroidCommandResult}

   *

   * @throws JSONException

   *

   * @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android.

   * bootstrap.AndroidCommand)

   */

  @Override

  public AndroidCommandResult execute(final AndroidCommand command)

      throws JSONException {

    if (command.isElementCommand()) {

      // Only makes sense on an element

      final JSONObject res = new JSONObject();

      try {

        final AndroidElement el = command.getElement();

        final Rect rect = el.getBounds();

        res.put("width", rect.width());

        res.put("height", rect.height());

      } catch (final UiObjectNotFoundException e) {

        return new AndroidCommandResult(WDStatus.NO_SUCH_ELEMENT,

            e.getMessage());

      } catch (final Exception e) { // handle NullPointerException

        return getErrorResult("Unknown error");

      }

      return getSuccessResult(res);

    } else {

      return getErrorResult("Unable to get text without an element.");

    }

  }

}

获取控件的宽和高,调用的是UiObject的getBounds()。得到一个矩形,然后获得其宽和高。

GetLocation

package io.appium.android.bootstrap.handler;

import android.graphics.Rect;

import io.appium.android.bootstrap.*;

import org.json.JSONException;

import org.json.JSONObject;

/**

 * This handler is used to get the text of elements that support it.

 *

 */

public class GetLocation extends CommandHandler {

  /*

   * @param command The {@link AndroidCommand} used for this handler.

   *

   * @return {@link AndroidCommandResult}

   *

   * @throws JSONException

   *

   * @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android.

   * bootstrap.AndroidCommand)

   */

  @Override

  public AndroidCommandResult execute(final AndroidCommand command)

      throws JSONException {

    if (!command.isElementCommand()) {

      return getErrorResult("Unable to get location without an element.");

    }

    try {

      final JSONObject res = new JSONObject();

      final AndroidElement el = command.getElement();

      final Rect bounds = el.getBounds();

      res.put("x", bounds.left);

      res.put("y", bounds.top);

      return getSuccessResult(res);

    } catch (final Exception e) {

      return new AndroidCommandResult(WDStatus.NO_SUCH_ELEMENT, e.getMessage());

    }

  }

}

获取控件的起始点坐标。调用的也是getBounds,然后得到其起始点的x,y 坐标

GetDataDir

package io.appium.android.bootstrap.handler;

import android.os.Environment;

import io.appium.android.bootstrap.AndroidCommand;

import io.appium.android.bootstrap.AndroidCommandResult;

import io.appium.android.bootstrap.CommandHandler;

/**

 * This handler is used to get the data dir.

 *

 */

public class GetDataDir extends CommandHandler {

  /*

   * @param command The {@link AndroidCommand} used for this handler.

   *

   * @return {@link AndroidCommandResult}

   *

   * @throws JSONException

   *

   * @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android.

   * bootstrap.AndroidCommand)

   */

  @Override

  public AndroidCommandResult execute(final AndroidCommand command) {

    return getSuccessResult(Environment.getDataDirectory());

  }

}

获取data的根目录。调用的是android的api:Environment.getDataDirectory()

原文地址:https://www.cnblogs.com/poptest/p/4950618.html