bootstrap之Swipe

Swipe

我定义为滑动,但它字面的意思又不是,事件的形式类似于小时候拿着一块石头片,朝水面飞过去,假设你手法能够那么就是swipe走的路线,假设你手法不行,接触水面的时候就没再飞起来那就会被人嘲笑的。

package io.appium.android.bootstrap.handler;

import com.android.uiautomator.core.UiDevice;
import com.android.uiautomator.core.UiObjectNotFoundException;
import io.appium.android.bootstrap.*;
import io.appium.android.bootstrap.exceptions.InvalidCoordinatesException;
import io.appium.android.bootstrap.utils.Point;
import org.json.JSONException;

import java.util.Hashtable;

/**
 * This handler is used to swipe.
 *
 */
public class Swipe 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 {
    final Hashtable<String, Object> params = command.params();
    final Point start = new Point(params.get("startX"), params.get("startY"));
    final Point end = new Point(params.get("endX"), params.get("endY"));
    final Integer steps = (Integer) params.get("steps");
    final UiDevice device = UiDevice.getInstance();

    Point absStartPos = new Point();
    Point absEndPos = new Point();

    if (command.isElementCommand()) {
      try {
        final AndroidElement el = command.getElement();
        absStartPos = el.getAbsolutePosition(start);
        absEndPos = el.getAbsolutePosition(end, false);
      } catch (final UiObjectNotFoundException e) {
        return getErrorResult(e.getMessage());
      } catch (final InvalidCoordinatesException e) {
        return getErrorResult(e.getMessage());
      } catch (final Exception e) { // handle NullPointerException
        return getErrorResult("Unknown error");
      }
    } else {
      try {
        absStartPos = getDeviceAbsPos(start);
        absEndPos = getDeviceAbsPos(end);
      } catch (final InvalidCoordinatesException e) {
        return getErrorResult(e.getMessage());
      }
    }

    Logger.debug("Swiping from " + absStartPos.toString() + " to "
        + absEndPos.toString() + " with steps: " + steps.toString());
    final boolean rv = device.swipe(absStartPos.x.intValue(),
        absStartPos.y.intValue(), absEndPos.x.intValue(),
        absEndPos.y.intValue(), steps);
    if (!rv) {
      return getErrorResult("The swipe did not complete successfully");
    }
    return getSuccessResult(rv);
  }
}

无论它怎样定义,先分析源代码最后再定义。

    final Hashtable<String, Object> params = command.params();
    final Point start = new Point(params.get("startX"), params.get("startY"));
    final Point end = new Point(params.get("endX"), params.get("endY"));
    final Integer steps = (Integer) params.get("steps");
    final UiDevice device = UiDevice.getInstance();

    Point absStartPos = new Point();
    Point absEndPos = new Point();

首先从命令里取得參数,然后解析出所须要的3个变量:起始点start、终点end、步骤steps。然后获得设备对象,定义2个私有Point对象,以备后用。

然后分条件处理,处理控件还是处理坐标。

控件

        final AndroidElement el = command.getElement();
        absStartPos = el.getAbsolutePosition(start);
        absEndPos = el.getAbsolutePosition(end, false);

首先获取控件对象,再通过getAbsolutePosition传入不同的參数获得在该控件上点击的起始点和结束点。

public Point getAbsolutePosition(final Point point,
      final boolean boundsChecking) throws UiObjectNotFoundException,
      InvalidCoordinatesException {
    final Rect rect = el.getBounds();
    final Point pos = new Point();
    Logger.debug("Element bounds: " + rect.toShortString());

    if (point.x == 0) {
      pos.x = rect.width() * 0.5 + rect.left;
    } else if (point.x <= 1) {
      pos.x = rect.width() * point.x + rect.left;
    } else {
      pos.x = rect.left + point.x;
    }
    if (boundsChecking) {
      if (pos.x > rect.right || pos.x < rect.left) {
        throw new InvalidCoordinatesException("X coordinate ("
            + pos.x.toString() + " is outside of element rect: "
            + rect.toShortString());
      }
    }

    if (point.y == 0) {
      pos.y = rect.height() * 0.5 + rect.top;
    } else if (point.y <= 1) {
      pos.y = rect.height() * point.y + rect.top;
    } else {
      pos.y = rect.left + point.y;
    }
    if (boundsChecking) {
      if (pos.y > rect.bottom || pos.y < rect.top) {
        throw new InvalidCoordinatesException("Y coordinate ("
            + pos.y.toString() + " is outside of element rect: "
            + rect.toShortString());
      }
    }

    return pos;
  }

上面的一大段代码,看起来非常复杂,事实上非常easy,业务非常容易理解,处理这样的点的时候就须要推断非常多东西。上面的代码首先分析x坐标然后分析y坐标。x和y坐标的推断和处理时一样的,所以我仅仅讲一下x坐标。

首先推断x坐标是否为0,假设为0,定义初始点的x坐标为控件的中心点的横坐标。假设x的坐标小于1,说明坐标为相对坐标,用百分比来求值,此时就要与宽度做乘积运算得到详细值。假设上面2种情况都不符合,那就是详细坐标值,那就直接元素的x坐标值加上控件的边框左坐标值。最后依据传入的boolean值来推断是否做一个超出边界的验证。假设超出边界就跑出异常。y坐标的获取方式类似。最后得到坐标值并返回,回到execute方法中。

坐标

absStartPos = getDeviceAbsPos(start);
        absEndPos = getDeviceAbsPos(end);

通过调用getDeviceAbsPos()方法得到坐标值来初始化之前声明的私有Point对象.

protected static Point getDeviceAbsPos(final Point point)
      throws InvalidCoordinatesException {
    final UiDevice d = UiDevice.getInstance();
    final Point retPos = new Point(point); // copy inputed point

    final Double width = (double) d.getDisplayWidth();
    if (point.x < 1) {
      retPos.x = width * point.x;
    }

    if (retPos.x > width || retPos.x < 0) {
      throw new InvalidCoordinatesException("X coordinate ("
          + retPos.x.toString() + " is outside of screen width: "
          + width.toString());
    }

    final Double height = (double) d.getDisplayHeight();
    if (point.y < 1) {
      retPos.y = height * point.y;
    }

    if (retPos.y > height || retPos.y < 0) {
      throw new InvalidCoordinatesException("Y coordinate ("
          + retPos.y.toString() + " is outside of screen height: "
          + height.toString());
    }

    return retPos;
  }

类似于上面的方法,也是要先推断传过来的坐标值是否小于1,假设小于1,当作百分比来球坐标值。假设超出屏幕的范围抛出异常,最后返回坐标值回到execute方法。

===============================================================================================================================

final boolean rv = device.swipe(absStartPos.x.intValue(),
        absStartPos.y.intValue(), absEndPos.x.intValue(),
        absEndPos.y.intValue(), steps);

最后调用UiDevice.swipe方法来运行命令,推断是否运行成功。

总结

运行swipe命令有2中命令格式

  • 控件
  • 坐标

坐标又分为相对坐标百分比和绝对坐标两种方法。

bootstrap之Swipe

时间: 2024-10-13 04:36:35

bootstrap之Swipe的相关文章

【Bootstrap】3.优化站点资源、完成响应式图片、让传送带支持手势

A.优化站点资源 速度很重要.用户很关心.我们的站点必须加载够快,否则用户就会走人.SEO 也很重要.我们的站点必须加载够快,否者搜索排名就会下降. 明白了这样,我们就来清点一下 [Bootstrap]2.作品展示站点 中的资源.特别的,来看一看我们能控制的.影响页面速度的重要因素 —— 文件大小,包括图片.CSS和 JavaScript 文件.只要简单几步,我们就可以给这些文件“瘦身”,缩短加载时间. A.1 优化图片 这些图片都通过 Photoshop 的 “保存为 Web 格式” 进行了一

bootstrap之Click大事

上一篇文章中谈到了bootstrap流程,本文开始把目光bootstrap它可以接受指令(从源代码视图的透视.因为appium该项目现在还处于不断更新,因此,一些指令已经实现.也许未来会实现一些.从视图的源代码的点的优点是对未来要知道将来也许appium哪些功能可以做). 在bootstrap项目中的io.appium.android.bootstrap.handler包中的类都是相应的相应的指令的类,里面都有execute方法来运行命令.先上上一篇文章中讲的map. private stati

Appuim源码剖析(Bootstrap)

Appuim源码剖析(Bootstrap) SkySeraph Jan. 26th 2017 Email:[email protected] 更多精彩请直接访问SkySeraph个人站点:www.skyseraph.com About Appuim Appium 是一个自动化测试开源工具,支持 iOS 平台和 Android 平台上的原生应用,web 应用和混合应用. 这里有很关键一点,跨平台.更多了解Appuim多平台支持相关信息,参考官方platform-support 相关概念 C/S 架

bootstrap之Flick

Flick package io.appium.android.bootstrap.handler; import com.android.uiautomator.core.UiDevice; import io.appium.android.bootstrap.*; import io.appium.android.bootstrap.exceptions.InvalidCoordinatesException; import io.appium.android.bootstrap.utils

【转】让Bootstrap轮播插件carousel支持左右滑动手势的三种方法

因为最近开发的项目涉及到移动设备上的 HTML5 开发,其中需要实现轮播效果.然后最快捷的方式,你知道的(Bootstrap),然后原生的 Bootstrap 的 carousel.js 插件并没有支持手势. 然后......自己想办法呗,再然后,就有下面3种解决方案 : jQuery Mobile (http://jquerymobile.com/download/) $("#carousel-generic").swipeleft(function() { $(this).caro

让Bootstrap轮播插件carousel支持左右滑动手势的三种方法

因为最近开发的项目涉及到移动设备上的 HTML5 开发,其中需要实现轮播效果.然后最快捷的方式,你知道的(Bootstrap),然后原生的 Bootstrap 的 carousel.js 插件并没有支持手势. 然后......自己想办法呗,再然后,就有下面3种解决方案 : jQuery Mobile (http://jquerymobile.com/download/) $("#carousel-generic").swipeleft(function() { $(this).caro

appium框架之bootstrap

(闲来无事,做做测试..)最近弄了弄appium,感觉挺有意思,就深入研究了下. 看小弟这篇文章之前,先了解一下appium的架构,对你理解有好处,推荐下面这篇文章:testerhome appium是开源项目,可以获得源码:appium-master 在eclipse中用maven导入会发现有2个项目:bootstrap和sauce_appium_junit. sauce_appium_junit是一些测试用例的集合,帮助学习的.bootstrap就是appium架构中放在手机端的一个服务器.

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

手机自动化测试:appium源码分析之bootstrap一 前言: poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.poptest推出手机自动化测试的课程,讲解appuim的实际应用,培训全程用商业项目,   大家可以加qq群进行交流:195983133 开源的项目最大的好处是可以获得源代码,我们可以在源代码的基础上进行修改代码,编译,开发出符合我们要求的项目.如果想要做到可以修改源代码,首先要读懂代码了解代码.国内的一些公司

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

手机自动化测试:appium源码分析之bootstrap六 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.poptest测试开发工程师就业培训请大家咨询qq:908821478)移动端自动化测试是未来的测试工程师的技术要求,我们需要打好基础. Flick package io.appium.android.bootstrap.handler; import com.android.uiautomator.core.UiDev