0

I am running a test nightly via Jenkins. About 95% of the time it passes. But occasionally it is failing doing this:

driver.findElement(By.xpath("//div[contains(@id, 'stage')]/div[contains(@class, 'tabMenu')]/span[contains(@class, 'menuItem') and contains(text(),'Employer')]"))

with an org.openqa.selenium.InvalidSelectorException. Note: this almost always works.

So I debug using Eclipse and Java and Selenium. Again, I had to run the test about 30 times before getting this error.

I am using Selenium and IE. IE does not have good debugging so using Eclipse Debug Shell I write the page source to a file, rename the file to an html file and edit with Chrome. In the inspect window I do a search for

 //div[contains(@id, 'stage')]/div[contains(@class, 'tabMenu')]/span[contains(@class, 'menuItem') and contains(text(),'Employer')]

and it finds it and highlights it. When I from debug shell do a

 driver.findElement(By.xpath("//div[contains(@id, 'stage')]/div[contains(@class, 'tabMenu')]/span[contains(@class, 'menuItem') and contains(text(),'Employer')]"))

I get the

 org.openqa.selenium.InvalidSelectorException:Unable to locate an element ... because of the following error:
 [object Error] (WARNING: The server did not provide any stacktrace information)

So I thought I would just get all the divs and get their IDs:

 driver.findElement(By.xpath("//div"))

and I get

 org.openqa.selenium.InvalidSelectorException: Unable to locate an element with the xpath expression //div because of the following error:
[object Error] (WARNING: The server did not provide any stacktrace information)

so OK. I try driver.findElement(By.xpath("//*")) and still get the InvalidSelectorException

so "//*" would have to find elements. And even if it didn't, shouldn't it return something like a NoSuchElementException rathe than an InvalidSelectorException? Anyone know what is happening? I did a search to find the meaning of InvalidSelectorException and found usage but not really a definition.

So I guess I have two questions: 1. why aren't any elements (even "//*") being found, and 2. Shouldn't it be returning NoSuchElementException and not InvalidSelectorExmaple?

Cosmin
  • 2,354
  • 2
  • 22
  • 39
Tony
  • 1,127
  • 1
  • 18
  • 29
  • you're giving the driver a pretty confusing xpath... it mixes a path based selectors indicating the first span after a certain div (with relative requirements) with a directive that it must contain two values. Find a less brittle xpath and possibly add a webdriverwait there since this happens only sometimes which suggests a timing issue. Post the HTML of the element you are targetting. ("//*" doesn't really point to any specific element which might be why it's returning as invalid. It's like saying "return 1 element that is anything at any place" maybe findElements would work...) – pcalkins Jan 08 '21 at 19:04

2 Answers2

0

NoSuchElementException

NoSuchElementException is the exception thrown by WebDriver.findElement(By by) and WebElement.findElement(By by) methods if no matching elements are found.

NoSuchElementException

You can find a couple of detailed discussions on NoSuchElementException in:


InvalidSelectorException

InvalidSelectorException is the exception thrown when using the selector no element can be identified and as mentioned earlier is the direct known subclass of NoSuchElementException.

InvalidSelectorException

You can find a couple of relevant detailed discussions in:


Curious case of Internet Explorer

However in a dozen of previous discussions users in favor of say that it is more readable and faster especially when running against .

You can find a detailed discussion in Why should I ever use CSS selectors as opposed to XPath for automated testing?


This usecase

This line of code...

driver.findElement(By.xpath("//div[contains(@id, 'stage')]/div[contains(@class, 'tabMenu')]/span[contains(@class, 'menuItem') and contains(text(),'Employer')]"))

...apperantly looks perfect.

However, as per the best practices I would suggest to avoid mixing up contains() and text(). You can use either of them as follows:

  • Using contains():

    driver.findElement(By.xpath("//div[contains(@id, 'stage')]/div[contains(@class, 'tabMenu')]/span[contains(@class, 'menuItem') and contains(.,'Employer')]"))
    
  • Using text():

    driver.findElement(By.xpath("//div[contains(@id, 'stage')]/div[contains(@class, 'tabMenu')]/span[contains(@class, 'menuItem') and text()='Employer']"))
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • true, but then it would fail every time and not just like 10% – Tony Jan 09 '21 at 01:39
  • What seems to work is if I catch the Exception, do a page refresh, accept the alert, and then set the driver to the page. – Tony Jan 13 '21 at 15:35
0

The InvalidSelectorException and NoSuchElementException are completely different exceptions.

As you can see this exception is thrown when the xpath is invalid.

Why you may get InvalidSelectorException

You mentioned running your tests on IE, however IE browser doesn't have a native xpath engine for finding elements. So to be able to find elements by xpath in IE, the driver will have to use a JavaScript xpath query engine.

The above I know to be true for IE versions up until including 9. Not sure about IE10 and IE11 but you also don't mention what IE version you're using, so this may be one of the root causes.

Your xpath is syntactically correct however it may not be the case for IE.

What can you try to fix your issue

  • your already making use of classes and ids so you may as well try to change selector strategy to CSS Selector. At least for the elements that are failing
  • try updating your xpaths selector to be a bit less complex (if possible)
  • switch to a more modern browser: Chrome, Firefox, Edge, if possible (however I doubt that anyone is using IE out of pure choice)
Cosmin
  • 2,354
  • 2
  • 22
  • 39
  • IE is 11.1845 version – Tony Jan 09 '21 at 01:44
  • No, we are not using IE out of pure choice. About 80% or so of our projects run in Chrome, but some have to run in IE for one reason or another (using ColdFusion or some other reasons). Believe me, I would love it if this used Chrome. But I do write the page source to a file, remove all the and then edit with chrome. If the xpath were invalid it would fail all the time. So it sounds like the find command could be returning something other than an element in this case? But "//div" should always work and it has the same problem. – Tony Jan 09 '21 at 01:47
  • Forgot to mention one thing. The following error is "[object error]" – Tony Jan 11 '21 at 13:12