Appium 求大神指教,如何获取到 Android 混合应用里面的 web 元素

Vicki · 2015年07月10日 · 最后由 平凡白影 回复于 2016年03月15日 · 2638 次阅读

如何使用 Appium 测试 Android 混合应用,登录注册是原生部分,里面的内容就是用 HTML5 写的,我要怎样才能获取到 web 元素呢?
我使用 xpath 获取元素,为什么获取不到呢?求大神指教

代码:

WebElement element2 = (new WebDriverWait(dr, 30))
    .until(new ExpectedCondition<WebElement>() {
        @Override
        public WebElement apply(WebDriver d) {
            return d.findElement(By.xpath("/html/body/div[3]/div/div/ul/li[1]/a"));
        }
    });

    element2.click();

共收到 14 条回复 时间 点赞

里面网页开发的都是在 webview 里,需要先切换到 webview 里去
driver.switch_to.context("WEBVIEW")
或是 driver.context(“WEBVIEW”)

#1 楼 @ding7473417 为什么我一用这个 driver.context(“WEBVIEW”),就报错呢?org.openqa.selenium.NoSuchElementException: An element could not be located on the page using the given search parameters. (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 10.62 seconds
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '2.41.0', revision: '3192d8a6c4449dc285928ba024779344f5423c58', time: '2014-03-27 11:29:39'
System info: host: '123TY-20150623B', ip: '172.16.18.133', os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.6.0_38-ea'
Session ID: 1d9d6db2-062c-4cea-a309-e87df1551ce9
Driver info: io.appium.java_client.AppiumDriver
Capabilities [{platform=WINDOWS, app=D:\andriod\test\apps\智农通 V2.2.5.apk, javascriptEnabled=true, appActivity=com.dbn.OAConnect.UI.LauncherSwitchActivity, browserName=, networkConnectionEnabled=true, desired={platformVersion=4.3, platform=WINDOWS, app=D:\andriod\test\apps\智农通 V2.2.5.apk, platformName=Android, deviceName=test, browserName=, appActivity=com.dbn.OAConnect.UI.LauncherSwitchActivity, appPackage=com.dbn.OAConnect}, locationContextEnabled=false, appPackage=com.dbn.OAConnect, platformVersion=4.4.2, databaseEnabled=false, deviceName=emulator-5554, platformName=Android, webStorageEnabled=false, warnings={}, takesScreenshot=true}]
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:193)
at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:145)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:595)
at io.appium.java_client.AppiumDriver.execute(AppiumDriver.java:76)
at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:348)
at org.openqa.selenium.remote.RemoteWebDriver.findElementById(RemoteWebDriver.java:389)
at org.openqa.selenium.By$ById.findElement(By.java:214)
at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:340)
at com.Nxin.test.TestMall.test(TestMall.java:130)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

#1 楼 @ding7473417 我查了一下,说是要用 4.4 的,我用模拟器,4.4.2 的也是报这个错

报错原因是没有找到 WEBVIEW,你 dump 一下页面看看

WEBVIEW 的 context 名字不是固定的,是 Appium 根据你的设备具体的 webview 进程来获取的。
你要先获取 。。。

#5 楼 @wang04170 请教下,切 webview 时的 contextName 一般会是 “WEBVIEW_应用包名” 么?我看到好几个应用是这样的,不知道 contextName 有没有什么固定的命名规范?谢谢~

#6 楼 @alex_sheng 你可以看下 appium 的运行日志,它取的 context 名字,其实是用 adb shell 下的命令 cat /proc/net/unix 去正则寻找 WEBVIEW 的 PID 再根据 ps 命令查找 PID 对应的包名做组合的。 所以 你可以自己试试这些命令 或者看下运行的 LOG,一般来说 如果支持的 webveiw 的名字都是你说的规律的

直接用 get_contexts 获取所有 context ,然后切换到 webview 开头的 context 就好了。

@ding7473417 @wang04170 @chenhengjie123 谢谢,问题顺利解决,好开心,谢谢谢谢

请问调用微信授权登陆的页面怎么获取如图的元素

Vicki #11 · 2015年09月07日 Author

@ding7473417 @chenhengjie123 @wang04170 在对混合型 APP 进行测试的时候,嵌入到 App 中的第三方 WebView,在查上下文信息的时候,找不到对应的 WebView。用 get_contexts 获取所有 context,也只获取到了 NATIVE_APP。没办法切换到 webview,我要获取里面的元素,该怎么办呢?

@vicki 你是怎么解决的啊??可以分享一下吗??我现在也遇到这个问题了,

@vicki 怎么解决的呀

遇到一样的问题,怎么解决的呀?

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