Take the 2-minute tour ×

In my application when I open page X I expect to see either element A or element B. They are placed in different locations in DOM and can be found using their ids, for example driver.findElement(By.id("idA"))

How can I ask webdriver to find either A or B?

There is method driver.findElements(By) which will stop waiting when at least one element is found, but this method forces me to use the same locator for A and B.

What is the proper way to reliably find either A or B, so that I don't have to wait implicit timeout?

share|improve this question
I played a bit around with driver.findElements(By.cssSelector("[id=a] [id=b]")) but that's not an or. I haven't found a css or selector. –  VolkerK Oct 23 '12 at 8:18

4 Answers 4

up vote 2 down vote accepted

Element with id I1 or element with id I2

xpath: //E1[@id=I1] | //E2[@id=I2]

css: css=E1#I1,E2#I2

driver.findElement(By.xpath(//E1[@id=I1] | //E2[@id=I2]))

don't forget about fluentWait mechanism:

   public WebElement fluentWait(final By locator){
                    .withTimeout(30, TimeUnit.SECONDS)
                    .pollingEvery(5, TimeUnit.SECONDS)
            WebElement foo = wait.until(
                    new Function<WebDriver, WebElement>() {
                        public WebElement apply(WebDriver driver) {
                            return driver.findElement(locator);
            return  foo;              }     ;

you can get more info about fluentWait here

IMHO solution to your issue be like:


FYI: here is nice xpath,cssSelector manual

hope this helps you.

share|improve this answer
approach using xpath OR operand worked like a charm! First I find any of those elements and then just check element.getAttribute("id") to find which one I actually found. Thank you! By the way, do I understand correctly that FluentWait allows to override default implicit timeout set by driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS); ? –  pavel_kazlou Oct 23 '12 at 21:37
What webdriver version are you using ? With 2.22 driver.findElement(By.cssSelector(E1#I1,E2#I2)) lead to an Exception org.openqa.selenium.WebDriverException: Compound selectors not permitted –  VolkerK Oct 24 '12 at 7:17
added one more answer on fluentWait –  eugene.polschikov Oct 24 '12 at 9:51
@VolkerK, I am using 2.24.1 . this piece of code: driver.get("tut.by/"); driver.manage().timeouts().implicitlyWait(5,TimeUnit.SECONDS); String cssAlternativeLink="[id=\"search-7-target\"]>a,[id=\"search-1-target\"]>a"; List<WebElement> a=driver.findElements(By.cssSelector(cssAlternativeLink)); a.get(0).click(); worked for me. Regards. –  eugene.polschikov Oct 24 '12 at 12:37
If "xpath: //E1[@id=I1] | //E2[@id=I2]" checks presence of one of the two elements, how would the the syntax look like for checking presence of all elements listed? –  Rado Koňuch Feb 28 at 10:37

Here is my solution, which uses a fluent wait as others have suggested. You would need to replace any calls to getDriver() or references to a driver with a driver object or your own method that fetches it.

 * Waits for any one of a given set of WebElements to become displayed and
 * enabled.
 * @param locators
 *            An array of locators to be sought.
 * @param timeout
 *            Timeout in seconds.
protected void waitForOneOfManyToBePresent(By[] locators, int timeout) {
    try {
        (new WebDriverWait(getDriver(), timeout))
    } catch (TimeoutException timeoutEx) {
        // Do what you wish here to handle the TimeoutException, or remove
        // the try/catch and let the TimeoutException fly. I prefer to
        // rethrow a more descriptive Exception

 * Condition for presence of at least one of many elements.
 * @param locators
 *            An array of By locators to be sought.
 * @return Boolean T if at least one element is present, F otherwise.
protected ExpectedCondition<Boolean> somethingIsPresent(By[] locators) {
    final By[] finalLocators = locators;
    return new ExpectedCondition<Boolean>() {
        public Boolean apply(WebDriver driver) {
            boolean found = false;
            for (By locator : finalLocators) {
                if (isElementPresent(locator)) {
                    found = true;
            return new Boolean(found);

 * Similar to does element exist, but also verifies that only one such
 * element exists and that it is displayed and enabled.
 * @param by
 *            By statement locating the element.
 * @return T if one and only one element matching the locator is found, and
 *         if it is displayed and enabled, F otherwise.
protected boolean isElementPresent(By by) {
    // Temporarily set the implicit timeout to zero
    driver.manage().timeouts().implicitlyWait(0, TimeUnit.MILLISECONDS);
    // Check to see if there are any elements in the found list
    List<WebElement> elements = driver.findElements(by);
    boolean isPresent = (elements.size() == 1)
            && elements.get(0).isDisplayed() && elements.get(0).isEnabled();
    // Return to the original implicit timeout value
                .implicitlyWait(Properties.TIMEOUT_TEST, TimeUnit.SECONDS);
    // Properties.TIMEOUT_TEST is from other personal code, replace with your 
    // own default timeout setting.
    return isPresent;

My version also checks to make sure that any found element is singular, visible and enabled, but you can remove that easily if you only want to check for existence or if you don't care if your locators are finding multiple matching elements. Checking for the presence of an element by suppressing the default timeout and then calling findElements() may seem clunky, but it's apparently the recommended way to do so in the Selenium API.

share|improve this answer

@pavel_kazlou, well concerning your question on FluentWait: basically there are two types of wait: Explicit wait


Implicit wait


Difference is

  • Obvious - Implicit wait time is applied to all elements in your script but Explicit only for particular element
  • In Explicit you can configure, how frequently (instead of 500 millisecond) you want to check condition.
  • In Explicit you can also configure to ignore other exceptions than "NoSuchElement" till timeout.. Use a FluentWait which works similarly to WebDriverWait (which in fact extends FluentWait) but gives you a little more flexibility.

here is WebDriverWait usage example(Use a different WebDriverWait constructor to specify the element polling interval (measured in milliseconds).):

new WebDriverWait(webDriver(), 10, 50).until(ExpectedConditions.elementToBeClickable(By.xpath(menuItemXpath)));

Using a FluentWait which works similarly to WebDriverWait (which in fact extends FluentWait) but gives you a little more flexibility:in particular the ability to choose the WebDriver exception to ignore. usage example:

new FluentWait(webDriver())
.withTimeout(timeout, TimeUnit.SECONDS)
.pollingEvery(50, TimeUnit.MILLISECONDS)

To conclude my note: fluentWait is an Explicit type of wait and provides you possibility to choose explicitly what type of WebDriver exception to ignore, where as any implicit wait includes fixed amount of time to wait for any webElement. IMHO fluentWait approach is more robust from this point of view.

share|improve this answer

I wrote an ExpectedCondition for this feel free to use it.

public static ExpectedCondition<By> titleIs(final By[] selectors) {
    return new ExpectedCondition<By>() {
        public By apply(WebDriver driver) {
            WebElement el=null;
            for (By selector:selectors) {
                try {
                    el = driver.findElement(selector);
                } catch (NoSuchElementException ex) {
                    // ignore as we are waiting for that to stop
                if (el!=null) return selector; 
            return null;
share|improve this answer

Your Answer


