在高版本的android手機(例如android 7.0 , 8.0等等),必須使用高版本的appium, 以及對應的selenium版本,那麼不少的appium或者selenium方法會變得沒法直接調用,這裏是一個彙總收集。java
本文以io.appium.java-client 3.14.0版本爲例,爲2018年最新版本android
最新引入了express
PointOption api
ElementOption app
WaitOptionside
KeyEventpost
TouchActionui
The-event firing (時間與元素監聽)this
AppiumFunction (新的等待元素的方法)spa
//老版本的操做線,從元素附近的某個點移動到元素中心,新版本不容許出現: press(element,x,y)的語法 // TouchAction action0 = (new TouchAction(driver)).press(el, center.getX(), center.getY() - yOffset).moveTo(el).release(); // TouchAction action1 = (new TouchAction(driver)).press(el, center.getX(), center.getY() + yOffset).moveTo(el).release(); TouchAction action0 = (new TouchAction(driver)).press(PointOption.point(center.getX(), center.getY() - yOffset)).moveTo(ElementOption.element(el)).release(); TouchAction action1 = (new TouchAction(driver)).press(PointOption.point(center.getX(), center.getY() + yOffset)).moveTo(ElementOption.element(el)).release();
action.press(PointOption.point(x, y)).waitAction(WaitOptions.waitOptions(Duration.ofMillis(500))).perform();
KeyEvent key=new KeyEvent(); key.withKey(AndroidKey.KEYCODE_ZOOM_IN); //driver.pressKeyCode(KEYCODE_ZOOM_IN);//老版操做: 放大鍵
JAVA-Client 在新版裏面提供了以下(等待元素)方法:
//waiting for elements private final AppiumFunction<WebDriver, List<WebElement>> searchingFunction = input -> { List<WebElement> result = input.findElements(By.tagName("a")); if (result.size() > 0) { return result; } return null; }; //waiting for some context using regular expression pattern private final AppiumFunction<Pattern, WebDriver> contextFunction = input -> { Set<String> contexts = driver.getContextHandles(); String current = driver.getContext(); contexts.forEach(context -> { Matcher m = input.matcher(context); if (m.find()) { driver.context(context); } }); if (!current.equals(driver.getContext())) { return driver; } return null; };
等待元素能夠直接使用:
//using one function as pre-condition
@Test public void tezt() { .... Wait<Pattern> wait = new FluentWait<>(Pattern.compile("WEBVIEW")) .withTimeout(30, TimeUnit.SECONDS); List<WebElement> elements = wait.until(searchingFunction.compose(contextFunction)); .... }
import org.openqa.selenium.support.ui.FluentWait; import org.openqa.selenium.support.ui.Wait; @Test public void tezt() { .... Wait<Pattern> wait = new FluentWait<>(Pattern.compile("WEBVIEW")) .withTimeout(30, TimeUnit.SECONDS); List<WebElement> elements = wait.until(contextFunction.andThen(searchingFunction)); .... }
TouchAction
private final ActionSupplier<TouchAction> horizontalSwipe = () -> { driver.findElementById("io.appium.android.apis:id/gallery"); AndroidElement gallery = driver.findElementById("io.appium.android.apis:id/gallery"); List<MobileElement> images = gallery .findElementsByClassName("android.widget.ImageView"); Point location = gallery.getLocation(); Point center = gallery.getCenter(); return new TouchAction(driver).press(images.get(2), -10, center.y - location.y) .waitAction(2000).moveTo(gallery, 10, center.y - location.y).release(); }; private final ActionSupplier<TouchAction> verticalSwiping = () -> new TouchAction(driver).press(driver.findElementByAccessibilityId("Gallery")) .waitAction(2000).moveTo(driver.findElementByAccessibilityId("Auto Complete")).release();
//水平與垂直的swipe @Test public void tezt() { ... horizontalSwipe.get().perform(); ... verticalSwiping.get().perform(); ... }
//普通的tap
import io.appium.java_client.TouchAction; ... //tap new TouchAction(driver) .tap(driver .findElementById("io.appium.android.apis:id/start")).perform();
... //swipe TouchAction swipe = new TouchAction(driver).press(images.get(2), -10, center.y - location.y) .waitAction(2000).moveTo(gallery, 10, center.y - location.y).release(); swipe.perform();
...
//tap by few fingers MultiTouchAction multiTouch = new MultiTouchAction(driver); for (int i = 0; i < fingers; i++) { TouchAction tap = new TouchAction(driver); multiTouch.add(tap.press(element).waitAction(duration).release()); } multiTouch.perform();
public class GestureUtils { public static ActionSupplier<TouchAction> swipe(final AppiumDriver<?> driver, final params) { return () -> { new TouchAction(driver).press(params) .waitAction(params).moveTo(params).release(); }; } }
//能夠直接使用以下方法進行swipe public class SomeTest { @Test public void tezt() { ... GestureUtils.swipe(driver, params).get().perform(); ... } }
Java-client 更新了The-event firing (新增了element/event的監聽)
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.
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);
如何使用事件監聽呢?
//and so on ... import io.appium.java_client.events.EventFiringWebDriverFactory; ... AndroidDriver driver = new AndroidDriver(parameters); driver = EventFiringWebDriverFactory.getEventFiringWebDriver(driver);
若是你本身想封裝的話,能夠以下操做:
import org.openqa.selenium.support.events.WebDriverEventListener; import io.appium.java_client.events.api.general.AppiumWebDriverEventListener; public class UsersWebDriverEventListener implements WebDriverEventListener, AppiumWebDriverEventListener { ... }
//或者以下操做 import io.appium.java_client.events.api.general.AppiumWebDriverEventListener; public class UsersWebDriverEventListener implements AppiumWebDriverEventListener { ... }