【问题标题】:ClassCastException with new Appium-java TouchActions带有新 Appium-java TouchActions 的 ClassCastException
【发布时间】:2018-07-05 15:18:30
【问题描述】:

我遇到了新的 TouchActions 类的错误。

  • JDK 版本:1.8
  • Appium:1.7.2
  • appium.java-client.version: 6.0.0-BETA2
  • selenium.java.version: 3.8.1

 

TouchActions actions = new TouchActions(appiumDriver);

运行时错误:

java.lang.ClassCastException: io.appium.java_client.ios.IOSDriver 无法转换为 org.openqa.selenium.interactions.HasTouchScreen

然而,下面的旧版本一切正常:

TouchAction touchAction = new TouchAction(appiumDriver);

【问题讨论】:

  • 同样的问题,你解决了吗?
  • 没有。还没有。所以我同时依赖于像 tap() 这样的折旧函数。
  • 即使使用 3.11.05.0.46.0.0-BETA4 我们得到同样的错误。有人有解决方法吗?谢谢

标签: appium


【解决方案1】:

显然,这仍然是 appium 中的一个问题。目前,在原生 Android 中执行此操作的唯一方法是使用 adb 命令:

adb shell input touchscreen swipe <x> <y> <x> <y> <durationMs>

在 Java 中,您可以使用以下代码来实现:

    public static String swipe(int startx, int starty, int endx, int endy, int duration) {
        return executeAsString("adb shell input touchscreen swipe "+startx+" "+starty+" "+endx+" "+endy+" "+duration);
    }

    private static String executeAsString(String command) {
        try {
            Process pr = execute(command);
            BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream()));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = input.readLine()) != null) {
                if (!line.isEmpty()) {
                    sb.append(line);
                }
            }
            input.close();
            pr.destroy();
            return sb.toString();
        } catch (Exception e) {
            throw new RuntimeException("Execution error while executing command" + command, e);
        }
    }    

    private static Process execute(String command) throws IOException, InterruptedException {
        List<String> commandP = new ArrayList<>();
        String[] com = command.split(" ");
        for (int i = 0; i < com.length; i++) {
            commandP.add(com[i]);
        }
        ProcessBuilder prb = new ProcessBuilder(commandP);
        Process pr = prb.start();
        pr.waitFor(10, TimeUnit.SECONDS);
        return pr;
    }

但是,如果您使用的是具有 web 视图的应用程序,则可以更好地使用 JavaScript 进行滚动。向下滚动的代码是:

((JavascriptExecutor)driver).executeScript("window.scrollBy(0,500)", "");

或向上滚动:

((JavascriptExecutor)driver).executeScript("window.scrollBy(0,-500)", "");

或者滚动到某个元素:

((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element);

在使用这个之前一定要切换到 webview 上下文。

【讨论】:

  • 感谢您详细说明。但是您能否建议如何为 iOS / iOS Cordova WebView 实现这一目标?谢谢
  • 在 webview 中你应该可以使用 JavaScript:((JavascriptExecutor)driver).executeScript("window.scrollBy(0,500)", "");。请报告它是否有效。
  • 是的。 window.scrollTo() 和 window.scrollBy() 方法正在工作。但我需要滚动到某个元素,而不是滚动固定长度。
  • 下面应该滚动到一个元素:((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element);。您可能需要等待大约 250 毫秒才能让元素真正滚动到视图中 (Thread.sleep(250);)。
【解决方案2】:

解决方案是使用 Appium TouchAction 而不是 Selenium TouchActions

import io.appium.java_client.TouchAction;

public AndroidDriver<MobileElement> driver = new TouchAction(driver);

public void tap(MobileElement element) {

  getTouchAction()
    .tap(
      new TapOptions().withElement(
        ElementOption.element(
          element)))
    .perform();
}

调用方法():

tap(myMobileElement);

【讨论】:

    【解决方案3】:

    使用 W3C Actions API 来执行手势。

    public void horizontalSwipingTest() throws Exception {
        login();
        driver.findElementByAccessibilityId("slider1").click();
        wait.until(ExpectedConditions.presenceOfElementLocated(MobileBy.AccessibilityId("slider")));
        MobileElement slider = driver.findElementByAccessibilityId("slider");
    
        Point source = slider.getLocation();
    
        PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger");
        Sequence dragNDrop = new Sequence(finger, 1);
        dragNDrop.addAction(finger.createPointerMove(Duration.ofMillis(0),
                PointerInput.Origin.viewport(), source.x, source.y));
        dragNDrop.addAction(finger.createPointerDown(PointerInput.MouseButton.MIDDLE.asArg()));
        dragNDrop.addAction(new Pause(finger, Duration.ofMillis(600)));
        dragNDrop.addAction(finger.createPointerMove(Duration.ofMillis(600),
                PointerInput.Origin.viewport(),
                source.x + 400, source.y));
        dragNDrop.addAction(finger.createPointerUp(PointerInput.MouseButton.MIDDLE.asArg()));
        driver.perform(Arrays.asList(dragNDrop));
    }
    
    
    public void verticalSwipeTest() throws InterruptedException {
        login();
        wait.until(ExpectedConditions.presenceOfElementLocated(MobileBy.AccessibilityId("verticalSwipe")));
        driver.findElementByAccessibilityId("verticalSwipe").click();
        wait.until(ExpectedConditions.presenceOfElementLocated(MobileBy.AccessibilityId("listview")));
        verticalSwipe("listview");
    }
    
    private void verticalSwipe(String locator) throws InterruptedException {
        Thread.sleep(3000);
        MobileElement slider = driver.findElementByAccessibilityId(locator);
        Point source = slider.getCenter();
        PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger");
        Sequence dragNDrop = new Sequence(finger, 1);
        dragNDrop.addAction(finger.createPointerMove(Duration.ofMillis(0),
                PointerInput.Origin.viewport(),
                source.x / 2, source.y + 400));
        dragNDrop.addAction(finger.createPointerDown(PointerInput.MouseButton.MIDDLE.asArg()));
        dragNDrop.addAction(finger.createPointerMove(Duration.ofMillis(600),
                PointerInput.Origin.viewport(), source.getX() / 2, source.y / 2));
        dragNDrop.addAction(finger.createPointerUp(PointerInput.MouseButton.MIDDLE.asArg()));
        driver.perform(Arrays.asList(dragNDrop));
    }
    

    其他手势的示例可以在这里找到:https://github.com/saikrishna321/VodQaAdvancedAppium/blob/master/src/test/java/com/appium/gesture/GestureTest.java

    文档位于:https://appiumpro.com/editions/29

    【讨论】:

      【解决方案4】:

      使用io.appium.java_client.TouchAction 类。

      第 1 步

      TouchAction action = new TouchAction(driver);
      

      这里的driverAppiumDriver 的一个实例。

      第 2 步

      WebElement ele = driver.findElement(By.id("locator"));
      
      action.tap(new TapOptions().withElement(new ElementOption().withElement(ele))).perform();
      

      使用TouchAction 的新实现,您不能直接传递weblement。

      使用的依赖

      <dependency>
              <groupId>io.appium</groupId>
              <artifactId>java-client</artifactId>
              <version>7.0.0</version>
          </dependency>
      

      【讨论】:

        猜你喜欢
        • 2019-01-10
        • 1970-01-01
        • 2019-01-22
        • 1970-01-01
        • 2011-04-05
        • 1970-01-01
        • 2020-04-06
        • 2016-04-12
        • 2014-05-14
        相关资源
        最近更新 更多