测试积点老人 发表于 2019-1-7 16:35:55

appium三种等待元素的方法

学过selenium的都知道,一般等待元素加载有三种办法:
(1)sleep                  强制等待。示例:Thread.sleep(60000)
(2)implicitlyWait   隐式等待。全局等待30s不管元素是否已经加载

示例:driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
(3)WebDriverWait   显示等待,这个需要增加一定等待时间,显示等待时间可以通过WebDriverWait 和util来决定,比如这个timeOut是60,如果该元素60s以内出现就不在等待
WebDriverWait wait = new WebDriverWait(driver, 60);
    WebElement e= wait.until(newExpectedCondition<WebElement>() {
            @Override
            public WebElement apply(WebDriver d) {
                return d.findElement(By.id("q"));
            }
      })以上三种方法中,只用WebDriverWait是selenium所特有,在java-client中也找不到相应的,如果想使用这种方法怎么办?改造轮子,首先添加AndroidDriverWait.java, 其实是将WebDriverWait的类型改成AndroidDriverWait具体代码如下:import org.openqa.selenium.NotFoundException;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.Clock;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Sleeper;
import org.openqa.selenium.support.ui.SystemClock;

import io.appium.java_client.android.AndroidDriver;

import java.util.concurrent.TimeUnit;

/**
* A specialization of {@link FluentWait} that uses WebDriver instances.
*/
public class AndroidDriverWait extends FluentWait<AndroidDriver> {
   public final static long DEFAULT_SLEEP_TIMEOUT = 500;
   private final WebDriver driver;

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

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

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

   @Override
   protected RuntimeException timeoutException(String message, Throwable lastException) {
   TimeoutException ex = new TimeoutException(message, lastException);
   ex.addInfo(WebDriverException.DRIVER_INFO, driver.getClass().getName());
   if (driver instanceof RemoteWebDriver) {
       RemoteWebDriver remote = (RemoteWebDriver) driver;
       if (remote.getSessionId() != null) {
         ex.addInfo(WebDriverException.SESSION_ID, remote.getSessionId().toString());
       }
       if (remote.getCapabilities() != null) {
         ex.addInfo("Capabilities", remote.getCapabilities().toString());
       }
   }
   throw ex;
   }
}接着需要修改接口:ExpectedCondition,将其WebDriver的类型替换为AndroidDriver具体代码:public interface ExpectedCondition<T> extends Function<AndroidDriver, T> {}经过修改之后,就可以在appium中直接使用: //wait for 60s if WebElemnt show up less than 60s , then return , until 60s
      WebElement showClose = new AndroidDriverWait(driver, 60)
                .until(new ExpectedCondition<WebElement>() {
                  public WebElement apply(AndroidDriver d) {
                        return d.findElement(By
                              .id("com.zhihu.android:id/showcase_close"));
                  }

                });



页: [1]
查看完整版本: appium三种等待元素的方法