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

来源:互联网 发布:91毁了多少家庭知乎 编辑:程序博客网 时间:2024/05/20 18:04

摘要


大体看了下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 方法会输入原有字符的原因及解决方案

0 0
原创粉丝点击