feat: add SplitLayout, Card and AvatarGroup testers - #196
feat: add SplitLayout, Card and AvatarGroup testers#196totally-not-ai[bot] wants to merge 3 commits into
Conversation
None of these components had a @Tests-annotated tester, so the locator processor emitted no find*() entry point for them and they had to be driven through raw component calls. - SplitLayoutTester.dragSplitterTo(percentage) reports the drag the way the client does, by firing SplitterDragEndEvent with the resulting flex basis values, so the component recalculates its own splitter position and user listeners see fromClient=true. - CardTester reports the title and subtitle text the user actually sees, covering both the string and the component flavour and the fact that a header component takes their place. - AvatarGroupTester splits the items into the ones rendered as individual avatars and the ones collapsed behind the overflow avatar, following the client's maxItemsVisible rule (minimum two slots, the overflow avatar taking the last one). Width-based collapsing needs a layout and is out of scope. Part of #181.
getVisibleItems() returned the component's own unmodifiable view of the item list when there was no overflow, and a copy otherwise, so the same method handed out either a live view or a snapshot depending on maxItemsVisible. Both getters now copy, and the visible count replaces the nullable limit that forced the two branches. Also pin three untested boundaries: a group that fits within the clamped two-slot minimum keeps both avatars and shows no overflow avatar, splitter drags to 0 and 100 are accepted, and a card with neither a string nor a component title reports empty title text.
| * @throws IllegalStateException | ||
| * if the component is not usable | ||
| */ | ||
| public List<Component> getFooterComponents() { |
There was a problem hiding this comment.
There's a method to get footer components, but nothing for header, header prefix and suffix.
We should probably add them or remove this one as well.
There was a problem hiding this comment.
Good catch — went with adding them rather than dropping the footer one, since the point of these getters is to let a test assert what the card actually shows without reaching past the tester.
CardTester now has getHeader(), getHeaderPrefix(), getHeaderSuffix() and getMedia() alongside getFooterComponents(), each with the same usability check, so every slot is covered. Each returns the component or null, mirroring Card's own API. I included media too, as it is the same kind of single-component slot and would have been the next gap.
Note that getTitleText() / getSubtitleText() deliberately keep reporting empty while a header component is set — the header takes their place in the DOM — whereas getHeader() and friends just report their slot contents.
getFooterComponents() was the only slot accessor, so asserting on the header or the media meant dropping out of the tester. Add getHeader(), getHeaderPrefix(), getHeaderSuffix() and getMedia(), each usability-checked like the rest, so every slot the user can see is reachable.
Summary
Adds testers for
SplitLayout,CardandAvatarGroup. These three components had no tester, so tests had to drive them through raw component calls. Now they can be used like every other component in a browserless test.Part of #181.
What changed
SplitLayoutTester—dragSplitterTo(percentage)simulates the drag the way the client does: it fires aSplitterDragEndEventwith the resulting flex basis values, so the component recalculates its own splitter position and user listeners getfromClient = true. Values outside0..100are rejected. Also exposesgetSplitterPosition(),getPrimaryComponent()andgetSecondaryComponent().CardTester— reports the title and subtitle text the user actually sees, covering both the string and the component flavour, and returning empty text when a header component takes their place. Also gives access to every visible slot:getHeader(),getHeaderPrefix(),getHeaderSuffix(),getMedia()andgetFooterComponents().AvatarGroupTester— splits the items into the ones drawn as individual avatars and the ones collapsed behind the overflow avatar, following the client'smaxItemsVisiblerule (at least two slots, the overflow avatar taking the last one). Both getters return copies, never a live view of the component's list. Width-based collapsing needs a real layout, so it is out of scope.TesterWrappersgets atest(...)overload for each new tester, and the README component count moves from 65+ to 68+.Use case
You have a booking page built from
Cards, and you want a fast test that the card shows the right title and that the footer button is there — without starting a browser.API Changes
com.vaadin.browserless.TesterWrappers
com.vaadin.flow.component.avatar.AvatarGroupTester
com.vaadin.flow.component.card.CardTester
com.vaadin.flow.component.splitlayout.SplitLayoutTester
Test summary
dragSplitterTo(30)moves the splitter to 30 and notifies the drag end listener withfromClient = trueIllegalArgumentExceptionand leaves the splitter where it was0and100are acceptednullwhen the slot is empty), and the footer returns only footer contentmaxItemsVisible, all items are visible, overflow is empty and the abbreviation isnullmaxItemsVisible = 3and 5 items, 2 items are visible, 3 overflow and the abbreviation is+3maxItemsVisible = 1is clamped to two slots; with exactly two items nothing overflowsmaxItemsVisibleequal to the item count produces no overflowdragSplitterTothrowIllegalStateExceptionon a hidden componentgetVisibleItems()/getOverflowItems()are snapshots, not live views of the component's item listAvatarGroupTesterrefactor changed; nothing fails today if a live view leaks backTests covering each row:
SplitLayoutTesterTest.dragSplitterTo_updatesPositionAndNotifiesListener→ 1SplitLayoutTesterTest.dragSplitterTo_positionOutsideRange_throws→ 2SplitLayoutTesterTest.dragSplitterTo_positionAtRangeEnds_accepted→ 3SplitLayoutTesterTest.getSplitComponents_returnSlottedComponents→ 6SplitLayoutTesterTest.dragSplitterTo_notUsable_throws,SplitLayoutTesterTest.getters_notUsable_throw→ 11CardTesterTest.getTitleText_returnsStringAndComponentTitles→ 4CardTesterTest.getSubtitleText_returnsSubtitle→ 4CardTesterTest.headerComponent_hidesTitleAndSubtitle→ 5CardTesterTest.getFooterComponents_returnsFooterContentOnly,CardTesterTest.getSlottedComponents_returnContentOfEachSlot→ 6CardTesterTest.getters_notUsable_throw→ 11AvatarGroupTesterTest.noMaxItemsVisible_allItemsVisible→ 7AvatarGroupTesterTest.maxItemsVisible_overflowAvatarTakesLastVisibleSlot→ 8AvatarGroupTesterTest.maxItemsVisibleBelowTwo_stillShowsTwoSlots→ 9AvatarGroupTesterTest.maxItemsVisibleFitsAllItems_noOverflow→ 10AvatarGroupTesterTest.getters_notUsable_throw→ 11Left untested on purpose: the plain pass-through getters are only checked through the assertions above, the generated
find*()entry points come from the existing@Testslocator processor and are covered by its own tests, and width-based avatar collapsing is not emulated because it needs a real layout.