Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selenium: searching children of a By locator in Java

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));
like image 940
bagelmakers Avatar asked Dec 01 '25 08:12

bagelmakers


2 Answers

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"]')));   
like image 181
alecxe Avatar answered Dec 03 '25 22:12

alecxe


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-

like image 43
Chris R Avatar answered Dec 03 '25 22:12

Chris R



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!