I wrote a simple method to check to see if a WebElement is enabled and put this method in my test case Super Object:
protected boolean isElementEnabled(By by) {
// Temporarily set the implicit timeout to zero
int originalTimeout = Integer.parseInt(System.getProperty(
"com.brainshark.uitests.timeout", "120"));
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 isEnabled = (elements.size() == 1)
&& elements.get(0).isEnabled();
// Return to the original implicit timeout value
driver.manage().timeouts()
.implicitlyWait(originalTimeout, TimeUnit.SECONDS);
return isEnabled;
}
I have been using it quite a bit without issue, but suddenly I am faced with a repeatable instance where this method throws an InvalidElementStateException:
org.openqa.selenium.InvalidElementStateException: findElements execution failed; SYNTAX_ERR: DOM Exception 12 (WARNING: The server did not provide any stacktrace information) Command duration or timeout: 13 milliseconds Build info: version: '2.23.1', revision: 'unknown', time: '2012-06-08 12:33:29' System info: os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.7.0_05' Driver info: driver.version: RemoteWebDriver Session ID: ed1a9cbb238fa4dfb616ad81e7f60141
It appears that the failure depends on the locator that I'm searching for. Is there something inherently wrong with this locator?
final By AdministrationButton = By
.cssSelector("div#top-nav a[href~=CorpAdmin/DisplayInformation]");
To verify, the above locator is trying to locate the anchor element with an href attribute that contains "CorpAdmin/DisplayInformation" which is a descendant of a div with id=top-nav. Shouldn't a CSS Locator like the one I'm using work for ChromeDriver? Does anyone know why methods like findElements throw InvalidElementStateExceptions? Thanks in advance!
Addendum: Further investigating is showing that the method is failing only after I navigate from one page to another via a different method. It feels like something is getting stale or referring to elements that no longer exist or something to that effect. However, I can't fathom what that is; the same driver object is made available to the test cases and page objects, and is being employed every time isElementEnabled is called. No WebElements from previous pages are being cached or referenced. Is there something I need to do with my driver to alert it that the page has changed?
Addendum 2: The plot thickens. Now I'm not so sure about that previous addendum. Things still fail after navigating to a new page, but I'm not certain if that locator is the problem or not. I tried peppering my code with calls like this:
debug("Attempt 3...");
things = getDriver().findElements(By.cssSelector("div a"));
debug("Attempt 3 found " + things.size() + " things!");
These calls succeed until I navigate away from the page I started on. They locate 35 elements on the page matching the simple locator. However, once I navigate to the new page I get a new Exception:
org.openqa.selenium.WebDriverException: findElements returned invalid value: "[{\"ELEMENT\": \":wdc:1347370086846\"}, {\"ELEMENT\": \":wdc:1347370086847\"}, {\"ELEMENT\": \":wdc:1347370086848\"}, {\"ELEMENT\": \":wdc:1347370086849\"}, {\"ELEMENT\": \":wdc:1347370086850\"}, {\"ELEMENT\": \":wdc:1347370086851\"}, {\"ELEMENT\": \":wdc:1347370086852\"}, {\"ELEMENT\": \":wdc:1347370086853\"}, {\"ELEMENT\": \":wdc:1347370086854\"}, {\"ELEMENT\": \":wdc:1347370086855\"}, {\"ELEMENT\": \":wdc:1347370086856\"}, {\"ELEMENT\": \":wdc:1347370086857\"}, {\"ELEMENT\": \":wdc:1347370086858\"}, {\"ELEMENT\": \":wdc:1347370086859\"}, {\"ELEMENT\": \":wdc:1347370086860\"}, {\"ELEMENT\": \":wdc:1347370086861\"}, {\"ELEMENT\": \":wdc:1347370086862\"}, {\"ELEMENT\": \":wdc:1347370086863\"}, {\"ELEMENT\": \":wdc:1347370086864\"}, {\"ELEMENT\": \":wdc:1347370086865\"}, {\"ELEMENT\": \":wdc:1347370086866\"}, {\"ELEMENT\": \":wdc:1347370086867\"}, {\"ELEMENT\": \":wdc:1347370086868\"}, {\"ELEMENT\": \":wdc:1347370086869\"}]" (WARNING: The server did not provide any stacktrace information) Command duration or timeout: 9 milliseconds Build info: version: '2.23.1', revision: 'unknown', time: '2012-06-08 12:33:29' System info: os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.7.0_05' Driver info: driver.version: RemoteWebDriver Session ID: 174adf3205213984172556afa718f6a1
Is that how Selenium represents WebElements? I imagine those are just references to the objects themselves. There are only 26 of them, rather than the 35 that were previously returned (since we are on a different page, this may be the correct number). Unsure why something is invalid or what though. If I instead call isElementEnabled on the locator for my AdministrationButton above, I get the InvalidElementSateException as before.