【问题标题】:Wait for element to be present or clickable等待元素出现或可点击
【发布时间】:2020-03-29 05:31:47
【问题描述】:

我在尝试测试的应用程序上等待元素时遇到问题。有时 Appium 无法定位元素。

这是我的 BaseTests 类

package Base;

import helpers.TestValues;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;

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

public class BaseTests {
    protected AndroidDriver<AndroidElement> driver;

    @BeforeMethod
    public void setup () throws MalformedURLException {
        DesiredCapabilities caps = new DesiredCapabilities();
        caps.setCapability("deviceName", TestValues.devicesInfo.Honor10);
        caps.setCapability("platformName", TestValues.devicesInfo.PlatformName);
        caps.setCapability("platformVersion", TestValues.devicesInfo.Android810Version);
        caps.setCapability("skipUnlock", TestValues.devicesInfo.SkipUnlock);
        caps.setCapability("appPackage", TestValues.devicesInfo.AppPackageWageName);
        caps.setCapability("appActivity", TestValues.devicesInfo.AppPackageWageActivity);
        caps.setCapability("noReset","false");
        driver = new AndroidDriver<AndroidElement>(new URL("http://127.0.0.1:4723/wd/hub"),caps);
        driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
       }

    @AfterMethod
    public void teardown(){
        driver.quit();
    }
}

这是带有页面对象的 MainPage 类

package PageObjects;

import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import io.appium.java_client.pagefactory.AndroidFindBy;
import io.appium.java_client.pagefactory.AppiumFieldDecorator;
import org.openqa.selenium.support.PageFactory;



public class MainPage {
    private AndroidDriver<AndroidElement> driver;

    public MainPage(AndroidDriver<AndroidElement> driver) {
        this.driver = driver;
        PageFactory.initElements(new AppiumFieldDecorator(driver) ,this);
    }
    @AndroidFindBy(id = "add_task_button")
    private AndroidElement AddTaskButton;

    @AndroidFindBy(id = "com.android.packageinstaller:id/permission_allow_button")
    private AndroidElement PermissionAllowButton;

    public void ClickOnAllowButton(){
        PermissionAllowButton.click();
    }
    public boolean IsAddTaskVisible(){
        return AddTaskButton.isDisplayed();
    }
    public void ClickOnAddTaskButton() {

        AddTaskButton.click();
    }

}

还有测试

@Test
public void PostTask (){
_landingPage.clickOnLoginButton();
_loginPage.TypeEmail(TestValues.Credentials.CorrectEmail);
_loginPage.TypePassword(TestValues.Credentials.CorrectPassword);
_loginPage.ClickOnLoginBUtton();
_mainPage.ClickOnAllowButton();
//here is loading spinner because app fetch data from API
_mainPage.ClickOnAddTaskButton();
_mainPage.ClickOnAllowButton();
_postTaskPage.SendPhoto();
}

在大多数情况下,我的测试在单击添加任务按钮时失败,即使加载微调器消失 Appium 尝试找到它,因为我在控制台中看到

[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got data from client: {“cmd”:“action”,“action”:“find”,“params”:{“strategy”:“id”,“selector”:“add_task_button”,“context”:"",“multiple”:false}}

    [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got command of type ACTION

    [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got command action: find

    [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Finding 'add_task_button' using 'ID' with the contextId: '' multiple: false

    [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Using: UiSelector[INSTANCE=0, RESOURCE_ID=io.wageapp.android:id/add_task_button]

    [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Using: UiSelector[INSTANCE=0, RESOURCE_ID=android:id/add_task_button]

    [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Using: UiSelector[INSTANCE=0, RESOURCE_ID=add_task_button]

    [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Using: UiSelector[DESCRIPTION=add_task_button, INSTANCE=0]

    [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Failed to locate element. Clearing Accessibility cache and retrying.

    [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Finding 'add_task_button' using 'ID' wi

但大多数情况下它会因错误而失败

org.openqa.selenium.NoSuchElementException: Can’t locate an element by this strategy: By.chained({By.id: add_task_button})

但 id 是正确的(有时它会成功定位) https://i.postimg.cc/KjVYPnQF/2019-12-04-12-52-38-Appium.png 我究竟做错了什么?以及我应该如何正确处理“等待”以使我的测试能够抵抗这种情况。

提前致谢

【问题讨论】:

    标签: testing automated-tests appium qa appium-android


    【解决方案1】:

    首先:当您能够找到具有其他属性的元素时,不要使用xpath。在您的特定情况下,您可以通过调用 driver.findElementByAccessibilityId("Add offer");

    找到您的元素

    其次:如果您不想获取NoSuchElementException,请确保该元素在页面中。对于这种情况,您可以使用!driver.findElementsByAccessibilityId("Add offer").isEmpty();,如果它返回true,则查找获取此元素。

    注意:该方法名称是findElementsByAccessibilityId,它返回List&lt;T&gt;

    第三:确保你的元素有相应的属性,如vivsibleclickable等(根据你的需要)

    【讨论】:

    • 我使用了 id 和可访问性 id,在这两种情况下我得到了相同的结果,即使元素存在(并且它的 attrivutes 可点击并启用设置为 true),它找到了一次,两次或三次次没有找到,然后又找到了,依此类推:(
    • 这应该是这样的??: ``` AndroidElement element = null; boolean elementisVisible = !driver.findElementsByAccessibilityId("添加报价").isEmpty(); if(elementisVisible) element = driver.findElementByAccessibilityId("添加报价");元素.click(); ```
    猜你喜欢
    • 2022-11-28
    • 1970-01-01
    • 2015-10-11
    • 2016-12-29
    • 2020-02-23
    • 1970-01-01
    • 2016-05-09
    • 2012-03-26
    • 2020-02-23
    相关资源
    最近更新 更多