appium源码分析(九)-getText,setText

摘要

大体看了下getText以及setText方法,getText很简单,直接就是通过获取到AndroidElement中的UiObject 对象元素之后直接调用getText方法。

但是setText就不是这么简单了,因为用过UiAutomator的童鞋应该都应该知道,UiAutomator是不支持中文输入的,当然如果安装第三发的输入法就另当别论了。同样appium 的desired_capabilities中unicodeKeyboard如果为True的情况下,appium默认是会给你的手机安装一个appium的输入法,这个输入法对我们来说更多的是解决了中文输入的问题。

所以在setText上,appium肯定是会做一些不小的变化的。我们这次主要就是来分析setText它到底是如何实现的。

正文

其实我阅读代码的能力真的挺弱的,所以对于较为复杂的代码要不调试,要不就是看log,boottrap不太会调试,但是我们可以通过看appium server来分析问题,所以我们这里首先先来一段测试的代码吧

self.driver.find_element_by_id("com.seewo.easicare.demo:id/care_new_notice").click()
notice_edit_text = self.driver.find_element_by_id("com.seewo.easicare.demo:id/care_add_notice_content")
notice_edit_text.send_keys("helo.\n   everyone")

简单的一个文本输入内容,我们看看appium server 的log吧

appium server log

对照着log 我们看下setText的源代码吧

public AndroidCommandResult execute(final AndroidCommand command)
      throws JSONException {

    AndroidElement el = null;
    if (command.isElementCommand()) {
      Logger.debug("Using element passed in.");
      el = command.getElement();
    } else {
      try {
        Logger.debug("Using currently-focused element.");
        AndroidElementsHash  elements = AndroidElementsHash.getInstance();
        el = elements.getElement(new UiSelector().focused(true), "");
      } catch (ElementNotFoundException e) {
        Logger.debug("Error retrieving focused element: " + e);
        return getErrorResult("Unable to set text without a focused element.");
      }
    }
    try {
      final Hashtable<String, Object> params = command.params();
      boolean replace = Boolean.parseBoolean(params.get("replace").toString());
      String text = params.get("text").toString();
      boolean pressEnter = false;
      if (text.endsWith("\\n")) {
        pressEnter = true;
        text = text.replace("\\n", "");
        Logger.debug("Will press enter after setting text");
      }
      boolean unicodeKeyboard = false;
      if (params.get("unicodeKeyboard") != null) {
        unicodeKeyboard = Boolean.parseBoolean(params.get("unicodeKeyboard").toString());
      }
      String currText = el.getText();
      new Clear().execute(command);
      if (!el.getText().isEmpty()) {
        // clear could have failed, or we could have a hint in the field
        // we'll assume it is the latter
        Logger.debug("Text not cleared. Assuming remainder is hint text.");
        currText = "";
      }
      if (!replace) {
        text = currText + text;
      }
      final boolean result = el.setText(text, unicodeKeyboard);
      if (!result) {
        return getErrorResult("el.setText() failed!");
      }
      if (pressEnter) {
        final UiDevice d = UiDevice.getInstance();
        d.pressEnter();
      }
      return getSuccessResult(result);
    } catch (final UiObjectNotFoundException e) {
      return new AndroidCommandResult(WDStatus.NO_SUCH_ELEMENT,
          e.getMessage());
    } catch (final Exception e) { // handle NullPointerException
      return getErrorResult("Unknown error");
    }
  }

其实到这里 很多代码应该都能看明白了。

  • 首先定位元素:判断命令是否是针对于元素的,如果不是的话,再去获取当前处于焦点的元素,
  • 解析命令:判断是否使用unicodeKeyBoard ,判断setText是文本替换,还是文本追加,默认情况下都是进行追加文本的。但是这里有个地方要注意。也是我一开始一直疑惑的一个地方:
    • 首先通过getText获取当前元素的文字,存到currText中
    • 使用new Clear().execute(command);清除当前元素的所有文字
    • .再次获取当前元素文字。如果文字仍不为空,认定它是hint text并把currText置空(由于此处也有可能是clear方法出错导致没有clear成功,因此留了一个log说明假设还存在的text是hint text)
    • 如果replace不是true,在text前面加入currText。
      所以说并不是说replace为true的情况下就进行文本追加了,最后判断文本结尾是否有回车,如果是的话就要按下回车键。
  • 最后就是调用setText()方法了,只是说appium server又对setText做了一个封装,因为我们输入的内容可能是个中文,所以这个时候就要进行一些encode的处理了。

再来可以看下testerhome的这篇文章,作者写的真心棒

appium 中 sendkeys 方法会输入原有字符的原因及解决方案

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值