2

I have two elements I can wait for, I want to wait until either of them appears on the page.

I am trying to use xpath locator. But it is not working.

By.xpath("//*[(contains(@id,'idNumber1')) or (contains(@id,'idNumber2'))]"));

Is this achievable?
Please help me out.

DebanjanB
  • 118,661
  • 30
  • 168
  • 217
  • not working mean what. getting any error or anything else ? – NarendraR Jul 18 '17 at 12:23
  • Possible duplicate of [XPath OR operator for different nodes](https://stackoverflow.com/questions/5350666/xpath-or-operator-for-different-nodes) – JeffC Jul 19 '17 at 02:01

4 Answers4

5

It is possible to wait for one of two elements in the page using ExpectedConditions.or():

WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.or(
    ExpectedConditions.elementToBeClickable(By.id("idNumber1")),
    ExpectedConditions.elementToBeClickable(By.id("idNumber2"))
)); 

You can also do an OR with a CSS selector using a comma ,:

wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#idNumber1, #idNumber2"));
JeffC
  • 18,375
  • 5
  • 25
  • 47
DebanjanB
  • 118,661
  • 30
  • 168
  • 217
  • @JeffC Thanks for the edit. But I am still wondering about your comment **"Removed references to XPath that didn't exist in code"**. The two code changes you made are: replaced the name of object from `wait9` to `wait` & replaced `wait10` to `wait`. Where is the **references to XPath ?**. Please clarify. Additionally, is a object name as `wait9` & `wait10` invalid? Please explain. Thanks – DebanjanB Jul 19 '17 at 03:01
  • Exactly... there were no XPaths in your code but your descriptions referenced them twice, "It is possible to wait for one of two elements in the page using selenium **xpath**" and, "Using **`xpath`**:". You can see in the edits for yourself. – JeffC Jul 19 '17 at 13:25
  • `wait9` and `wait10` aren't invalid but what do they mean? What is `wait9` vs `wait10`? How will another user, or yourself in a few months, know what the difference is. In your sample code, the two waits were exactly the same so there's no need to have different variable names. Once `wait` is declared, it can be reused for any other scenario that can use a 10s wait. I think people forget that often because I see it in answers.. I simplified it here as a part of the cleanup/edit. – JeffC Jul 19 '17 at 13:26
  • @JeffC This was the `xpath` code block where you needlessly converted `wait9` to `wait`: `WebDriverWait wait9 = new WebDriverWait(driver, 10); wait9.until(ExpectedConditions.or( ExpectedConditions.elementToBeClickable(By.id("idNumber1")), ExpectedConditions.elementToBeClickable(By.id("idNumber2")) )); ` – DebanjanB Jul 19 '17 at 13:33
  • I saw the code before and I can see it now in the edits. You didn't answer my questions. There's no need to slap a 9 on the end of the variable name... where are the other 8? What does the 9 mean? It means nothing in this context so I removed it... which I already explained. – JeffC Jul 19 '17 at 13:38
  • 1
    @JeffC This was the `css` code block where you needlessly removed the line `WebDriverWait wait10 = new WebDriverWait(driver, 10);`, orphaned the line: `WebDriverWait wait10 = new WebDriverWait(driver, 10); wait10.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#idNumber1, #idNumber2"));` and needlessly converted `wait10` to `wait` which looks to me unethical as per stackoverflow standards. Thanks – DebanjanB Jul 19 '17 at 13:40
  • Are you going to nitpick every change I made? I already explained why I did it. I removed the second `wait` declaration because it was exactly the same as the first, which is already contained in the first code block, so there is no need to have it twice. – JeffC Jul 19 '17 at 13:42
  • @JeffC Whats wrong in a object name as `Obj10` or `obj100` or `_time` ? – DebanjanB Jul 19 '17 at 13:42
  • I'm not going to keep answering the same question over and over. Read my previous two replies. You need to explain why you need the 9 or 10 appended to the variable here... what purpose does it serve? – JeffC Jul 19 '17 at 13:44
  • I think you need to understand `Java`, `Python`, etc languages have their own variable naming convention and standards. As far as my code follows them and produces accurate results there shouldn't be any nitpicks. Thanks – DebanjanB Jul 19 '17 at 13:49
0

Please provide few seconds of wait before move to this code, so your driver may able to find the web-element.

Try this xpath

//*[contains(@id, 'idNumber1') or contains(@id, 'idNumber2')]
Jainish Kapadia
  • 2,535
  • 4
  • 14
  • 28
  • 2
    Any specific difference with what OP have ? – NarendraR Jul 18 '17 at 12:19
  • Yes, there is no specific difference between above @karthik and mine `xpath`. But it's makes difference in term of syntax only. for more details on this please refer this link. https://www.w3schools.com/xml/xpath_syntax.asp – Jainish Kapadia Jul 18 '17 at 12:39
0

The xpath looks valid. Use explicit wait to wait for visibility

WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[(contains(@id,'idNumber1')) or (contains(@id,'idNumber2'))]")));
Guy
  • 34,831
  • 9
  • 31
  • 66
0

Try this Xpath :-

By.xpath("//*[contains(@id,'idNumber1') or (contains(@id,'idNumber2'))]"))
Ankur Singh
  • 1,139
  • 1
  • 5
  • 17