Appium无法通过content-description / accessibilityID找到元素

时间:2016-12-08 17:07:35

标签: android testing appium

我一直在尝试使用Java进行Appium测试设置以在Android上进行测试。为了验证我的元素,我一直在使用AndroidUiAutomator。在UI Automator Viewer中,我可以看到已传播辅助功能标签(请参阅附图)。当我使用findElement(By.name | By.AccessibilityId | etc时,它通常只会超时,并且必须重新启动Appium服务器终端控制台才能运行测试。我使用FindByXPath获得类似的结果。我尝试使用超时和等待驱动程序等待确保元素已加载,但无济于事。我已经尝试了下面代码中列出的所有内容。

        /**
        * Created by appium on 12/6/16.
        */
     import io.appium.java_client.AppiumDriver;
    import io.appium.java_client.android.AndroidDriver;
    import io.appium.java_client.MobileElement;
    import io.appium.java_client.android.AndroidElement;
    import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.WebDriver;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.support.ui.Select;
import java.util.*;



import java.net.URL;

public class FirstTest {
    AndroidDriver   driver;

    @Before
    public void setUp() throws Exception {

        DesiredCapabilities capabilities = new DesiredCapabilities();


        capabilities.setCapability("deviceName", "Android Emulator");
        capabilities.setCapability("BROWSER_NAME", "Android");
        capabilities.setCapability("app", apkloc);


        capabilities.setCapability("VERSION", "5.0.0");
        capabilities.setCapability("platformName", "Android");

        driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
        // Thread.sleep(100);
        //driver.manage().timeouts().implicitlyWait(100000, TimeUnit.SECONDS);

        System.out.println("driver1=" + driver);


    }




    @Test
    public void login() throws InterruptedException {
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        MobileElement mo = (MobileElement) driver.findElementByAndroidUIAutomator("new UiSelector().text(\"username\")");
        WebDriverWait wait = new WebDriverWait(driver, 1000);
        System.out.println("driver4=" + driver);
        WebElement element = driver.findElement(By.xpath("//EditText[@text='username']"));
        WebElement  elly = driver.findElementByXPath("//[@id=wutitdo]");
        System.out.println("olly-mint: "+elly);

        WebElement element2 = driver.findElementByName("password");
        //WebElement element3 = driver.findElementByXPath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.webkit.WebView[1]/android.view.View[4]");
        //WebElement element4 = driver.findElementByName("");

        //WebElement element3 = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.webkit.WebView[1]/android.view.View[4]")));
        // WebElement exp = (WebElement) (new WebDriverWait(driver, 15)).until(ExpectedConditions.presenceOfElementLocated(By.name("Trip")));
        System.out.println("dr" + driver);
        //element.click();
        //WebDriverWait wait = new WebDriverWait(driver, 10);
       // element2.click();
        Thread.sleep(1000);
        //element3.click();

        //WebElement current = (new WebDriverWait(driver,100)).until(ExpectedConditions.presenceOfElementLocated(By.name("username")));
        //current.sendKeys();
       // WebElement dropdown = driver.findElement(By.xpath("//*[@id='wrapper']/table[2]/tbody/tr[24]/td[3]/select[1]"));

        //WebElement dropdown = driver.findElement(By.xpath("//*[@id='wrapper']/table[2]/tbody/tr[24]/td[3]/select[1]"));


        //Select listbox = new Select(driver.findElement(By.xpath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.webkit.WebView[1]/android.view.View[1]/android.view.View[0]")));
        //listbox.selectByIndex(0);
        //listbox.selectByIndex(3);
        //driver.findElement(By.xpath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.webkit.WebView[1]/android.view.View[1]/android.view.View[3]")).click();
        //Thread.sleep(2000);

        //element4.click();
        //Thread.sleep(1000);
    }



    @After
    public void tearDown() throws Exception {


        System.out.println("driver3=" + driver);
        driver.quit();


    }

}


[![enter image description here][1]][1]


  [1]: https://i.stack.imgur.com/JPegT.png

3 个答案:

答案 0 :(得分:1)

您未使用default timeout,因此如果定位符正确,appium服务器可以花时间搜索元素。您应该使用显式等待来正确加载元素。

在功能中添加超时。

capabilities.setCapability("newCommandTimeout", 50);

如果element是,则根据元素类型使用这些显式等待函数 clickable try等待clickable,如果元素不是clickable,请尝试 仅包含元素的可见性

WebDriverWait wait = new WebDriverWait(driver, 30);

public void waitForMobileElementVisible(MobileElement element)
    {
           wait.until(ExpectedConditions.visibilityOf(element));

     }



    public void waitForMobileElementClickable(By by)
    {
            wait.until(ExpectedConditions.elementToBeClickable(by));
     }

答案 1 :(得分:0)

要在Android上使用按内容说明查找,您必须使用以下内容:

public WebElement getByContentDescription(String string){
    return driver.findElement(By.ByXPath("//*[@content-desc='"+string+"']");
}

答案 2 :(得分:0)

import pandas as pd
import numpy as np

df = pd.DataFrame({
        'Time' : ['09:00:00.1','09:00:00.1','09:00:00.1','09:00:00.1','09:00:00.1','09:00:00.2','09:00:00.2','09:00:00.2','09:00:00.2','09:00:00.2'],                 
        'Label' : ['A','B','C','D','E','A','B','C','D','E'],                 
        'X' : [8,4,3,8,7,7,3,3,4,6],
        'Y' : [3,3,3,4,3,2,1,2,4,2],
        })

# make the radii explicit
df.loc[:, 'norm2'] = np.linalg.norm(df.loc[:, ['X', 'Y']].values, axis=1)
# 517 µs ± 4.68 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

# with radii appended
In [1]: df
Out[1]:
         Time Label  X  Y     norm2
0  09:00:00.1     A  8  3  8.544004
1  09:00:00.1     B  4  3  5.000000
2  09:00:00.1     C  3  3  4.242641
3  09:00:00.1     D  8  4  8.944272
4  09:00:00.1     E  7  3  7.615773
5  09:00:00.2     A  7  2  7.280110
6  09:00:00.2     B  3  1  3.162278
7  09:00:00.2     C  3  2  3.605551
8  09:00:00.2     D  4  4  5.656854
9  09:00:00.2     E  6  2  6.324555


# indexing the DataFrame before counting with `groupby`

In [2]: df[df['norm2'] < 4].groupby(['Time', 'Label'])['norm2'].count()
Out[2]:
Time        Label
09:00:00.2  B        1
            C        1
Name: norm2, dtype: int64

我建议使用Appium的Java客户端提供的注释来通过内容描述查找元素。有一些好处:

1)速度-在需要它以减少点击前的时间之前进行查找

2)自定义-无需与iOS保持一致,因为您可以在其他注释的顶部使用@iOSXCUITFindBy(id =“ Accessibility ID”)

3)懒惰地查找元素-仅在需要时才查找元素!