Мне нужно подождать, пока результат JavaScript не совпадет со строкой или логическим значением.

С помощью этого JavaScript:

document.getElementById('video_html5').seeking;

Я получаю значение "false" / "true", и мне нужно подождать, пока значение не станет "false", поэтому я уверен, что видео не ищет, но я нашел только способ ожидания значения команды javascript а не способ проверить, что значение соответствует некоторому тексту.

new WebDriverWait(driver, 30)
    .until(ExpectedConditions.jsReturnsValue("return document.getElementById('video_html5').seeking;"));

Потому что в некоторых случаях я получаю строку, отличную от логического, и мне нужно сравнить эти строки.

Я нашел, как это сделать в Ruby, но не в Java:

wait_element = @wait.until { @driver.execute_script("return document.getElementById('vid1_html5_api_Shaka_api').seeking;").eql? false }
0
Lea Chescotta 9 Янв 2017 в 21:33

4 ответа

Лучший ответ

Вы можете написать свои собственные ожидаемые условия.

public class MyCustomConditions {

  public static ExpectedCondition<Boolean> myCustomCondition() {
    return new ExpectedCondition<Boolean>() {
      @Override
      public Boolean apply(WebDriver driver) {
        return (Boolean) ((JavascriptExecutor) driver)
          .executeScript("return document.getElementById('video_html5').seeking === 'string_value' || ... ");
      }
    };
  }
}

И тогда в ваших тестах вы можете использовать условие следующим образом.

WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(MyCustomConditions.myCustomCondition());
2
cjungel 9 Янв 2017 в 18:58

Общий способ сделать это (где command - это JavaScript, который вы хотите запустить с webdriver в timeout секундах):

public Object executeScriptAndWaitOutput(WebDriver driver, long timeout, final String command) {
  WebDriverWait wait = new WebDriverWait(driver, timeout);
  wait.withMessage("Timeout executing script: " + command);

  final Object[] out = new Object[1];
  wait.until(new ExpectedCondition<Boolean>() {
    @Override
    public Boolean apply(WebDriver d) {
      try {
        out[0] = executeScript(command);
      } catch (WebDriverException we) {
        log.warn("Exception executing script", we);
        out[0] = null;
      }
      return out[0] != null;
    }
  });
  return out[0];
}
1
Boni García 10 Янв 2017 в 12:41

Наконец я сделал следующее и работал, получая идеи из разных ответов:

public Boolean checkStateSeeking() throws InterruptedException {
        JavascriptExecutor js = (JavascriptExecutor) driver;
        Boolean seekingState = (Boolean) js
                .executeScript("return document.getElementById('vid1_html5').seeking;");

        while (seekingState) {
            // System.out.println(seekingState);
            seekingState = (Boolean) js
                    .executeScript("return document.getElementById('vid1_html5').seeking;");
        }

        return seekingState;
    }
0
Lea Chescotta 10 Янв 2017 в 18:59

Получая идеи для всех ответов, я создаю функцию для ожидания изменения элемента каждый раз и ожидания N секунд, используя xpath элемента и ожидаемое значение.

 public static String checkValueChanged(WebDriver driver, String expectedValue, String path, int waitTime) throws InterruptedException {
    JavascriptExecutor js = (JavascriptExecutor) driver;
    String elementValue = (String) js
            .executeScript("return document.evaluate(\""+path+"\", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.value;");

    while (!(elementValue.equals(expectedValue)) && (waitTime>0)) {
        Thread.sleep(1000);
        waitTime--;
        elementValue = (String) js
                .executeScript("return document.evaluate(\""+path+"\", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.value;");
    }
    return elementValue;
}
0
Jorge Quiros 13 Мар 2019 в 20:56