美文网首页
app特殊元素定位

app特殊元素定位

作者: testerPM | 来源:发表于2020-03-22 19:55 被阅读0次

    页面元素无法获取到的场景

    Ex:bilibili的登录页面
    登录页面做了截图限制,不能通过外部的工具(如appium检查器,adb命令)进行截图,像一些银行类的app某些页面也可能会做限制不让截图
    问题:如何知道页面是否做了截图限制
    (1)appium检查器如果能打开,则没有做限制,打不开就做了限制


    image.png

    (2)通过adb截图,如下命令,截取当前正在运行的页面保存到手机/sdcard/目录下,如果手机/sdcard/目录下有此登录页的截图,说明没有做限制,如果没有截图,则做了限制

    adb  shell  screencap -p /sdcard/aaa.png
    

    既然页面做了截图限制,无法用外部工具获取元素的定位信息,那么怎么解决呢?

    解决方案:使用getPageSource API来获取页面的定位信息即:获取当前页面的源代码,然后在源代码中查找是否有页面的元素定位信息,如下图是获取的源代码,红色部分就是要定位的元素


    image.png

    代码如下:

    package com.leom.day03;
    
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.util.concurrent.TimeUnit;
    
    import org.openqa.selenium.By;
    import org.openqa.selenium.remote.DesiredCapabilities;
    import org.testng.annotations.BeforeTest;
    import org.testng.annotations.Test;
    
    import io.appium.java_client.android.AndroidDriver;
    
    public class SpecialLocate {
        public AndroidDriver androidDriver;
    
        /**
         * 初始化的一些操做就相等于是appium的检测器会话, 即:不通过检查器会话连接手机,而是通过代码代替客户端来连接手机设备
         */
        @BeforeTest
        public void setup() throws MalformedURLException {
            // 1.实例化 DesiredCapabilities--》所需能力
            DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
            // 2.添加手机配置
            desiredCapabilities.setCapability("deviceName", "127.0.0.1:62001");// 设备名(值可以自己定义)
            desiredCapabilities.setCapability("platformName", "Android");// 连接的设备是安卓平台
            desiredCapabilities.setCapability("appPackage", "tv.danmaku.bili");// app包名
            desiredCapabilities.setCapability("appActivity", "tv.danmaku.bili.ui.splash.SplashActivity");// app启动入口
            desiredCapabilities.setCapability("noReset", "true");
            // 3.Appium服务连接地址
            URL url = new URL("http://127.0.0.1:4723/wd/hub");
            // 4.实例化AndroidDriver
            androidDriver = new AndroidDriver(url, desiredCapabilities);
            // 5.设置隐式等待
            androidDriver.manage().timeouts().implicitlyWait(8, TimeUnit.SECONDS);
    
        }
    
        @Test
        public void test() throws InterruptedException {
    
            androidDriver.findElement(By.id("tv.danmaku.bili:id/drawer_handler")).click();
            androidDriver.findElement(By.id("tv.danmaku.bili:id/login")).click();
            Thread.sleep(8000);// 等待的时间设置长一点,app加载的有点慢
            //辅助的功能-》用来获取页面元素信息
            // System.out.println( androidDriver.getPageSource());
            androidDriver.findElement(By.id("tv.danmaku.bili:id/et_phone_number")).sendKeys("13323234545");
    
        }
    
    }
    
    
    

    Toast元素获取

    》提示信息,出现的时机是没有规律的(与响应时间和网络有关系),出现之后过几秒就会消失--》可以用来做断言
    获取要求:(1)手机系统版本5.0或者以上(2) Appium设置uiautomator2引擎(Appium默认就是uiautomator2引擎)
    xpath表达式获取://*[contains(@text,'错误的账号信息)]

    
    @Test
        public void test() throws InterruptedException {
            // 登录
            androidDriver.findElement(By.id("com.lemon.lemonban:id/navigation_tiku")).click();
            androidDriver.findElement(By.id("com.lemon.lemonban:id/button_go_login")).click();
            androidDriver.findElement(By.id("com.lemon.lemonban:id/et_mobile")).sendKeys("13323234545");
            androidDriver.findElement(By.id("com.lemon.lemonban:id/et_password")).sendKeys("12345678");
            androidDriver.findElement(By.id("com.lemon.lemonban:id/btn_login")).click();
            // 获取toast信息
            // appium点击登录截取不到toast的,只有模拟器点击登录,appium再刷新,才能再appium中看到toast信息
            // 且:通过选择元素,toast也是选择不了的,但是toast却是存在当前页面中,=》对于这种特殊元素定位方式
            // 采用xpath:这里的text是元素的属性,*代表任意标签
            WebElement element = androidDriver.findElement(By.xpath("//*[contains(@text,'错误的账号信息')]"));
            //打印出toast文本
            System.out.println(element.getText());
    
        }
    
    

    滑动列表元素-》页面元素需要像上滑动才可以看见的元素

    定位方式:根据文本定位
    需要滑动几次?->有些元素不需要滑动,有些元素需要滑动多次才可以加载出来-》解决方式:循环滑动
    什么时候结束滑动呢?(1)滑动到了底部,还没有找到元素,就跳出循环 (2)默认页面已加载出来元素,不需要滑动时,也跳出循环
    如何判断是否滑动到了底部呢?-》滑动到了底部,页面不能继续向上滑动了,所以可以根据pageSource判断,当滑动前和滑动后pageSource相等,说明滑动到了底部
    代码如下:

    
    /**
         * 滑动列表元素定位
         */
        @Test
        public void test02() {
            // 1 点击 题库
            androidDriver.findElement(By.id("com.lemon.lemonban:id/navigation_tiku")).click();
            // 2.通过文本定位-》比如这里 我们要定位 “ 逻辑思维题"
            // androidDriver.findElementByAndroidUIAutomator("new
            // UiSelector().text(\"逻辑思维题 \")").click();
            slide("软件测试基础");
        }
    
        public void slide(String text) {
            String BeforepageSource = "";
            String AfterpageSource = " ";
            // 条件:什么时候结束滑动?
            // 1.到了底部还是找不到元素,就跳出循环
            // 2.默认的页面就有元素,不需要滑动,也跳出循环
            while (true) {
                // 滑动前的pageSource
                BeforepageSource = androidDriver.getPageSource();
                if (BeforepageSource.contains(text )) {
                    //注意:\""  -》不能写成 \" " 不能加空格,否则会找不到元素,相当于元素文本有空格
                    androidDriver.findElementByAndroidUIAutomator("new UiSelector().text(\"" + text + "\")")
                            .click();
                    break;
                }
                // 向上滑动
                swipeUp();
                // 滑动后的pageSource
                AfterpageSource = androidDriver.getPageSource();
                if (BeforepageSource.equals(AfterpageSource)) {
                    break;
    
                }
    
            }
    
        }
            /**向上滑动
         * 
         */
        public void swipeUp() {
    
            int height = androidDriver.manage().window().getSize().getHeight();
            int width = androidDriver.manage().window().getSize().getWidth();
            int startx = width / 2;
            int starty = height * 3 / 4;
            int endx = width / 2;
            int endy = height / 4;
            int duration = 500;
            // 1.实例化触摸动作对象
            TouchAction touchAction = new TouchAction(androidDriver);
            // 2.将原始坐标转化成PointOption类型(java client高版本不能直接传坐标值)
            PointOption startPoint = PointOption.point(startx, starty);
            PointOption endPoint = PointOption.point(endx, endy);
            // 3.把原始时间转换成WaitOptions类型的(原始时间是毫秒,所以调用ofMillis()
            Duration duration2 = Duration.ofMillis(duration);
            WaitOptions waitOptions = WaitOptions.waitOptions(duration2);
            // 4.配置滑动的动作
            touchAction.press(startPoint).waitAction(waitOptions).moveTo(endPoint).release();
            // 5.让滑动生效
            touchAction.perform();
    
        }
    
    
    
    

    相关文章

      网友评论

          本文标题:app特殊元素定位

          本文链接:https://www.haomeiwen.com/subject/fzhvyhtx.html