APPIUM Version: 1.6.3
JAVA Client: 5.0.0
JAVA: 1.8
UiAutomator2 Drvier: 0.2.6
//capabilities
capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.ANDROID_UIAUTOMATOR2);
//click the button to verify the toast message
driver.findElementByXPath("//*[contains(@text,'Button')]").click();
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[contains(@text, 'port')]")))
Toast.makeText(getBaseContext(), "Change port successfully", Toast.LENGTH_SHORT).show();
使用 uiautomator2 启动应用是成功的,点击也是成功的,但是尝试验证 Toast 消息时,没有成功过。错误信息如下:
org.openqa.selenium.TimeoutException: Expected condition failed: waiting for presence of element located by: By.xpath: //*contains(@text, 'port')
手机中有安装两个应用:
//同样的代码,定位符改成一个Button的定位符,是能找到的
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@text='Button']")));
源码打开后,这里的红色标记怎么解决啊,没有任何报错啊,编译也没有问题
@Test
public void toastVerificationTest() throws JSONException {
getUiDevice().waitForIdle();
scrollTo("Views"); // Due to 'Views' option not visible on small screen
waitForElement(By.accessibilityId("Views"), 10 * SECOND);
click(findElement(By.accessibilityId("Views")));
scrollTo("Popup Menu");
waitForElement(By.accessibilityId("Popup Menu"), 10 * SECOND);
click(findElement(By.accessibilityId("Popup Menu")));
waitForElement(By.accessibilityId("Make a Popup!"), 10 * SECOND);
click(findElement(By.accessibilityId("Make a Popup!")));
waitForElement(By.xpath(".//*[@text='Search']"), 10 * SECOND);
click(findElement(By.xpath(".//*[@text='Search']")));
waitForMilliSeconds(500);
element = findElement(By.xpath("//*[@text='Clicked popup menu item Search']"));
String toastMSG = getText(element);
assertEquals("Clicked popup menu item Search", toastMSG);
Logger.info("[AppiumUiAutomator2Server]", " findElement By.xpath: " + element);
assertTrue(By.xpath("//*[@text='Clicked popup menu item Search']") + "not found", isElementPresent(element));
click(findElement(By.accessibilityId("Make a Popup!")));
waitForElement(By.xpath(".//*[@text='Add']"), 10 * SECOND);
click(findElement(By.xpath(".//*[@text='Add']")));
waitForMilliSeconds(500);
element = findElement(By.xpath("//*[contains(@text,'Clicked popup menu item Add')]"));
Logger.info("[AppiumUiAutomator2Server]", " findElement By.xpath: " + element);
assertTrue(By.xpath("//*[@text='Clicked popup menu item Add']") + "not found", isElementPresent(element));
toastMSG = getText(element);
assertEquals("Clicked popup menu item Add", toastMSG);
click(findElement(By.accessibilityId("Make a Popup!")));
waitForElement(By.xpath(".//*[@text='Edit']"), 10 * SECOND);
click(findElement(By.xpath(".//*[@text='Edit']")));
waitForMilliSeconds(500);
element = findElement(By.xpath("//*[@text='Clicked popup menu item Edit']"));
Logger.info("[AppiumUiAutomator2Server]", " findElement By.xpath: " + element);
assertTrue(By.xpath("//*[@text='Clicked popup menu item Edit']") + "not found", isElementPresent(element));
toastMSG = getText(element);
assertEquals("Clicked popup menu item Edit", toastMSG);
click(findElement(By.xpath(".//*[@text='Share']")));
waitForMilliSeconds(1000);
element = findElement(By.xpath("//*[@text='Clicked popup menu item Share']"));
Logger.info("[AppiumUiAutomator2Server]", " findElement By.xpath: " + element);
assertTrue(By.xpath("//*[@text='Clicked popup menu item Share']") + "not found", isElementPresent(element));
toastMSG = getText(element);
assertEquals("Clicked popup menu item Share", toastMSG);
}
单元测试执行方法:
am instrument -w -e class io.appium.uiautomator2.unittest.test.HandlersTest#toastVerificationTest io.appium.uiautomator2.e2etest.test/android.support.test.runner.AndroidJUnitRunner
单元测试日志:
04-20 12:08:19.134 6055 6068 I appium : [AppiumUiAutomator2Server] Starting S
erver
04-20 12:08:19.379 6055 6068 I appium : [AppiumUiAutomator2Server] waiting fo
r app to launch
04-20 12:08:30.028 6055 6068 I appium : [AppiumUiAutomator2Server] findElemen
t By.xpath: {"sessionId":":sessionId","status":0,"value":{"ELEMENT":"f2e952ea-d5
0c-4b4b-a81e-c1244240c30d"}}
04-20 12:08:32.122 6055 6068 I appium : [AppiumUiAutomator2Server] findElemen
t By.xpath: {"sessionId":":sessionId","status":0,"value":{"ELEMENT":"4e141e0b-a5
3a-4e46-82d4-cec7cd748640"}}
04-20 12:08:34.646 6055 6068 I appium : [AppiumUiAutomator2Server] findElemen
t By.xpath: {"sessionId":":sessionId","status":0,"value":{"ELEMENT":"3a16e7f8-86
2d-453e-90be-d70eec2bb85b"}}
04-20 12:08:36.705 6055 6068 I appium : [AppiumUiAutomator2Server] findElemen
t By.xpath: {"sessionId":":sessionId","status":0,"value":{"ELEMENT":"9fc430ea-19
d5-44cd-b121-031275152d9b"}}
从日志来看,单元测试执行时,是有找到 toast 元素的,但是我在 eclipse 里面写测试用例的时候就是报没有找到,真是头疼
private class Listener extends Thread{
private long previousTime = currentTimeMillis();
public void run() {
while (true) {
AccessibilityEvent accessibilityEvent = null;
toastMessages = init();
//return true if the AccessibilityEvent type is NOTIFICATION type
UiAutomation.AccessibilityEventFilter eventFilter = new UiAutomation.AccessibilityEventFilter() {
@Override
public boolean accept(AccessibilityEvent event) {
return event.getEventType() == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED;
}
};
Runnable runnable = new Runnable() {
@Override
public void run() {
// Not performing any event.
}
};
try {
//wait for AccessibilityEvent filter
accessibilityEvent = UiAutomatorBridge.getInstance().getUiAutomation()
.executeAndWaitForEvent(runnable /*executable event*/, eventFilter /* event to filter*/, 500 /*time out in ms*/);
} catch (Exception ignore) {}
if (accessibilityEvent != null) {
toastMessages = accessibilityEvent.getText();
previousTime = currentTimeMillis();
Logger.info("toastMessages:" + toastMessages);
GetToastMessage.toastMessage = toastMessages.toString();// add by carl
}
if(stopLooping){
break;
}
}
}
引用 uiautomator2.0 server 的相关 jar,不要引 android.jar,json jar: json-20070829.jar
try {
Runtime.getRuntime().exec("adb forward tcp:"+ 8201 +" tcp:6790");
Thread.sleep(2000);
String sessionId = "";
//create session
sessionId = TestHelper.post("/wd/hub/session", new JSONObject().put("desiredCapabilities", new JSONObject()).toString());
System.out.println(sessionId);
if (sessionId.contains("sessionId")) {
sessionId = new JSONObject(sessionId).getString("sessionId");
System.out.println("sessionId:" + sessionId);
} else {
sessionId = "c04ada9b-38cf-4778-9168-12faf6747159";
}
// System.out.println(TestHelper.get("/wd/hub/session/" + sessionId + "/getPostMsg"));
// System.exit(1);
String elementId = "";
//find element: Make a Popup!
JSONObject element = new JSONObject("{\"strategy\":\"xpath\",\"selector\":\"//*[contains(@text,'Make a Popup!')]\",\"context\":\"\",\"multiple\":false}");
elementId = TestHelper.post("/wd/hub/session/" + sessionId + "/element", element.toString());
System.out.println("elementId:" + elementId);
elementId = new JSONObject(elementId).getJSONObject("value").getString("ELEMENT");
//click one element
JSONObject click = new JSONObject().put("elementId", elementId);
TestHelper.post("/wd/hub/session/" + sessionId + "/element/" + elementId + "/click", click.toString());
TestHelper.waitTimes(2000);
elementId = TestHelper.post("/wd/hub/session/" + sessionId + "/element", new JSONObject("{\"strategy\":\"xpath\",\"selector\":\"//*[@text='Search']\",\"context\":\"\",\"multiple\":false}").toString());
System.out.println("elementId:" + elementId);
elementId = new JSONObject(elementId).getJSONObject("value").getString("ELEMENT");
//click one element
TestHelper.post("/wd/hub/session/" + sessionId + "/element/" + elementId + "/click", new JSONObject().put("elementId", elementId).toString());
for (int i=0; i<2000; i++) {
elementId = TestHelper.post("/wd/hub/session/" + sessionId + "/element", new JSONObject("{\"strategy\":\"xpath\",\"selector\":\"//*[@text='Clicked popup menu item Search']\",\"context\":\"\",\"multiple\":false}").toString());
if (!elementId.contains("not")) {
System.out.println("i=" + i);
System.out.println("elementId:" + elementId);
elementId = new JSONObject(elementId).getJSONObject("value").getString("ELEMENT");
System.out.println(TestHelper.get("/wd/hub/session/" + sessionId + "/element/" + elementId+ "/attribute/text"));
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
这绝对是个坑,不过让我学习了 uiautomator2.0 drvier server 的原代码,和 uiautomator1.0 不一样,有点意思。
本人做的改动主要包含:
package io.appium.uiautomator2.handler;
import io.appium.uiautomator2.handler.request.SafeRequestHandler;
import io.appium.uiautomator2.http.AppiumResponse;
import io.appium.uiautomator2.http.IHttpRequest;
import io.appium.uiautomator2.server.WDStatus;
import io.appium.uiautomator2.utils.Logger;
public class GetToastMessage extends SafeRequestHandler {
public static String toastMessage = "defalut value is null";//值由GetToastMessage.toastMessage = toastMessages.toString();// add by carl这句更新
public GetToastMessage(String mappedUri) {
super(mappedUri);
}
@Override
public AppiumResponse safeHandle(IHttpRequest request) {
Logger.info("GetToastMessage command");
return new AppiumResponse(getSessionId(request), WDStatus.SUCCESS, toastMessage);
}
}