New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
StaleElementReferenceException with Wait* keywords #475
Comments
Please verify your ChromeDriver version, from the Trace we see: On Thu, Jul 30, 2015 at 1:58 PM, Tatu Aalto notifications@github.com
|
Ah, did accidentally copy from wrong log file. Here is the correct example:
|
I was reading the code and I do not quite understand, where the other selenium errors (like NoSuchElementException) are suppressed, but I was thinking could this resolve the problem: https://github.com/aaltat/robotframework-selenium2library/commit/9df1e8e132c63c67c771d9b0f45582fc4b35ca6c Just a raise a discussion and me to figure out, am I in the right track? |
My idea is not actually good, because it wont fix the other Wait* keywords. Therefore finding a better solution is needed. In my case the StaleElementReferenceException happen most often with Wait Until Element Is Visible keyword, because I use it also quite often. @zephraph I returned from my holidays this week, so enjoy yours. Shutting down the email (+other social media apps) usually helps :-) |
Actually @aaltat I was thinking something similar, although I would have first tried catching the error up within I am not sure it is proper to exclude this error in all the Wait* keywords. I think one needs to ask what is a proper error and maybe what is not. This was part of the discussion we had in the users group. Under some of the Wait* keywords I could see that a StaleElementReferenceException is an error that would/should cause an error and in others it could be ignored till the timeout period has completed. |
[Thinking out loud...] What if _waiting._wait_until_no_error() had an additional parameter for errors to ignore...? |
@emanlove Well, sounds a good idea to me... |
Those methods do look similar as what the selenium API now days recommends to use with explicit waits: http://selenium-python.readthedocs.org/en/latest/waits.html?highlight=waiting#explicit-waits And there is ready made conditions that would suite in many of our needs (just an assumption), like:visibility_of_element_located. But I do not know the codebase that well to estimate, how big change that would be and would it require to raise the minimum required selenium version. |
Concerning the minimum required selenium version, I see several points in the CHANGES log,
I think we can get by with what we currently require. The change in 2.45.0 looks to just add debuging information on a TimeoutException. |
If we can get by using current selenium version, which way you would like to proceed?
I can think many pros/cons for each way. |
Just my two cents, but I'd prefer getting as close to the webdriver as possible, so I'd vote 2. Granted, that may come with a greater risk than option 1. |
If I could freely choose, I would go also for option 2, Also from the same reason which @zephraph mentions. Also I think, it could make the code much easier to read and maintain. At least for me the waiting/finding logic in S2L was not so easy to read and understand. Of course the option 2, is lot more work and my gut feeling says that there are many things which will cause a pain in... Of course the option 1 would be relatively easy to do, but somehow I feel that the maintenance burden would grow with option 1. |
I too think that 2 is the better option. We should prototype something up and see what the difference is. I think also a good explanation of what the wait is doing all the way through would be good to have. |
OK, I will try to muster up some sort of prototype, perhaps I get something done at the end of the week. But I was thinking that this means the separation between the Waiting* and other keywords in means how the element is located. Other keywords would still use the existing functionality to locate/interact with elements but Waiting* keywords would be moved closer to the selenium 2 world. Just trying to limit the scope, because I do not want to do rewrite for the whole library... |
Well, I created the slack channel and am always available through there. @emanlove, you should definitely give it a go too if you haven't already. |
There is an instant messaging site with nice features like file posting and You will have to create an account, after that you may request access at On Wed, Aug 5, 2015 at 7:50 PM, Tatu Aalto notifications@github.com wrote:
|
I finally found some time to prototype this.
The above could perhaps work, but I did found some issues.
and our implementation is much wider. I would need extend the By class someway, but first I need to read, what our all strategies actually do and how they do it.
|
I have been thinking this issue and more I think it more reluctant I have come to change the existing keyword functionality. It feels like a big rewrite and those things don't usually end well. So could we find an another way to implement the webdriver native waiting? Could we create duplicate keyword, like: Wait Until Page Contains 2 or something to implement this functionality in smaller and more controlled commits. Or any good idea how to introduce the change in the library in controlled manner? |
I don't like the idea of having |
I also do not like the idea having two keywords, with same functionality. Nor I do not like the idea to make new arguments to define which way the search is made. I can not think a good way to change the functionality, without doing a quite a big re-write. Perhaps best way would to write the new underlying functionality to separate classes and not to aim for re-write. Perhaps even do one keyword at the time. |
I'm experiencing the same problem with Firefox. Selenium2Library . Wait Until Element Is Visible //div[contains(@id, "table_grid_TreeGrid")]//table[@Class = "gridxRowTable"] StaleElementReferenceException: Message: Element not found in the cache - perhaps the page has changed since it was looked up |
This issue is similar to #173. I would like to know in what waits it is not appropriate to ignore certain exceptions where in others it would be. Wait For Condition does not need to ignore exceptions like StaleElementReferenceException, but they are not going to occur anyways, so no harm done in my opinion. |
I was just wondering if this is a decent enough patch for now, until the problem is solved more elegantly: ***************
*** 17,24 ****
--- 17,25 ----
import time
from SeleniumLibrary.base import LibraryComponent, keyword
from SeleniumLibrary.errors import ElementNotFound
+ from selenium.common.exceptions import StaleElementReferenceException
from SeleniumLibrary.utils import is_noney, is_truthy, secs_to_timestr
class WaitingKeywords(LibraryComponent):
***************
*** 227,234 ****
--- 228,238 ----
if condition():
return
except ElementNotFound as err:
not_found = str(err)
+ except StaleElementReferenceException:
+ continue
else:
not_found = None
time.sleep(0.2)
raise AssertionError(not_found or error) Or am I missing a reason why this is a terrible idea? [Edit]: As requested by @emanlove here's a little more context of the code snippet: def _wait_until_worker(self, condition, timeout, error):
max_time = time.time() + timeout
not_found = None
while time.time() < max_time:
try:
if condition():
return
except ElementNotFound as err:
not_found = str(err)
except StaleElementReferenceException:
continue
else:
not_found = None
time.sleep(0.2)
raise AssertionError(not_found or error) (This is in the |
It's been a long while since I have reviewed this issue and I see this thread has gotten really long. That said, in general, it seems to me like a bad idea to generically and blindly handle state element exceptions within the core library. I suspect different users will have different needs, desires, and method to handle when it comes to stale elements. @bartkl Can you show a little more or add a link to here this by line in the code? I'd just like to see a few lines above this.. |
At some point I thought it would be great if SL could always handle stale elements automatically, but nowadays I tend to agree with @boakley who generally considers them bugs in the application that should not be silenced. With @emanlove and others interested to see where the proposed change would be can go to https://github.com/robotframework/SeleniumLibrary/blob/master/src/SeleniumLibrary/keywords/waiting.py#L222 |
I wouldn't necessarily say they were bugs in the application. There are
many good reasons for elements to go stale.They are probably more correctly
described as bugs in the test stemming from a misunderstanding of how the
application works. If you understand how an application works, and you code
your tests appropriately, you should never see a stale element exception.
It's not always easy, but I think it's always possible.
…On Wed, Jan 31, 2018 at 4:43 PM, Pekka Klärck ***@***.***> wrote:
At some point I thought it would be great if SL could always handle stale
elements automatically, but nowadays I tend to agree with @boakley
<https://github.com/boakley> who generally considers them bugs in the
application that should not be silenced. With Wait ... keywords that also
gracefully handle elements missing altogether the situation is somewhat
different, though, and I feel it would be OK to do the change proposed by
@bartkl <https://github.com/bartkl>. I don't know the domain well enough
to have a strong opinion about this, though, and would be dine @aaltat
<https://github.com/aaltat> making the decision one way or the other.
@emanlove <https://github.com/emanlove> and others interested to see
where the proposed change would be can go to https://github.com/
robotframework/SeleniumLibrary/blob/master/src/SeleniumLibrary/keywords/
waiting.py#L222
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#475 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABEmYgeaPD-VGchir3ruJNTuYSKafALEks5tQOyfgaJpZM4Fiu7j>
.
|
I agree that for this problem, finding a solution that would suite for all is impossible. But I think that what inexperienced users are doing, using WUKS or sleep, is not good solution either. If one is working with a application, that has a clear state, like an loading indicator in the UI, then suppressing StaleElementReferenceException is not right course of action. But I have also worked with applications where knowing the state was next to impossible and I really hate those kind of legacy applications. But for those type of legacy applications, just retrying is mostly best course of action. But if we blindly allow users to suppress the error, then we deny them the change to improve and learn. Failing provides best way to learn. In my opinion, blindly applying this for all |
It's good to be wary when editing core functionality like this, and I agree there should be a good consideration as to what possible use cases and scenarios are involved. In my (limited) experience I have encountered exclusively situations where it is desirable for the @aaltat I agree with your statement in general, but -and correct me if I'm wrong- I feel that in the case of elements going stale during All in all, I guess I agree with @pekkaklarck that it seems (like him and possibly even more so, I'd like to be careful) the |
The reason I think In my opinion element not existing and element being invalid are so close to each others that they should be handled the same way. They both cause a failure with normal keywords, and I see no harm in both of them being ignored with wait keywords. If I've understood it correctly, now wait keyword passing or failing may depend on timing. As I wrote above, I think these two error situations should be handled the same way. That could be easily and explicitly done like this: def _wait_until_worker(self, condition, timeout, default_error):
max_time = time.time() + timeout
error = None
while time.time() < max_time:
try:
if condition():
return
except (ElementNotFound, StaleElementReferenceException) as err:
error = str(err)
else:
error = None
time.sleep(0.2)
raise AssertionError(error or default_error) PS: That |
An obvious benefit of wait keywords handling state element errors like proposed above is that they could be used to workaround stale element problems. As @aaltat commented, handling them "correctly" with legacy applications can be really hard. |
User's perspective: I've just spent a year in a shop dealing with apps written using a framework which was basically a stale element exception generator (SAPUI5, may you burn in hell). We used the SL monkeypatched to do exactly what Pekka posted above, and it was totally fine for us. We somehow knew the behavior is sort-of wrong but we were not able to fix the framework that caused the problems (different team, big corp). As you say, especially with |
Perhaps we could implement the change for
Anyone who would like to do the above, specially the help on point two is predicated. |
This doesn't just occur on waits. I applied the above patch that handles the wait, but still have a problem when I was pulling data out of a table cell and got the same error. The web application I'm testing is an angular based. I have a huge amount of data that I'm filtering using two-way data binding. As I'm inputting search terms, javascript is fltering this data and displaying it in a table. If I find that what I'm looking for is in the table, I then move forward trying to get a value out of a cell. The table could still be re-written on me giving this same error. I've worked with @Byteme8199 on this, he's been doing the angular work for the application, and if there's any questions on on the details of the javascript he should be able to help. |
The error can happen with any keyword which interacts with an element. I have been thinking about the problem and for me it feels that writing test to solve the problem is actually quite difficult in the acceptance level. Because of how browsers, timing and life. Therefore this problem is easier to solve in the unit test level. Mocking element and deciding what element does is easier in the unit level. |
Holding my thumbs that a fix for this long-runner makes it into v3.3.0. That would be awesome. Thanks @aaltat and everybody else for your dedicated work with RF. |
Closing issue because it is replaced by #1270 |
With Chrome 44.0.2403, Chrome driver 2.16 Selenium2Library 1.7.2 and selenium 2.46.1 when I use Wait* keywords, the StaleElementReferenceException might occur. Documentation says that keyword should only fail if condition is not met before the timeout, example for Wait Until Page Contains Element keyword, documentation says: Fails if timeout expires before the element appears.
But if StaleElementReferenceException happens, then I see this:
and keyword did fail immediately. But I did expect that keyword would simply re-try search for the element if the StaleElementReferenceException or any other selenium related error happens before the timeout.
The text was updated successfully, but these errors were encountered: