appium测试,如何模拟多指操作屏幕图片等进行放大缩放的zoom功能(Android,Java)

本文介绍了一种使用Appium实现图片缩放的方法,通过模拟双指缩放手势,实现了图片的放大和缩小功能。该方法利用角度和弧度定义手指运动轨迹,通过创建Sequence对象并设置运动时间和等待来完成zoom操作。
想要对图片进行zoom功能,手指操作很灵活,可是用appium实现起来很不容易,在appium官网上有个MultiTouch的伪代码,尝试后发现未达到期望效果,操作会分步执行,造成图片仅仅做单方向移动;

在这里插入图片描述

于是乎继续查找,发现国外一位前辈写的一个方法,大概的原理是利用角度和弧度作为手指运动轨迹,分别将不同手指的轨迹保存至集合返回,然后设定运动时间和等待,完成zoom操作;

细节上大家有能力和精力的可以去深入理解(原作者写了详细的步骤解释和思路,文章最后有链接);
原作部分解释:在这里插入图片描述

我这边稍微改一下,作为自己的一个工具类进行引用:

package com.gvbrain.brainapp.api.util;

import com.gvbrain.brainapp.api.driver.Driver;
import io.appium.java_client.AppiumDriver;
import org.openqa.selenium.Point;
import org.openqa.selenium.interactions.Pause;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import java.time.Duration;
import java.util.Arrays;
import java.util.Collection;

public class ZoomUtil {

    private Collection<Sequence> zoom(Point locus, int startRadius, int endRadius, int pinchAngle, Duration duration) {
// convert degree angle into radians. 0/360 is top (12 O'clock).
        double angle = Math.PI / 2 - (2 * Math.PI / 360 * pinchAngle);

// create the gesture for one finger
        Sequence fingerAPath = zoomSinglefinger("fingerA", locus, startRadius, endRadius, angle, duration);

// flip the angle around to the other side of the locus and get the gesture for the second finger
        angle = angle + Math.PI;
        Sequence fingerBPath = zoomSinglefinger("fingerB", locus, startRadius, endRadius, angle, duration);

        return Arrays.asList(fingerAPath, fingerBPath);
    }

    /*
    Used by the `zoom` method, for creating one half of a zooming pinch gesture.
    This will return the tough gesture for a single finger, to be put together with
    another finger action to complete the gesture.
    fingerName: name of this input finger for the gesture. Used by automation system to tell inputs apart
    locus: the center of the touch gesture, the point that fingers are pinching away from or towards. They won't actually touch this point though
    startRadius: distance from center that fingers begin at
    endRadius: distance from center that fingers end at
    angle: at what angle the fingers pinch around the locus, in radians.
    duration: the total amount of time the pinch gesture will take
    */
    private Sequence zoomSinglefinger(String fingerName, Point locus, int startRadius, int endRadius, double angle, Duration duration) {
        PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, fingerName);
        Sequence fingerPath = new Sequence(finger, 0);

        double midpointRadius = startRadius + (endRadius > startRadius ? 1 : -1) * 20;

// find coordinates for starting point of action (converting from polar coordinates to cartesian)
        int fingerStartx = (int)Math.floor(locus.x + startRadius * Math.cos(angle));
        int fingerStarty = (int)Math.floor(locus.y - startRadius * Math.sin(angle));

// find coordinates for first point that pingers move quickly to
        int fingerMidx = (int)Math.floor(locus.x + (midpointRadius * Math.cos(angle)));
        int fingerMidy = (int)Math.floor(locus.y - (midpointRadius * Math.sin(angle)));

// find coordinates for ending point of action (converting from polar coordinates to cartesian)
        int fingerEndx = (int)Math.floor(locus.x + endRadius * Math.cos(angle));
        int fingerEndy = (int)Math.floor(locus.y - endRadius * Math.sin(angle));

// move finger into start position
        fingerPath.addAction(finger.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), fingerStartx, fingerStarty));
// finger comes down into contact with screen
        fingerPath.addAction(finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg()));
// finger moves a small amount very quickly
        fingerPath.addAction(finger.createPointerMove(Duration.ofMillis(1), PointerInput.Origin.viewport(), fingerMidx, fingerMidy));
// pause for a little bit
        fingerPath.addAction(new Pause(finger, Duration.ofMillis(100)));
// finger moves to end position
        fingerPath.addAction(finger.createPointerMove(duration, PointerInput.Origin.viewport(), fingerEndx, fingerEndy));
// finger lets up, off the screen
        fingerPath.addAction(finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg()));

        return fingerPath;
    }

    /*
    Simplified method for zooming in.
    Defaults to a 45 degree angle for the pinch gesture.
    Defaults to a duration of half a second
    Fingers start 50px from locus

    locus: the center of the pinch action, fingers move away from here
    distance: how far fingers move outwards, starting 100px from the locus
    */
    private Collection<Sequence> zoomIn(Point locus, int distance) {
        return zoom(locus, 200, 200 + distance, 45, Duration.ofMillis(25));
    }

    /*
    Simplified method for zooming out.
    Defaults to a 45 degree angle for the pinch gesture.
    Defaults to a duration of half a second
    Fingers finish 50px from locus

    locus: the center of the pinch action, fingers move towards here
    distance: how far fingers move inwards, they will end 100px from the locus
    */
    private Collection<Sequence> zoomOut(Point locus, int distance) {
        return zoom(locus, 200 + distance, 200, 45, Duration.ofMillis(25));
    }


    public void ZoomInAndOut() throws InterruptedException {
        AppiumDriver driver = Driver.getInstance().appiumDriver;

        driver.perform(zoomOut(new Point(960,600), 450));

        Thread.sleep(1000);

        driver.perform(zoomIn(new Point(960,600), 450));

        Thread.sleep(1000);

        driver.perform(zoomOut(new Point(960,600).moveBy(0, 250), 300));

        Thread.sleep(1000);

        driver.perform(zoomIn(new Point(960,600).moveBy(0, -250), 300));

        Thread.sleep(3000);
    }
}

运行效果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值