Appium 操作 webview 弹出提示框

全文 · 2014年09月13日 · 最后由 布衣熊2007 回复于 2014年11月04日 · 2396 次阅读

背景:被测应用有部分功能是 html5 实现的,目前准备使用 appium 来进行自动化脚本的编写

出现问题功能点的流程介绍:
流程:JS 调用 prompt 函数,java 端进行拦截,如果发现是 h5 的调用,就不会弹框,进行逻辑处理。

预期结果:点击修改密码 webview,打开密码修改页面

实际结果:触发 webview,打开一个对话框 (对话框只能关闭应用,不然对话框没法取消) --这种情况,在手工测试不存在

以下为尝试的一些功能代码
//第一种方法
driver.findElement(By.id("changePassBtn")).click();

/第二种方法
JavascriptExecutor jse = (JavascriptExecutor) driver;
jse.executeAsyncScript("document.getElementById('changePassBtn').click()");
/

/* 第三种方法

TouchAction touch = new TouchAction(driver);
WebElement we = driver.findElement(By.linkText("修改密码"));
driver.performTouchAction(touch.press(we));
Thread.sleep(2000);*/

配置信息:
appium 1.2.0.0
android4.4.4
win7 64bit

appium 日志:

ERROR: debug: Appium request initiated at /wd/hub/session/063c92cb-338f-0946-7720-20fbca1e38b8/element
ERROR: debug: Request received with params: {"using":"id","value":"changePassBtn"}
ERROR: debug: Proxying command to localhost:8080
ERROR: debug: Making http request with opts: {"url":"http://localhost:8080/wd/hub/session/063c92cb-338f-0946-7720-20fbca1e38b8/element,method:POST,json:{using:id,value:changePassBtn}"}
ERROR: debug: Proxied response received with status 200: {"value":{"ELEMENT":":wdc:1410545493144"},"status":0,"sessionId":"063c92cb-338f-0946-7720-20fbca1e38b8"}
info: <-- POST /wd/hub/session/063c92cb-338f-0946-7720-20fbca1e38b8/element 200 383.973 ms - 104
info: --> POST /wd/hub/session/063c92cb-338f-0946-7720-20fbca1e38b8/element/%3Awdc%3A1410545493144/click {"id":":wdc:1410545493144"}
ERROR: debug: Appium request initiated at /wd/hub/session/063c92cb-338f-0946-7720-20fbca1e38b8/element/%3Awdc%3A1410545493144/click
ERROR: debug: Request received with params: {"id":":wdc:1410545493144"}
ERROR: debug: Proxying command to localhost:8080
ERROR: debug: Making http request with opts: {"url":"http://localhost:8080/wd/hub/session/063c92cb-338f-0946-7720-20fbca1e38b8/element/%3Awdc%3A1410545493144/click,method:POST,json:{id::wdc:1410545493144}"}
ERROR: debug: Proxied response received with status 200: {"value":"","status":0,"sessionId":"063c92cb-338f-0946-7720-20fbca1e38b8"}
info: <-- POST /wd/hub/session/063c92cb-338f-0946-7720-20fbca1e38b8/element/%3Awdc%3A1410545493144/click 200 824.407 ms - 74
info: --> DELETE /wd/hub/session/063c92cb-338f-0946-7720-20fbca1e38b8 {}
ERROR: debug: Appium request initiated at /wd/hub/session/063c92cb-338f-0946-7720-20fbca1e38b8
info: Shutting down appium session
ERROR: debug: Request received with params: {}
ERROR: debug: Stopping selendroid server
ERROR: debug: Making http request with opts: {"url":"http://localhost:8080/wd/hub/session/063c92cb-338f-0946-7720-20fbca1e38b8,method:DELETE"}
ERROR: debug: executing: "D:\AndroidSDK\adt-bundle-windows-x86_64-20131030\sdk\platform-tools\adb.exe" -s 03b9af73f0b4ff81 shell "am force-stop cn.uc.gamesdk.demo"
ERROR: debug: [SELENDROID] mSeq=0 mSystemUiVisibility=0x0
ERROR: debug: [SELENDROID] mSystemDecorRect=[0,0][1080,665] last=[0,0][1080,665]
ERROR: debug: Stopping logcat capture
ERROR: debug: Logcat terminated with code null, signal SIGTERM
info: <-- DELETE /wd/hub/session/063c92cb-338f-0946-7720-20fbca1e38b8 200 597.623 ms - 76 {"status":0,"value":null,"sessionId":"063c92cb-338f-0946-7720-20fbca1e38b8"}
ERROR: debug: Cleaning up appium session
ERROR: debug: Responding to client with success: {"status":0,"value":null,"sessionId":"063c92cb-338f-0946-7720-20fbca1e38b8"}

共收到 8 条回复 时间 点赞

@lonely 这个失败估计和链接背后绑定的 event 有关,建议第二种方法直接 js 模拟 click 背后触发的 event 试试,如能执行 jquery 那就最好了,第三种方法试试 precise tap,通过坐标直接 screen/element 精确 tap!

感觉前两种方法不对吧. 对于混合应用的操作需要先进入 context 才行. js 弹出框 Uiautomator 是否能识别, 我还没验证, 建议大家试试

#2 楼 @seveniruby 现在的情况是这样子,
1:capabilities.setCapability("automationName", "selendroid");把这一行注释掉,
2:然后运行脚本,然后再 uiautomatorviewer 查看 webview 的时候,看到的就是一个一个 view,而不是 webview
3:driver.findElementByAndroidUIAutomator("new UiSelector().className(\"android.view.View\").description(\"修改密码 Link\")").click();这行脚本执行会提示 noSuchElementException

//这个语句打印的值是 native_app
Set contextNames = driver.getContextHandles();
for (String contextName : contextNames) {
System.out.println(contextName);
}

所以结论就是,不用 selendroid 能看到元素,但是不能操作,暂时不知道为什么,求助大神

#1 楼 @luis
现在的情况是这样子,
1:capabilities.setCapability("automationName", "selendroid");把这一行注释掉,
2:然后运行脚本,然后再 uiautomatorviewer 查看 webview 的时候,看到的就是一个一个 view,而不是 webview
3:driver.findElementByAndroidUIAutomator("new UiSelector().className(\"android.view.View\").description(\"修改密码 Link\")").click();这行脚本执行会提示 noSuchElementException

//这个语句打印的值是 native_app
Set contextNames = driver.getContextHandles();
for (String contextName : contextNames) {
System.out.println(contextName);
}

所以结论就是,不用 selendroid 能看到元素,但是不能操作,暂时不知道为什么,求助大神

@lonely 实在没看懂你为什么又要切到 uiautomator,首先你 app 有几个 webview,其次你的修改密码 link 是 native 还是 web,点击之后跳转到的修改密码页面是 web 还是 native. 还有你的问题不是解决如何不弹出提示框吗?你已经出发了 click,只要让 app 知道你的 agent 也是 html5 不弹出框就行了。还有我觉得模拟 screen 的精确 tap 肯定可以解决你的问题。

想问下,我的登陆框是嵌入的 html5 页面的形式,html5 里面的元素可以定位到吗?

#6 楼 @dh_shave 可以定位到的

@lonely 能具体说说么?我加了句//capabilities.setCapability("automationName", "selendroid");这个后,每次 app 都被重启两次了。。。。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册