Appium 微信 webview 的自动化技术

seveniruby · 发布于 2016年12月30日 · 最后由 cchenlll 回复于 2017年06月26日 · 10731 次阅读
本帖已被设为精华帖!

最近好多人问微信webview自动化的事情, 碰巧我也在追微信webview的自动化和性能分析方法.
先发出来一点我的进展给大家参考下. 此方法用于android平台, iOS请自行解决

微信的设置

用微信打开debugx5.qq.com, 这是个微信的x5内核调试页面. 你可以在任何聊天窗口内输入这个网址. 并打开它.
勾选"是否打开TBS内核Inspector调试功能"

使用ChromeDriver编写测试用例

首先安装ChromeDriver
从官方下载或者从你的appium的安装路径里面找chromedriver. 在appium的执行日志里面其实也会打印chromedriver的路径的
然后在电脑上启动它, 设置好端口

chromedriver --url-base=wd/hub --port=8000

可以使用selenium或者appium的客户端去编写测试用例.
如下是我的scalatest的测试用例. 大家可以自己用其他的语言实现

test("test chromedriver weixin") {
  val options = new ChromeOptions()
  options.setExperimentalOption("androidPackage", "com.tencent.mm")
  options.setExperimentalOption("androidUseRunningApp", true)
  options.setExperimentalOption("androidActivity", ".plugin.webview.ui.tools.WebViewUI")
  options.setExperimentalOption("androidProcess", "com.tencent.mm:tools")
  val capability = DesiredCapabilities.chrome()
  capability.setCapability(ChromeOptions.CAPABILITY, options)
  val url = "http://127.0.0.1:8000/wd/hub"
  val driver = new AndroidDriver[WebElement](new URL(url), capability)
  driver.get("https://testerhome.com/topics/6954")
  println(driver.getPageSource)
  driver.quit()
}

使用appium编写测试用例

有人会经常问为什么android上appium不能自动化微信webview, 其实是可以的. 主要是目前的appium有个bug导致的.
在appium中context的切换时, 没有带上一个关键的androidProcess配置导致的.
他会导致appium识别webview的时候, 把com.tencent.mm:tools的webview识别成com.tencent.mm的webview. 从而导致context切换失败.

正确的用appium测试微信h5的方法如下

test("test weixin h5") {
  val capability = new DesiredCapabilities()
  capability.setCapability("app", "")
  capability.setCapability("appPackage", "com.tencent.mm")
  capability.setCapability("appActivity", ".ui.LauncherUI")
  capability.setCapability("deviceName", "emulator-5554")
  capability.setCapability("fastReset", "false")
  capability.setCapability("fullReset", "false")
  capability.setCapability("noReset", "true")
  //capability.setCapability("unicodeKeyboard", "true")
  //capability.setCapability("resetKeyboard", "true")

  //关键是加上这段
  val options = new ChromeOptions()
  options.setExperimentalOption("androidProcess", "com.tencent.mm:tools")
  capability.setCapability(ChromeOptions.CAPABILITY, options)

  val url = "http://127.0.0.1:4723/wd/hub"
  val driver = new AndroidDriver[WebElement](new URL(url), capability)
  println(driver.getPageSource)
  driver.findElementByXPath("//*[@text='我']").click
  driver.findElementByXPath("//*[@text='收藏']").click
  driver.findElementByXPath("//*[contains(@text, '美团外卖')]").click
  println(driver.getPageSource)
  println(driver.getContextHandles)
  driver.context("WEBVIEW_com.tencent.mm:tools")
  println(driver.getPageSource)
}

最关键的就是这句

val options = new ChromeOptions()
options.setExperimentalOption("androidProcess", "com.tencent.mm:tools")
capability.setCapability(ChromeOptions.CAPABILITY, options)

后记

之前测试加上ChromeOptions配置的时候没有成功, 我以为是appium不支持ChromeOptions, 就给appium-android-driver提交了一个PR
后来jlipps提醒了我一下

我就又追查了几遍, 最后发现是我本地安装appium时候加上的http_proxy环境变量干扰了ChromeDriver的执行.
Appium其实是支持ChromeOptions的

结论也就是现在的Appium其实是可以完美的做微信自动化的

我在想我是不是国内第一个提供微信webview自动化方法的人 😅
借鉴此思路的同学转发请注明原链. https://testerhome.com/topics/6954

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 102 条回复
1楼 已删除
605 chenhengjie123 将本帖设为了精华贴 12月30日 22:19
605

加精理由:简单实用,解决了很多人难以对微信 webview 自动化的问题。

3623

很棒

3049

新年第一个赞给你

D92907

意思是还不能用appium server去做android webview的测试吧?

104

#7楼 @wuhao 快了. 我的补丁合并过去就能用appium测试了

4365

👍 赞,学习了

10660

棒棒哒,解决大问题。

214

赞,问一下思寒,结论是appium支持ANDROID的webview自动化吗?目前版本还不支持吧

110

#11楼 @oscar webview一直支持

5920

尝试了这个方法,但是一直提示org.openqa.selenium.WebDriverException: Not yet implemented

详细日志
org.openqa.selenium.WebDriverException: Not yet implemented. Please help us: http://appium.io/get-involved.html (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 37 milliseconds
Build info: version: '2.53.1', revision: 'a36b8b1', time: '2016-06-30 17:37:03'
System info: host: 'BY-01-0734', ip: '172.20.133.17', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_101'
Driver info: io.appium.java_client.android.AndroidDriver
Capabilities [{appPackage=com.tencent.mm, networkConnectionEnabled=true, noReset=true, warnings={}, databaseEnabled=false, deviceName=7N2RDQ1484001994, fullReset=false, platform=ANDROID, appActivity=.ui.LauncherUI, desired={appPackage=com.tencent.mm, appActivity=.ui.LauncherUI, noReset=true, newCommandTimeout=600, platformVersion=4.4, fastReset=false, autoWebview=true, chromeOptions={args=[], extensions=[], androidProcess=com.tencent.mm:tools}, platformName=Android, deviceName=Android Emulator, fullReset=false, platform=ANDROID}, newCommandTimeout=600, platformVersion=4.4.2, webStorageEnabled=false, locationContextEnabled=false, browserName=Android, takesScreenshot=true, javascriptEnabled=true, fastReset=false, autoWebview=true, chromeOptions={args=[], extensions=[], androidProcess=com.tencent.mm:tools}, platformName=Android}]
Session ID: 99db07db-1d87-4c45-ba8e-3d63a95d6c94
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:206)
at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:158)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:678)
at io.appium.java_client.DefaultGenericMobileDriver.execute(DefaultGenericMobileDriver.java:40)
at io.appium.java_client.AppiumDriver.execute(AppiumDriver.java:1)
at io.appium.java_client.android.AndroidDriver.execute(AndroidDriver.java:1)
at org.openqa.selenium.remote.RemoteWebDriver.get(RemoteWebDriver.java:316)
at com.boyaa.test.startAppium(test.java:40)
at com.boyaa.test.main(test.java:77)

1317

已实验,完美支持,下面这段最关键。

// 关键是加上这段
ChromeOptions options = new ChromeOptions();
options.setExperimentalOption("androidProcess", "com.tencent.mm:tools");
capabilities.setCapability(ChromeOptions.CAPABILITY, options);
13790

@yanzilove ,我和你一样 的问题,解决了吗?

96

有用python的吗,想了半天,还是不知道怎么做

96

你好,driver切换到webview失败,appium日志如下,请问如何解决

> info: [debug] Available contexts: NATIVE_APP,WEBVIEW_com.tencent.mm:tools
> info: [debug] Connecting to chrome-backed webview
> info: Chromedriver: Changed state to 'starting'
> info: Chromedriver: Set chromedriver binary as: D:\Appium\node_modules\appium\node_modules\appium-chromedriver\chromedriver\win\chromedriver.exe
> info: Chromedriver: Killing any old chromedrivers, running: FOR /F "usebackq tokens=5" %a in (`netstat -nao ^| findstr /R /C:"9515 "`) do (FOR /F "usebackq" %b in (`TASKLIST /FI "PID eq %a" ^| findstr /I chromedriver.exe`) do (IF NOT %b=="" TASKKILL /F /PID %a))
> info: Chromedriver: No old chromedrivers seemed to exist
> info: Chromedriver: Spawning chromedriver with: D:\Appium\node_modules\appium\node_modules\appium-chromedriver\chromedriver\win\chromedriver.exe --url-base=wd/hub --port=9515
> info: Chromedriver: [STDOUT] Starting ChromeDriver 2.27.440174 (e97a722caafc2d3a8b807ee115bfb307f7d2cfd9) on port 9515
> Only local connections are allowed.
> info: JSONWP Proxy: Proxying [GET /status] to [GET http://127.0.0.1:9515/wd/hub/status] with no body
> info: JSONWP Proxy: Got response with status 200: "{\"sessionId\":\"\",\"status\":0,\"value\":{\"build\":{\"version\":\"alpha\"},\"os\":{\"arch\":\"x86_64\",\"name\":\"Windows NT\",\"version\":\"10.0.14393\"}}}"
> info: JSONWP Proxy: Proxying [POST /session] to [POST http://127.0.0.1:9515/wd/hub/session] with body: {"desiredCapabilities":{"chromeOptions":{"androidPackage":"com.tencent.mm","androidUseRunningApp":true,"androidDeviceSerial":"71MBBKU24CU7"}}}
> info: [debug] Didn't get a new command in 60 secs, shutting down...
> info: Shutting down appium session
> info: [debug] Pressing the HOME button
> info: [debug] executing cmd: D:\android-sdk-windows\platform-tools\adb.exe -s 71MBBKU24CU7 shell "input keyevent 3"
> info: [debug] Resetting IME to 'com.meizu.flyme.input/com.meizu.input.MzInputService'
> info: [debug] executing cmd: D:\android-sdk-windows\platform-tools\adb.exe -s 71MBBKU24CU7 shell "ime set com.meizu.flyme.input/com.meizu.input.MzInputService"
> info: [debug] Stopping logcat capture
> info: [debug] Logcat terminated with code null, signal SIGTERM
> info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"shutdown"}
> info: [debug] [BOOTSTRAP] [debug] Got command of type SHUTDOWN
> info: [debug] [BOOTSTRAP] [debug] Returning result: {"status":0,"value":"OK, shutting down"}
> info: [debug] Sent shutdown command, waiting for UiAutomator to stop...
> info: [debug] [UIAUTOMATOR STDOUT] [CDS]close[4724]
> info: [debug] [BOOTSTRAP] [debug] Closed client connection
104 seveniruby 使用 appium 进行微信小程序的自动化测试 中提及了此贴 01月10日 11:10
D92907

capability.setCapability("deviceName", "emulator-5554")
模拟器是用的什么创建的呢?

14281

#16楼 @kgdtkggfqp 我也想知道 请问你解决了嘛

104

#19楼 @wuhao 随便写个即可. 如果写错了默认取第一个链接的设备 名字对才选择特定的名字的设备.

104

#17楼 @balaroth 是不是你本地有http_proxy环境变量什么干扰了

96

@seveniruby 没有哇,无论如何就是切不到webview,contests是可以打印出来的,这是代码

#encoding: utf-8
import os
import unittest
import selenium
from appium import webdriver
from time import sleep

PATH = lambda p: os.path.abspath(
    os.path.join(os.path.dirname(__file__), p)
)

class xcxTests(unittest.TestCase):
    def setUp(self):
        desired_caps = {}
        desired_caps['platformName'] = 'Android'
        desired_caps['fastReset'] = 'false'
        desired_caps['fastReset'] = 'false'
        desired_caps['deviceName'] = 'm1_note'
        desired_caps['appPackage'] = 'com.tencent.mm'
        desired_caps['appActivity'] = '.ui.LauncherUI'
        desired_caps['fullReset'] = 'false'
        desired_caps['unicodeKeyboard'] = 'True'
        desired_caps['resetKeyboard'] = 'True'

        options = selenium.webdriver.ChromeOptions()
        options.add_experimental_option('androidProcess', 'com.tencent.mm:tools')

        desired_caps['ChromeOptions.CAPABILITY'] = 'options'

        self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)

    def tearDown(self):
        self.driver.quit()

    def test_didibus(self):
        self.driver.find_element_by_name('发现').click()
        self.driver.find_element_by_name('小程序').click()
        self.driver.find_element_by_name('搜索').click()
        sleep(5)
        self.driver.find_element_by_class_name('android.widget.EditText').send_keys('滴滴公交查询')
        os.popen('adb shell ime set com.meizu.flyme.input/com.meizu.input.MzInputService')
        self.driver.find_element_by_class_name('android.widget.EditText').click()
        os.popen('adb shell input keyevent 66')
        sleep(5)
        print(self.driver.contexts)
        self.driver.switch_to.context(u'WEBVIEW_com.tencent.mm:tools')
        self.driver.find_element_by_class_name('search_item_inner').click()

if __name__ == '__main__':
    suite = unittest.TestLoader().loadTestsFromTestCase(xcxTests)
    unittest.TextTestRunner(verbosity=2).run(suite)

搞了一天了。。。

104

#23楼 @balaroth
这句话明显有问题啊. options是个对象. 被你搞成字符串了. 同样ChromeOptions.CAPABILITY也是一样. 这是个变量你必须换成你python版本的变量, 他也不是字符串. 这个变量真正的字符串是"ChromeOptions"

desired_caps['ChromeOptions.CAPABILITY'] = 'options'
14281
ChromeOptions options = new ChromeOptions();
options.setExperimentalOption("androidProcess", "com.tencent.mm:tools");
capabilities.setCapability(ChromeOptions.CAPABILITY, options);

这段用python怎么实现 ,搞了一天都没跑通

26楼 已删除
96

@seveniruby 可以了!谢谢

96

#27楼 @balaroth 能分享下你的最终代码吗,我也研究这个问题,目前还没进展

96

@balaroth 分享下你python 最终代码 为什么我用 谷歌//inspect/#devices定位path 一直报错 用法不对吗

96

@balaroth 还有我贴options = selenium.webdriver.ChromeOptions() 这段代码的时候 ‘ webdriver’

96

@dzousigma @weijiatiancai

from appium import webdriver
***********
def setUp(self):

        desired_caps = {
            'platformName': 'Android',
            'fastReset': 'false',
            'deviceName': 'm1_note',
            'appPackage': 'com.tencent.mm',
            'appActivity': '.ui.LauncherUI',
            'fullReset': 'false',
            'unicodeKeyboard': 'True',
            'resetKeyboard': 'True',
            'chromeOptions': {
                'androidProcess' : 'com.tencent.mm:appbrand3'
                }
            }

        self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)

com.tencent.mm:appbrand3这个根据webview的context改
这是setUp方法的写法,已经可以切到微信的webview了,不过有一些webview控件定位的细节还是不太懂,谁弄明白搞一份示例代码贴出来谢谢了

96

@balaroth 你代码前面都没什么问题 就是最后 搜索出来的 ‘滴滴公交搜索‘ 这时候已经切换到webview界面了 然后执行点击

self.driver.find_element_by_class_name('search_item_inner').click() 执行失败报错
然后我用
self.driver.find_element_by_xpath('//*[@id="search_result"]/div[3]/div[1]/div/ul/li/div').click() 也报错了

有大神知道问题的说下 用的是谷歌的inspect定位 报错代码如下:
Error
Traceback (most recent call last):

File "/Users/daodaoge/PycharmProjects/untitled2/test.py", line 160, in test_scroll
self.driver.find_element_by_xpath('//*[@id="search_result"]/div[3]/div[1]/div/ul/li/div').click()
File "/Library/Python/2.7/site-packages/selenium-2.53.6-py2.7.egg/selenium/webdriver/remote/webdriver.py", line 293, in find_element_by_xpath
return self.find_element(by=By.XPATH, value=xpath)
File "/Library/Python/2.7/site-packages/selenium-2.53.6-py2.7.egg/selenium/webdriver/remote/webdriver.py", line 752, in find_element
'value': value})['value']
File "/Library/Python/2.7/site-packages/selenium-2.53.6-py2.7.egg/selenium/webdriver/remote/webdriver.py", line 236, in execute
self.error_handler.check_response(response)
File "build/bdist.macosx-10.6-intel/egg/appium/webdriver/errorhandler.py", line 29, in check_response
raise wde
NoSuchElementException: Message: An element could not be located on the page using the given search parameters.

13790

@weijiatiancai ,我的成功运行,调试过程中也出现过你这个错误。从报错来看,应该是没有切换到webview,检查chromeOptions配置,和switch_to.context方法有没有问题 。

96

@hukui51770 chromeOptions已经打开TBS 内核Inspector调试

print(self.driver.contexts) :内容如下
[u'NATIVE_APP', u'WEBVIEW_com.tencent.mm:tools']
我感觉应该是进入了 print结果如下:
NATIVE_APP
未找到
WEBVIEW_undefined
未找到
success
我Setup:
'chromeOptions': {
'androidProcess' : 'com.tencent.mm:appbrand1'
}
我一直不理解 appbrand1 代表什么意思 可以是appbrand2?appbrand3?吗
执行操作进入webview界面 代码:
self.driver.switch_to.context(u'WEBVIEW_com.tencent.mm:tools')

不知道到底哪里错误 用的是谷歌的inspect定位
求大神指点...

96

@hukui51770 能贴个你成功完整的代码不 谢谢了 搞了二天没成功 ☹️😞

13790

@weijiatiancai ,driver.contexts print出来的是WEBVIEW_com.tencent.mm:tools,所以配置'chromeOptions': {
'androidProcess' : 'com.tencent.mm:tools',切换进入也是switch_to.context('WEBVIEW_com.tencent.mm:tools')。

96

@hukui51770 @balaroth 我想问一下你们 楼主说的那个 chromedriver 你们启动了么 需要添加环境变量吗 , 具体的操作能说说么 不是太懂这个插件 还有楼主说的端口 设置成8000...有影响吗

13790

@xiaoxuxu 。没有添加chromedriver环境变量和启动它,appium会自己启动它。微信要打开Inspector调试,下面是我的全部代码

from appium import webdriver
import time

desired_caps = {'platformName': 'Android',
'platformVersion': '5.1.1',
'deviceName': '8692_A00',
'app': '',
'appPackage': 'com.tencent.mm',
'appActivity':'.ui.LauncherUI',
'unicodeKeyboard': True,
'resetKeyboard': True,
'chromeOptions': {'androidProcess': 'com.tencent.mm:tools'}
}

driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
driver.implicitly_wait(10)

driver.find_element_by_id('com.tencent.mm:id/bm6').click()
driver.find_element_by_id('com.tencent.mm:id/adq').click()
driver.find_element_by_name('佣金提现').click()
time.sleep(3)
print(driver.contexts)
driver.switch_to.context('WEBVIEW_com.tencent.mm:tools') #切换进入webview
driver.find_element_by_xpath('/html/body/section/section/div/div[3]/ul/li[1]/a').click()
driver.quit()

96

@hukui51770 真心非常感激 你webview定位的元素用的什么工具? 我用的appium版本1.4

13790

@xiaoxuxu 微信上切换到webview页面,在google浏览器中输入chrome://inspect/#devices,会看到自己的webview页面地址,点击inspect 就在网页打开了,然后就和web定位控件一样,找到你想要的控件,右键copy xpath就ok了。也可以自己把那个链接复制,在浏览器打开然后点击google开发者工具,和前面一样操作

96

@hukui51770 非常感谢 很详细 !!

96

#38楼 @hukui51770
非常感谢!

96

@seveniruby @hukui51770 @balaroth 请问下 我print(self.driver.contexts) 如:
[u'NATIVE_APP', u'WEBVIEW_com.tencent.mm:tools', u'WEBVIEW_com.android.quicksearchbox']
然后我self.driver.switch_to.context('WEBVIEW_com.android.quicksearchbox')
执行程序的时候一直处于缓冲状态 没报错也没执行 等了10分钟还是老样子 请问这是什么情况
'chromeOptions': {
'androidProcess' : 'WEBVIEW_com.android.quicksearchbox'
求指教

96


已经找到web view了 然后self.driver.switch_to.context('WEBVIEW_com.tencent.mm:tools') 一直处于缓冲状态!!有大神知道原因么

我是在mac上 chromedriver 已放在appium的路径下

贴下报错代码
self.driver.find_element_by_class_name("gj-home-lock-tip").click()
self.error_handler.check_response(response)
File "build/bdist.macosx-10.6-intel/egg/appium/webdriver/errorhandler.py", line 29, in check_response
raise wde
NoSuchElementException: Message: no such element: Unable to locate element: {"method":"class name","selector":"gj-home-lock-tip"}
(Session info: webview=37.0.0.0)
(Driver info: chromedriver=2.18.343837 (52eb4041461e46a6b73308ebb19e85787ced4281),platform=Mac OS X 10.11.5 x86_64)

进行转换webview界面的时候 等了大概1分钟左右 然后print提示成功了...之后执行界面元素定位 就报错

96

@seveniruby 你说 appium时候加上的http_proxy环境变量干扰了ChromeDriver的执行 需要怎么解决这个问题?

47楼 已删除
104

#46楼 @Tester957 去掉不就行了. unset下. 你这是要别人手把手的教啊...回复的内容干扰版面, 我先删除了

96

@sevenlruby 请问楼主 我appium提示 chrome not reachable是什么情况?

96

#31楼 @balaroth 有个问题想请教,搜索出来 ‘滴滴公交搜索‘ 的结果后,控件定位也没报错,但怎么点击控件以后没有跳转页面...你那边是否有这种情况?
为了验证是否有执行点击操作,我特意写了几个点击操作,都顺利执行了,就是点击后无反应
self.driver.switch_to.context(u'WEBVIEW_com.tencent.mm:tools')
self.driver.find_element_by_xpath('//[@id="search_result"]/div[3]/div[1]/div/ul/li[1]').click()
print "1"
self.driver.find_element_by_xpath('//
[@id="search_result"]/div[3]/div[1]/div/ul/li/div/div[2]/div/p[1]').click()
print "2"
self.driver.find_element_by_xpath('//*[@id="search_result"]/div[3]/div[1]/div/ul/li/div/div[2]/div').click()
print "3"
另外发现在谷歌开发者工具的inspect页面能拉动该结果页面,但点击也是没有跳转动作的😂 😂 只有我遇到这种情况吗?

96

我的报错代码 :
Chromedriver: Error: An error occurred (Original error: chrome not reachable
(Driver info: chromedriver=2.18.343837 (52eb4041461e46a6b73308ebb19e85787ced4281),platform=Mac OS X 10.11.5 x86_64))
at JWProxy.command$ (lib/proxy.js:149:15)
at tryCatch (/Applications/Appium.app/Contents/Resources/node_modules/appium/node_modules/appium-chromedriver/node_modules/babel-runtime/regenerator/runtime.js:67:40)
at GeneratorFunctionPrototype.invoke as _invoke
at GeneratorFunctionPrototype.prototype.(anonymous function) as next
at GeneratorFunctionPrototype.invoke (/Applications/Appium.app/Contents/Resources/node_modules/appium/node_modules/appium-chromedriver/node_modules/babel-runtime/regenerator/runtime.js:136:37)
at bound (domain.js:254:14)
at GeneratorFunctionPrototype.runBound (domain.js:267:12)
at run (/Applications/Appium.app/Contents/Resources/node_modules/appium/node_modules/appium-chromedriver/node_modules/babel-runtime/node_modules/core-js/library/modules/es6.promise.js:89:39)
at /Applications/Appium.app/Contents/Resources/node_modules/appium/node_modules/appium-chromedriver/node_modules/babel-runtime/node_modules/core-js/library/modules/es6.promise.js💯28
at process._tickDomainCallback (node.js:381:11)
{ [Error: An error occurred (Original error: chrome not reachable
(Driver info: chromedriver=2.18.343837 (52eb4041461e46a6b73308ebb19e85787ced4281),platform=Mac OS X 10.11.5 x86_64))]
status: 100,
value: { message: 'chrome not reachable\n (Driver info: chromedriver=2.18.343837 (52eb4041461e46a6b73308ebb19e85787ced4281),platform=Mac OS X 10.11.5 x86_64)' },
httpCode: 200 }

info: --> GET /wd/hub/status {}

error: Could not proxy command to remote server. Original error: connect ECONNREFUSED

info: JSONWP Proxy: Proxying [GET /wd/hub/status] to [GET http://127.0.0.1:9515/wd/hub/status] with body: {}

info: --> GET /wd/hub/status {}

error: Could not proxy command to remote server. Original error: connect ECONNREFUSED

info: JSONWP Proxy: Proxying [GET /wd/hub/status] to [GET http://127.0.0.1:9515/wd/hub/status] with body: {}

info: --> GET /wd/hub/status {}

error: Could not proxy command to remote server. Original error: connect ECONNREFUSED

info: JSONWP Proxy: Proxying [GET /wd/hub/status] to [GET http://127.0.0.1:9515/wd/hub/status] with body: {}

info: --> GET /wd/hub/status {}

error: Could not proxy command to remote server. Original error: connect ECONNREFUSED

info: JSONWP Proxy: Proxying [GET /wd/hub/status] to [GET http://127.0.0.1:9515/wd/hub/status] with body: {}

info: --> GET /wd/hub/status {}

96

error: Chromedriver: Chromedriver exited unexpectedly with code null, signal SIGTERM

info: Chromedriver: Changed state to 'stopped'

error: Chromedriver: Error: An error occurred (Original error: chrome not reachable
(Driver info: chromedriver=2.18.343837

96

warn: Chromedriver for context WEBVIEW_com.tencent.mm:tools stopped unexpectedly
warn: Chromedriver quit unexpectedly, but it wasn't the active context, ignoring

96


我的不知道为什么context只有native_app

96

#38楼 @hukui51770 您好 想问一下 您是怎么获取到context的 我也有打印 但是没有这个呢

6853

一直提示这玩意

WebDriverException: Message: unknown error: Chrome version must be >= 54.0.2840.0

看了下手机的chrome都55了

96

我也遇到一样的问题@codeskyblue,提示:unknown error: Chrome version must be >= 54.0.2840.0\n (Driver info: chromedriver=2.27.440174 。不知道怎么处理。

6853

#58楼 @happymff 猜测是微信的WebKit版本不够导致的,或许应该把chromedriver或者selenium的版本降低一点

96

#59楼 @codeskyblue 您好,我的微信的Webview显示的是53.0.2785.49,然后我手机上的Chrome是55的,这个有影响么?chromedriver具体是根据哪个版本来选择合适的?是根据微信Webview的么?

6853

#60楼 @happymff 应该是微信的WebView,你降低chromedriver版本,试验的效果怎么样?另外微信WebView的版本号你是在哪里看到的?

96

#61楼 @codeskyblue chromedriver我降到了2.3,2.4,2.5,2.2,2.1,目前提示的错误信息不一样了,代码运行到切换webview之后,一直没有响应,最后提示org.openqa.selenium.NoSuchSessionException: no such session。server端的提示信息是:我上传一个截图吧。

微信的WebView版本可以通过Chrome 的ADB plugins在Inspect页面元素的时候看到。

96

@codeskyblue 你那边的微信小程序,测试是可以通过的么?谢谢~

6853

#63楼 @happymff 还是没搞定

96

#64楼 @codeskyblue 我觉得我这边现在是切换到了WebView,但是不能对其元素进行操作,不知道具体问题在哪了,也可能是权限问题,H5开发的时候,不让对其元素进行操作,这是我的猜测。你那边要是解决了,到时候分享一下哈~

6853

#65楼 @happymff 我也只是为了测试ATX对WEBVIEW支持的情况如何才弄的,应该不会怎么关注。

96

@codeskyblue 谢谢,我的问题解决了,最终用的chromedriver2.5,解决了问题,配置代码如下:
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability("platform", "ANDROID");
caps.setCapability("platformVersion", "5.1.1");
caps.setCapability("deviceName", "A02AECPB2CLTG");
caps.setCapability("browserName", "");
caps.setCapability("app", "");

caps.setCapability("appPackage", "com.tencent.mm");
caps.setCapability("appActivity", ".ui.LauncherUI");
caps.setCapability("fastReset", "false");
caps.setCapability("fullReset", "false");
caps.setCapability("noReset", "true");

ChromeOptions options = new ChromeOptions();
options.setExperimentalOption("androidProcess", "com.tencent.mm:appbrand1");
caps.setCapability(ChromeOptions.CAPABILITY, options);
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), caps);
实现代码如下:
@Test
public void miniProgramTest() throws Exception {

// println(driver.getPageSource)
driver.findElementByXPath("//[@text='发现']").click();
Thread.sleep(1000);
driver.findElementByXPath("//
[@text='小程序']").click();
Thread.sleep(1000);
driver.findElementByXPath("//[contains(@text, 'QQ阅读')]").click();
Thread.sleep(3000);
driver.findElementByXPath("//
[@text='书库']").click();
Set contextNames = driver.getContextHandles();
Thread.sleep(1000);
for (String contextName : contextNames) {
System.out.println(contextName);
}
driver.context("WEBVIEW_com.tencent.mm:tools");
Thread.sleep(1000);
System.out.println("已经进入WEBVIEW啦");
//System.out.println(driver.getPageSource());
String s1 = driver.getWindowHandle();

driver.findElementByXPath("//*[contains(@url, '古代')]").click();
driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);
Set set1 = driver.getWindowHandles();
//System.out.println(set1);
for(String windows: set1){
if (windows.equalsIgnoreCase(s1)){

}else{
driver.switchTo().window(windows);
}
}
//driver.manage().timeouts().implicitlyWait(60,TimeUnit.SECONDS);
Thread.sleep(2000);
driver.findElementByXPath("//[contains(@url, 'bid=716295')]").click();
String s2 = driver.findElementByXPath("//
[contains(@url, 'bid=716295')]").getText();
System.out.println(s2);
Assert.assertTrue(s2.contains("美人榻"));
Thread.sleep(3000);
driver.context("NATIVE_APP");
System.out.println("已经回到NativeAPP啦");
driver.findElementById("com.tencent.mm:id/io").click();
//driver.findElement(By.id("com.tencent.mm:id/io")).click();
}
代码运行正常了,有遇到同样的问题,可以尝试一下我的方法。

389

@zrleo 我也遇到你这个情况,只有一个context,请问你后来怎么解决的?

96

谢谢楼主,很赞!
其实楼主的意思就是现在Appium切换context到webview的时候有bug,所以新建Appium实例的时候需要加个参数,Ruby的代码没这么复杂

caps = 
  { "platformName" => "Android",
    "platformVersion" => "5.1",
    "deviceName" => "",
    "appPkg" => "com.tencent.mm",
    "appWaitPackage" => "com.tencent.mm",
    "appActivity" => ".ui.LauncherUI",
    "appWaitActivity" => ".ui.LauncherUI",
    "noReset" => true,
    "chromeOptions" => { "androidProcess" => "com.tencent.mm:tools" } }
Appium::Driver.new(caps: caps).start_driver
96

大家有没有遇到,在webview操作,点击跳转到另一个页面后就不能进行点击、输入等操作了

File "C:/Users/Administrator/Desktop/h5.py", line 58, in test_h5
self.dr.find_element_by_class_name("weui_navbar_item").click()
AttributeError: 'NoneType' object has no attribute 'click'

96

#72楼 @D6666666 有的!在webview里进另一个页面再去find_element的话,服务端会报ESOCKETTIMEDOUT的错误。

[MJSONWP] Encountered internal error running command: Error: Could not proxy. Proxy error: Could not proxy command to remote server. Original error: Error: ESOCKETTIMEDOUT
    at doJwpProxy$ (../../../lib/mjsonwp/mjsonwp.js:343:13)
    at tryCatch (/usr/local/lib/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:67:40)
    at GeneratorFunctionPrototype.invoke [as _invoke] (/usr/local/lib/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:315:22)
    at GeneratorFunctionPrototype.prototype.(anonymous function) [as throw] (/usr/local/lib/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:100:21)
    at GeneratorFunctionPrototype.invoke (/usr/local/lib/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:136:37)
96

#73楼 @chaoli46 是的,你解决了吗?

96

#74楼 @D6666666 没有呢,刚去github提了个bug ( https://github.com/appium/appium/issues/7863 ),不过看起来像是微信的bug。

76楼 已删除
77楼 已删除
79楼 已删除
4442

@all,谁知道 .net 应该怎么写,下面这样写切换不成功:

AndroidDriver<IWebElement> driver = null;
IWebElement element = null;
DesiredCapabilities capabilities = new DesiredCapabilities();
//capabilities.SetCapability("app", "");
capabilities.SetCapability("deviceName", "android emulator");
capabilities.SetCapability("browserName", "");
capabilities.SetCapability("platformName", "android");
capabilities.SetCapability("platformVersion", "7.0");//手机操作系统版本
capabilities.SetCapability("newCommandTimeout", "300"); ////设置命令超时时间,单位:秒。达到超时时间仍未接收到新的命令时 Appium 会假设客户端退出然后自动结束会话。
capabilities.SetCapability("unicodeKeyboard", "True");//使用 Unicode 输入法。默认值 false
capabilities.SetCapability("resetKeyboard", "True"); //在设定了 unicodeKeyboard 关键字的 Unicode 测试结束后,重置输入法到原有状态。如果单独使用,将会被忽略。默认值 false
capabilities.SetCapability("appPackage", "com.tencent.mm");
capabilities.SetCapability("appActivity", ".ui.LauncherUI");
capabilities.SetCapability("automationName", "appium");
capabilities.SetCapability("fastReset", "false");
capabilities.SetCapability("fullReset", "false");
capabilities.SetCapability("noReset", "true");

ChromeOptions options  = new ChromeOptions();
options.AddAdditionalCapability("androidProcess", "com.tencent.mm:tools");
capabilities.SetCapability(ChromeOptions.Capability, options);


Uri serverUri = new Uri("http://127.0.0.1:4723/wd/hub");
try
{
    //System.IO.File.AppendAllText("D:\\PageSources.xml",driver.PageSource);
    driver = new AndroidDriver<IWebElement>(serverUri, capabilities, TimeSpan.FromSeconds(180));
    driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(1));
    driver.FindElementByXPath("//*[@text='通讯录']").Click();
    driver.FindElementByXPath("//*[@text='公众号']").Click();
    driver.FindElementByAccessibilityId("搜索").Click();
    driver.FindElementByXPath("//*[@text='搜索']").SendKeys("美");
    driver.FindElementByXPath("//*[@text='美团']").Click(); 
    driver.FindElementByXPath("//*[@text='吃喝玩乐']").Click();
    driver.FindElementByXPath("//*[contains(@text,'附近优惠')]").Click();
    Console.WriteLine(driver.Contexts);
    Console.WriteLine(driver.PageSource);

    var contexts = ((IContextAware)driver).Contexts;
    string webviewContext = null;
    for (int i = 0; i < contexts.Count; i++)
    {
        Console.WriteLine(contexts[i]);
        if (contexts[i].Contains("WEBVIEW"))
        {
            webviewContext = contexts[i];
            break;
        }
    }
    Assert.IsNotNull(webviewContext);
    ((IContextAware)driver).Context = webviewContext;

    Thread.Sleep(3000);
    driver.Quit();
}
catch (Exception)
{
    if (driver != null)
    {
        driver.Quit();
    }
}

报错信息:

[2017-03-22 12:15:38][AndroidDriver] Connecting to chrome-backed webview context 'WEBVIEW_com.tencent.mm:tools'
[2017-03-22 12:15:38][AndroidDriver] A port was not given, using random port: 8000
[2017-03-22 12:15:38][Chromedriver] Changed state to 'starting'
[2017-03-22 12:15:38][Chromedriver] Set chromedriver binary as: C:\Users\stephen\AppData\Local\Programs\appium-desktop\resources\app\node_modules\appium-chromedriver\chromedriver\win\chromedriver.exe
[2017-03-22 12:15:38][Chromedriver] Killing any old chromedrivers, running: FOR /F "usebackq tokens=5" %a in (netstat -nao ^| findstr /R /C:"8000 ") do (FOR /F "usebackq" %b in (TASKLIST /FI "PID eq %a" ^| findstr /I chromedriver.exe) do (IF NOT %b=="" TASKKILL /F /PID %a))
[2017-03-22 12:15:38][Chromedriver] No old chromedrivers seemed to exist
[2017-03-22 12:15:38][Chromedriver] Spawning chromedriver with: C:\Users\stephen\AppData\Local\Programs\appium-desktop\resources\app\node_modules\appium-chromedriver\chromedriver\win\chromedriver.exe --url-base=wd/hub --port=8000 --adb-port=5037
[2017-03-22 12:15:38][Chromedriver] [STDOUT] Starting ChromeDriver 2.26.436362 (5476ec6bf7ccbada1734a0cdec7d570bb042aa30) on port 8000
Only local connections are allowed.
[2017-03-22 12:15:38][JSONWP Proxy] Proxying [GET /status] to [GET http://127.0.0.1:8000/wd/hub/status] with no body
[2017-03-22 12:15:38][JSONWP Proxy] Got response with status 200: "{\"sessionId\":\"\",\"status\":0,\"value\":{\"build\":{\"version\":\"alpha\"},\"os\":{\"arch\":\"x86_64\",\"name\":\"Windows NT\",\"version\":\"10.0.10240\"}}}"
[2017-03-22 12:15:38][JSONWP Proxy] Proxying [POST /session] to [POST http://127.0.0.1:8000/wd/hub/session] with body: {"desiredCapabilities":{"chromeOptions":{"androidPackage":"com.tencent.mm","androidUseRunningApp":true,"BinaryLocation":null,"LeaveBrowserRunning":false,"Proxy":null,"Arguments":[],"Extensions":[],"DebuggerAddress":null,"MinidumpPath":null,"PerformanceLoggingPreferences":null,"androidDeviceSerial":"APU7N16309003842"}}}
[2017-03-22 12:15:38][JSONWP Proxy] Got response with status 200: {"sessionId":"1cf680ec27eb7ed6a73be8c1e88c798c","status":13,"value":{"message":"unknown error: cannot parse capability: chromeOptions\nfrom unknown error: unrecognized chrome option: Arguments\n (Driver info: chromedriver=2.26.436362 (5476ec6bf7ccbada1734a0cdec7d570bb042aa30),platform=Windows NT 10.0.10240 x86_64)"}}
[2017-03-22 12:15:38][JSONWP Proxy] Proxying [POST /session] to [POST http://127.0.0.1:8000/wd/hub/session] with body: {"desiredCapabilities":{"chromeOptions":{"androidPackage":"com.tencent.mm","androidUseRunningApp":true,"BinaryLocation":null,"LeaveBrowserRunning":false,"Proxy":null,"Arguments":[],"Extensions":[],"DebuggerAddress":null,"MinidumpPath":null,"PerformanceLoggingPreferences":null,"androidDeviceSerial":"APU7N16309003842"}}}
[2017-03-22 12:15:38][JSONWP Proxy] Got response with status 200: {"sessionId":"157d64dd57fef1ceb42aca0f3c6282dd","status":13,"value":{"message":"unknown error: cannot parse capability: chromeOptions\nfrom unknown error: unrecognized chrome option: Arguments\n (Driver info: chromedriver=2.26.436362 (5476ec6bf7ccbada1734a0cdec7d570bb042aa30),platform=Windows NT 10.0.10240 x86_64)"}}
[2017-03-22 12:15:38][JSONWP Proxy] Proxying [POST /session] to [POST http://127.0.0.1:8000/wd/hub/session] with body: {"desiredCapabilities":{"chromeOptions":{"androidPackage":"com.tencent.mm","androidUseRunningApp":true,"BinaryLocation":null,"LeaveBrowserRunning":false,"Proxy":null,"Arguments":[],"Extensions":[],"DebuggerAddress":null,"MinidumpPath":null,"PerformanceLoggingPreferences":null,"androidDeviceSerial":"APU7N16309003842"}}}
[2017-03-22 12:15:38][JSONWP Proxy] Got response with status 200: {"sessionId":"f2b4c509ad0b66b50e6204cda6949705","status":13,"value":{"message":"unknown error: cannot parse capability: chromeOptions\nfrom unknown error: unrecognized chrome option: Arguments\n (Driver info: chromedriver=2.26.436362 (5476ec6bf7ccbada1734a0cdec7d570bb042aa30),platform=Windows NT 10.0.10240 x86_64)"}}
[2017-03-22 12:15:38][JSONWP Proxy] Proxying [POST /session] to [POST http://127.0.0.1:8000/wd/hub/session] with body: {"desiredCapabilities":{"chromeOptions":{"androidPackage":"com.tencent.mm","androidUseRunningApp":true,"BinaryLocation":null,"LeaveBrowserRunning":false,"Proxy":null,"Arguments":[],"Extensions":[],"DebuggerAddress":null,"MinidumpPath":null,"PerformanceLoggingPreferences":null,"androidDeviceSerial":"APU7N16309003842"}}}
[2017-03-22 12:15:38][JSONWP Proxy] Got response with status 200: {"sessionId":"2bebd54f4a175642d051bbafee2d7a5f","status":13,"value":{"message":"unknown error: cannot parse capability: chromeOptions\nfrom unknown error: unrecognized chrome option: Arguments\n (Driver info: chromedriver=2.26.436362 (5476ec6bf7ccbada1734a0cdec7d570bb042aa30),platform=Windows NT 10.0.10240 x86_64)"}}
[2017-03-22 12:15:38][Chromedriver] Chromedriver exited unexpectedly with code null, signal SIGTERM
[2017-03-22 12:15:38][Chromedriver] Changed state to 'stopped'
[2017-03-22 12:15:38][Chromedriver] Error: unknown error: cannot parse capability: chromeOptions
from unknown error: unrecognized chrome option: Arguments
(Driver info: chromedriver=2.26.436362 (5476ec6bf7ccbada1734a0cdec7d570bb042aa30),platform=Windows NT 10.0.10240 x86_64)
at Chromedriver.callee$2$0$ (C:\Users\stephen\AppData\Local\Programs\appium-desktop\resources\app\node_modules\appium-chromedriver\lib\chromedriver.js:176:15)
at tryCatch (C:\Users\stephen\AppData\Local\Programs\appium-desktop\resources\app\node_modules\appium-chromedriver\node_modules\babel-runtime\regenerator\runtime.js:67:40)
at GeneratorFunctionPrototype.invoke as _invoke
at GeneratorFunctionPrototype.prototype.(anonymous function) as next
at GeneratorFunctionPrototype.invoke (C:\Users\stephen\AppData\Local\Programs\appium-desktop\resources\app\node_modules\appium-chromedriver\node_modules\babel-runtime\regenerator\runtime.js:136:37)
Error: unknown error: cannot parse capability: chromeOptions
from unknown error: unrecognized chrome option: Arguments
(Driver info: chromedriver=2.26.436362 (5476ec6bf7ccbada1734a0cdec7d570bb042aa30),platform=Windows NT 10.0.10240 x86_64)
at Chromedriver.callee$2$0$ (C:\Users\stephen\AppData\Local\Programs\appium-desktop\resources\app\node_modules\appium-chromedriver\lib\chromedriver.js:176:15)
at tryCatch (C:\Users\stephen\AppData\Local\Programs\appium-desktop\resources\app\node_modules\appium-chromedriver\node_modules\babel-runtime\regenerator\runtime.js:67:40)
at GeneratorFunctionPrototype.invoke as _invoke
at GeneratorFunctionPrototype.prototype.(anonymous function) as next
at GeneratorFunctionPrototype.invoke (C:\Users\stephen\AppData\Local\Programs\appium-desktop\resources\app\node_modules\appium-chromedriver\node_modules\babel-runtime\regenerator\runtime.js:136:37)
[2017-03-22 12:15:38][MJSONWP] Encountered internal error running command: Error: unknown error: cannot parse capability: chromeOptions
from unknown error: unrecognized chrome option: Arguments
(Driver info: chromedriver=2.26.436362 (5476ec6bf7ccbada1734a0cdec7d570bb042aa30),platform=Windows NT 10.0.10240 x86_64)
at Chromedriver.callee$2$0$ (C:\Users\stephen\AppData\Local\Programs\appium-desktop\resources\app\node_modules\appium-chromedriver\lib\chromedriver.js:176:15)
at tryCatch (C:\Users\stephen\AppData\Local\Programs\appium-desktop\resources\app\node_modules\appium-chromedriver\node_modules\babel-runtime\regenerator\runtime.js:67:40)
at GeneratorFunctionPrototype.invoke as _invoke
at GeneratorFunctionPrototype.prototype.(anonymous function) as next
at GeneratorFunctionPrototype.invoke (C:\Users\stephen\AppData\Local\Programs\appium-desktop\resources\app\node_modules\appium-chromedriver\node_modules\babel-runtime\regenerator\runtime.js:136:37)
[2017-03-22 12:15:38][HTTP] <-- POST /wd/hub/session/1f06a81d-0a2e-4840-a4da-b800c9c7e26e/context 500 1441 ms - 407

4442 happystone [该话题已被删除] 中提及了此贴 03月22日 15:26
4442
4442happystone 回复
  • 已解决 -

将下代码


ChromeOptions options = new ChromeOptions();
options.AddAdditionalCapability("androidProcess", "com.tencent.mm:tools");
capabilities.SetCapability(ChromeOptions.Capability, options);

替换为:

DesiredCapabilities option = new DesiredCapabilities();
option.SetCapability("androidProcess", "com.tencent.mm:tools");
capabilities.SetCapability(ChromeOptions.Capability, option.ToDictionary());
F3d86f

请问楼主有没有 在native_app 与 webview 之间进行多次切换测试?我只发现第一次从native_app 切到webview 是成功的,从webview 切回native_app ,再切到webview 就失败了。@seveniruby

3bae02
32yukikla 回复

同问,我也遇到了同样的问题,不知道楼主解决没?

949fdc
32chaoli46 回复

开始有点问题,后来发现是没切换context,我也是用ruby,多交流。

16590


为什么这两句话执行了以后不报错,但是点击事件也没生效呢?
driver.find_element_by_xpath('//[@id="combo"]/li[1]/div[1]').click()
driver.find_element_by_xpath('//
[@id="combo"]/li[1]/div[2]').click()
xpath是用谷歌调试那个找的,应该没问题

16590
32yukikla 回复

我也卡在这里了,请问你的问题解决了吗

96
16590Wanglx 回复

之前也遇到了相同问题,换了一些其他公众号的webview试了一下,有些是可以的(比如填写表单),有些就不行(比如点击项目跳转),结论是的确切换到了webview并且找到了该元素(用getText方法能得到text),不然会报unable to find xxxxx,猜想是不是当前webview本身有什么限制

16590
32evon4555 回复

我卡在这里一个星期了,我用xpath可以定位到,但是就是click事件不生效。而且现在业务就在微信一块,如果不能跑通那自动化根本就搞不起来😂

16590
32evon4555 回复

https://testerhome.com/topics/3591
刚刚看了下这篇帖子,好像有点思路了。我去试试看

96
16590Wanglx 回复

成功了求指点啊

我刚把我要测的页面在电脑上用chrome打开,发现电脑上也不能用常规的操作进行点击,你试试看你的页面
如果是这样的话,我还是觉得微信平台上限制了什么。。。我得找开发问问去

所以如果电脑上搞定了,可以点击,app上一定可以用相同的方法处理H5

16590
32evon4555 回复

我这边查资料总算查出来了一点头绪,

我可以用这两句话来对webview页面进行操作了,头疼的就是这个定位问题不好解决,但是总算是可以对页面进行操作了
方法可以参考这个网址http://www.exceptionhelp.com/autotestdetail?articleId=82
这个是扩展用法:http://www.exceptionhelp.com/autotestdetail?articleId=69

96

坑,fastReset 和 fullReset 千万不要写!!刚刚血一样的教训,我微信的数据全被清空了!!!!!!!!!!!!!!!!!!!!!!!!

F1f23c
104seveniruby 回复

想请问一下,就是切换之后一直在等待状态是什么原因呢?

然后有时能成功进行转换后的操作,有时候又不行。

[36minfo[39m: Chromedriver: Changed state to 'starting'
[36minfo[39m: Chromedriver: Set chromedriver binary as: C:\Program Files\Appium\node_modules\appium\node_modules\appium-chromedriver\chromedriver\win\chromedriver.exe
[36minfo[39m: Chromedriver: Killing any old chromedrivers, running: FOR /F "usebackq tokens=5" %a in (`netstat -nao ^| findstr /R /C:"9515 "`) do (FOR /F "usebackq" %b in (`TASKLIST /FI "PID eq %a" ^| findstr /I chromedriver.exe`) do (IF NOT %b=="" TASKKILL /F /PID %a))
[36minfo[39m: Chromedriver: No old chromedrivers seemed to exist
[36minfo[39m: Chromedriver: Spawning chromedriver with: C:\Program Files\Appium\node_modules\appium\node_modules\appium-chromedriver\chromedriver\win\chromedriver.exe --url-base=wd/hub --port=9515
[36minfo[39m: Chromedriver: [STDOUT] Starting ChromeDriver 2.18.343845 (73dd713ba7fbfb73cbb514e62641d8c96a94682a) on port 9515
Only local connections are allowed.
[36minfo[39m: JSONWP Proxy: Proxying [GET /status] to [GET http://127.0.0.1:9515/wd/hub/status] with no body
[36minfo[39m: JSONWP Proxy: Got response with status 200: "{\"sessionId\":\"\",\"status\":0,\"value\":{\"build\":{\"version\":\"alpha\"},\"os\":{\"arch\":\"x86_64\",\"name\":\"Windows NT\",\"version\":\"6.1 SP1\"}}}"
[36minfo[39m: JSONWP Proxy: Proxying [POST /session] to [POST http://127.0.0.1:9515/wd/hub/session] with body: {"desiredCapabilities":{"chromeOptions":{"androidPackage":"com.tencent.mm","androidUseRunningApp":true,"args":[],"extensions":[],"androidProcess":"com.tencent.mm:tools","androidDeviceSerial":"DBH9X...
[36minfo[39m: Shutting down appium session
[36minfo[39m: JSONWP Proxy: Got response with status 200: {"sessionId":"9a59fc16f0e2597ef205cad6275ca31c","status":100,"value":{"message":"chrome not reachable\n  (Driver info: chromedriver=2.18.343845 (73dd713ba7fbfb73cbb514e62641d8c96a94682a),platform=W...
[36minfo[39m: JSONWP Proxy: Proxying [POST /session] to [POST http://127.0.0.1:9515/wd/hub/session] with body: {"desiredCapabilities":{"chromeOptions":{"androidPackage":"com.tencent.mm","androidUseRunningApp":true,"args":[],"extensions":[],"androidProcess":"com.tencent.mm:tools","androidDeviceSerial":"DBH9X...
[36minfo[39m: JSONWP Proxy: Got response with status 200: {"sessionId":"9034159efd8e429fca558c83cb652a75","status":0,"value":{"acceptSslCerts":true,"applicationCacheEnabled":false,"browserConnectionEnabled":false,"browserName":"chrome","chrome":{},"cssSel...
[36minfo[39m: Chromedriver: Changed state to 'online'
65aa74

大家有遇到这个错误么,求帮忙解决一下:WebDriverException: An unknown server-side error occurred while processing the command. Original error: session not created exception: please close 'com.tencent.mm' and try again
我的代码:driver.context("WEBVIEW_com.tencent.mm:tools")(使用这个driver)

我的chromeDriver版本:

异常信息:

Appium出错信息:

65aa74
65aa74baxia 回复

已经找到出错的原因了。是因为我测试的app不是微信(只是测试我的apk跳转到微信的webview页面点击操作),可能是当前测试应用和配置的webview的那个driver不相匹配而失败的。如果这不是根本原因还请大家指正

96
F3d86fAirFisher 回复

切换回NATIVE_APP,杀掉chromedriver,再进入webview

185
32uglina 回复

我也碰到了类似问题。杀chromedriver进程有点儿郁闷。各位大神还有别的好办法么? @Lihuazhang @seveniruby

5081

@skytraveler 用appium1.5版本 设置 desired_caps['recreateChromeDriverSessions'] = True 切换到非chrome-Driver会kill掉session,就不需要手动kill了。

185
5081silly 回复

问题解决了。可以来回切换了。感谢!

185

感谢黄老师和各位提供细节的同学,全搞定了。作为appium的新手菜鸟回馈一下几个细节:

1.chromedriver可以在起appium的时候当启动参数参数,这样就不用单起了 appium --no-reset --chromedriver-port 8000
2.capabilities.setCapability("recreateChromeDriverSessions", "True"); 这句很重要,否则webview和native来回切会有问题。
3.在微信里打开调试选项后,可以用chrome的内建插件inspect H5的文档结构。

贴下比较low的代码,代码实现了根据给定列表遍历给定公众号历史文章的demo功能,期间数次native和webview的切换:

import io.appium.java_client.android.AndroidDriver;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.DesiredCapabilities;

import java.net.URL;
import java.util.ArrayList;

import org.junit.*;

/**
 * Created by lucas on 2017/5/31.
 */
public class AndroidTest {

    private static final int NUMBER_ALLOWED = 3;

    @Test
    public void invokeSnowball() throws Exception {


        AndroidDriver driver = this.GetAndroidDriver();

        //进入公众号列表
        this.GotoList(driver);

        //遍历列表
        for (String name : this.GetSearchList()) {
            if (this.GotoMessageHistory(driver, name)) {
                //遍历列表给出的文章
                this.getArticleDetail(driver, name);
            }
            //返回公众号列表
            this.GoBackToList(driver);
        }
    }

    //进入公众号列表的操作
    private void GotoList(AndroidDriver driver) throws Exception {
        Thread.sleep(5000);
        driver.findElement(By.xpath("//android.widget.TextView[@text='通讯录']")).click();
        Thread.sleep(2000);
        driver.findElement(By.xpath("//android.widget.TextView[@text='公众号']")).click();
    }

    //定义搜索列表
    private ArrayList<String> GetSearchList() {
        return new ArrayList<String>() {{
            add("漫画项目管理");
            add("阿尔法工场");
            add("阿里研究院");
            add("安卓开发精选");
        }};
    }

    private void getArticleDetail(AndroidDriver driver, String name) throws Exception {

        for (int i = 1; i <= NUMBER_ALLOWED; i++) {
            driver.context("WEBVIEW_com.tencent.mm:tools");
            System.out.println("切换到WEBVIEW上下文");
            if (isElementExist(driver, By.xpath("//*[@id='js_msg_card']"))) {
                System.out.println("获取到了公众号文章列表");

                //点击文章
                if (isElementExist(driver, By.xpath("//*[@class='weui_msg_card_bd']/div[" + i + "]"))) {
                    driver.findElement(By.xpath("//*[@class='weui_msg_card_bd']/div[" + i + "]")).click();
                    Thread.sleep(2000);
                    System.out.println("公众号:" + name + "第" + i + "篇文章被点击");

                    //切换回native的context
                    driver.context("NATIVE_APP");
                    System.out.println("NATIVE_APP");
                    if (isElementExist(driver, By.id("h4"))) {
                        driver.findElement(By.id("h4")).click(); //返回对应公众号的文章列表.
                        System.out.println("关闭公众号文章,回到H5列表");
                    } else {
                        System.out.println("未能正常回退,请关注");
                    }

                }

            } else {
                System.out.println("公众号没有历史文章");
            }

        }
        //最后回到公众号列表,需要后退,切回native方式.
        driver.context("NATIVE_APP");
        System.out.println("NATIVE_APP");


    }


    //搜索一个公众号,并进入历史文章列表
    private boolean GotoMessageHistory(AndroidDriver driver, String name) throws Exception {

        Thread.sleep(2000);
        driver.findElement(By.xpath("//android.widget.TextView[@content-desc='搜索']")).click();
        Thread.sleep(2000);
        WebElement inputGZ = driver.findElement(By.xpath("//android.widget.EditText[@text='搜索']"));
        inputGZ.click();
        inputGZ.sendKeys(name);
        Thread.sleep(2000);

        //搜到了的处理方式
        if (isElementExist(driver, By.xpath("//android.widget.TextView[@text='" + name + "']"))) {
            driver.findElement(By.xpath("//android.widget.TextView[@text='" + name + "']")).click();
            Thread.sleep(2000);
            Thread.sleep(2000);
            driver.findElement(By.xpath("//android.widget.TextView[@content-desc='聊天信息']")).click();
            Thread.sleep(2000);
            driver.findElement(By.xpath("//android.widget.TextView[@text='查看历史消息']")).click();
            Thread.sleep(5000);  //页面加载时间太长
            return true;
        } else {
            System.out.println("未能找到公众号:"+name);
            return false;
        }

    }

    private AndroidDriver GetAndroidDriver() throws Exception {
        DesiredCapabilities capabilities = new DesiredCapabilities();
        capabilities.setCapability("platformVersion", "7.0");
        capabilities.setCapability("deviceName", "Android Emulator");
        capabilities.setCapability("platformName", "Android");
        capabilities.setCapability("appPackage", "com.tencent.mm");
        capabilities.setCapability("appActivity", ".ui.LauncherUI");
        capabilities.setCapability("unicodeKeyboard", "True");
        capabilities.setCapability("resetKeyboard", "True");
        capabilities.setCapability("recreateChromeDriverSessions", "True");

        //加入微信webwiew调试能力.
        ChromeOptions options2 = new ChromeOptions();
        options2.setExperimentalOption("androidProcess", "com.tencent.mm:tools");
        capabilities.setCapability(ChromeOptions.CAPABILITY, options2);
        return new AndroidDriver<WebElement>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
    }


    //回到list
    private void GoBackToList(AndroidDriver driver) throws Exception {


        while (isElementExist(driver, By.id("h4"))) {
            driver.findElement(By.id("h4")).click(); //碰上h4就不停返回
            Thread.sleep(2000);
        }

        if (isElementExist(driver, By.id("go"))) {
            driver.findElement(By.id("go")).click(); //再多试一遍
            Thread.sleep(2000);
        }

        if (isElementExist(driver, By.id("gw"))) {
            driver.findElement(By.id("gw")).click(); //再多试一遍
            Thread.sleep(2000);
        }
        System.out.println("已经回到搜索列表");

    }


    private boolean isElementExist(AndroidDriver driver, By locator) {
        try {
            driver.findElement(locator);
            return true;
        } catch (NoSuchElementException ex) {
            return false;
        }
    }


}
6816
185skytraveler 回复

代码封装的不错,但是一个疑问和一个问题
1、capabilities.setCapability("deviceName", "Android Emulator"); 在模拟器中运行,实际微信在模拟器中运行不了的吧
2、进入“查看历史消息” 查看context ,只有一个NATIVE_APP 没有看到有WEBVIEW_com.tencent.mm:tools,所以没有办法切换过去。是我用的微信版本不对?

15904
6816testerway 回复

是的,有个WEBVIEW_com.tencent.mm:tools识别错误的bug,思寒有一篇这个说明的帖子,你去查看吧

6816
15904YOYO9527 回复

我这边遇到的情况是:前几天试验都是有web view的,突然从今天下午开始,即使在h5页面,也看不到web view,用uiautomatorview查看h5页面,居然能识别h5页面的元素,感觉h5页面变成了原生android元素了,这样一来,反而不用切换到webview就能直接操作了,这个转变蛮好的,但是不知道什么决定了这个转变?由谁知道?

90a5a8

请教各位大侠,我测微信小程序的时候,切换webview报错

基本设置:
ChromeOptions options = new ChromeOptions();
options.setExperimentalOption("androidProcess", "com.tencent.mm:appbrand0");
capabilities.setCapability(ChromeOptions.CAPABILITY, options);

当代码执行到这里就报错了:
driver.context("WEBVIEW_com.tencent.mm:tools");

控制台日志:
org.openqa.selenium.WebDriverException: An unknown server-side error occurred while processing the command. Original error: session not created exception: please close '' and try again
(Driver info: chromedriver=2.24.417431 (9aea000394714d2fbb20850021f6204f2256b9cf),platform=Windows NT 6.1.7601 SP1 x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 4.98 seconds
Build info: version: '2.53.0', revision: '35ae25b', time: '2016-03-15 17:00:58'
System info: host: 'YK-DZ-4711702', ip: '172.168.16.110', os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.8.0_121'
Driver info: io.appium.java_client.android.AndroidDriver
Capabilities [{appPackage=com.tencent.mm, noReset=true, deviceName=05157df5a207d11f, fullReset=false, platform=LINUX, deviceUDID=05157df5a207d11f, desired={appPackage=com.tencent.mm, noReset=true, deviceName=05157df5a207d11f, fullReset=false, appActivity=.ui.LauncherUI, platformVersion=6.0.1, browserName=, fastReset=false, unicodeKeyboard=true, chromeOptions={args=[], extensions=[], androidProcess=com.tencent.mm:appbrand0}, udid=05157df5a207d11f, platformName=Android, resetKeyboard=true}, platformVersion=6.0.1, webStorageEnabled=false, takesScreenshot=true, browserName=, javascriptEnabled=true, unicodeKeyboard=true, udid=05157df5a207d11f, platformName=Android, deviceManufacturer=samsung, resetKeyboard=true, deviceScreenSize=1440x2560, networkConnectionEnabled=true, warnings={}, databaseEnabled=false, appActivity=.ui.LauncherUI, locationContextEnabled=false, deviceModel=SM-G9208, fastReset=false, chromeOptions={args=[], extensions=[], androidProcess=com.tencent.mm:appbrand0}}]
Session ID: a9c2ce80-0091-43d1-8c71-73ac8e955e02

appium日志:
[Chromedriver] Error: session not created exception: please close '' and try aga
in
(Driver info: chromedriver=2.24.417431 (9aea000394714d2fbb20850021f6204f2256b9
cf),platform=Windows NT 6.1.7601 SP1 x86_64)
at Chromedriver.callee$2$0$ (../../lib/chromedriver.js:176:15)
at tryCatch (C:\Users\Administrator\AppData\Roaming\npm\node_modules\appium\
node_modules\babel-runtime\regenerator\runtime.js:67:40)
at GeneratorFunctionPrototype.invoke as _invoke
at GeneratorFunctionPrototype.prototype.(anonymous function) as next
at GeneratorFunctionPrototype.invoke (C:\Users\Administrator\AppData\Roaming
\npm\node_modules\appium\node_modules\babel-runtime\regenerator\runtime.js:136:3
7)
Error: session not created exception: please close '' and try again
(Driver info: chromedriver=2.24.417431 (9aea000394714d2fbb20850021f6204f2256b9
cf),platform=Windows NT 6.1.7601 SP1 x86_64)
at Chromedriver.callee$2$0$ (../../lib/chromedriver.js:176:15)
at tryCatch (C:\Users\Administrator\AppData\Roaming\npm\node_modules\appium\
node_modules\babel-runtime\regenerator\runtime.js:67:40)
at GeneratorFunctionPrototype.invoke as _invoke
at GeneratorFunctionPrototype.prototype.(anonymous function) as next
at GeneratorFunctionPrototype.invoke (C:\Users\Administrator\AppData\Roaming
\npm\node_modules\appium\node_modules\babel-runtime\regenerator\runtime.js:136:3
7)
[MJSONWP] Encountered internal error running command: Error: session not created
exception: please close '' and try again
(Driver info: chromedriver=2.24.417431 (9aea000394714d2fbb20850021f6204f2256b9
cf),platform=Windows NT 6.1.7601 SP1 x86_64)
at Chromedriver.callee$2$0$ (../../lib/chromedriver.js:176:15)
at tryCatch (C:\Users\Administrator\AppData\Roaming\npm\node_modules\appium\
node_modules\babel-runtime\regenerator\runtime.js:67:40)
at GeneratorFunctionPrototype.invoke as _invoke
at GeneratorFunctionPrototype.prototype.(anonymous function) as next
at GeneratorFunctionPrototype.invoke (C:\Users\Administrator\AppData\Roaming
\npm\node_modules\appium\node_modules\babel-runtime\regenerator\runtime.js:136:3
7)
[HTTP] <-- POST /wd/hub/session/a9c2ce80-0091-43d1-8c71-73ac8e955e02/context 500
4980 ms - 357

请问是怎么回事呢?

96
4442happystone 回复

好像Contexts集合里面只有一个Native返回,并没有对应的WebView_com.tencent.mm:tools。同样还是得不到WebView里面的内容。

6816
32zhuxiongjian 回复

可以试下这样行不行:如果只有一个native,就可以停止运行脚本,保持H5页面一直处于显示状态,用uiautomatorviewer.bat 查看,可以定位到页面元素,这样就不用切换context,就可以直接findelementbyxpath("xxxx")操作了。

185
6816testerway 回复

1.插上真机就变成真机了,我是appium小白,机理不知道,猜测有个优先调用顺序。我微信在genymode里安装失败了,别的没试过。
2.只有微信历史列表是h5写的,并且需要操作它的元素,所以才切换,每次循环都切回来。我那个版本的代码有瑕疵,现在为了搞定各种异常,代码量已经翻了三四倍了,凑合着当例子看吧。
3.微信装在不同android机的同一个按钮竟然叫法不同。也是醉了。所以就算是要得到一个返回按钮的id,要这么写:

public String PickID(AndroidDriver driver){

if(isElementExist(driver, By.id("h4")))
return "h4";
if(isElementExist(driver, By.id("gw")))
return "gw";
if(isElementExist(driver, By.id("go")))
return "go";
if(isElementExist(driver, By.id("gg")))
return "gg";
return null;

}
4.写前端自动化的代码是非常不愉快的经历。
5.仍旧觉得前端自动化如不是实在绕不过去,别花太多精力。投入产出比太低了。

185
6816testerway 回复

不同版本,不同id登录好像都有细微差别。猜测能热更新,并有各种灰度。坑不小。

185

本周微信热更了新的X5,切换不好使了。chromedriver拿不到session了。具体见这个贴:https://testerhome.com/topics/8990

高手碰到过不? @seveniruby @chenhengjie123

96
6816testerway 回复

昨天改用Java也试了一下,同样只有一个Native。然后,采用最新1.6.5beta版本偶然发现直接可以录制到H5内容。今天重新尝试似乎又不行了。好奇怪,配置没有发生任何变化。
如何保持H5一直显示状态?暂时没发现对应的调用入口。Java or .net

185
32zhuxiongjian 回复

微信升了H5的内核。用chromedriver获取不了session了。

6816
32zhuxiongjian 回复

保持H5页面 一直显示,意思就是在只有一个Native时,把H5页面一直保持显示,关闭appium 服务端,启动uiautomatorviewer.bat ,查看被测试的android h5 页面元素,就能看到H5页面元素,再用appium 操作你想操作的元素,我这边是这样做的

F1f23c
185skytraveler 回复

想问一下微信更了新的X5,和微信的版本有关系么?

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