Reputation: 409
I have an enum list of By locators for WebElements on a page. I want to be able to select a specific option of a select box using a combination of the enum as well as additional information of the value of the option I wish to select. Is there any way to do this? I notice that the By
class also has the method findElement(searchContext)
. Could I use this as something along the lines of:
public enum Dictionary {
TYPE (By.id("vehType")),
PROVINCE (By.id("provId")),
TERRITORY (By.id("territoryId")),
STAT_CODE (By.id("statCodeId")),
CLASS (By.id("class1Id"));
private final By locator;
private DetailVehicleDictionary (By value) {
this.locator = value;
}
public By getLocation() {
return this.locator;
}
}
And then if CLASS is a select box with HTML of:
<select id="class1Id" name="select_box">
<option value="1"/>
<option value="2"/>
<option value="3"/>
</select>
Can I do something along the lines of:
WebElement specificValue = driver.findElement(Dictionary.CLASS.getLocation().findElement(By.cssSelector("option[value=2]"));
I need to have access to the actual element so that I can wait for the value to be present in the DOM. I plan on implementing this in a wait command such as:
wait.until(ExpectedConditions.presenceOfElementLocated(specificValue));
Upvotes: 3
Views: 2085
Reputation: 2564
I was trying to do something similar to you - use a WebDriverWait
with an ExpectedConditions
so that I could wait for the element to be there and located it as a child element relative to an existing one.
Additional methods are now available in Selenium to handle this:
static ExpectedCondition<WebElement> presenceOfNestedElementLocatedBy(By locator, By sub_locator)
An expectation for checking child WebElement as a part of parent element to present
static ExpectedCondition<WebElement> presenceOfNestedElementLocatedBy(WebElement element, By sub_locator)
An expectation for checking child WebElement as a part of parent element to be present
static ExpectedCondition<java.util.List<WebElement>> presenceOfNestedElementsLocatedBy(By locator, By sub_locator)
An expectation for checking child WebElement as a part of parent element to present
So for your case you could do the following:
wait.until(ExpectedConditions.presenceOfNestedElementLocatedBy(Dictionary.CLASS.getLocation(), By.cssSelector("option[value=2]")));
See here for the Javadocs: https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html#presenceOfNestedElementLocatedBy-org.openqa.selenium.By-org.openqa.selenium.By-
Upvotes: 1
Reputation: 473873
Selenium has a special mechanism to handle "select/option" cases:
import org.openqa.selenium.support.ui.Select; // this is how to import it
WebElement select = driver.findElement(Dictionary.CLASS.getLocation());
Select dropDown = new Select(select);
dropDown.selectByValue("1");
Answer to a follow-up question: use an Explicit Wait:
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement select = wait.until(ExpectedConditions.presenceOfElement(Dictionary.CLASS.getLocation()));
In case of waiting for an option to load inside a select, I am afraid, you would need to make a custom ExpectedCondition
(not tested):
public static ExpectedCondition<Boolean> selectContainsOption(
final WebElement select, final By locator) {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
try {
return elementIfVisible(select.findElement(locator));
} catch (StaleElementReferenceException e) {
return null;
}
}
};
}
Usage:
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement select = wait.until(ExpectedConditions.presenceOfElement(Dictionary.CLASS.getLocation()));
WebElement option = wait.until(selectContainsOption(select, By.cssSelector('.//option[@value = "1"]')));
Upvotes: 3