Reputation: 351
I need to wait until the result of a javascript match a string or a boolean value.
With this javascript:
document.getElementById('video_html5').seeking;
I get a "false" / "true" value, and i need to wait until the value is "false", so I'm sure that the video is not seeking, but I only found the way to wait for a javascript command value and not the way to check that the value matches some text.
new WebDriverWait(driver, 30)
.until(ExpectedConditions.jsReturnsValue("return document.getElementById('video_html5').seeking;"));
Because in some cases I get a string other than boolean and need to compare those strings.
I have found how to do it in Ruby but not in Java:
wait_element = @wait.until { @driver.execute_script("return document.getElementById('vid1_html5_api_Shaka_api').seeking;").eql? false }
Upvotes: 1
Views: 6669
Reputation: 11
Getting ideas for all the answers I create a function to wait for an element to change each and waiting N seconds, using the xpath of the element and the expected value.
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;
}
Upvotes: 0
Reputation: 351
Finally i did the following and worked, getting ideas from different answers:
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;
}
Upvotes: 0
Reputation: 4858
A generic way to do it (where command
is the JavaScript you want to run with webdriver
in timeout
seconds):
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];
}
Upvotes: 1
Reputation: 3791
You can write your own custom expected conditions.
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' || ... ");
}
};
}
}
And then in your tests you can use the condition as follows.
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(MyCustomConditions.myCustomCondition());
Upvotes: 6