Я хочу провести, чтобы найти / найти элемент, который присутствует в приложении IOS - PullRequest
0 голосов
/ 19 сентября 2019

У меня есть приложение Ios, и я делаю его автоматизацию пользовательского интерфейса.У меня есть элемент / кнопка, которая прокручивает страницу вниз.Я видел, что appium обесценил большинство функций, таких как прокрутка, перемещение и пролистывание.поскольку вся помощь связана с этим.Я использую Appium версии 1.13.0 (1.13.0.20190505.5)

Ответы [ 3 ]

1 голос
/ 19 сентября 2019

Используйте этот метод вместо методов appium:

JavascriptExecutor js = (JavascriptExecutor) driver;
HashMap<String, String> scrollObject = new HashMap<>();
scrollObject.put("direction", "down");
js.executeScript("mobile: swipe", scrollObject);

измените direction на up, если вы хотите провести пальцем вверх

0 голосов
/ 23 сентября 2019

Мне никогда не удавалось использовать ни один из методов прокрутки Javascript.Я реализовал метод ScrollDown, который использует простое перелистывание по координатам для прокрутки вниз.

Прокрутка вниз - это то же самое, что прикоснуться к экрану в одном месте, удерживая касание и двигаясь вверх, затем отпуская касание.Мы можем реализовать это действие, используя библиотеки Appium.MultiTouch и Appium.Interfaces:

private static void Swipe(this IPerformsTouchActions driver, int startX, int startY, int endX, int endY)
{
     new TouchAction(driver).Press(startX, startY).MoveTo(endX, endY).Release().Perform();
}

startX, startY относятся к координатам, с которых вы «начнете» свайп.Для прокрутки вниз эти координаты должны отображаться на экране ниже, чем ваши endX, endY координаты.

Поскольку мы просто прокручиваем, обычно startX равно endX.Здесь будет изменяться только координата y.

Наконец, Swipe требует, чтобы ваш AppiumDriver был упакован в тип IPerformsTouchActions.Это означает, что если вы хотите выполнить другие действия WebDriver в вызывающем методе, например FindElement, вам нужно будет обернуть свой вызов Swipe как таковой.Вот полный пример метода Swipe и вызывающего его метода в действии:

        public static void ScrollDown(this AndroidDriver<AppiumWebElement> driver, int numberOfScrolls = 3, int startX = 0, int startY = 0, int endY = 0)
        {
            // set coordinates to default vals in middle of screen if not provided
            if (startX == 0) startX = 397;
            if (startY == 0) startY = 914;
            if (endY == 0) endY = 706;

            // wrap this method so we can use IPerformsTouchActions driver type
            for (int i = 0; i < numberOfScrolls; i++)
            {
                Swipe(driver, startX, startY, startX, endY);
                Thread.Sleep(500);
            }
        }

         private static void Swipe(this IPerformsTouchActions driver, int startX, int startY, int endX, int endY)
         {
              new TouchAction(driver).Press(startX, startY).MoveTo(endX, endY).Release().Perform();
         }


0 голосов
/ 19 сентября 2019

Эта реализация является более общей и работает как для iOS, так и для Android.Сначала он попытается найти элемент на странице, а в случае его отсутствия он выполнит жест свайпинга.

package io.testproject.addons.mobile.elementfinder.Base;

import io.appium.java_client.*;
import io.appium.java_client.touch.WaitOptions;
import io.appium.java_client.touch.offset.PointOption;
import io.testproject.java.sdk.v2.drivers.AndroidDriver;
import io.testproject.java.sdk.v2.drivers.IOSDriver;
import io.testproject.java.sdk.v2.enums.ExecutionResult;
import io.testproject.java.sdk.v2.exceptions.FailureException;
import io.testproject.java.sdk.v2.internal.Driver;
import io.testproject.java.sdk.v2.reporters.ActionReporter;
import org.openqa.selenium.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.time.Duration;
import java.time.Instant;

protected ExecutionResult execute(Driver driver, By searchCriteria, ActionReporter reporter) throws FailureException {
            validateParameters();

            // In case the element is already visible, no need to to perform the swipe action
            if (isElementVisible(driver, searchCriteria)) {
                reporter.result("The element was already in the DOM. Don't need to swipe to the element");
                return ExecutionResult.PASSED;
            }


            // Get device screen size to calculate start /end points
            Dimension screenSize = null;
            if (driver instanceof AndroidDriver) {
                screenSize = ((AndroidDriver) driver).manage().window().getSize();
            } else if (driver instanceof IOSDriver) {
                screenSize = ((IOSDriver) driver).manage().window().getSize();
            } else {
                reporter.result("The provided driver is not an Android or iOS driver");
                return ExecutionResult.FAILED;
            }


            // Handle margins
            Point topPoint = null, bottomPoint = null;
            if (topMarginPercent == 0) {
                topPoint = new Point(screenSize.width / 2, screenSize.height);
            } else {
                topPoint = new Point(screenSize.width / 2, screenSize.height * topMarginPercent / 100);
            }

            if (bottomMarginPercent == 0) {
                bottomPoint = new Point(screenSize.width / 2, screenSize.height);
            } else {
                bottomPoint = new Point(screenSize.width / 2, screenSize.height - screenSize.height * topMarginPercent / 100);
            }


            // iOS Needs the second coordinate as relative distance
            if (driver instanceof IOSDriver) {
                if (swipeDirection.equalsIgnoreCase("DOWN")) {
                    bottomPoint.y = bottomPoint.y - topPoint.y;
                } else if (swipeDirection.equalsIgnoreCase("UP")) {
                    topPoint.y = topPoint.y - bottomPoint.y;
                }
            }


            // Set start / end pints for swiping
            PointOption startPoint = PointOption.point(topPoint);
            PointOption endPoint = PointOption.point(bottomPoint);


            // Reverse start /end points if swiping up
            if (swipeDirection.equalsIgnoreCase("UP")) {
                startPoint = PointOption.point(bottomPoint);
                endPoint = PointOption.point(topPoint);
            }


            // Swipe until element is found or maxSwipes reached or timeout occurs
            int swipesCounter = 1;
            long startTimestamp = Instant.now().toEpochMilli();
            boolean isFound = false;

            while ((swipesCounter <= maxSwipes) && (Instant.now().toEpochMilli() < startTimestamp + timeoutMilliseconds)) {
                swipesCounter++;

                TouchAction touchAction = new TouchAction((PerformsTouchActions) driver);
                touchAction
                        .press(startPoint)
                        .waitAction(WaitOptions.waitOptions(Duration.ofMillis(waitBetweenSwipes)))
                        .moveTo(endPoint)
                        .release()
                        .perform();

                try {
                    // Wait a bit for UI to settle
                    Thread.sleep(waitBetweenSwipes);

                    // Try to find the element
                    isFound = isElementVisible(driver, searchCriteria);

                    if (isFound) {
                        reporter.result(String.format("Element found after %d swipes (%d milliseconds)", swipesCounter - 1, Instant.now().toEpochMilli() - startTimestamp));
                        return ExecutionResult.PASSED;
                    }
                } catch (NoSuchElementException e) {
                    log.debug("Couldn't find the element, moving to the next iteration");
                    continue;
                } catch (InterruptedException e) {
                    log.warn("Interrupted while waiting for UI to settle", e);
                    throw new FailureException("Interrupted while waiting for UI to settle");
                }
            }

            // Set failure message
            if (swipesCounter - 1 <= maxSwipes) {
                reporter.result(String.format("Maximum swipes (%d) performed, element was not found", swipesCounter - 1));
            } else {
                reporter.result(String.format("Max timeout of %d milliseconds reached while searching for the element", timeoutMilliseconds, swipesCounter - 1));
            }
            return ExecutionResult.FAILED;
        }


        private void validateParameters() throws FailureException {
            if (StringUtils.isEmpty(swipeDirection) ||
                    !(swipeDirection.equalsIgnoreCase("UP") ||
                    swipeDirection.equalsIgnoreCase("DOWN"))) {
                throw new FailureException("Swipe direction must be either UP or DOWN");
            }
            if (timeoutMilliseconds == 0 && maxSwipes == 0) {
                throw new FailureException("At least one loop exit parameter must be set: maxSwipes or timeout");
            }
        }

        private boolean isElementVisible(Driver driver, By searchCriteria) {
            boolean isVisible = false;
            if (driver instanceof AndroidDriver) {
                isVisible = ((AndroidDriver) driver).testproject().isVisible(searchCriteria, 0);
            } else if (driver instanceof IOSDriver) {
                isVisible = ((IOSDriver) driver).testproject().isVisible(searchCriteria, 0);
            }
            return isVisible;
        }
...