This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The given selector ".//h1 is either invalid or does not resultin a Webelement. The following error occurred: | |
[InvalidSelectorError] Unable to locate elements with the xpath expression .//h1 because of the following error: | |
[Exception... "Component returned failure code: 0x80070057 (NS_ERROR_ILLEGAL_VALUE) [nsIDOMXPathEvaluator.createNSResolver]" nsresult: "0x80070057 (NS_ERROR_ILLEGAL_VALUE)" location: "JS frame :: resource://fxdriver/modules/atoms.js :: <TOP_LEVEL> :: line 2360" data: no] (Selenium::WebDriver::Error::InvalidSelectorError) |
You've run into selenium issue 2099. It appears what happens with this error is that the test is executing before the page has fully loaded, causing it to fail. Old school race conditions. Nice.
So how do we get around this? There's been a few postings on how to handle this with Capybara, but what about tools that use selenium-webdriver more directly? Here's a monkey patch that hacks over the Ruby bindings to enable tools like watir-webdriver to retry. This patch will retry the find until selenium-webdriver receives an error that is not related to the strange InvalidSelectorError that it gets when the Firefox isn't done loading the page. I just stuff this file into the support directory in a Cucumber suite.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if WEBDRIVER && BROWSER_TYPE == :firefox | |
module Selenium | |
module WebDriver | |
module SearchContext | |
def find_element(*args) | |
how, what = extract_args(args) | |
unless by = FINDERS[how.to_sym] | |
raise ArgumentError, "cannot find element by #{how.inspect}" | |
end | |
bridge.find_element_by by, what.to_s, ref | |
rescue Selenium::WebDriver::Error::InvalidSelectorError => e | |
e.message =~ /nsIDOMXPathEvaluator.createNSResolver/ ? retry : raise | |
end | |
def find_elements(*args) | |
how, what = extract_args(args) | |
unless by = FINDERS[how.to_sym] | |
raise ArgumentError, "cannot find elements by #{how.inspect}" | |
end | |
bridge.find_elements_by by, what.to_s, ref | |
rescue Selenium::WebDriver::Error::InvalidSelectorError => e | |
e.message =~ /nsIDOMXPathEvaluator.createNSResolver/ ? retry : raise | |
end | |
end | |
end | |
end | |
end |
Since this is hacky and a monkey patch, I'm very keen on ideas on how to improve this implementation, since my Ruby skills are very raw.