fix: find slotted Dialog and Card children via ComponentUtil.getAllChildren - #2291
Merged
Merged
Conversation
…tQuery Vaadin 25.3 slots the Dialog header/footer wrappers into the light DOM and excludes them from Dialog.getChildren(), so the browserless component tree walker no longer sees components added via getHeader()/getFooter(). Adds a failing test that queries header, content and footer components of an opened Dialog.
Vaadin 25.3 slots the Dialog header and footer wrappers into the light DOM and Dialog.getChildren() filters those wrappers out, so components added via getHeader()/getFooter() were no longer part of the walked component tree and ComponentQuery could not find them. Card has the same behaviour: it excludes every child carrying a slot attribute from getChildren(). Union the component's own children with ComponentUtil.getAllChildren(), which walks the element hierarchy (regular and virtual children, descending through non-component wrapper elements). Neither source alone is complete, since getChildren() may hide element children while getAllChildren() misses children that are not part of the element tree, such as ContextMenu items. Ports vaadin/browserless-test#142 to the vaadin-testbench-unit modules.
Artur-
approved these changes
Sep 7, 2026
Artur-
enabled auto-merge (squash)
September 7, 2026 12:06
Artur-
disabled auto-merge
September 7, 2026 12:06
Artur-
enabled auto-merge (squash)
September 7, 2026 12:06
73 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Component tree walking in
TestingLifecycleHook.getAllChildrennow unions a component's owngetChildren()withComponentUtil.getAllChildren(component), instead of usinggetChildren()plus virtual children only.Why
Vaadin 25.3 slots the
Dialogheader and footer wrappers into the light DOM, andDialog.getChildren()filters those wrappers out. As a result, components added throughgetHeader()/getFooter()were no longer part of the walked component tree, andComponentQuerycould not find them:Cardbehaves the same way — it excludes every child carrying aslotattribute fromgetChildren(), sosetHeader(),setHeaderPrefix(),setHeaderSuffix()andaddToFooter()content was invisible to queries too.How
The fallback branch of the walker now merges both sources and de-duplicates:
Neither source is complete on its own:
getChildren()can hide element children (Dialog,Cardand their slotted content).ComponentUtil.getAllChildren()walks the element hierarchy — regular and virtual children, descending through non-component wrapper elements — but misses children that are not part of the element tree at all, e.g.ContextMenu, which keeps its items in a server-sideMenuManagerlist thatgetChildren()delegates to.Using
getAllChildren()also keeps the virtual children previously added for karibu-testing#85, so that fix is preserved. The special-cased branches above the fallback (MenuItemBase,MenuBar, templates,Grid.Column,ColumnGroup,Composite) are untouched.This ports vaadin/browserless-test#142 to the
vaadin-testbench-unitmodules.Test summary
Dialog, the button added viagetHeader().add(...)is returned by$(Button.class).withText("Header").single()and is the same instance held by the viewgetFooter().add(...)Dialog.getChildren()tooDialogcontent added withdialog.add(...)is still foundCard, content plussetHeader,setHeaderPrefix,setHeaderSuffixandaddToFootercomponents are all found by queryCardexcludes everyslot-carrying child, covering the second affected component.single(), so a component appearing twice in the walked tree fails the testContextMenuitems — which live in a server-sideMenuManagerand are absent from the element tree — are still discoverableComponentUtil.getAllChildren()alone would lose them; pinned by pre-existingContextMenuTesterTest(unchanged here)Tests added/changed on this branch:
DialogTesterTest.openedDialog_headerAndFooterComponentsAreFoundByQuery— rows 1, 2, 3, 5CardTesterTest.slottedComponentsAreFoundByQuery— rows 4, 5DialogView(fixture) — adds header/content/footer buttons used by rows 1–3;CardView(new fixture) — backs row 4ContextMenuTesterTest, deliberately left as-is to act as the regression guard for thegetChildren()half of the unionDeliberately untested: the untouched special-case branches of the walker (
MenuBar, templates,Grid.Column,Composite), which keep their existing coverage; and thejunit6/quarkus/vaadin-testbench-unitmodules, which consume the same shared Kotlin code path exercised by thejunit5tests.