栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Appium搜索某app demo

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Appium搜索某app demo

package com.ybjdw.tool.test;

import com.alibaba.fastjson.JSONObject;
import com.ybjdw.tool.utils.SeleniumUtil;
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.android.AndroidDriver;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.Point;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.math.BigDecimal;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;


public class AppiumTest {
    private static Logger logger = LoggerFactory.getLogger(AppiumTest.class);

    public static void main(String[] args) {
        // 设置驱动相关信息
        DesiredCapabilities des = new DesiredCapabilities();
        des.setCapability("platformName", "Android");
        des.setCapability("platformVersion", "7.1.2");
        des.setCapability("deviceName", "Android Emulator");
        des.setCapability("noReset", true);
        des.setCapability("appPackage", "com.yishouapp.fumi");
        des.setCapability("appActivity", "com.yishouapp.fumi.activity.YishouMainActivity");

        AndroidDriver androidDriver = null;
        try {
            androidDriver = new AndroidDriver(new URL("http://192.168.1.186:4723/wd/hub"),des);
            androidDriver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);

            yiShouLogin(androidDriver);

            yiShouHotCategory(androidDriver);

        } catch (Exception e) {
            logger.error("appium异常,测试用例不通过!", e);
        }finally{
            if(androidDriver != null){
                // 停掉app
                androidDriver.terminateApp("com.yishouapp.fumi.activity.YishouMainActivity");
                androidDriver.quit();
            }
        }
    }

    
    private static void yiShouHotCategory(AndroidDriver androidDriver) throws Exception {

        logger.debug("首页开始上滑!");
        int windowHeight = androidDriver.manage().window().getSize().getHeight();
        SeleniumUtil.swipe(androidDriver, 10,new BigDecimal(windowHeight*0.8).intValue(), 10, new BigDecimal(windowHeight*0.05).intValue(), 3);

        // 进入一手热销
        logger.debug("开始进入一手热销!");
        WebElement webElement = SeleniumUtil.findElementAndWait(androidDriver, By.id("com.yishouapp.fumi:id/rv_list_ihtm"), 3);
        if(webElement == null){
            return;
        }
        webElement = SeleniumUtil.findElementAndWait(webElement, By.xpath(".//androidx.recyclerview.widget.RecyclerView/android.widget.LinearLayout[4]"), 3);
        if(webElement == null ){
            return;
        }
        webElement = SeleniumUtil.findElementAndWait(webElement, By.xpath(".//android.widget.ImageView[1]"), 3);
        if(webElement == null ){
            return;
        }
        webElement.click();
        Thread.sleep(5000);

        // 判断是否存在富文本区域
        WebElement varyContent = SeleniumUtil.findElementAndWait(androidDriver, By.id("com.yishouapp.fumi:id/vary_content"), 3);
        if(varyContent == null ){
            return;
        }

        // 点击销量降序排序
        logger.debug("开始点击销量排序!");
        webElement = SeleniumUtil.findElementAndWait(varyContent, By.xpath(".//android.webkit.WebView/android.webkit.WebView/android.view.View/android.view.View/android.view.View[4]/android.view.View/android.view.View[2]/android.view.View[1]/android.view.View[2]"), 3);
        if(webElement == null ){
            return;
        }
        webElement.click();

        // 打开筛选条件面板
        logger.debug("开始打开条件筛选面板!");
        webElement = SeleniumUtil.findElementAndWait(varyContent, By.xpath(".//android.webkit.WebView/android.webkit.WebView/android.view.View/android.view.View/android.view.View[4]/android.view.View/android.view.View[2]/android.view.View[1]/android.view.View[4]"), 3);
        if(webElement == null ){
            return;
        }
        webElement.click();
        Thread.sleep(3000);

        // 选择筛选条件 7日爆款
        logger.debug("开始选择筛选面板中的7日爆款!");
        webElement = SeleniumUtil.findElementAndWait(varyContent, By.xpath(".//android.webkit.WebView/android.webkit.WebView/android.view.View/android.view.View/android.view.View[4]/android.view.View[3]/android.view.View[3]/android.widget.CheckBox[3]/android.widget.TextView"), 3);
        if(webElement == null ){
            return;
        }
        webElement.click();

        // 确定筛选条件
        logger.debug("开始确定筛选条件!");
        webElement = SeleniumUtil.findElementAndWait(varyContent, By.xpath(".//android.webkit.WebView/android.webkit.WebView/android.view.View/android.view.View/android.view.View[4]/android.view.View[3]/android.view.View[5]"), 3);
        if(webElement == null ){
            return;
        }
        webElement.click();
        Thread.sleep(1000);

        logger.debug("开始上滑app!");
        SeleniumUtil.swipe(androidDriver, 10, windowHeight /2, 10, 10, 3);

        searchYiShouCategory(androidDriver);
    }

    private static void searchYiShouCategory(AndroidDriver androidDriver) throws InterruptedException {
        // 搜索所有品类
        int searchItemIndex = 0;
        int searchCategoryIndex = 0;
        int lastCategoryY = 0;
        List searchCategoryNameList = new ArrayList<>();
        for(int i=0; i < 10; i++){
            WebElement varyContent = SeleniumUtil.findElementAndWait(androidDriver, By.id("com.yishouapp.fumi:id/vary_content"), 2);
            String searchCategory1 = ".//android.webkit.WebView/android.webkit.WebView/android.view.View/android.view.View/android.view.View[3]/android.view.View/android.view.View[1]/android.view.View/android.widget.TabWidget/android.view.View";
            String searchCategory2 = ".//android.webkit.WebView/android.webkit.WebView/android.view.View/android.view.View/android.view.View[2]/android.view.View/android.view.View[1]/android.view.View/android.widget.TabWidget/android.view.View";
            List categoryElements = SeleniumUtil.findElementList(varyContent, By.xpath(searchCategory1), 2);
            if(categoryElements == null || categoryElements.size() ==0){
                categoryElements = SeleniumUtil.findElementList(varyContent, By.xpath(searchCategory2), 2);
            }
            if(categoryElements == null || categoryElements.size() == 0){
                continue;
            }

            // 第一个品类是精选,跳过,从第二个开始
            for(int subCategoryIndex=2; subCategoryIndex < categoryElements.size() && subCategoryIndex < 5; subCategoryIndex++){
                Point startPoint = new Point(3,0);
                Point endPoint = new Point(3,0);
                Point categoryFirstLocation = null; // 品类第一个元素的位置,用于纠正位置偏差

                // 搜索品类目录
                String categoryPath = searchCategory1 + "[" + subCategoryIndex + "]";
                WebElement webElement = SeleniumUtil.findElementAndWait(varyContent, By.xpath(categoryPath),2);
                if(webElement == null){
                    categoryPath = searchCategory2 + "[" + subCategoryIndex + "]";
                    webElement = SeleniumUtil.findElementAndWait(varyContent, By.xpath(categoryPath),2);
                }
                if(webElement == null || StringUtils.isBlank(webElement.getText())){
                    continue;
                }
                String categoryName = webElement.getText();
                if(searchCategoryNameList.contains(categoryName)){
                    continue;
                }
                searchCategoryNameList.add(categoryName);

                Point location = webElement.getLocation();
                Dimension size = webElement.getSize();
                lastCategoryY = location.getY() + 5;
                webElement.click();
                Thread.sleep(2000);
                logger.debug("搜索品类顺序:{},定位到第{}个子品类:{},location:{},size:{}", searchCategoryIndex, subCategoryIndex, categoryName, location, size);

                // 不断上滑app界面,每次获取完整展示的2个商品(1/2或3/4)
                JSONObject productJson;
                int categoryProductIndex = 0;
                List productList = new ArrayList<>();
                for(int pageSwipeNum = 0; pageSwipeNum < 25; pageSwipeNum++){
                    logger.trace("搜索品类顺序:{},子品类:{}商品页面第{}次上滑!", searchCategoryIndex, categoryName, pageSwipeNum);
                    if(pageSwipeNum == 0){ // 第一行2个商品
                        for(int productIndex=0; productIndex < 2; productIndex++){
                            String productXPath = ".//android.webkit.WebView/android.webkit.WebView/android.view.View/android.view.View/android.view.View[3]/android.view.View/android.view.View[2]/android.view.View[2]/android.view.View["+(productIndex+1)+"]";
                            webElement = SeleniumUtil.findElementAndWait(varyContent, By.xpath(productXPath), 2);
                            if(webElement != null){
                                if(categoryFirstLocation == null){
                                    categoryFirstLocation = webElement.getLocation();
                                }
                                productJson = parseYiShouProductSmart(categoryName, webElement);
                                if(productJson != null){
                                    productJson.put("categoryProductIndex", ++categoryProductIndex);
                                    productList.add(productJson);
                                    logger.debug("搜索品类顺序:{},品类:{},定位到第{}个商品:{},", searchCategoryIndex, categoryName, ++searchItemIndex, productJson);
                                }

                                // 重置移动轨迹
                                resetMovePoint(startPoint, endPoint, categoryFirstLocation, webElement);
                            }
                        }
                        // 搜索完品类前2个商品后下滑
                        SeleniumUtil.swipe(androidDriver, startPoint.getX(), startPoint.getY(), endPoint.getX(), endPoint.getY(), 2);
                        Thread.sleep(3000);
                        continue;
                    }

                    String productTotalViewPath = "//android.view.View[@resource-id="app"]/android.view.View/android.view.View[2]/android.view.View/android.view.View[2]/android.view.View/android.view.View";
                    if(searchCategoryIndex >= 2){
                        productTotalViewPath = "//android.view.View[@resource-id="app"]/android.view.View/android.view.View[2]/android.view.View/android.view.View[2]/android.view.View[2]/android.view.View";
                    }
                    logger.debug("品类:{}搜索商品列表定位路径:{}", categoryName, productTotalViewPath);
                    List elementList = SeleniumUtil.findElementList(androidDriver, By.xpath(productTotalViewPath), 2);
                    if(elementList == null){
                        break;
                    }
                    logger.debug("商品列表 elementList.size():{}", elementList.size());
                    if(elementList.size() >= 4){
                        // 第3个商品
                        webElement = elementList.get(2);
                        JSONObject thirdEleJson = parseYiShouProductSmart(categoryName, webElement);
                        if(thirdEleJson != null){
                            logger.debug("搜索品类顺序:{},品类:{},定位到第{}个商品:{},第3个元素", searchCategoryIndex, categoryName, ++searchItemIndex, thirdEleJson);
                            thirdEleJson.put("categoryProductIndex", ++categoryProductIndex);
                            productList.add(thirdEleJson);

                            // 重置移动轨迹
                            resetMovePoint(startPoint, endPoint, categoryFirstLocation, webElement);
                        }

                        // 第4个商品
                        webElement = elementList.get(3);
                        productJson = parseYiShouProductSmart(categoryName, webElement);
                        if(productJson != null){
                            logger.debug("搜索品类顺序:{},品类:{},定位到第{}个商品:{},第4个元素", searchCategoryIndex, categoryName, ++searchItemIndex, productJson);
                            productJson.put("categoryProductIndex", ++categoryProductIndex);
                            productList.add(productJson);
                        }

                        // 获取最后一个view的文字 没有更多了
                        webElement = elementList.get(elementList.size() - 1);
                        String text = webElement.getText();
                        if(text.contains("没有更多了")){
                            logger.debug("发现没有更多了,停止品类搜索!");
                            break;
                        }
                    }
                    // 搜索完品类商品后下滑
                    SeleniumUtil.swipe(androidDriver, startPoint.getX(), startPoint.getY(), endPoint.getX(), endPoint.getY(), 2);
                    Thread.sleep(3000);
                }
                logger.debug("第{}轮品类:{}遍历结束,已搜索品类:{},已搜索商品数量:{}", searchCategoryIndex, categoryName, searchCategoryNameList, productList.size());
                searchCategoryIndex++;
            }

            // 每次搜索页面展示品类的第2 3 4,再左滑半个屏幕,注意品类展示会随着点击移动
            int windowWidth = androidDriver.manage().window().getSize().getWidth();
            logger.debug("开始第{}次左滑,屏幕宽带:{},品类顺序:{}!", i+1, windowWidth,searchCategoryIndex);
            SeleniumUtil.swipe(androidDriver, windowWidth/2, lastCategoryY,5,lastCategoryY, 2);
            Thread.sleep(3000);
        }
        logger.debug("搜索结束,遍历的品类集合:{}!", searchCategoryNameList);
    }

    private static void resetMovePoint(Point startPoint, Point endPoint, Point categoryFirstLocation, WebElement webElement) {
        try{
            logger.trace("重新定义上滑位置!");
            if(webElement == null){
                return;
            }

            startPoint.y = webElement.getLocation().getY() + webElement.getSize().getHeight();
            endPoint.y = webElement.getLocation().getY() + 5;

            if(categoryFirstLocation != null){
                endPoint.y = categoryFirstLocation.getY() + 5;
            }
        }catch (Exception e){
            logger.error("重置上滑位置异常!", e);
        }
    }

    
    public static JSONObject parseYiShouProductSmart(String categoryName, WebElement productEle) {
        JSONObject retJson = new JSONObject();
        try {
            if(productEle == null){
                return null;
            }

            String saleText = "0";
            String priceText = "0";
            String productName = "未找到名称";
            WebElement webElement = null;

            // 商品名(长度超过10)、销量(含已拼)
            List webElementList = SeleniumUtil.findElementList(productEle, By.xpath(".//android.widget.TextView"), 3);
            if (webElementList == null || webElementList.size() == 0) {
                logger.warn("未定位到商品名称和销量");

//                while(true){
//                    Scanner scanner = new Scanner(System.in);
//                    logger.debug("请在下一行输入定位路径!");
//                    if(scanner.hasNext()){
//                        String input = scanner.next();
//                        if("q".equals(input)){
//                            break;
//                        }
//                        webElement = SeleniumUtil.findElementAndWait(productEle, By.xpath(input), 3);
//                        if(webElement != null){
//                            logger.debug("文本内容:{}", webElement.getText());
//                        }else{
//                            logger.debug("未找到!");
//                        }
//                    }
//                }

                return null;
            }else{
                for(WebElement textView:webElementList){
                    String viewText = textView.getText();
                    if(viewText.contains("已拼")){ // 销量
                        saleText = viewText;
                        saleText = saleText.replace("已拼", "").replace("今日","");
                        break;
                    }
                    if(viewText.length() > 10 && "未找到名称".equals(productName)){ // 商品名
                        productName = viewText;
                    }
                    logger.trace("商品名称:{}",productName);
                }
            }

            // 价格(含¥ ¥)
            webElementList = SeleniumUtil.findElementList(productEle, By.xpath(".//android.view.View"), 3);
            if (webElementList == null || webElementList.size() == 0) {
                logger.warn("未定位到商品价格");
                return null;
            }else{
                for(WebElement textView:webElementList){
                    String viewText = textView.getText();
                    if(viewText.contains("¥") || viewText.contains("¥")){ // 商品价格
                        priceText = viewText;
                        priceText = priceText.replace("¥", "").replace("¥", "");
                        logger.trace("商品价格:{}", priceText);
                        break;
                    }
                }
            }

            List elementList = SeleniumUtil.findElementList(productEle, By.xpath(".//android.widget.Image"), 2);
            if(elementList!= null && elementList.size() >0){
                for(WebElement subEle:elementList){
                    if(subEle.getSize().getHeight() > 100){
                        webElement = subEle;
                        logger.trace("找到图片元素{}", subEle.getSize());
                        break;
                    }
                }
            }
            if(webElement == null){
                logger.debug("未找到图片元素,使用这个商品元素!");
                webElement = productEle;
            }

            File screenShotFile = webElement.getScreenshotAs(OutputType.FILE);
            String picPath = "E:\tmp\yishou\" + productName + ".jpg";
            FileUtils.copyFile(screenShotFile, new File(picPath));

            logger.trace("品类:{},名称:{},价格:{},销量:{},图片路径:{}", categoryName, productName, priceText, saleText, picPath);
            retJson.put("categoryName", categoryName);
            retJson.put("productName", productName);
            retJson.put("priceText", priceText);
            retJson.put("saleText", saleText);
            retJson.put("picPath", picPath);
        }catch (Exception e){
            logger.error("解析商品异常!", e);
        }
        return retJson;
    }

    
    private static void parseYiShouProduct(String categoryName, WebElement productEle) {
        try {
            String saleText = "";
            String priceText = "";
            WebElement webElement;

            // 商品名 长度超过10
            webElement = SeleniumUtil.findElementAndWait(productEle, By.xpath(".//android.widget.TextView[2]"), 3);
            if (webElement == null) {
                logger.warn("未定位到商品名称");
                return;
            }
            String productName = webElement.getText();
            logger.debug("开始解析商品:{}", webElement.getText());

            // 价格 销量
            webElement = SeleniumUtil.findElementAndWait(productEle, By.xpath(".//android.view.View[5]/android.view.View"), 3);
            if (webElement != null) {
                priceText = webElement.getText();
            }
            webElement = SeleniumUtil.findElementAndWait(productEle, By.xpath(".//android.view.View[5]/android.widget.TextView"), 3);
            if (webElement != null) {
                saleText = webElement.getText();
            }
            if (StringUtils.isBlank(priceText) || StringUtils.isBlank(saleText)) {
                webElement = SeleniumUtil.findElementAndWait(productEle, By.xpath(".//android.view.View[4]/android.view.View"), 3);
                if (webElement != null) {
                    priceText = webElement.getText();
                }
                webElement = SeleniumUtil.findElementAndWait(productEle, By.xpath(".//android.view.View[4]/android.widget.TextView"), 3);
                if (webElement != null) {
                    saleText = webElement.getText();
                }
            }

            // 下载图片
            webElement = SeleniumUtil.findElementAndWait(productEle, By.xpath(".//android.view.View[1]/android.widget.Image"), 3);
            if (webElement == null) {
                logger.warn("未定位到商品图片");
                return;
            }
            File screenShotFile = webElement.getScreenshotAs(OutputType.FILE);
            String picName = "E:\tmp\yishou\" + productName + ".jpg";
            FileUtils.copyFile(screenShotFile, new File(picName));

            logger.debug("品类:{},名称:{},价格:{},销量:{},图片路径:{}", categoryName, productName, priceText, saleText, picName);
        }catch (Exception e){
            logger.error("解析商品异常!", e);
        }
    }

    public static void yiShouLogin(AppiumDriver driver) throws Exception {
        logger.debug("appium开始进行一手登录检测!");

        // 允许app拨打电话
        WebElement webElement = SeleniumUtil.findElementAndWait(driver, By.id("com.android.packageinstaller:id/permission_allow_button"), 1);
        if(webElement != null) {
            webElement.click();
        }

        // 切换到密码登录界面
        webElement = SeleniumUtil.findElementAndWait(driver,By.id("com.yishouapp.fumi:id/tv_phonelogin_pwdlogin"),1);
        if(webElement != null) {
            logger.debug("一手未登录,开始切换到密码登录!");
            webElement.click();
            Thread.sleep(2000);

            // 输入手机号
            webElement = SeleniumUtil.findElementAndWait(driver,By.id("com.yishouapp.fumi:id/et_phonepwdlogin_phone"),1);
            if(webElement != null){
                webElement.sendKeys("15910761260");
                Thread.sleep(500);
            }

            // 输入密码
            webElement = SeleniumUtil.findElementAndWait(driver,By.id("com.yishouapp.fumi:id/et_phonepwdlogin_pwd"),1);
            if(webElement != null){
                webElement.sendKeys("a123456");
                Thread.sleep(500);
            }

            // 同意隐私政策
            webElement = SeleniumUtil.findElementAndWait(driver,By.id("com.yishouapp.fumi:id/cb_user_privacy"),1);
            if(webElement != null){
                webElement.click();
            }

            // 点击登录
            webElement = SeleniumUtil.findElementAndWait(driver,By.id("com.yishouapp.fumi:id/btn_phonepwdlogin_confirm"),1);
            if(webElement != null){
                webElement.click();
                Thread.sleep(2000);
            }
        }else{
            logger.debug("一手已登录!");
        }

        // 允许app访问照片等媒体文件
        webElement = SeleniumUtil.findElementAndWait(driver,By.id("com.android.packageinstaller:id/permission_allow_button"),1);
        if(webElement != null){
            webElement.click();
            Thread.sleep(500);
        }

        // 新版本提示
        logger.debug("开始搜索是否有新版本提示!");
        webElement = SeleniumUtil.findElementAndWait(driver, By.id("com.yishouapp.fumi:id/common_multiple_layout_buttons"), 1);
        if(webElement != null) {
            webElement = SeleniumUtil.findElementAndWait(webElement, By.xpath(".//android.widget.TextView[1]"), 1);
            if(webElement != null){
                logger.debug("开始关闭新版本提示!");
                webElement.click();
                Thread.sleep(500);
            }
        }

        // 关闭推荐
        webElement = SeleniumUtil.findElementAndWait(driver,By.id("com.yishouapp.fumi:id/rl_close_container"),1);
        if(webElement != null){
            webElement.click();
            Thread.sleep(500);
        }

        logger.debug("appium一手登录检测完成!");
    }

    public static void qqLiteTest(String[] args) {
        //打包DesiredCapabilities这个类
        DesiredCapabilities des = new DesiredCapabilities();
        des.setCapability("platformName", "Android");
        des.setCapability("platformVersion", "7.1.2");
        des.setCapability("deviceName", "Android Emulator");
        des.setCapability("noReset", true);
        //获取包名及第一个页面的activity
        des.setCapability("appPackage", "com.tencent.qqlite");
        des.setCapability("appActivity", "com.tencent.mobileqq.activity.SplashActivity");

        //创建AppiumDriver对象,连接上Appium服务器,并将相应的键值对传过去
        AppiumDriver driver = null;
        try {
            driver = new AppiumDriver(new URL("http://192.168.1.186:4723/wd/hub"),des);
            driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

            // 步骤1:在登录页面用户名文本框中输入qq号码
            driver.findElementByAccessibilityId("请输入QQ号码或手机或邮箱").clear();
            driver.findElementByAccessibilityId("请输入QQ号码或手机或邮箱").sendKeys("xxxx");
            Thread.sleep(1000);

            // 步骤2:在登录页面密码文本框中输入密码
            driver.findElementById("com.tencent.qqlite:id/password_eye").click(); // 显示密码
            driver.findElementById("com.tencent.qqlite:id/password").click();
            driver.findElementById("com.tencent.qqlite:id/password").clear();
            driver.findElementById("com.tencent.qqlite:id/password").sendKeys("xxxx");
            Thread.sleep(1000);

            // 步骤3:点击登录按钮
            driver.findElementByAccessibilityId("登录QQ").click();
            // 滑动验证码的图标到相应的位置
            //driver.swipe(169, 334, 347, 344, 3000);
            Thread.sleep(10*1000);

            Thread.sleep(30*1000);

        } catch (Exception e) {
            logger.error("appiium异常,测试用例不通过!", e);
        }finally{
            if(driver != null){
                driver.quit();
            }
        }
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/877355.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号