since 4.1.0
This feature allows end user to organize the event logging on the client side. Also this feature may be useful in a binding with standard or custom reporting frameworks.
The API was designed the way which allows end user to select events (searching, navigation, exception throwing etc.) which should be listened to. It contains the following list of interfaces (new items may be added further):
io.appium.java_client.events.api.Listeneris the basic interfaceio.appium.java_client.events.api.general.AlertEventListeneris for the listening to alertsio.appium.java_client.events.api.general.ElementEventListeneris for the listening to actions related to elementsio.appium.java_client.events.api.general.JavaScriptEventListeneris for the listening to java script executingio.appium.java_client.events.api.general.ListensToExceptionis for the listening to exceptions which are thrownio.appium.java_client.events.api.general.NavigationEventListeneris for the listening to events related to navigationio.appium.java_client.events.api.general.SearchingEventListeneris for the listening to events related to the searching.io.appium.java_client.events.api.general.WindowEventListeneris for the listening to actions on a windowio.appium.java_client.events.api.mobile.ContextEventListeneris for the listening to the switching to mobile contextio.appium.java_client.events.api.mobile.RotationEventListeneris for the listening to screen rotationio.appium.java_client.events.api.general.AppiumWebDriverEventListenerwas added to provide the compatibility with user's implementation oforg.openqa.selenium.support.events.WebDriverEventListener. Also it extends some interfaces above.
This is pretty similar solution as the org.openqa.selenium.support.events.EventFiringWebDriver of the Selenium project. You
can read about this thing there The blog post.
Here we were trying to improve existing drawbacks and restrictions using:
-
API splitting, see above.
-
the binding of some Spring framework engines with AspectJ.
It is easy.
import io.appium.java_client.events.api.general.AlertEventListener;
public class AlertListener implements AlertEventListener {
...
}
...
import io.appium.java_client.events.api.general.ElementEventListener;
public class ElementListener implements ElementEventListener {
...
}
//and so on
...
import io.appium.java_client.events.EventFiringWebDriverFactory;
import io.appium.java_client.events.api.Listener;
...
AndroidDriver driver = new AndroidDriver(parameters);
driver = EventFiringWebDriverFactory.getEventFiringWebDriver(driver, new AlertListener(),
new ElementListener());
//or
AndroidDriver driver2 = new AndroidDriver(parameters);
List<Listener> listeners = new ArrayList<>();
listeners.add(new AlertListener());
listeners.add(new ElementListener());
driver = EventFiringWebDriverFactory.getEventFiringWebDriver(driver2, listeners);In order to avoid the repeating actions an end user is free to do these things:
- create folders
/META-INF/servicesand put the fileio.appium.java_client.events.api.Listenerthere. Please read about SPI.
- define the list of default listeners at the
io.appium.java_client.events.api.Listener
And then it is enough
//and so on
...
import io.appium.java_client.events.EventFiringWebDriverFactory;
...
AndroidDriver driver = new AndroidDriver(parameters);
driver = EventFiringWebDriverFactory.getEventFiringWebDriver(driver);If there are listeners defined externally when this collection is merged with default set of listeners.
If an end user has their own org.openqa.selenium.support.events.WebDriverEventListener implementation then in order to
make it compatible with this engine it is enough to do the following.
import org.openqa.selenium.support.events.WebDriverEventListener;
import io.appium.java_client.events.api.general.AppiumWebDriverEventListener;
public class UsersWebDriverEventListener implements WebDriverEventListener, AppiumWebDriverEventListener {
...
}or just
import io.appium.java_client.events.api.general.AppiumWebDriverEventListener;
public class UsersWebDriverEventListener implements AppiumWebDriverEventListener {
...
}As soon as Appium java client has Java 8-style API (methods with default implementation) there was provided the ability to get objects created by these interfaces (anonymous types) listenable. Also there is an option to make some objects (some single element that has been found, for example) listenable too.
import static io.appium.java_client.events.EventFiringObjectFactory.getEventFiringObject;
...
AppiumDriver<AndroidElement> appiumDriver = new AppiumDriver<AndroidElement>(parameters);
FindsByAndroidUIAutomator<AndroidElement> findsByAndroidUIAutomator =
new FindsByAndroidUIAutomator<AndroidElement>() {
@Override
public AndroidElement findElement(String by, String using) {
return appiumDriver.findElement(String by, String using);
}
@Override
public List<AndroidElement> findElements(String by, String using) {
return appiumDriver.findElements(by, using);
}
};
findsByAndroidUIAutomator =
getEventFiringObject(findsByAndroidUIAutomator, appiumDriver, listeners);
