-
Notifications
You must be signed in to change notification settings - Fork 569
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
Iterator should reload the collection on every loop cycle #797
Comments
Hello @asolntsev ,
It's not a perfect example, but it's demonstrate an issue.
Both cases are using iterator which uses fetch() as collection snapshot for faster iteration. But in this cases, we are losing the ability to avoid StaleElementReferenceException in case if an element in DOM was changed. Possible way to avoid such error is using get(int idx) of collection. Example will work without errors:
But in such case we are loosing performance on big collections. P.S. I faced with such error a lot and proposing support both: reload on each call and lazy ways of working with collections |
@asolntsev any updates on this one? Provided examples look like valid. Anyway, would be great to have this nasty issue fixed. Thanks in advance. |
@slipwalker Thank you for the reminder. I was busy with Selenide 5.0.0 major refactoring during last month... I looked at your examples. There is no a single correct answer, of course, but I tend to think that these are not good tests. Ideally, there should not be any loops and ifs in test. I mean, you should always know exactly how many elements there should be on a page, and click every of them explicitly. Loop is a bad solution: if there is NO elements at all, such test would also be green. It also seems natural to me to get element again if I know that the page has been reloaded meanwhile. That's why using |
@asolntsev Let me clarify couple details:
p.s. it worked perfectly before reverting some changes in collections (#696) |
Hi. And the reason is not new Iterator and fetch() method in ElementsCollection but the fact that WebElementsCollectionWrapper.getElements() always returns one old Array of elements without getting them from dom again And I couldn't find any option to avoid this but to write spikes which create 2 new ElementCollections for my locator between some intervals and comparing them with some poll interval. @asolntsev Using plain old get(int idx) instead of streams looks very unnatural to me on the contrary |
@TuXuuTT Once again: typically I also prefer stream instead if |
Yes, this is absolutely reasonable. This is the reason why I was in doubt when releasing Selenide 4.12.3 (in which iterator caches the collection)
To summarize, we have two options:
@vinogradoff @BorisOsipov @rosolko @symonk |
@asolntsev As I remember some one from community also have this issue even with |
@asolntsev Second point is about performance because of current and previous implementation of collection's access.
That's why I'm proposing support both solutions (reload strategy) as @rosolko mentioned. |
@rosolko I don't like the idea of introducing "reload strategy" because it makes things more complex. It makes user's life harder if Selenide has too many options.
|
Another reload strategy can check element state before return it and reload collection if needed (as it was). Compare to fetching collection without the ability to reload (which is not safe and can produce |
@kalumpiwarra @vinogradoff @BorisOsipov @rosolko @symonk After thinking a while, I suggest to select option 2 from #797 (comment):
So, we will have 2 options to iterate a collection:
|
That's exactly what I've requested. It also will make iterator behavior predictable, I mean no difference between collection access via iterator or index. Reload is the default behavior; accessing snapshot should be explicit. |
@asolntsev any chances to see this feature implemented any time soon? :) |
@bereg2k Yes, I am always thinking about it :) Probably the ideal solution to me would be to change |
@asolntsev Regarding the backward compatibility: if you make Having said that, I like the idea of having a separate method for converting collections to |
…rator" This reverts commit 3b02b00.
@asolntsev thank you for your effort! I reviewed the PR, the method names sound descriptive enough. Also, "fixed iterable" and "dynamic iterable" sound more like proper counterparts to each other. |
Thank you for the review! |
Implemented in #1688 |
With #696 that was introduced in Selenide version 4.12.3, some of our UI autotests that have deals with Selenide's setValue() method started suddenly to fail with next exception:
Element we trying to set value to is having validation (red border in case of empty value). Element is present and displayed before passing it to setValue() method. So it may look like collection containing that element becomes stale when element's validation occurs (when clear() action happens within setValue() method). But, everything works perfect for this test when rollback to previous version. Cannot share tests code, but will try to do my best to reproduce it somewhere else as well.
The text was updated successfully, but these errors were encountered: