转载地址:https://www.cnblogs.com/nebie/articles/9483307.html
在一些混合应用中,有很多页面都是用的内嵌webview窗口来展示的,如我们APP的登录新设备验证页面(用的就是内嵌webview)。 
在用Appium 做此类页面的测试时,一般都是用 switch_to.context(参数是webview的context) 来进行窗口切换,但是需要注意一下几点:
1.在做窗口切换之前,首先要查看当前页面有多少个视窗,可以用以下方法:
WebView = driver.contexts print(WebView)
如果输出结果是:

那很遗憾,当前页面是不能直接使用 switch_to.context() 该函数的。
针对这种情况,一般的处理方法是让开发人员帮你在APP源码中加入:
WebView.setWebContentsDebuggingEnabled(true);
将Debug模式打开,然后重新打个包给你测试。
当然 自己有APP源码的话,你自己也可以修改源码打开Debug模式,加入:
WebView.setWebContentsDebuggingEnabled(true);
具体最好可以咨询下开发人员,然后重新打个包。
一般情况下,重新打包后,再使用1中的方法,可以打印出以下结果:

打印出如图所示结果,就表示你已经获取到了当前页面Webview 的 context ,接下来就是考虑如何去切换到Webview叻
2.切换Webview
想要操作Webview上页面内元素,首先需要切换环境(context),就好象selenium的切换iframe,切换handle思路是一样
切换环境,可以理解为切换窗口,从原生的NATIVE窗口切换到Webview窗口。可以用switch_to.context()方法来操作。注:括号内参数填写Webview的context
通过操作1,可以获取到的 “WebView” 是一个list对象,而在这里咱们要Webview页面的context,即获取该list对象的第二个参数WebView[1]。

获取到Webview页面的context之后,就可以进行切换:

切换完成后就可以对对应的元素进行操作了。
在操作完成后,想回到原本的NATIVE窗口,对原生部分的元素进行操作,就需要切换会原本的NATIVE窗口,即切换回WebView[0]:
driver.switch_to.context(WebView[0])
可以通过这种方式来实现回切,:

参考代码如下:
def get_web_view():
sleep(30)
print('开始切换')
#获取当前界面的所有窗口
WebView = driver.contexts
print(WebView)
View = WebView[1]
print(View)
#切换到Webview窗口
driver.switch_to.context(View)
#获取当前所处的环境窗口
New_View = driver.current_context
print('New_View is :',New_View)
#切换到NATIVE窗口
driver.switch_to.context(WebView[0])
#获取当前所处的环境窗口
New_View = driver.current_context
print('New_View is :',New_View)
3.使用switch_to.context()方法的时候出现报错。
Traceback (most recent call last):
File "E:AppiumFXJC_Appium_PythonStart_Appium.py", line 207, in <module>
get_web_view()
File "E:AppiumFXJC_Appium_PythonStart_Appium.py", line 109, in get_web_view
driver.switch_to.context('WEBVIEW_com.cs_credit_bank')
File "C:Python36libsite-packagesappiumwebdriverswitch_to.py", line 31, in context
self._driver.execute(MobileCommand.SWITCH_TO_CONTEXT, {'name': context_name})
File "C:Python36libsite-packagesseleniumwebdriver
emotewebdriver.py", line 320, in execute
self.error_handler.check_response(response)
File "C:Python36libsite-packagesappiumwebdrivererrorhandler.py", line 29, in check_response
raise wde
File "C:Python36libsite-packagesappiumwebdrivererrorhandler.py", line 24, in check_response
super(MobileErrorHandler, self).check_response(response)
File "C:Python36libsite-packagesseleniumwebdriver
emoteerrorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: An unknown server-side error occurred while processing the command. Original error: No Chromedriver found that can automate Chrome '39.0.0'. See https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/web/chromedriver.md for more details.
[Finished in 44.6s]
由上面的报错可以得知Appium在运行过程中找不到设备系统自带浏览器Webview版本所对应版本的Chromedriver。导致了报错。
这个时候我们可以通过将Appium目录下的Chromedriver文件更换成对应版本的Chromedriver就可以解决该问题了。
Chromedriver在Appium(1.6.3版本)下的目录“C:Program Files (x86)Appium esourcesapp ode_modulesappium ode_modulesappium-chromedriverchromedriverwin”
偶尔可能遇到更换后还是会继续报错的情况,我就遇到了这种情况,
我的解决方法是在脚本内Appium的driver配置内指定Chromedriver的路径,如下图:

即增加一个:
"chromedriverExecutable": "C:\Program Files (x86)\Appium\resources\app\node_modules\appium\node_modules\appium-chromedriver\chromedriver\win\chromedriver.exe",
然后再次运行原来的代码

可以运行成功啦~~~
大家如果有更好的解决方案,欢迎留言补充
desired_caps['chromedriverExecutable']=r'/usr/local/bin/chromedriver'
