Skip to content

feat!: return the component the grid rendered from GridTester.getCellComponent (#250) (CP: 25.3) - #257

Merged
mcollovati merged 1 commit into
25.3from
cherry-pick-250-to-25.3-1789799537168
Sep 21, 2026
Merged

mcollovati merged 1 commit into
25.3from
cherry-pick-250-to-25.3-1789799537168

Conversation

@vaadin-bot

Copy link
Copy Markdown
Collaborator

This PR cherry-picks changes from the original PR #250 to branch 25.3.

Original PR description

Summary

GridTester.getCellComponent used to render the cell again on every call and attach the fresh copy to the grid, so a test never acted on the component the grid actually shows. It now returns the component the grid rendered for that row and column. The old behaviour is still available as the new renderCellComponent.

Fixes #235

What changed

Breaking: getCellComponent(int, int) and getCellComponent(int, String) behave differently. This affects every test that reads a component cell.

  • It returns the component the grid rendered for the client, which is the one the browser shows. Reading the same cell twice gives the same instance, and the instance is replaced when the row is rendered anew (for example after refreshItem(...)).
  • Nothing is attached to the grid any more, so a later find(...) no longer reports leftover copies. Tests that counted those copies will see fewer components.
  • A row the client has not asked for yet is scrolled into view first, the way a user reaches it. Reading a cell can therefore scroll the grid.
  • It now throws IllegalStateException for a cell the grid renders nothing for: a hidden column, or a data provider whose items are not equal across fetches. The message points at renderCellComponent.
  • getCellText on a ComponentRenderer column reads the same rendered component. For a renderer that returns no component it now returns "" instead of null, because the grid renders an empty text node in that place. It can also throw for the cases listed above.

New, additive:

  • renderCellComponent(int, int) and renderCellComponent(int, String) keep the old behaviour — render the cell on its own and attach the copy to the grid. Use them for cells the grid does not render, such as those of a hidden column, and to keep older tests working.
  • An internal helper class reads the rendered components from the column's data generator.

A column index addresses only visible columns, so a hidden column's cells are reachable only by key, through renderCellComponent(int, String).

README and the find(...) javadocs were updated to match.

Use case

You have a grid with a component column of "Approve" buttons. A test clicks the button on the second row and checks that the row's item was really approved. With the old behaviour the click went to a throwaway copy, so nothing in the grid reacted.

var grid_ = test(view.requestGrid);

// the button the grid shows on row 1
var approve = (Button) grid_.getCellComponent(1, "approve");
test(approve).click();

assertTrue(view.requests.get(1).isApproved());

// after the row is refreshed, read the cell again to get the new button
view.requestGrid.getListDataView().refreshItem(view.requests.get(1));
var updated = (Button) grid_.getCellComponent(1, "approve");
assertEquals("Approved", updated.getText());

For a column that is hidden on purpose, render the cell instead:

Button hidden = (Button) grid_.renderCellComponent(1, "hiddenAction");

API Changes

com.vaadin.flow.component.grid.GridTester

// Added
public Component renderCellComponent(int row, int column) // former getCellComponent behaviour: renders a fresh copy and attaches it to the grid
public Component renderCellComponent(int row, String columnName) // former getCellComponent behaviour; the only way to reach a hidden column's cell

// Changed
- public Component getCellComponent(int row, int column) // rendered a new component per call and appended it to the grid
+ public Component getCellComponent(int row, int column) // returns the component the grid rendered; scrolls the row into view; throws IllegalStateException when the grid rendered none
- public Component getCellComponent(int row, String columnName) // rendered a new component per call and appended it to the grid
+ public Component getCellComponent(int row, String columnName) // returns the component the grid rendered; throws IllegalStateException for a hidden column
- public String getCellText(int row, int column) // returned null for a ComponentRenderer cell that rendered no component
+ public String getCellText(int row, int column) // reads the grid-rendered component; returns "" instead of null; may scroll or throw IllegalStateException

com.vaadin.browserless.internal.RenderedComponentSupport

// Added
public final class RenderedComponentSupport // for internal use only
public static Component getRenderedComponent(Grid.Column<?> column, String itemKey, BiFunction<Class<?>, String, Field> fieldGetter)

Test summary

  • Reading the same component cell twice returns one and the same instance, and leaves nothing attached to the grid for find(...) to report.
  • Refreshing an item replaces the cell's component: the old one is detached and the new one is the attached, rendered instance.
  • A row the client has not asked for yet is scrolled into view and stays rendered on later reads.
  • A hidden column and a data provider whose items differ across fetches both fail with a clear message that points at renderCellComponent, which then returns a component for those cells.
  • renderCellComponent still renders a new copy per call, attaches it to the grid, and that copy is not the component the grid shows.
  • A renderer that returns no component yields the empty text node the grid renders, so the cell text is "".

…Component (#250)

`GridTester.getCellComponent` used to render the cell again on every
call and attach the fresh copy to the grid, so a test never acted on the
component the grid actually shows. It now returns the component the grid
rendered for that row and column. The old behaviour is still available
as the new `renderCellComponent`.

Fixes #235
@mcollovati
mcollovati merged commit 802153b into 25.3 Sep 21, 2026
6 checks passed
@mcollovati
mcollovati deleted the cherry-pick-250-to-25.3-1789799537168 branch September 21, 2026 06:24
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.

2 participants