Appium Java Client从4.1.0版本开始引入了event firing(引发事件),处理方式和`org.openqa.selenium.support.events.EventFiringWebDriver` selenium的这个类有点类似,也绑定了 一些Spring框架里的东西:(https://projects.spring.io/spring-framework/) with [AspectJ](https://en.wikipedia.org/wiki/AspectJ).
目的:
为了帮助用户更好的组织事件日志也方便用户和标准或者其他的日志框架集成。
API
API的设计目的是允许用户选择性的监听事件(例如:搜索事件、导航事件、异常处理等),包括以下接口
- `io.appium.java_client.events.api.Listener` 基本的接口
- `io.appium.java_client.events.api.general.AlertEventListener` 监听弹窗事件
- `io.appium.java_client.events.api.general.ElementEventListener` 监听与控件相关的一些操作(如:点击、发送文本)
- `io.appium.java_client.events.api.general.JavaScriptEventListener` 用来监听JavaScript的执行
- `io.appium.java_client.events.api.general.ListensToException` 用来监听异常的抛出
- `io.appium.java_client.events.api.general.NavigationEventListener`用来监听导航事件
- `io.appium.java_client.events.api.general.SearchingEventListener`用来监听搜索事件
- `io.appium.java_client.events.api.general.WindowEventListener`用来监听窗口操作事件
- `io.appium.java_client.events.api.mobile.ContextEventListener`用来监听上下文切换事件(如:Native_APP、Webview_APP)
- `io.appium.java_client.events.api.mobile.RotationEventListener` 监听屏幕旋转
- `io.appium.java_client.events.api.general.AppiumWebDriverEventListener` 添加是为了提供实现 `org.openqa.selenium.support.events.WebDriverEventListener`. 的兼容,也扩充一些上面的接口
怎么用
1、创建监听类,并实现相关的事件监听接口(如:控件相关的监听类需要实现ElementEventListener)
import io.appium.java_client.events.api.general.ElementEventListener;
public class ElementListener implements ElementEventListener {
...
}
import io.appium.java_client.events.api.general.AlertEventListener;
public class AlertListener implements AlertEventListener {
...
}
我这里创建了2个监听器:ElementListener、AlertListener
方法1:
AndroidDriver driver = new AndroidDriver(parameters);
driver = EventFiringWebDriverFactory.getEventFiringWebDriver(driver, new AlertListener(),
new ElementListener());
AndroidDriver driver2 = new AndroidDriver(parameters);
List listeners = new ArrayList<>();
listeners.add(new AlertListener());
listeners.add(new ElementListener());
driver = EventFiringWebDriverFactory.getEventFiringWebDriver(driver2, listeners);
/**
* 这些方法都是创建一个webdriver的监听实例 {@link org.openqa.selenium.WebDriver}
*
* @param driver 要监听的driver实例 {@link org.openqa.selenium.WebDriver}
* @param
* @return 返回一个 引发事件的webdriver实例{@link org.openqa.selenium.WebDriver}
*/
来看下具体的代码
监听器代码:
我这边只写了一个ElementListener监听器的代码,另外一个以此类推
ElementListener监听器的代码如下:
package event.test.listener;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import io.appium.java_client.events.api.general.ElementEventListener;
public class ElementListener implements
ElementEventListener {
@Override
public void beforeClickOn(WebElement arg0, WebDriver arg1) {
//messages.add("Attempt to click on the element");
System.out.println("准备点击:"+splitElement(arg0));
}
@Override
public void afterClickOn(WebElement arg0, WebDriver arg1) {
//messages.add("The element was clicked");
System.out.println("点击:" +splitElement(arg0));
}
@Override
public void beforeChangeValueOf(WebElement arg0, WebDriver arg1) {
//messages.add("Attempt to change value of the element");
System.out.println("准备改变控件:" +splitElement(arg0)+"数值");
}
@Override
public void afterChangeValueOf(WebElement arg0, WebDriver arg1) {
//messages.add("The value of the element was changed");
System.out.println("控件:" + splitElement(arg0) + "数值已改变");
}
// @Override
// protected void add() {
// // SingleListeners.listeners.put(ElementListener.class, this);
//
// }
@Override
public void beforeChangeValueOf(WebElement element, WebDriver driver,
CharSequence[] keysToSend) {
// TODO 自动生成的方法存根
}
@Override
public void afterChangeValueOf(WebElement element, WebDriver driver,
CharSequence[] keysToSend) {
// TODO 自动生成的方法存根
}
//获取操作的控件字符串
private String splitElement(WebElement element) {
String str = element.toString().split("-> ")[1];
return str.substring(0, str.length() - 1);
}
}
AlertListener 代码如下(请感兴趣的同学自己实现):
package event.test.listener;
import org.openqa.selenium.Alert;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.security.Credentials;
import io.appium.java_client.events.api.general.AlertEventListener;
public class AlertListener implements AlertEventListener {
public void afterAlertAccept(WebDriver arg0, Alert arg1) {
// TODO 自动生成的方法存根
}
public void afterAlertDismiss(WebDriver arg0, Alert arg1) {
// TODO 自动生成的方法存根
}
public void afterAlertSendKeys(WebDriver arg0, Alert arg1, String arg2) {
// TODO 自动生成的方法存根
}
public void afterAuthentication(WebDriver arg0, Alert arg1, Credentials arg2) {
// TODO 自动生成的方法存根
}
public void beforeAlertAccept(WebDriver arg0, Alert arg1) {
// TODO 自动生成的方法存根
}
public void beforeAlertDismiss(WebDriver arg0, Alert arg1) {
// TODO 自动生成的方法存根
}
public void beforeAlertSendKeys(WebDriver arg0, Alert arg1, String arg2) {
// TODO 自动生成的方法存根
}
public void beforeAuthentication(WebDriver arg0, Alert arg1,
Credentials arg2) {
// TODO 自动生成的方法存根
}
}
测试代码
package event.test.listener;
import java.net.MalformedURLException;
import java.net.URL;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.events.EventFiringWebDriverFactory;
public class ListstenerTest {
protected static AndroidDriver> driver;
@BeforeClass
public static void setUp() throws MalformedURLException {
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("deviceName", "7N2RDQ1496009372");
capabilities.setCapability("appPackage", "com.updrv.lifecalendar");
capabilities.setCapability("unicodeKeyboard", true);
capabilities.setCapability("resetKeyboard", true);
capabilities.setCapability("appActivity",
".activity.user.LoginExtActivity");
driver = new AndroidDriver<>(new URL("http://127.0.0.1:4723/wd/hub"),
capabilities);
driver = EventFiringWebDriverFactory.getEventFiringWebDriver(driver,
new AlertListener(), new ElementListener());
}
@Test
public void testLisetener() {
WebElement user_accounts = driver.findElement(By
.id("com.updrv.lifecalendar:id/user_accounts"));
user_accounts.sendKeys("applexx");
;
WebElement user_password = driver.findElement(By
.id("com.updrv.lifecalendar:id/user_password"));
user_password.sendKeys("xxxxx");
;
WebElement btn = driver.findElement(By
.id("com.updrv.lifecalendar:id/btn_login"));
btn.click();
}
@AfterClass
public static void afterClass() {
if (driver != null) {
driver.quit();
}
}
}
五月 01, 2017 10:46:41 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@4802796d: startup date [Mon May 01 10:46:41 CST 2017]; root of context hierarchy
准备改变控件:id: com.updrv.lifecalendar:id/user_accounts数值
控件:id: com.updrv.lifecalendar:id/user_accounts数值已改变
准备改变控件:id: com.updrv.lifecalendar:id/user_password数值
控件:id: com.updrv.lifecalendar:id/user_password数值已改变
准备点击:id: com.updrv.lifecalendar:id/btn_login
点击:id: com.updrv.lifecalendar:id/btn_login
大功告成!已经成功的对一个登陆操作中的sendkeys和click方法进行了监听。
参考:https://github.com/appium/java-client/blob/master/docs/The-event_firing.md