differences between InvalidSelectorException and NoSuchElementException and locating items - selenium

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?

The InvalidSelectorException and NoSuchElementException are completely different exceptions.
NoSuchElementException
This is raised when locator strategy used is correct but no element matching it can be found in the page's DOM.
InvalidSelectorException
This is raised when the locator string that is being used is invalid. In the Selenium java implementation there are a couple of examples where this exception should be thrown:
testShouldThrowInvalidSelectorExceptionWhenXPathIsSyntacticallyInvalidInDriverFindElement
testShouldThrowInvalidSelectorExceptionWhenXPathReturnsWrongTypeInDriverFindElement
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)

NoSuchElementException
NoSuchElementException is the exception thrown by WebDriver.findElement(By by) and WebElement.findElement(By by) methods if no matching elements are found.
NoSuchElementException extends NotFoundException which in turn extends WebDriverException.
It's direct known subclass is InvalidSelectorException
You can find a couple of detailed discussions on
NoSuchElementException in:
NoSuchElementException, Selenium unable to locate element
Exception in thread “main” org.openqa.selenium.NoSuchElementException: Unable to locate element:
//*[#id='login-email']
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.
You can find a couple of relevant detailed discussions in:
Invalid selector: Compound class names not permitted error using Selenium
Selenium CSS selector throwing OpenQA.Selenium.InvalidSelectorException - what's
wrong?
Curious case of Internet Explorer
However in a dozen of previous discussions users in favor of css-selectors say that it is more readable and faster especially when running against internet-explorer.
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']"))

Related

Performance comparison of #FindBy() and driver.findElement()

I am using selenium framework to automate a web application wherein basically, driver.findElement() is commonly used. but I got the suggestion that #FindBy() works faster than driver.findElement(). suggest me which is better to use ?
When the code - PageFactory.initElements(....) is run it creates Proxy objects for all the fields which are annotated with #FindBy (or even #FindBys and #FindAll). So initially no searching of WebElements are performed.
Then if something like element.sendKeys(...) is run, the actual WebElement is searched using driver.findElement(...) before sendKeys() is run. Then if the same sendKeys() code is run the element is found again.
But if you add the CacheLookup annotation to the field then the second lookup is not performed but element is returned from the cache. So there is a performance gain. But the problem occurs in a javascript or ajax heavy page, stale element exception can show up.
For any non-trivial application testing use the PageObjectModel framework. Makes things organized and not littered with findElements and locators, even if you do not use the CacheLookUp annotation.

Getting RemoteWebDriver error

I am not using Selenium RC or Remote WebDriver, but When I am trying to run my test , its throwing me error -
remotewebdriver.unpackAndThrowOnError(Response errorResponse)
My script has simple code:
driver.FindElement(By.XPath("xpath");
Error thrown at:
RemoreWebDriver.FindelementByXPath(String XPath);
Please help me resolving the issue
Because of the architecture of WebDriver, all discrete browser-specific drivers (FirefoxDriver, ChromeDriver, etc.), are subclasses of RemoteWebDriver. This means that, in keeping with good Object-oriented programming principles, the error handling code is common to all implementations, and is located in the base class, or RemoteWebDriver. This means that in the stack trace for any error, it’s common, even expected, to see RemoteWebDriver methods in the call stack.
Having said all of this, I suspect that the question you’re really asking is not, “Why do I see RemoteWebDriver in my stack trace when I’m not using remote?” Rather, I suspect the question you’re asking is, “Why is my FindElement call failing?” The answer to that depends on a lot of factors, but the most common is that the element isn’t located by the locator you’re specifying, or that the element isn’t actually in the page’s DOM when you attempt to find it. In the former case, you should fix the locator; in the latter case, you should wait for the element to be present before finding it (usually by using WebDriverWait, or a similar construct).
Of course, without the HTML you’re attempting to automate, and the full WebDriver code you’re attempting to use, more detailed advice is impossible to provide.

Selenium continue without loading page

While I was doing testing in Eclipse, my java program has to wait for the page in Firefox driver to load completely. Is their any way that i can tell my program to continue executing the next step without waiting?
In my professional opinion, you shouldn't do this. You should let Selenium do its duty, and make sure the page is fully loaded before you continue.
One thing to note, is that when you call click() on a WebElement, Selenium doesn't actually wait for the page to load. driver.get() does however.
What you are asking, isn't a very "common practice", so this may or may not work.
Try just setting the pageLoadTimeout "0".
driver.manage().timeouts().pageLoadTimeout(0L, TimeUnit.MILLISECONDS);
(this syntax is of course if you are using Java. you don't have the question marked as a specific language, so take it as it is and convert it to your language of choice)

What is the solution for this error in Junit 4.0? The error is "dom locators are not implemented yet"

I have generated the script using Selenium IDE. But not giving me proper output.
ERROR: Caught exception [Error: Dom locators are not implemented yet!]
ERROR: Caught exception [Error: Dom locators are not implemented yet!]
This gets displayed instead of the element code.
I have tried xpath locator. But its not working.
Read the error.
Dom locators are not implemented yet!
That could maybe, I'm not sure, mean, that the DOM locators are not implemented yet and you need to use another locator strategy. Look at all available locator strategies and pick one. The often used ones are id, name, css, xpath, ideally in this order (from weakest to strongest, but also from fastest to slowest).
By the way, Selenium RC has been oficially deprecated two years ago in favor of the new and shiny Selenium WebDriver. If you want to use something that's actually supported and developed, export your scripts to WebDriver.

Can HTMLUnit package be used with PhantomJsDriver.java

I am using "org.openqa.selenium.phantomjs.PhantomJsDriver" Java class.
At times, I need to identify whether a given WebElement is a particular type of web element; eg: Is this webelement a input type element or not.
This does not seem to come with PhantomJsDriver package.
"com.gargoylesoftware.htmlunit." package seems to have useful wrappers on top of web elements. I can write code like "element instanceof HtmlInput".
Question here is
- Can I really HTMLunit package with phantomjsdriver ? Am I using two libraries which are not supposed to be used with one-another ?
No. Unfortunately, you can't do this the way you're doing it. PhantomJsDriver is backed by WebKit, while HtmlUnitDriver is backed by HtmlUnit which has its own browser core. Selenium is able to wrap both these (and some more) under one hood, but we can't use them interchangeably.
There are, however, different ways of doing what you're trying to do, the best probably being using Selenium's own methods getTagName() and getAttribute() if needed.
If you ran getTagName() on your input element, it would gladly return "input".