-
Notifications
You must be signed in to change notification settings - Fork 575
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
#623: Add methods to get first and last n elements of the collection #624
#623: Add methods to get first and last n elements of the collection #624
Conversation
Codecov Report
@@ Coverage Diff @@
## master #624 +/- ##
============================================
- Coverage 60.3% 60.21% -0.09%
- Complexity 767 768 +1
============================================
Files 148 148
Lines 2741 2745 +4
Branches 269 269
============================================
Hits 1653 1653
- Misses 984 988 +4
Partials 104 104
Continue to review full report at Codecov.
|
public void canGetLastNElements() { | ||
ElementsCollection collection = $$x("//select[@name='domain']/option"); | ||
collection.last(2).shouldHaveSize(2); | ||
collection.last(10).shouldHaveSize(collection.size()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The expected result as a part of test logic should be explicit.
I would change the corresponding line to:
collection.last(10).shouldHaveSize(10);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The size of the collection in this case is 4. If you try to get elements that are out of array boundaries the method will just return the full collection instead of throwing an error. That's what that line is testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, good, then you should put 4 explicitly in the assert, not collection.size()
.map(SelenideElement::getText) | ||
.collect(Collectors.toList()); | ||
|
||
Assert.assertEquals(regularSublist, selenideSublist); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yet the test logic is not explicit in the test... I recommend to explicitly verify what texts should be in the sub-collection.
.map(SelenideElement::getText) | ||
.collect(Collectors.toList()); | ||
|
||
Assert.assertEquals(regularSublist, selenideSublist); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In addition - just a few tests are not enough. It does make sense to check error messages for such "sub-collections"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What error messages do you have in mind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In Selenide we have kind of "informative error messages" in cases when the "should" method failed, or some operation on collection element failed. In such cases the message should be really informative. The user should understand from the error message what was the collection that he tried to deal with.
Just run:
$$(".item").last(3).shouldHaveSize(4)
And check the error message. It should be informative. But probably it will not:)
And we should have tests for such cases too.
*/ | ||
public ElementsCollection first(int elements) { | ||
List<WebElement> sublist = getActualElements().subList(0, Math.min(elements, size())); | ||
return new ElementsCollection(new WebElementsCollectionWrapper(sublist)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This implementation is not correct. It's not "reactive" enough.
GIVEN "1", "2", "c", "d" texts in the '.item' list during first 1 second
WHEN texts change to "a", "b", "c", "d" during next 5 seconds
THEN the code $$(".item").first(2).shouldHave(texts("a", "b"))
still will fail on timeout of 6 seconds
BUT it should pass.
This test by the way should also be added to the test suite.
The correct way to implement these methods is the same as for "filterBy" method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like timeout after 6 seconds for collections is the default selenide behavior. Using your example, lets say we have one element with text "1" which changes text to "a" after 5 seconds. If you call $$(".item").shouldHave(texts("a"))
without my first()/last() method, it will still fail after 6 seconds. Even if you set the Configuration.timeout to any other value that line still fails after 6 seconds timeout.
This line works fine: $(".item").shouldHave(text("a"))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was not about waiting 6 seconds. It's about waiting at most 6 seconds and succeed to find elements if they appear or change. Your implementation is not dynamic, it will not succeed. It will remember the exact number of elements at the very beginning - and will not update them after they change during the period of 6 seconds or whatever is set in the Configuration.collectionTimeout
Nevertheless - write a test and check it:)
Just a few tests is not enough for good test coverage of a new feature ;)
You checked only the "subListing" in context of counting size.
But selenide is much more - it is also:
- dynamic elements that are updated when needed
- waiting elements
- informative error messages
I believe we should ensure that all those features are supported by the implementation of new first/last methods, and so we should have tests for them
Proposed changes
As per this request, I added first() and last() methods to get the first and last n elements of the elements list.
Checklist
gradle check chrome htmlunit
command