appium 3-31626 toast识别

1.toast弹窗,普通方式不能获取

例如使用getPageSource是无法找到toast的信息,uiautomatorViewer加载页面时间较长,也很难采集到toast信息

2.通过curl命令探测toast

for i in `seq 1 1000`;do
	date
	curl -X POST http://localhost:4723/wd/hub/session/d3608ba7-08fd-4f2c-8e24-d0e58cf8f05c/elements --data-binary '{"using":"xpath","value":"//*[@class=\"android.widget.Toast\"]"}' -H "Content-Type:application/json;charset=UTF-8"
	sleep 0.5
done

3.Uiautomator2对toast的支持

//Uiautomator2对toast的处理,尝试从当前界面去找toast,如果发现toast,就将toast生成一个节点(只给了text, className="android.widget.Toast", packageName="com.android.settings"3个属性)加到appium的元素树里,
     private void addToastMsgRoot(CharSequence tokenMSG){
        AccessibilityNodeInfo node = AccessibilityNodeInfo.obtain();
        node.setText(tokenMSG);
        node.setClassName(Toast.class.getName());
        node.setPackageName("com.android.settings");
        this.children.add(new UiAutomationElement(node));
}

3.1根据以上代码,可以使用xpath查找

  • 通过//*[@class='android.widget.Toast']
  • 通过//*[contains(@text,"xxxx")]
  • 通过//*[@package="com.android.settings"] 使用包名去匹配toast时,注意不要和当前应用冲突,例如设置

3.2使用Java脚本探测

TestToast.java代码

#java
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.TimeUnit;

public class TestToast {
    private AndroidDriver driver;
    @Before
    public void setUp() throws MalformedURLException {

        DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
        desiredCapabilities.setCapability("platformName","android");
        desiredCapabilities.setCapability("deviceName","demo");
        desiredCapabilities.setCapability("appPackage","io.appium.android.apis");
        desiredCapabilities.setCapability("appActivity",".ApiDemos");
        desiredCapabilities.setCapability("noReset",true);
        desiredCapabilities.setCapability("newCommandTimeout",120);
        desiredCapabilities.setCapability("automationName","UiAutomator2");
        URL RemoteURL = new URL("http://localhost:4723/wd/hub");
        driver = new AndroidDriver(RemoteURL,desiredCapabilities);
        driver.manage().timeouts().implicitlyWait(20000,TimeUnit.SECONDS);


    }
    public boolean Exist(String str) throws InterruptedException{
        try{
            driver.findElementByXPath(str);
            return true;
        }catch (Exception e){
            return false;
        }

    }
    @Test
    public void test() throws InterruptedException{
        SwipeClass swipe = new SwipeClass();
        driver.findElementByXPath("//*[@text='Views']").click();
        for(int i=0;i<5;i++){
            if (Exist("//*[@text=\"Popup Menu\"]")){
                driver.findElementByXPath("//*[@text=\"Popup Menu\"]").click();
                break;
            }else {
                swipe.swipeToUp(driver);
                Thread.sleep(1000);
            }
        }
        Thread.sleep(2000);
        driver.findElementByXPath("//*[@text=\"MAKE A POPUP!\"]").click();
        Thread.sleep(1000);
        driver.findElementByXPath("//*[@text=\"Search\"]").click();
        Thread.sleep(1000);
        System.out.println(driver.findElementByXPath("//*[@class=\"android.widget.Toast\"]").getText());
        //System.out.println(driver.findElementByXPath("//*[@package=\"com.android.settings\"]").getText());
        //System.out.println(driver.findElementByXPath("//*[contains(@text,'Clicked popup')]").getText());
    }
    @After
    public void tearDown(){
        driver.quit();
    }
}

4.扩展:自动化滚动

官方示例
java_client/android/AndroidSearchingTest.java

  • 方法1
    public void testAutoSwipe1(){
        System.out.println("MethodName: "+Thread.currentThread().getStackTrace()[1].getMethodName());
        driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);
        WebDriverWait wait = new WebDriverWait(driver,10);
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@text='Views']")));
        driver.findElementByXPath("//android.widget.TextView[@text=\"Views\"]").click();
        WebElement radioGroup = driver
                .findElementByAndroidUIAutomator("new UiScrollable(new UiSelector()"
                        + ".resourceId(\"android:id/list\")).scrollIntoView("
                        + "new UiSelector().text(\"Popup Menu\"));");
        driver.findElementByXPath("//*[@text='Popup Menu']").click();
        driver.findElementByXPath("//*[@text=\"MAKE A POPUP!\"]").click();
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@text=\"Search\"]")));
        driver.findElementByXPath("//*[@text=\"Search\"]").click();
        System.out.println(driver.findElementByXPath("//*[@package=\"com.android.settings\"]").getText());
    }
* 方法2,滑动找到元素直接点击 ```#java public void testAutoSwipe2(){ System.out.println("MethodName: "+Thread.currentThread().getStackTrace()[1].getMethodName()); driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS); WebDriverWait wait = new WebDriverWait(driver,10); wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@text='Views']"))); driver.findElementByXPath("//android.widget.TextView[@text=\"Views\"]").click(); driver.findElementByAndroidUIAutomator("new UiScrollable(new UiSelector()" +".resourceId(\"android:id/list\")).scrollIntoView(" +"new UiSelector().text(\"Popup Menu\"));").click(); driver.findElementByXPath("//*[@text=\"MAKE A POPUP!\"]").click(); wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@text=\"Search\"]"))); driver.findElementByXPath("//*[@text=\"Search\"]").click(); System.out.println(driver.findElementByXPath("//*[@class=\"android.widget.Toast\"]").getText()); } ```
  • 方法3
    public void testAutoSwipe3() throws InterruptedException{
        System.out.println("MethodName: "+Thread.currentThread().getStackTrace()[1].getMethodName());
        WebDriverWait wait = new WebDriverWait(driver,10);
        WebElement el = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//android.widget.TextView[@text=\"Views\"]")));
        driver.findElementByXPath("//android.widget.TextView[@text=\"Views\"]").click();
        WebElement list = driver.findElement(By.id("android:id/text1"));
        MobileElement webview = list.findElement(MobileBy.AndroidUIAutomator("new UiScrollable(new UiSelector()).scrollIntoView("+"new UiSelector().text(\"Popup Menu\"));"));
        driver.findElementByXPath("//android.widget.TextView[@text=\"Popup Menu\"]").click();
        Thread.sleep(1000);
        driver.findElementByXPath("//*[@text=\"MAKE A POPUP!\"]").click();
        Thread.sleep(1000);
        driver.findElementByXPath("//*[@text=\"Search\"]").click();
        Thread.sleep(1000);
        System.out.println(driver.findElementByXPath("//*[contains(@text,'Clicked popup')]").getText());

    }

FAQ

1.自动滚动去寻找元素,会提示引用类型错误的提示

解决办法:只要将MobileElement替换为WebElement即可
posted on 2018-10-06 21:54  singleSpace  阅读(451)  评论(0编辑  收藏  举报