最近升级 appium 的 driver 从 uiautomator1.0 升到 uiautomator2.0,之前的 xpath 中部分使用不了
案例:
(//*[@text='' and @content-desc='start_pager' and @resource-id='com.suning.snmessenger:id/loading_item_view'])[1]
05-03 17:04:29.346 18582-19939/io.appium.uiautomator2.server E/appium: Element not found:
io.appium.uiautomator2.common.exceptions.ElementNotFoundException: Could not find an element using supplied strategy.
at io.appium.uiautomator2.handler.FindElement.getXPathUiObject(FindElement.java:79)
at io.appium.uiautomator2.handler.FindElement.findElement(FindElement.java:161)
at io.appium.uiautomator2.handler.FindElement.safeHandle(FindElement.java:110)
at io.appium.uiautomator2.handler.request.SafeRequestHandler.handle(SafeRequestHandler.java:54)
at io.appium.uiautomator2.server.AppiumServlet.handleRequest(AppiumServlet.java:204)
at io.appium.uiautomator2.server.AppiumServlet.handleHttpRequest(AppiumServlet.java:195)
at io.appium.uiautomator2.http.ServerHandler.channelRead(ServerHandler.java:44)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:345)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:345)
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:435)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:267)
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:250)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:345)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1294)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:911)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:611)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysPlain(NioEventLoop.java:514)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:468)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:438)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:140)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
at java.lang.Thread.run(Thread.java:818)
https://github.com/appium/appium/issues/8329
提交了 issue,跟 appium 的同学请教后,原因是@text=''导致的
修改 uiautomator server 源码
public AppiumResponse safeHandle(IHttpRequest request) {
try {
Logger.info("Find element command");
KnownElements ke = new KnownElements();
final JSONObject payload = getPayload(request);
final String method = payload.getString("strategy");
String selector = payload.getString("selector");
if (selector.contains("@text=''")) {
selector = selector.replace("@text=''", "not(boolean(string(@text)))");
}
if (selector.contains("@content-desc=''")) {
selector = selector.replace("@content-desc=''", "not(boolean(string(@content-desc)))");
}
if (selector.contains("@resource-id=''")) {
selector = selector.replace("@resource-id=''", "not(boolean(string(@resource-id)))");
}
final String contextId = payload.getString("context");
Logger.info(String.format("find element command using '%s' with selector '%s'.", method, selector));
final By by = new NativeAndroidBySelector().pickFrom(method, selector);
这样原来 ui1.0 设计的许多脚本就不用逐一修改了。
切到 ui2.0 后,如何点击弹窗的?分两个场景: