準(zhǔn)備條件
(1)準(zhǔn)備一臺(tái)系統(tǒng)版本5.0以上的安卓手機(jī)或者安卓模擬器
(2)安裝一個(gè)輔助工具(pc端安裝):uc-devtool(UC開發(fā)者工具,不需要翻墻),uc-devtool安裝成功-》選擇設(shè)置->勾選 本地Devtools inpsector資源
參考文章:https://www.cnblogs.com/yyoba/p/9969394.html
uc-devtool作用: 用來幫助定位app內(nèi)嵌套的web頁面元素信息

(3)被測試的app->需要打開Web調(diào)試開關(guān)->如何打開開關(guān):
第一種方式:讓開發(fā)在app源代碼中加入一行代碼(開發(fā)知道在哪里添加)-》再重新打包給到測試
WebView.setWebContentDebuggingEnabled(true);
webview(其實(shí)就是手機(jī)自帶的系統(tǒng)應(yīng)用)
負(fù)責(zé)web頁面展示,解析,渲染web頁面,其實(shí)就是微型的瀏覽器(幫助第三方app來展示web頁面)
如下圖使用appium無法定位到具體的元素信息,選擇元素-》選中的是整塊區(qū)域

webview每個(gè)手機(jī)都有這個(gè)應(yīng)用,是以一個(gè)apk存在手機(jī)里面的,如何查看手機(jī)是否有webView?
手機(jī)-》設(shè)置->應(yīng)用->全部

點(diǎn)擊可以查看版本

問題: 可以使用文章text進(jìn)行定位,但是text會(huì)變,所以這里需要借助uc-devtool獲取元素定位信息
開發(fā)步驟
(1)uc開發(fā)者工具識(shí)別web頁面的元素信息
打開uc-devtool: 設(shè)置-》勾選
沒有打開app時(shí),如下圖沒有檢測到webView

進(jìn)入到app主頁(由于主頁不是一個(gè)web頁面,所以也沒有檢測到webView)

進(jìn)入到web頁面(檸檬社區(qū)),如下圖,檢測到了webView
下圖中的:com.lemon.lemonban是app的包名
127.0.0.1:62001 ->是當(dāng)前連接的設(shè)備名
74.0.3627.136是webView的版本

上圖點(diǎn)擊 inspect即可進(jìn)入deBug控制臺(tái)
如下圖(其實(shí)就是根f12效果差不多),這樣就可以使用web自動(dòng)化提供的xpath等方式進(jìn)行元素定位了

(2)開發(fā)腳本:
原生和web面需要切換context才能進(jìn)行元素定位。
Context是在編寫Android程序經(jīng)常使用到的對(duì)象,意思為上下文對(duì)象。原生和網(wǎng)頁屬于不同的context
@Test
public void test() throws InterruptedException {
//1.主頁點(diǎn)擊 檸檬社區(qū)
androidDriver.findElementByAndroidUIAutomator("new UiSelector().text(\"檸檬社區(qū)\")").click();
//2.等待web頁面加載完成
//這里不能使用隱式等待(不會(huì)生效)->因?yàn)椋哼@里不是找元素,而是進(jìn)行context切換,所以不會(huì)生效,只能用硬性等待
Thread.sleep(8000);
//3.獲取到當(dāng)前狀態(tài)所有的context
Set contextHandles = androidDriver.getContextHandles();
//打印出來看看-》打印結(jié)果:[NATIVE_APP,WEBVIEW_com.lemon.lemonban]
System.out.println(contextHandles);
//4.切換context-》根據(jù)web頁面對(duì)應(yīng)的context名字進(jìn)行切換
androidDriver.context("WEBVIEW_com.lemon.lemonban");
Thread.sleep(2000);
//5.web頁面元素定位
androidDriver.findElement(By.xpath("http://a[@title=\"App 抓包提示網(wǎng)絡(luò)異常怎么破?\"]")).click();
}
執(zhí)行上面代碼。如果報(bào)錯(cuò),請(qǐng)看下面的注意(5)
注意
(1) 原生頁面對(duì)應(yīng)的context->是NATIVE_APP
不管你是主頁還是登錄頁,只要是原生的頁面,對(duì)應(yīng)的context就是NATIVE_APP
(2)Web頁面對(duì)應(yīng)的context->是 WEBVIEW_com.lemon.lemonban
(3)打開app之后默認(rèn)是在原生的context中,所以如果要定位web頁面中的元素,需要切換context
(4)context切換之后,對(duì)web頁面元素進(jìn)行元素定位,為什么依然使用androidDriver,而不是( ie,firefox,chrome對(duì)應(yīng)的driver呢)-->這是因?yàn)椋篈ppium自帶chromedriver,內(nèi)部會(huì)進(jìn)行driver驅(qū)動(dòng)的替換,會(huì)把原來的androidDriver替換成chromedriver->為什么不是 IE,firrfox的driver呢,因?yàn)榘沧肯到y(tǒng)是chrome開發(fā)的,webView也是chrome開發(fā)的,所以自動(dòng)替換的就是chromeDriver
(5)webView和chromedriver版本不對(duì)應(yīng)-》上面代碼執(zhí)行console會(huì)報(bào)下面錯(cuò)誤
io.appium.java_client.NoSuchContextException: An unknown server-side error occurred while processing the command. Original error: No Chromedriver found that can automate Chrome '74.0.3729'. See https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/web/chromedriver.md for more details.
Build info: version: '3.12.0', revision: '7c6e0b3', time: '2018-05-08T14:04:26.12Z'
appium報(bào)錯(cuò)日志如下:

根據(jù)報(bào)錯(cuò)信息可以知道:webView和chromedriver版本不匹配導(dǎo)致的
解決辦法:
(1)找到appium自帶的chromeview安裝路徑:
查看版本:

(2)模擬器查看系統(tǒng)自帶的webview版本:
手機(jī)設(shè)置-》應(yīng)用-》全部

(3)查看版本對(duì)照表
https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/web/chromedriver.md

appium自帶的chromedriver版本是:75 ,模擬器自帶的webView版本是74
參考版本對(duì)照表:webview71對(duì)應(yīng)chromedriver是2.46 ,沒有webview74版本,不過我們這里先下載2.46的試試看(下載完成后,將原來的chromedriver覆蓋更新即可):結(jié)果發(fā)現(xiàn)是還是報(bào)湊
ChromeDriver 2.39 and newer require adb version 1.0.38 or newer. Run 'adb version' in your terminal of the host device to find your version of adb.
上面的報(bào)錯(cuò)信息說的是:
ChromeDriver 2.39及更高版本需要adb 1.0.38或更高版本。在主機(jī)設(shè)備的終端中運(yùn)行“adb version”以查找adb的版本。
下圖發(fā)現(xiàn)我的adb版本太低【1.0.36】【這里的adb用的是模擬器中的adb,因?yàn)橹皊dk 自己的adb和模擬器中的adb版本不對(duì)應(yīng)導(dǎo)致adb connect連接失敗-》解決辦法:將sdk中的adb替換成模擬器中的adb】

現(xiàn)在需要怎么解決呢?-》升級(jí)adb版本:將模擬器中adb換成sdk中的adb,sdk還用自己的adb

adb替換ok,需要重啟adb,重啟命令:adb kill-server,重啟完adb后,再輸入adb devices ,adb就會(huì)自動(dòng)起來
再重新執(zhí)行代碼:發(fā)現(xiàn)context切換成功,下面代碼可以定位到元素。
androidDriver.findElement(By.xpath("http://a[@title=\"App 抓包提示網(wǎng)絡(luò)異常怎么破?\"]")).click();
注意:這里為什么不是對(duì)webview進(jìn)行升級(jí)而是替換chromeDriver呢?
因?yàn)椋菏謾C(jī)自帶的webview升級(jí)很麻煩
(6)當(dāng)回到原生頁面進(jìn)行測試時(shí),需要將context切換回來
@Test
public void test() throws InterruptedException {
// 1.主頁點(diǎn)擊 檸檬社區(qū)
androidDriver.findElementByAndroidUIAutomator("new UiSelector().text(\"檸檬社區(qū)\")").click();
// 2.等待web頁面加載完成
// 這里不能使用隱式等待(不會(huì)生效)->因?yàn)椋哼@里不是找元素,而是進(jìn)行context切換,所以不會(huì)生效,只能用硬性等待
Thread.sleep(8000);
// 3.獲取到當(dāng)前狀態(tài)所有的context
Set contextHandles = androidDriver.getContextHandles();
// 打印出來看看-》打印結(jié)果:[NATIVE_APP,WEBVIEW_com.lemon.lemonban]
System.out.println(contextHandles);
// 4.切換context-》根據(jù)web頁面對(duì)應(yīng)的context名字進(jìn)行切換
androidDriver.context("WEBVIEW_com.lemon.lemonban");
Thread.sleep(2000);
// 5.web頁面元素定位
androidDriver.findElement(By.xpath("http://a[@title=\"App 抓包提示網(wǎng)絡(luò)異常怎么破?\"]")).click();
// 6.回到主頁
// 6.1當(dāng)回到原生頁面中進(jìn)行元素定位時(shí),context需要切換回來(由于左上角x是在原生頁面里面,需要需要切換,否則定位不到)
androidDriver.context("NATIVE_APP");
// 6.2定位到x按鈕->退出
androidDriver.findElement(By.className("android.widget.ImageButton")).click();
// 6.3定位確定按鈕-》確定 退出到主頁
androidDriver.findElement(By.id("com.lemon.lemonban:id/tv_sure")).click();
}
如果context不切換,就會(huì)報(bào)如下錯(cuò)誤:
org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"class name","selector":"android.widget.ImageButton"}
app中使用瀏覽器打開web頁面,代碼怎么寫?
(1)如果使用的瀏覽器是手機(jī)系統(tǒng)自帶的apk
那么如何獲取瀏覽器apk的包名和啟動(dòng)入口呢?-》解決辦法:將手機(jī)中的apk拉取到pc端


(2)再使用aapt解析apk的包名和啟動(dòng)入口
(3) 地址欄是原生的 用Androiddriver sendkeys方法 再輸入enter鍵操作
androidDriver.get(url)這種是不可以的