opeatx 的 uiautomator2 可以实现在不连接数据线的环境下实现 UI 自动化,但是好像对 app 内的 webview 还没有很好得支持。
在论坛里搜相关的帖子发现@codeskyblue 在 atx 项目中已经实现了对 Android Webview 的支持
https://testerhome.com/topics/7232
看了看源码,发现用 uiautomator2 应该也是可以来操作 Webview 的
把实践的步骤写出来供大家参考:
uiautomator2 的安装及配置就不介绍了可以看之前论坛的帖子:
https://testerhome.com/topics/12521
https://testerhome.com/topics/11357
下面是具体的操作步骤
通过访问 chrome://inspect 安卓手机连接到电脑,可以查到当前 App 使用的 WebView 版本
从https://npm.taobao.org/mirrors/chromedriver
下载对应版本的 chromedriver 到本地,并添加到 PATH 中。
不同版本对应的 chromedriver 的版本可以在这里看到
https://npm.taobao.org/mirrors/chromedriver/2.37/notes.txt
下载正确的 chromedriver 版本就好了
手动安装额外的依赖库
pip install selenium
从https://github.com/NetEaseGame/ATX/blob/master/atx/ext/chromedriver.py
将代码复制到本地,也保存为chromedriver.py
,并对相关的代码进行修改
只要改这 5 行就可以了
用 macac 的 demo 演示的 apk 来测试一下看看,apk 下载地址:
https://npmcdn.com/android-app-bootstrap@latest/android_app_bootstrap/build/outputs/apk/android_app_bootstrap-debug.apk
在手机有线连接电脑的情况下,执行以下代码
import time
import uiautomator2 as u2
from chromedriver import ChromeDriver #将chromedriver.py和该脚本放在同一目录下
d = u2.connect()
d.app_start('com.github.android_app_bootstrap')
d(text='Login').click()
d(text='Baidu').click()
time.sleep(3)
driver = ChromeDriver(d).driver()
driver.find_element_by_id('index-kw').click()
driver.find_element_by_id('index-kw').send_keys('Python')
driver.find_element_by_id('index-bn').click()
driver.quit()
在手机连接在电脑的情况下,上述的代码可以直接跑成功了,说明使用 uiautomator2 也是可以对 Webview 实现操作的嘛。
不过有个问题,selenium 调用的时候是要获取 devices 的。连线的时候d.serial
可以直接获取到,但是数据线断了的时候怎么办呢?
这时候,chromedriver.py
中增加的devices_ip
这个就有用了,具体操作看下面。
由于 chromedriver.py 的使用需要用到 adb 要想在手机不连接电脑的情况下,实现操作还需要对手机进行操作
操作步骤:
adb devices
看是否能列出该设备)。
adb tcpip 5555
uiautomator2 init
之后安装的小汽车可以看到手机的 ip
adb connect <device-ip-address>
这里的 <device-ip-address>
就是上一步中找到的设备 IP 地址。
adb devices
如果能看到
<device-ip-address>:5555 device
说明连接成功。
如果连接不了,请确认 Android 设备与电脑是连接到了同一个 WiFi,然后再次执行 adb connect <device-ip-address>
那一步;
如果还是不行的话,通过 adb kill-server
重新启动 adb 然后从头再来一次试试。
确保在拔掉数据线后 执行adb devices
能够发现设备<device-ip-address>:5555 device
修改代码,再次执行看看
import time
import uiautomator2 as u2
from chromedriver import ChromeDriver #将chromedriver.py和该脚本放在同一目录下
d = u2.connect('10.33.103.214') #手机的ip 为10.33.103.214
d.app_start('com.github.android_app_bootstrap')
d(text='Login').click()
d(text='Baidu').click()
time.sleep(3)
driver = ChromeDriver(d).driver(device_ip='10.33.103.214:5555') #增加device_ip参数
driver.find_element_by_id('index-kw').click()
driver.find_element_by_id('index-kw').send_keys('Python')
driver.find_element_by_id('index-bn').click()
driver.quit()
后面步骤的adb tcpip
可以代码层面实现下,只是懒得去想了 先分享出来再说。。。。。
要自动化 webview,需要把被测 APP 的 webview 的 setWebContentsDebuggingEnabled 打开,需要开发人员支持,或者跑在模拟器上
不错不错
请问运行这个 demo 的脚本时,总是在 driver = ChromeDriver(d).driver() 这一行报错何解?但设备一直在线的
后来我改用无线连接,然后报这个错,
请问你那用的是哪个版本的 chromedirver,我用了几个版本都不行
看看你手机 chrome://inspect 对应的 webview 的版本 然后去下载对应的就好了
我更新下帖子
这个是不是说明我的 chrome 版本是 v55,然后我是用了
2.25-2.28 四个版本的 chromedriver 版本,均是同一个问题
提示我的设备不在线,但我的设备一直在线的,而且都是在那 driver = ChromeDriver(d).driver() 这一行时才报错,在这上面的代码都运行了,在手机端也是可以看到的
重新 init 了,adb devices 结果也是对的,但就是一直报这个错,我如果只是运行 u2 跑纯 native 的 app 是没有问题,另外我的手机虽然跑 appium,但我把 appium 相关的都停止了,也是没用。。。。
遇到了和 ancining 同样的问题,用同样的 chromedriver 版本 appium 切换 webview 都成功了,但是 u2 还是不行。而且把上面对应关系中的几个 chromedriver 版本都试过了,都是报同样的问题,怎么破呢。
您好,请问这是什么原因呢?
Java 可以使用吗?
Traceback (most recent call last):
File "C:/Users/Admin/Desktop/python-鱼/8.9/qu_tou_tiao.py", line 20, in
driver = ChromeDriver(d).driver(device_ip='192.168.0.20')
File "C:\Users\Admin\Desktop\python-鱼\8.9\chromedriver.py", line 58, in driver
dr = webdriver.Remote('http://localhost:%d' % self.port, capabilities)
File "D:\Python3.5.4\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 154, in __init_
self.start_session(desired_capabilities, browser_profile)
File "D:\Python3.5.4\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 243, in start_session
response = self.execute(Command.NEW_SESSION, parameters)
File "D:\Python3.5.4\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 312, in execute
self.error_handler.check_response(response)
File "D:\Python3.5.4\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 237, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: unknown error: Device 192.168.0.20 is not online
(Driver info: chromedriver=2.31.488763 (092de99f48a300323ecf8c2a4e2e7cab51de5ba8),platform=Windows NT 10.0.17134 x86_64)
谁解决了, 求教, 加 qq837497936 有偿
Traceback (most recent call last):
File "C:/Users/Administrator/PycharmProjects/ATX/WebView.py", line 25, in <module>
main()
File "C:/Users/Administrator/PycharmProjects/ATX/WebView.py", line 17, in main
driver = ChromeDriver(d).driver()
File "D:\Anaconda3\lib\site-packages\atx\ext\chromedriver.py", line 59, in driver
dr = webdriver.Remote('http://localhost:%d' % self._port, capabilities)
File "D:\Anaconda3\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 156, in __init__
self.start_session(capabilities, browser_profile)
File "D:\Anaconda3\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 251, in start_session
response = self.execute(Command.NEW_SESSION, parameters)
File "D:\Anaconda3\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 320, in execute
self.error_handler.check_response(response)
File "D:\Anaconda3\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: unknown error: unable to discover open pages
(Driver info: chromedriver=2.29.461591 (62ebf098771772160f391d75e589dc567915b233),platform=Windows NT 10.0.17134 x86_64)
实例化 driver 的时候报错
app = self._d.current_app()
capabilities = {
'chromeOptions': {
'androidDeviceSerial': device_ip or self._d.serial,
'androidPackage': package or app['package'],
'androidUseRunningApp': attach,
'androidProcess': process or app['package'],
'androidActivity': activity or app['activity'],
}
}
楼主有用 atx 测小程序的实践吗? 我主要卡在 原生和 webview 切换的部分
driver = ChromeDriver(d).driver(device_ip = "30.7.80.246:5555"), driver() 里没加 device_ip, 还是走的 serial
有进展吗,可以切过去吗,我试了一下,会报错 selenium.common.exceptions.WebDriverException: Message: chrome not reachable
楼主,操作 webview 你除了用这个 bootstrap,还有用过别的 app 吗?发现换了别的 debug 版本 app 根本就不行呀,定位了 bootstrap 里面的元素,发现都是原生的,虽然不知道是什么情况,感觉楼主的这个方法根本就实现不了 webview 的操作
操作 webview 其实就是调用 selenium 来实现的 ,webview 里操作用的都是 selenium 封装的方法
可能你 Chromedriver 启动配置有问题吧
chromedriver 启动配置就是用的楼主上面提到的那 5 行代码,跑 bootstrap 完全没问题,别的 app 就不行了,完全没有头绪,报错跟 21 楼一样 unable to discover open pages,所以才问楼主有试过别的 app 吗,别只能跑 bootstrap,网上资料又太少了
不是,我自己公司的 app,也是在 app 里面打开百度,然而并不能像在 bootstrap 里面那样操作,用 appium 是可以的,排除了是 app 的问题,然后就不知道是哪里出了问题
没在别的 APP 试过,也许是 chromedriver 版本的问题 。好久之前写的东西 我都忘记怎么操作了
请问,这个需要怎么解决?
删掉就报这个错了
你的 chromedriver.py 文件没改好... def 那边没加上 device-ip 吧
Traceback (most recent call last):
File "D:\Programs\Python\Python35\lib\site-packages\urllib3\connection.py", line 171, in _new_conn
(self._dns_host, self.port), self.timeout, **extra_kw)
File "D:\Programs\Python\Python35\lib\site-packages\urllib3\util\connection.py", line 79, in create_connection
raise err
File "D:\Programs\Python\Python35\lib\site-packages\urllib3\util\connection.py", line 69, in create_connection
sock.connect(sa)
ConnectionRefusedError: [WinError 10061] 由于目标计算机积极拒绝,无法连接。
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "D:\Programs\Python\Python35\lib\site-packages\urllib3\connectionpool.py", line 600, in urlopen
chunked=chunked)
File "D:\Programs\Python\Python35\lib\site-packages\urllib3\connectionpool.py", line 354, in _make_request
conn.request(method, url, **httplib_request_kw)
File "D:\Programs\Python\Python35\lib\http\client.py", line 1107, in request
self._send_request(method, url, body, headers)
File "D:\Programs\Python\Python35\lib\http\client.py", line 1152, in _send_request
self.endheaders(body)
File "D:\Programs\Python\Python35\lib\http\client.py", line 1103, in endheaders
self._send_output(message_body)
File "D:\Programs\Python\Python35\lib\http\client.py", line 934, in _send_output
self.send(msg)
File "D:\Programs\Python\Python35\lib\http\client.py", line 877, in send
self.connect()
File "D:\Programs\Python\Python35\lib\site-packages\urllib3\connection.py", line 196, in connect
conn = self._new_conn()
File "D:\Programs\Python\Python35\lib\site-packages\urllib3\connection.py", line 180, in _new_conn
self, "Failed to establish a new connection: %s" % e)
urllib3.exceptions.NewConnectionError: : Failed to establish a new connection: [WinError 10061] 由于目标计算机积极拒绝,无法连接。
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "E:/PycharmProjects/mommonNewH5/LYnewH5/testCase/testMainTransfer.py", line 22, in setUp
self.driver = ChromeDriver(self.d).driver()
File "..\chromedriver.py", line 59, in driver
dr = webdriver.Remote('http://localhost:%d' % self.port, capabilities)
File "D:\Programs\Python\Python35\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 156, in __init_
self.start_session(capabilities, browser_profile)
File "D:\Programs\Python\Python35\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 251, in start_session
response = self.execute(Command.NEW_SESSION, parameters)
File "D:\Programs\Python\Python35\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 318, in execute
response = self.command_executor.execute(driver_command, params)
File "D:\Programs\Python\Python35\lib\site-packages\selenium\webdriver\remote\remote_connection.py", line 375, in execute
return self._request(command_info[0], url, body=data)
File "D:\Programs\Python\Python35\lib\site-packages\selenium\webdriver\remote\remote_connection.py", line 402, in _request
resp = http.request(method, url, body=body, headers=headers)
File "D:\Programs\Python\Python35\lib\site-packages\urllib3\request.py", line 72, in request
**urlopen_kw)
File "D:\Programs\Python\Python35\lib\site-packages\urllib3\request.py", line 150, in request_encode_body
return self.urlopen(method, url, **extra_kw)
File "D:\Programs\Python\Python35\lib\site-packages\urllib3\poolmanager.py", line 322, in urlopen
response = conn.urlopen(method, u.request_uri, **kw)
File "D:\Programs\Python\Python35\lib\site-packages\urllib3\connectionpool.py", line 667, in urlopen
**response_kw)
File "D:\Programs\Python\Python35\lib\site-packages\urllib3\connectionpool.py", line 667, in urlopen
**response_kw)
File "D:\Programs\Python\Python35\lib\site-packages\urllib3\connectionpool.py", line 667, in urlopen
**response_kw)
File "D:\Programs\Python\Python35\lib\site-packages\urllib3\connectionpool.py", line 638, in urlopen
_stacktrace=sys.exc_info()[2])
File "D:\Programs\Python\Python35\lib\site-packages\urllib3\util\retry.py", line 398, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='localhost', port=9515): Max retries exceeded with url: /session (Caused by NewConnectionError(': Failed to establish a new connection: [WinError 10061] 由于目标计算机积极拒绝,无法连接。',))
这是什么情况?好像执行到 self.driver = ChromeDriver(self.d).driver() 就报错了
你被测的 app 是调用 Android 自带的 webview 还是直接内置了腾讯的 x5 之类?
由于目标计算机积极拒绝,无法连接。
这个是因为 chromedriver.exe 路径不对的问题,修改一下 chromedriver.py 中的路径,我也是刚刚弄好的 F:\chromedriver.exe,填写自己的 chromedriver.exe 路径
def _launch_webdriver(self):
print("start chromedriver instance")
p = subprocess.Popen(['F:\chromedriver.exe', '--port=' + str(self._port)])
通过这个 chromedriver.py,无法实现 UC 的 webview。提示的错误是:selenium.common.exceptions.WebDriverException: Message: unknown error: Failed to get sockets matching:
通过 inspect 查到 UC 的版本是
WebView in com.UCMobile.dev (57.0.2987.108)
但是在运行,刚才的代码时,显示的是 (Driver info: chromedriver=71.0.3578.80 (2ac50e7249fbd55e6f517a28131605c9fb9fe897),platform=Mac OS X 10.14.2 x86_64)
是不是 ATX uiautomator2 实现 UC webview 是采用其他的方法呢?
请问,webview 切换后,唤起的页面是一片空白的是怎么回事呀?地址只是一个 data。
请教一下,为什么按照您的提示,连上了 chromedriver,也打开了一个空白页面 ,但是什么都没有显示, chrome://inspect/#devices 里面倒是有显示 webview 的内容
请教下 我运行例子里面的代码,启动的怎么是 PC 端的 chrome 呢?
if name == 'main':
import uiautomator2 as u2
import time
d = u2.connect()
d.app_stop('com.github.android_app_bootstrap')
d.app_start('com.github.android_app_bootstrap')
d(text='Login').click()
d(text='Baidu').click()
time.sleep(3)
driver = ChromeDriver(d).driver()
driver.find_element_by_id('index-kw').click()
driver.find_element_by_id('index-kw').send_keys('Python')
driver.find_element_by_id('index-bn').click()
driver.quit()
uiautomator2, 拉起 ChromeDriver 报错,是否是 Chrome 兼容问题
[1645163734.564][SEVERE]: bind() returned an error: ͨ��ÿ�����ֵ�ַ(Э��/�����ַ/�˿�)ֻ����ʹ��һ�Ρ� (0x2740)
Starting ChromeDriver 74.0.3729.6 (255758eccf3d244491b8a1317aa76e1ce10d57e9-refs/branch-heads/3729@{#29}) on port 9515
Only local connections are allowed.
Please protect ports used by ChromeDriver and related test frameworks to prevent access by malicious code.
IPv6 port not available. Exiting...
[1645163734.596][SEVERE]: bind() returned an error: ͨ��ÿ�����ֵ�ַ(Э��/�����ַ/�˿�)ֻ����ʹ��һ�Ρ� (0x2740)
Traceback (most recent call last):
File "D:\Program Files\Python38\lib\site-packages\atx\ext\chromedriver.py", line 70, in driver
dr = webdriver.Remote('http://localhost:%d' % self.port, capabilities,options)
File "D:\Program Files\Python38\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 268, in __init_
self.start_session(capabilities, browser_profile)
File "D:\Program Files\Python38\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 355, in start_session
capabilities.update({'firefox_profile': browser_profile.encoded})
AttributeError: 'Options' object has no attribute 'encoded'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "E:/APP/SmartMonkeyTest/uitest/android_uiparser_uiautomator.py", line 194, in
wd = ChromeDriver(d).driver()
File "D:\Program Files\Python38\lib\site-packages\atx\ext\chromedriver.py", line 77, in driver
dr = webdriver.Remote('http://localhost:%d' % self.port, capabilities)
File "D:\Program Files\Python38\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 268, in __init_
self.start_session(capabilities, browser_profile)
File "D:\Program Files\Python38\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 359, in start_session
response = self.execute(Command.NEW_SESSION, parameters)
File "D:\Program Files\Python38\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 424, in execute
self.error_handler.check_response(response)
File "D:\Program Files\Python38\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 247, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: unknown error: cannot find Chrome binary
d = uiautomator2.connect (getIp ()) # wifi 连接。
connect 的时候,要指定设备 id,或连接与电脑一致的 wifi