51Testing软件测试论坛

标题: appium三种等待元素的方法 [打印本页]

作者: 测试积点老人    时间: 2019-1-7 16:35
标题: appium三种等待元素的方法
学过selenium的都知道,一般等待元素加载有三种办法:
(1)sleep                  强制等待。示例:Thread.sleep(60000)
(2)implicitlyWait   隐式等待。全局等待30s不管元素是否已经加载

示例:driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
(3)WebDriverWait     显示等待,这个需要增加一定等待时间,显示等待时间可以通过WebDriverWait 和util来决定,比如这个timeOut是60,如果该元素60s以内出现就不在等待
  1. WebDriverWait wait = new WebDriverWait(driver, 60);
  2.     WebElement e= wait.until(new  ExpectedCondition<WebElement>() {
  3.             @Override
  4.             public WebElement apply(WebDriver d) {
  5.                 return d.findElement(By.id("q"));
  6.             }
  7.         })
复制代码

以上三种方法中,只用WebDriverWait是selenium所特有,在java-client中也找不到相应的,如果想使用这种方法怎么办?

改造轮子,首先添加AndroidDriverWait.java, 其实是将WebDriverWait的类型改成AndroidDriverWait

具体代码如下:

  1. import org.openqa.selenium.NotFoundException;
  2. import org.openqa.selenium.TimeoutException;
  3. import org.openqa.selenium.WebDriver;
  4. import org.openqa.selenium.WebDriverException;
  5. import org.openqa.selenium.remote.RemoteWebDriver;
  6. import org.openqa.selenium.support.ui.Clock;
  7. import org.openqa.selenium.support.ui.FluentWait;
  8. import org.openqa.selenium.support.ui.Sleeper;
  9. import org.openqa.selenium.support.ui.SystemClock;

  10. import io.appium.java_client.android.AndroidDriver;

  11. import java.util.concurrent.TimeUnit;

  12. /**
  13.   * A specialization of {[url=home.php?mod=space&uid=26824]@link[/url] FluentWait} that uses WebDriver instances.
  14.   */
  15. public class AndroidDriverWait extends FluentWait<AndroidDriver> {
  16.    public final static long DEFAULT_SLEEP_TIMEOUT = 500;
  17.    private final WebDriver driver;

  18.    /**
  19.     * Wait will ignore instances of NotFoundException that are encountered (thrown) by default in
  20.     * the 'until' condition, and immediately propagate all others.  You can add more to the ignore
  21.     * list by calling ignoring(exceptions to add).
  22.     *
  23.     * @param driver The WebDriver instance to pass to the expected conditions
  24.     * @param timeOutInSeconds The timeout in seconds when an expectation is called
  25.     * @see AndroidDriverWait#ignoring(java.lang.Class)
  26.     */
  27.    public AndroidDriverWait(AndroidDriver driver, long timeOutInSeconds) {
  28.      this(driver, new SystemClock(), Sleeper.SYSTEM_SLEEPER, timeOutInSeconds, DEFAULT_SLEEP_TIMEOUT);
  29.    }

  30.    /**
  31.     * Wait will ignore instances of NotFoundException that are encountered (thrown) by default in
  32.     * the 'until' condition, and immediately propagate all others.  You can add more to the ignore
  33.     * list by calling ignoring(exceptions to add).
  34.     *
  35.     * @param driver The WebDriver instance to pass to the expected conditions
  36.     * @param timeOutInSeconds The timeout in seconds when an expectation is called
  37.     * @param sleepInMillis The duration in milliseconds to sleep between polls.
  38.     * @see AndroidDriverWait#ignoring(java.lang.Class)
  39.     */
  40.    public AndroidDriverWait(AndroidDriver driver, long timeOutInSeconds, long sleepInMillis) {
  41.      this(driver, new SystemClock(), Sleeper.SYSTEM_SLEEPER, timeOutInSeconds, sleepInMillis);
  42.    }

  43.    /**
  44.     * @param driver The WebDriver instance to pass to the expected conditions
  45.     * @param clock The clock to use when measuring the timeout
  46.     * @param sleeper Object used to make the current thread go to sleep.
  47.     * @param timeOutInSeconds The timeout in seconds when an expectation is
  48.     * @param sleepTimeOut The timeout used whilst sleeping. Defaults to 500ms called.
  49.     */
  50.    public AndroidDriverWait(AndroidDriver driver, Clock clock, Sleeper sleeper, long timeOutInSeconds,
  51.        long sleepTimeOut) {
  52.      super(driver, clock, sleeper);
  53.      withTimeout(timeOutInSeconds, TimeUnit.SECONDS);
  54.      pollingEvery(sleepTimeOut, TimeUnit.MILLISECONDS);
  55.      ignoring(NotFoundException.class);
  56.      this.driver = driver;
  57.    }

  58.    @Override
  59.    protected RuntimeException timeoutException(String message, Throwable lastException) {
  60.      TimeoutException ex = new TimeoutException(message, lastException);
  61.      ex.addInfo(WebDriverException.DRIVER_INFO, driver.getClass().getName());
  62.      if (driver instanceof RemoteWebDriver) {
  63.        RemoteWebDriver remote = (RemoteWebDriver) driver;
  64.        if (remote.getSessionId() != null) {
  65.          ex.addInfo(WebDriverException.SESSION_ID, remote.getSessionId().toString());
  66.        }
  67.        if (remote.getCapabilities() != null) {
  68.          ex.addInfo("Capabilities", remote.getCapabilities().toString());
  69.        }
  70.      }
  71.      throw ex;
  72.    }
  73. }
复制代码

接着需要修改接口:ExpectedCondition,将其WebDriver的类型替换为AndroidDriver

具体代码:

public interface ExpectedCondition<T> extends Function<AndroidDriver, T> {}

经过修改之后,就可以在appium中直接使用:

  1. //wait for 60s if WebElemnt show up less than 60s , then return , until 60s
  2.         WebElement showClose = new AndroidDriverWait(driver, 60)
  3.                 .until(new ExpectedCondition<WebElement>() {
  4.                     public WebElement apply(AndroidDriver d) {
  5.                         return d.findElement(By
  6.                                 .id("com.zhihu.android:id/showcase_close"));
  7.                     }

  8.                 });
复制代码









欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2