Version: 1.0.14
I observed following exception in the test.
org.openqa.selenium.NoSuchElementException: Unable to find element with locator 'By.id: cityId'
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '3.2.0', revision: '8c03df6b79', time: '2017-02-23 10:51:31 +0000'
System info: host: 'jenkins-as.tes-rus.net', ip: '192.168.108.166', os.name: 'Linux', os.arch: 'amd64', os.version: '3.10.0-514.21.2.el7.x86_64', java.version: '1.8.0_131'
Driver info: driver.version: unknown
at com.wiley.autotest.selenium.elements.upgrade.NullTeasyElement.noSuchElementException(NullTeasyElement.java:210)
at com.wiley.autotest.selenium.elements.upgrade.NullTeasyElement.clear(NullTeasyElement.java:75)
at com.wiley.autotest.selenium.extensions.internal.TextFieldImpl.clear(TextFieldImpl.java:46)
at com.wiley.autotest.selenium.extensions.internal.TextFieldImpl.clearAndType(TextFieldImpl.java:76)
at com.wiley.wat.blocks.AffiliationForm.inputCity(AffiliationForm.java:166)
It was inconsistent and reproduced only when bunch of tests was running on grid, even if most of them were unrelated to falling code. It never happened on local launches, and when total amount of tests was no big enough (~30 was not, but ~70 was enough).
Code that caused exception looked like this:
public class AffiliationForm extends AbstractWebContainer {
...
private final static By CITY_LOCATOR = By.id("cityId");
...
private TextField cityTextField() {
return textField(CITY_LOCATOR);
}
...
But when I tried following workaround, error disappeared.
private TextField cityTextField() {
return new WebElementWrapper(element(CITY_LOCATOR, new SearchStrategy())).getTextField();
}
Following examples was run on the 1.0.8 version, but I don't think version matters, because first two of them are reproduced on the last version.
Turns out, SearchStrategy was sufficient, and following still caused error.
private TextField cityTextField() {
return new WebElementWrapper(element(CITY_LOCATOR)).getTextField();
}
It seems, that element call find visible element in one case, and don't in other. I can see the only difference between them: second call uses default element finder inside TeasyElementProvider, which has strategy created not by default constructor, but with constructor with timeout parameter, and it is instantiated with TeasyElementProvider.timeout value.
However, when I tried to figure out what the timeout is, following code
@Autowired
private AffiliationForm affiliationForm;
...
Field timeoutField = TeasyElementProvider.class.getDeclaredField("timeout");
timeoutField.setAccessible(true);
Long timeout = (Long) timeoutField.get(affiliationForm);
System.out.println(timeout);
System.out.println(SeleniumHolder.getTimeoutInSeconds());
prints 60 in both cases (second is used as a default timeout for SearchStrategy).
Moreover, it seems that element is not found for other reason then actual invisibility. I tried workaround and normal call together.
private TextField cityTextField() {
element(CITY_LOCATOR, new SearchStrategy().frameStrategy(SearchStrategy.FrameStrategy.IN_ALL_FRAMES));
return textField(CITY_LOCATOR);
}
First line passed, but second caused exception (at that point I assumed, that FrameStrategy might matter, but it seems not - later I removed it, and workaround worked, as I wrote above).
Error had been observed after we tried to introduce page blocks and moved some code to subclasses of AbstractWebContainer. When textField(CITY_LOCATOR)
was in the page class, it worked in the same test and the same consequence of actions.