Skip to content

feat!: add TreeGridTester with expand and collapse - #189

Merged
mcollovati merged 5 commits into
mainfrom
feat/treegrid-tester-expand-collapse
Sep 14, 2026
Merged

mcollovati merged 5 commits into
mainfrom
feat/treegrid-tester-expand-collapse

Conversation

@totally-not-ai

@totally-not-ai totally-not-ai Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds TreeGridTester, a tester made for TreeGrid, so tests can expand and collapse rows the same way a user does in the browser. Until now TreeGrid fell back to GridTester, and tests had to call treeGrid.expand(item) directly, which produced an ExpandEvent with isFromClient() as false. Fixes #176.

What changed

Breaking (source only): test(treeGrid) and test(treeGrid, itemType) now return TreeGridTester<TreeGrid<V>, V> instead of GridTester<Grid<V>, V>. The new overloads are more specific, so a TreeGrid argument resolves to them. This only affects code that assigns the result to an explicitly typed GridTester<Grid<V>, V> variable or passes it to a parameter of that type — that code no longer compiles. Fix it by widening the declaration to GridTester<? extends Grid<V>, V>, using var, or chaining the call directly. Binary compatibility is unaffected: test(Grid) and test(Grid, Class) are unchanged, so already compiled code keeps working.

New TreeGridTester (extends GridTester):

  • expand(int row) / collapse(int row) mirror a click on the tree toggle. They call the user-originated expand/collapse overloads, so ExpandEvent and CollapseEvent report isFromClient() as true.
  • isExpanded(int row) and hasChildren(int row) read the state of a row.
  • Row indexes address displayed rows only, so children of collapsed nodes are not counted.
  • expand/collapse throw IllegalStateException when the tree grid has no visible hierarchy column (the user would see no toggle), when the row is a leaf, or when the row is already in the target state — the same style as DetailsTester. Several hierarchy columns need no special handling, since each one renders a toggle for the same node.
  • getCellText(row, column) is overridden: a hierarchy column added with addHierarchyColumn(ValueProvider) renders through a LitRenderer over vaadin-grid-tree-toggle, not a column path, so the text is read from the toggle's own value provider. All other columns, including the component variant, are read as before by GridTester.

Use case

You test a view with a file tree. The app loads a folder's contents only when the user opens it, and it tracks opened folders for analytics — both hang off an expand listener that checks isFromClient(). With GridTester you could not trigger that path; now you can.

@Test
void openingFolder_loadsContentsAndTracksTheClick() {
    FileBrowserView view = navigate(FileBrowserView.class);
    var tree = test(view.fileTree);

    assertEquals(1, tree.size());          // only the root folder is shown
    assertTrue(tree.hasChildren(0));
    assertFalse(tree.isExpanded(0));

    tree.expand(0);                        // as if the user clicked the toggle

    assertTrue(tree.isExpanded(0));
    assertEquals("reports", tree.getCellText(1, 0));
    assertEquals(List.of("/"), view.analytics.getOpenedFolders());

    tree.collapse(0);
    assertEquals(1, tree.size());
}

API Changes

com.vaadin.browserless.TesterWrappers

// Added
default <V> TreeGridTester<TreeGrid<V>, V> test(TreeGrid<V> treeGrid) // more specific than test(Grid); a TreeGrid argument now resolves here
default <V> TreeGridTester<TreeGrid<V>, V> test(TreeGrid treeGrid, Class<V> itemType) // more specific than test(Grid, Class); a TreeGrid argument now resolves here

com.vaadin.flow.component.treegrid.TreeGridTester

// Added
public class TreeGridTester<T extends TreeGrid<Y>, Y> extends GridTester<T, Y>
public TreeGridTester(T component)
public void expand(int row) // fires a client originated ExpandEvent
public void collapse(int row) // fires a client originated CollapseEvent
public boolean isExpanded(int row)
public boolean hasChildren(int row)
public String getCellText(int row, int column) // overrides GridTester; reads the tree toggle's value provider for a hierarchy column

Test summary

# Status What the test verifies Why it matters
1 A TreeGrid passed to test(...) yields a TreeGridTester, even when the static type is Grid The whole feature is unreachable if the registry still picks GridTester
2 expand(row) makes children visible, and row indexes keep following the displayed rows when nesting deeper Wrong index mapping would silently point tests at the wrong item
3 collapse(row) hides the children again The inverse of the core feature
4 ExpandEvent and CollapseEvent carry the right items and report isFromClient() == true This is the exact gap the PR exists to close
5 isExpanded and hasChildren follow the state of the row before and after expanding Assertions in user tests build on these two reads
6 Toggling a leaf row throws IllegalStateException A user has no toggle there; silent success would hide a broken test
7 Expanding an expanded node, or collapsing a collapsed one, throws Same contract as DetailsTester; prevents impossible interactions
8 On a hidden tree grid, expand, collapse, isExpanded and hasChildren all throw The visibility guard is the documented contract of all four methods
9 expand/collapse throw when there is no hierarchy column, or when the only one is hidden; hasChildren still works Without a visible toggle the interaction is not something a user can perform
10 With two hierarchy columns, expand(0) toggles the node once Confirms several toggles need no special handling
11 getCellText reads the value-provider hierarchy column, the component hierarchy column and a plain column Hierarchy columns returned null before the override
12 gap test(treeGrid, itemType) returns a working TreeGridTester The second overload is never called by a test, so a typo there would not be caught
  • TreeGridTesterTest.treeGrid_resolvesToTreeGridTester — 1
  • TreeGridTesterTest.expand_childRowsBecomeVisible — 2
  • TreeGridTesterTest.expand_nestedRow_rowIndexesFollowTheDisplayedRows — 2
  • TreeGridTesterTest.collapse_childRowsHidden — 3
  • TreeGridTesterTest.expand_firesExpandEventFromClient — 4
  • TreeGridTesterTest.collapse_firesCollapseEventFromClient — 4
  • TreeGridTesterTest.isExpandedAndHasChildren_reflectRowState — 5
  • TreeGridTesterTest.expandOrCollapseLeafRow_throws — 6
  • TreeGridTesterTest.toggleRowAlreadyInTargetState_throws — 7
  • TreeGridTesterTest.hiddenTreeGrid_throws — 8
  • TreeGridTesterTest.withoutHierarchyColumn_expandAndCollapseThrow — 9
  • TreeGridTesterTest.hiddenHierarchyColumn_expandThrows — 9
  • TreeGridTesterTest.multipleHierarchyColumns_expandWorksAndTogglesTheSameNode — 10
  • TreeGridTesterTest.getCellText_readsHierarchyAndPlainColumns — 11
  • TreeGridTesterTest.getCellText_readsComponentHierarchyColumn — 11

Left untested on purpose: the constructor and the inherited GridTester behaviour (size, getRow), which every test above already goes through.

TreeGrid resolved to GridTester through the superclass walk in
TesterRegistry, which left the one interaction that distinguishes a
TreeGrid from a Grid unreachable: tests had to call treeGrid.expand(item)
directly, and the resulting ExpandEvent reported isFromClient() as false.

TreeGridTester mirrors what the hierarchy column's tree toggle does on
the client: it guards on HierarchicalDataCommunicator.hasChildren(item)
and then calls the protected expand/collapse overloads with
userOriginated set, so ExpandEvent and CollapseEvent are reported as
coming from the client. Row indexes address displayed rows, since
GridTester.getRow already walks the TreeGrid row sequence and skips
children of collapsed nodes.

Toggling a leaf row, or a row that is already in the target state,
throws IllegalStateException the way DetailsTester does, since neither
is something a user can do.

Fixes #176
isExpanded and hasChildren both document that they require a visible
component, but only expand and collapse were exercised against a hidden
tree grid. Extend the existing case to cover all four.
Comment thread junit6/src/test/java/com/vaadin/flow/component/treegrid/TreeGridTesterTest.java Outdated
Comment thread shared/src/main/java/com/vaadin/browserless/TesterWrappers.java
The expand toggle lives in the hierarchy column, and TreeGrid can be
configured with none, one or several of them. expand and collapse now
require at least one visible hierarchy column, since without one the
user is shown no toggle to click; several hierarchy columns each render
a toggle for the same node, so they need no special handling.

getCellText also returns null for a hierarchy column added through a
value provider, because that column renders the item through a
LitRenderer over vaadin-grid-tree-toggle rather than through a column
path. Read it from the toggle's own value provider instead. The
component variant is a ComponentRenderer and is already handled by
GridTester.

Also split the expand and collapse tests so that the row bookkeeping and
the client originated events are asserted separately, and pin the root
row positions before expanding.
@github-actions

github-actions Bot commented Sep 14, 2026

Copy link
Copy Markdown

Test Results

1 340 tests   1 340 ✅  39s ⏱️
  131 suites      0 💤
  131 files        0 ❌

Results for commit 445f1a7.

♻️ This comment has been updated with latest results.

@totally-not-ai

Copy link
Copy Markdown
Contributor Author

CI was red on AllTests with 32 failures of the form WelcomeView[@theme='padding spacing'] vs 'spacing padding'. Not from this branch — it reproduces on a clean checkout of the commit this branch was cut from, and re-running the job reproduced it identically, so it is not flaky either.

Root cause is that this branch was based on an older main, from before #207 stopped the tree assertions from depending on the order of theme names. Merged main in to pick that up, along with the other work that has landed since.

After the merge the suite is green: 1278 tests in junit6, including the 15 in TreeGridTesterTest. Nothing in the merge collided with the tester — GridTester gained deselect/deselectAll (#187) and the client-path value changes (#188) in the meantime, and TreeGridTester inherits both unchanged.

Unrelated heads-up while verifying: SpringPageTitleGeneratorTest fails two assertions for me on a clean main too, so it looks environment-specific rather than something either of us introduced.

The TreeGrid overloads of test() are more specific than the Grid ones,
so a TreeGrid argument now resolves to TreeGridTester. Spell that out on
the overloads themselves, together with what code that relied on the old
static type has to do instead.

BREAKING CHANGE: test(treeGrid) and test(treeGrid, itemType) now return
TreeGridTester<TreeGrid<V>, V> instead of GridTester<Grid<V>, V>. Code
that assigned the result to an explicitly typed GridTester<Grid<V>, V>,
or passed it to a parameter of that type, no longer compiles. Widen the
declaration to GridTester<? extends Grid<V>, V>, use var, or chain the
call directly. Binary compatibility is unaffected: test(Grid) and
test(Grid, Class) are unchanged, so already compiled code keeps working.
@totally-not-ai totally-not-ai Bot changed the title feat: add TreeGridTester with expand and collapse feat!: add TreeGridTester with expand and collapse Sep 14, 2026
@mcollovati

Copy link
Copy Markdown
Contributor

Looks good to me, but introduces a breaking change. To be released in the next minor.

@totally-not-ai

Copy link
Copy Markdown
Contributor Author

@mcollovati Thanks. Nothing further needed on the branch for that — it is already set up to land in a minor rather than a patch:

  • base is main (1.2-SNAPSHOT), with 1.1 maintained on its own branch, so this cannot reach the 1.1.x line
  • title is feat!: and the commit carries a BREAKING CHANGE: footer describing the narrowed return type and the migration
  • branch is level with main and all checks are green

One thing worth your call: 1.2.0-beta1 is already tagged, so merging as-is puts the break in 1.2.0 final. If 1.2 is meant to be API-frozen at beta, this should wait for the branch after it instead — happy either way, just leaving it unmerged until you decide.

@mcollovati
mcollovati merged commit c3069be into main Sep 14, 2026
6 checks passed
@mcollovati
mcollovati deleted the feat/treegrid-tester-expand-collapse branch September 14, 2026 13:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

No way to expand or collapse a TreeGrid node

1 participant