基本介绍
WebView 控件在 Appium 中的抽象
-
Native 层面支持
-
uiautomator 解析 WebView 中的内容并映射为原生控件
-
getPageSource 为 DOM 结构可发现 WebView 组件和控件
-
-
切换为 WebView 上下文
-
切换后才是正规的 Web
-
getPageSource 为 HTML
-
可以使用 CSS 定位等
-
Hybrid 测试流程
• 首先进去带有 WebView 的页面
• 使用 Contexts API 寻找 WebView
• 使用 Context 切换到 WebView
• 使用 CSS 等 Web 定位方式
• 使用 Context 重回 Native
- 真机进行 WebView 测试
- 低于 API 27的模拟器默认支持
实操
- 打开有webview的界面,在PC chrome浏览器输入 chrome://inspect/#devices
需要翻墙
通过Chrome的devtools可以调试手机的网页,但是要翻墙
图中2处是设备名称,图中3处是设备的webview版本,图中3处是html页面点击 inspect查看布局元素
点击菜单栏的箭头, 滑到界面上,可以锁定输入栏的标签元素,可以根据id,type,class,name单个或者组合形式定位元素。
编写用例
class WebViewPage(BasePage):
def search_baidu(self):
print(self.driver.contexts)#打印driver的上下文,基本是这样的 ['NATIVE_APP', 'WEBVIEW_com.mintegral.sdk.demo']
sleep(3)
self.driver.switch_to.context(self.driver.contexts[1])# 切换到webview上下文
print(self.driver.current_context)#打印当前上下文
self.driver.find_element_by_css_selector('input').send_keys('庄达菲')#通过selector为input定位百度输入栏,输入要搜索的内容
sleep(2)
self.driver.find_element_by_css_selector("button#index-bn[type='submit']").click()#通过selector/id/type组合定位‘百度一下’的按钮,并点击
sleep(2)
self.driver.switch_to.context(self.driver.contexts[0])#切换回native上下文
print(self.driver.current_context)
sleep(20)
跑起来可能失败,查看下面常见问题。
另外补充一些关于css selector定位元素的姿势:
一:单一属性定位
1:type selector
driver.find_element_by_css_selector(‘input’)
2:id 定位
driver.find_element_by_css_selector(’#index-kw’)
3:class 定位
driver.find_element_by_css_selector(’.se-input .adjust-input’)
4:其他属性定位
driver.find_element_by_css_selector("[name=‘word’]")
driver.find_element_by_css_selector("[type=‘search’]")
二:组合属性定位
1:id组合属性定位
driver.find_element_by_css_selector(“input#index-kw”)
2:class组合属性定位
driver.find_element_by_css_selector(“input.se-input”)
3:其他属性组合定位
driver.find_element_by_css_selector("input[name=‘word’]")
4:仅有属性名,没有值也可以
driver.find_element_by_css_selector(“input[name]”)
5:两个其他属性组合定位
driver.find_element_by_css_selector("[name=‘word’][autocomplete=‘off’]")
常见问题
1 chromedriver not found
2 chrome version must be >=
3 chrome not reachable
4 selenium.common.exceptions.WebDriverException: Message: An unknown server-side error occurred while processing the command. Original error: No Chromedriver found that can automate Chrome ‘37.0.0’. You could also try to enable automated chromedrivers download server feature. See https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/web/chromedriver.md for more details
上述四个问题,原因是你本地的chromedriver不可用。 根据前面截图里的devtools确定你的设备webview版本, 然后根据 https://raw.githubusercontent.com/appium/appium-chromedriver/master/config/mapping.json (key为chromedriver版本,value为webview版本)里找到你的webview版本应该使用的chromedriver版本。比如我的webview是78.0.3904.108,找不到该版本 ,那就找相近的 低于78.0.3904.108的78.0.3904.105版本,对应的chromedriver版本也是78.0.3904.105. 如下图所示:
确定要用的chromedriver版本后,去https://chromedriver.storage.googleapis.com/index.html (翻墙)或 https://npm.taobao.org/mirrors/chromedriver(淘宝镜像,不用翻墙)去下载chromedriver。 下载下来的是zip包,解压到你保存的目录,我的是/Users/damon/temp/chromedriver/78.0.3904.105/,该路径需要用到。
必须要解压,需要chromedriver可执行程序,否则会报WebDriverException: Message: An unknown server-side error occurred while processing the command. Original error: Process didn’t end after 10000ms (cmd: ‘/Users/damon/temp/chromedriver/78.0.3904.105/chromedriver_mac64.zip --url-base=wd/hub --port=8000 --adb-port=5037 --verbose’)
在appium driver初始化的地方加入caps
caps["showChromedriverLog"] = True
# chromedriver可执行程序的完整路径,appium根据该路径去使用chromedriver
caps['chromedriverExecutable'] = '/Users/damon/temp/chromedriver/78.0.3904.105/chromedriver'
5 WebDriverException(‘An unknown server-side error occurred while processing the command. Original error: There must be at least one Chromedriver executable available for use if the current Chrome version cannot be determined’)
本地没有找到可用的chromedriver,如果已经下载好了可用的chromedriver,需要配置下capability
chromedriverExecutable
,让appium能够找到。
6 InvalidArgumentException: Message: invalid argument: invalid locator
E (Session info: chrome=78.0.3904.108)
使用错了find_element_by_id。 建议使用
find_element_by_css_selector
通过css定位符定位控件元素。