【问题标题】:Appium cannot find an element by content-description/accessibilityIDAppium 无法通过 content-description/accessibilityID 找到元素
【发布时间】:2017-04-24 00:32:03
【问题描述】:

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

        /**
        * 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

【问题讨论】:

  • 您使用的 Appium 版本是什么?
  • 我目前使用的是 1.6.2
  • 您可以从 uiauomatorviewer 屏幕发布元素详细信息吗?

标签: android testing appium


【解决方案1】:

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

在功能中添加超时。

capabilities.setCapability("newCommandTimeout", 50);

如果元素是,则使用这些基于元素类型的显式等待函数 可点击尝试等待可点击,如果元素不可点击尝试 仅具有元素的可见性

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));
     }

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 我试过这个,但它一直给我一个错误并告诉我它需要一个方法调用 ByXPath
    • 你能从 appium 控制台发布日志吗?因为这适用于我的 1.5.x ,还没有在 1.6.2 上尝试过
    • 信息:使用 javac 1.8.0_111 编译 java 源信息:java:编译模块“appiumTest”时发生错误信息:12/8/16,下午 1:13 - 编译完成,出现 1 个错误和2 秒 385 毫秒内出现 0 个警告 /Users/appium/IdeaProjects/appiumTest/src/FirstTest.java 错误:(33, 37) java:找不到符号符号:方法 ByXPath(java.lang.String) 位置:类 org.openqa.selenium .By 这就是我尝试运行发布的功能时得到的。它甚至不会开始。但是,当我执行 findByXPath 时,它会在终端中为我提供此输出
    • [AndroidBootstrap] [BOOTSTRAP LOG] [debug] 得到了 ACTION 类型的命令 [AndroidBootstrap] [BOOTSTRAP LOG] [debug] 得到了命令动作:find [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Finding ' //*[@content-desc='wutitdo']' 使用 'XPATH' 和 contextId: '' multiple: false
    • 我没有想法 :( 尝试其他定位器 By.name 或类似的,看看你是否能得到结果。如果没有一个定位器工作,那么它可能是一些能力属性丢失。跨度>
    【解决方案3】:
    @AndroidFindBy(accessibility = "Error Message")
    private MobileElement ERROR_MESSAGE;
    

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

    1) 速度——在您需要之前找到它以减少点击前的时间

    2) 自定义 -- 无需与 iOS 相同,因为您可以在其他注释之上使用 @iOSXCUITFindBy(id = "Accessibility ID")

    3) Lazily Finds Elements -- 只在需要时才找到元素!

    【讨论】:

      猜你喜欢
      • 2023-01-19
      • 2019-05-06
      • 2020-07-22
      • 2017-09-14
      • 2019-06-23
      • 1970-01-01
      • 2022-07-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多