selenium에서 스텔스로 기다릴까요 아니면 디스플레이로 기다릴까요

20813 단어 자동화 테스트

암시적 대기 vs 대기 표시


스텔스 대기
대기 표시
전역 성명, 코드 간결
부분적 성명, 코드 복잡 불필요
웹 드라이브 제어 브라우저에서 발생할 때까지 기다릴 때, 원소를 가져오는 데만 적용됩니다.
로컬에서 발생하는 코드 논리를 기다리며, 가져오는 조건을 사용자 정의할 수 있습니다
요소 가져오기만 지원되며 시간 초과를 찾을 수 없습니다.
대기 원소가 사라지는 것을 판단할 수 있습니다
반환 결과는 원소 또는 시간 초과 이상입니다
반환 결과는 사용자 정의할 수 있습니다

코드 대비

/**
*    
*/
WebDriver driver = new FirefoxDriver();
//       webDiver             10s
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("https://blog.csdn.net/zkf9044");
WebElement myDynamicElement = driver.findElement(By.id("uid"));

/**
*    
*/
WebDriver driver = new FirefoxDriver();
driver.get("https://blog.csdn.net/zkf9044");
//        ,                  10 
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement myDynamicElement = wait.until(
  ExpectedConditions.presenceOfElementLocated(By.id("uid"))//        
  );

다음은 예상 조건을 내장한 API: https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html

표시 대기 조건 사용자 정의


만약 당신이 어떻게 써야 할지 모른다면, 내장된 예상 조건의 원본 ExpectedConditions.presenceOfElementLocated(By.id("uid"))을 보십시오. 원본은 매우 간단하고, 읽기에 아무런 부담이 없습니다
 public static ExpectedCondition<WebElement> presenceOfElementLocated(
      final By locator) {
    return new ExpectedCondition<WebElement>() {
      @Override
      public WebElement apply(WebDriver driver) {
        return findElement(locator, driver);
      }

      @Override
      public String toString() {
        return "presence of element located by: " + locator;
      }
    };
  }

다시 wait.until(ExpectedConditions.presenceOfElementLocated(By.id("uid")));until 방법의 원본은 그가 Function류의 apply()방법을 집행하고 ExpectedConditionFunction의 자류이다.
계속해서 apply () 를 분석하고 실행합니다. 만약 반환값이 비어 있지 않고 boolean 유형일 때 반환 결과가true일 경우 반환 결과를 반환합니다. 그렇지 않으면 0.5초 동안 수면한 후에 검사하고, 대기시간이 설정된 최대 대기시간을 초과하면 이상 timeoutException을 던집니다.
public <V> V until(Function<? super T, V> isTrue) {
    long end = clock.laterBy(timeout.in(MILLISECONDS));
    Throwable lastException = null;
    while (true) {
      try {
        V value = isTrue.apply(input);
        if (value != null && Boolean.class.equals(value.getClass())) {
          if (Boolean.TRUE.equals(value)) {
            return value;
          }
        } else if (value != null) {
          return value;
        }
      } catch (Throwable e) {
        lastException = propagateIfNotIngored(e);
      }

      // Check the timeout after evaluating the function to ensure conditions
      // with a zero timeout can succeed.
      if (!clock.isNowBefore(end)) {
        String message = messageSupplier != null ?
            messageSupplier.get() : null;

        String toAppend = message == null ?
            " waiting for " + isTrue.toString() : ": " + message;

        String timeoutMessage = String.format("Timed out after %d seconds%s",
            timeout.in(SECONDS), toAppend);
        throw timeoutException(timeoutMessage, lastException);
      }

      try {
        sleeper.sleep(interval);
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new WebDriverException(e);
      }
    }
  }

원본 분석을 통해 알 수 있듯이 우리는 ExpectedCondition 인터페이스를 실현하여 apply을 다시 써야 한다
//              
private static ExpectedCondition<WebElement> elementToBeClickable(
		      final By locator) {
		      //  ExpectedCondition      WebElement
		    return new ExpectedCondition<WebElement>() {

		      public ExpectedCondition<WebElement> visibilityOfElementLocated =
		          ExpectedConditions.visibilityOfElementLocated(locator);

		      @Override
		      public WebElement apply(WebDriver driver) {
		      		//                apply()
		        WebElement element = visibilityOfElementLocated.apply(driver);
		        try {
		        	 String isDisabled=element.getAttribute("disabled");
		          if (element != null && element.isEnabled() && StringUtils.isEmpty(isDisabled)) {					
		          	//element              null    
		            return element;
		          } else {
		            return null;
		          }
		        } catch (Throwable e) {
		          return null;
		        }
		      }

		      @Override
		      public String toString() {
		        return "element to be clickable: " + locator;
		      }
		    };
		  }


//     
//               ,    
WebElement element= wait.until(elementToBeClickable(By.id("btn")));
element.click();

총결산


디스플레이를 사용하면 기다리는 것이 가장 좋고, 좋은 것은 비싼 것 외에는 무엇이든지 좋다.

좋은 웹페이지 즐겨찾기