From ba95e31aa13d95f041e379b2221fca20f39e5c64 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Mon, 22 Sep 2025 12:51:55 +0300 Subject: [PATCH 1/7] feat: Add horizontal scrolling support to GridElement (#8046) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements scrollToColumn method to enable horizontal scrolling in Grid, particularly useful when columnRendering is set to lazy. This addresses the issue where cells return null when columns are out of view. New features: - scrollToColumn(GridColumnElement) - scrolls to specific column - scrollToColumn(int columnIndex) - scrolls to column by index - isColumnInView(GridColumnElement) - checks if column is visible - Automatic column scrolling in getCell() method This enhancement allows reliable testing of grids with many columns and lazy column rendering, fixing the issue where it was impossible to distinguish between genuinely null cells and cells not rendered due to being out of view. Fixes #8046 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../grid/it/GridColumnScrollPage.java | 71 ++++++++ .../grid/it/GridScrollToColumnIT.java | 159 ++++++++++++++++++ .../component/grid/testbench/GridElement.java | 62 ++++++- 3 files changed, 291 insertions(+), 1 deletion(-) create mode 100644 vaadin-grid-flow-parent/vaadin-grid-flow-integration-tests/src/main/java/com/vaadin/flow/component/grid/it/GridColumnScrollPage.java create mode 100644 vaadin-grid-flow-parent/vaadin-grid-flow-integration-tests/src/test/java/com/vaadin/flow/component/grid/it/GridScrollToColumnIT.java diff --git a/vaadin-grid-flow-parent/vaadin-grid-flow-integration-tests/src/main/java/com/vaadin/flow/component/grid/it/GridColumnScrollPage.java b/vaadin-grid-flow-parent/vaadin-grid-flow-integration-tests/src/main/java/com/vaadin/flow/component/grid/it/GridColumnScrollPage.java new file mode 100644 index 00000000000..9bc9b06de44 --- /dev/null +++ b/vaadin-grid-flow-parent/vaadin-grid-flow-integration-tests/src/main/java/com/vaadin/flow/component/grid/it/GridColumnScrollPage.java @@ -0,0 +1,71 @@ +/* + * Copyright 2000-2025 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.flow.component.grid.it; + +import java.util.ArrayList; +import java.util.List; + +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.grid.Grid.Column; +import com.vaadin.flow.component.html.Div; +import com.vaadin.flow.router.Route; + +/** + * Test page for Grid column scrolling functionality. + */ +@Route("vaadin-grid/grid-column-scroll") +public class GridColumnScrollPage extends Div { + + public GridColumnScrollPage() { + Grid grid = new Grid<>(); + + // Set width to ensure not all columns are visible at once + grid.setWidth("800px"); + + // Enable lazy column rendering + grid.setColumnRenderingMode(Grid.ColumnRenderingMode.LAZY); + + // Add many columns to ensure horizontal scrolling is needed + for (int i = 0; i < 20; i++) { + final int columnIndex = i; + Column column = grid + .addColumn(item -> item.getValue(columnIndex)) + .setHeader("Column " + i).setWidth("150px"); + column.setKey("col" + i); + } + + // Add test data + List items = new ArrayList<>(); + for (int row = 0; row < 100; row++) { + items.add(new TestItem(row)); + } + grid.setItems(items); + + add(grid); + } + + public static class TestItem { + private final int rowIndex; + + public TestItem(int rowIndex) { + this.rowIndex = rowIndex; + } + + public String getValue(int columnIndex) { + return "R" + rowIndex + "C" + columnIndex; + } + } +} diff --git a/vaadin-grid-flow-parent/vaadin-grid-flow-integration-tests/src/test/java/com/vaadin/flow/component/grid/it/GridScrollToColumnIT.java b/vaadin-grid-flow-parent/vaadin-grid-flow-integration-tests/src/test/java/com/vaadin/flow/component/grid/it/GridScrollToColumnIT.java new file mode 100644 index 00000000000..7286a218154 --- /dev/null +++ b/vaadin-grid-flow-parent/vaadin-grid-flow-integration-tests/src/test/java/com/vaadin/flow/component/grid/it/GridScrollToColumnIT.java @@ -0,0 +1,159 @@ +/* + * Copyright 2000-2025 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.flow.component.grid.it; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.flow.component.grid.testbench.GridColumnElement; +import com.vaadin.flow.component.grid.testbench.GridElement; +import com.vaadin.flow.component.grid.testbench.GridTHTDElement; +import com.vaadin.flow.testutil.TestPath; +import com.vaadin.tests.AbstractComponentIT; + +/** + * Test for scrolling to columns in Grid, especially important when + * columnRendering is set to lazy. + */ +@TestPath("vaadin-grid/grid-column-scroll") +public class GridScrollToColumnIT extends AbstractComponentIT { + + private GridElement grid; + + @Before + public void init() { + open(); + waitForDevServer(); + grid = $(GridElement.class).first(); + } + + @Test + public void testScrollToColumn_bringsColumnIntoView() { + // Assuming grid has many columns and some are out of view + List columns = grid.getAllColumns(); + + if (columns.size() > 5) { + // Get a column that might be out of view + GridColumnElement lastColumn = columns.get(columns.size() - 1); + + // Scroll to the last column + grid.scrollToColumn(lastColumn); + + // Verify the column is now in view + Assert.assertTrue("Column should be in view after scrolling", + grid.isColumnInView(lastColumn)); + } + } + + @Test + public void testScrollToColumnByIndex_bringsColumnIntoView() { + List columns = grid.getVisibleColumns(); + + if (columns.size() > 5) { + int lastIndex = columns.size() - 1; + + // Scroll to the last column by index + grid.scrollToColumn(lastIndex); + + // Verify we can get the cell without it being null + GridTHTDElement cell = grid.getCell(0, lastIndex); + Assert.assertNotNull( + "Cell should not be null after scrolling to column", cell); + } + } + + @Test + public void testIsColumnInView_detectsVisibleColumns() { + List columns = grid.getVisibleColumns(); + + if (!columns.isEmpty()) { + // First column should typically be in view + GridColumnElement firstColumn = columns.get(0); + Assert.assertTrue("First column should be in view", + grid.isColumnInView(firstColumn)); + } + } + + @Test + public void testGetCell_automaticallyScrollsColumnIntoView() { + List columns = grid.getAllColumns(); + + if (columns.size() > 10) { + // Try to get a cell from a column that's likely out of view + GridColumnElement farColumn = columns.get(columns.size() - 1); + + // This should automatically scroll the column into view + GridTHTDElement cell = grid.getCell(0, farColumn); + + Assert.assertNotNull( + "Cell should not be null after automatic scrolling", cell); + Assert.assertTrue("Column should be in view after getCell", + grid.isColumnInView(farColumn)); + } + } + + @Test + public void testScrollToColumn_withLazyColumnRendering() { + // This test specifically addresses the issue mentioned in #8046 + // When columnRendering is lazy, cells out of view return null + + List columns = grid.getAllColumns(); + if (columns.size() > 5) { + // First, try to get cells from the first row + for (int i = 0; i < columns.size(); i++) { + GridColumnElement column = columns.get(i); + + // Ensure column is scrolled into view + if (!grid.isColumnInView(column)) { + grid.scrollToColumn(column); + } + + // Now the cell should be accessible + GridTHTDElement cell = grid.getRow(0).getCell(column); + Assert.assertNotNull("Cell at column " + i + + " should not be null after scrolling", cell); + } + } + } + + @Test + public void testScrollToColumn_multipleScrolls() { + List columns = grid.getVisibleColumns(); + + if (columns.size() > 10) { + // Scroll to last column + GridColumnElement lastColumn = columns.get(columns.size() - 1); + grid.scrollToColumn(lastColumn); + Assert.assertTrue("Last column should be in view", + grid.isColumnInView(lastColumn)); + + // Scroll back to first column + GridColumnElement firstColumn = columns.get(0); + grid.scrollToColumn(firstColumn); + Assert.assertTrue("First column should be in view", + grid.isColumnInView(firstColumn)); + + // Scroll to middle column + GridColumnElement middleColumn = columns.get(columns.size() / 2); + grid.scrollToColumn(middleColumn); + Assert.assertTrue("Middle column should be in view", + grid.isColumnInView(middleColumn)); + } + } +} diff --git a/vaadin-grid-flow-parent/vaadin-grid-testbench/src/main/java/com/vaadin/flow/component/grid/testbench/GridElement.java b/vaadin-grid-flow-parent/vaadin-grid-testbench/src/main/java/com/vaadin/flow/component/grid/testbench/GridElement.java index 6f29d8ee58e..8713ce00504 100644 --- a/vaadin-grid-flow-parent/vaadin-grid-testbench/src/main/java/com/vaadin/flow/component/grid/testbench/GridElement.java +++ b/vaadin-grid-flow-parent/vaadin-grid-testbench/src/main/java/com/vaadin/flow/component/grid/testbench/GridElement.java @@ -65,6 +65,61 @@ protected void scrollToFlatRow(int row) { waitUntilLoadingFinished(); } + /** + * Scrolls horizontally to bring the specified column into view. This is + * useful when working with grids that have lazy column rendering. + * + * @param column + * the column to scroll into view + */ + public void scrollToColumn(GridColumnElement column) { + executeScript("const grid = arguments[0];" + + "const columnId = arguments[1];" + + "const col = grid._getColumns().find(c => c.__generatedTbId === columnId);" + + "if (col) {" + + " const index = grid._getColumns().indexOf(col);" + + " grid.$.table.scrollToColumn(index);" + "}", this, + column.get__generatedId()); + // Wait a bit for the scrolling to complete + try { + Thread.sleep(100); + } catch (InterruptedException e) { + // Ignore + } + } + + /** + * Scrolls horizontally to bring the column at the specified index into + * view. This is useful when working with grids that have lazy column + * rendering. + * + * @param columnIndex + * the index of the column to scroll into view + */ + public void scrollToColumn(int columnIndex) { + GridColumnElement column = getVisibleColumns().get(columnIndex); + scrollToColumn(column); + } + + /** + * Checks if the specified column is currently in the visible viewport. + * + * @param column + * the column to check + * @return {@code true} if the column is visible, {@code false} otherwise + */ + public boolean isColumnInView(GridColumnElement column) { + return (Boolean) executeScript("const grid = arguments[0];" + + "const columnId = arguments[1];" + + "const col = grid._getColumns().find(c => c.__generatedTbId === columnId);" + + "if (!col || !col._cells || col._cells.length === 0) return false;" + + "const cell = col._cells[0];" + + "const cellRect = cell.getBoundingClientRect();" + + "const gridRect = grid.getBoundingClientRect();" + + "return cellRect.left >= gridRect.left && cellRect.right <= gridRect.right;", + this, column.get__generatedId()); + } + /** * Gets the page size used when fetching data. * @@ -120,7 +175,7 @@ public GridTHTDElement getCell(int rowIndex, int colIndex) { /** * Gets the grid cell for the given row and column. *

- * Automatically scrolls the given row into view + * Automatically scrolls the given row and column into view * * @param rowIndex * the row index @@ -133,6 +188,11 @@ public GridTHTDElement getCell(int rowIndex, GridColumnElement column) { scrollToFlatRow(rowIndex); } + // Also scroll column into view if needed + if (!isColumnInView(column)) { + scrollToColumn(column); + } + GridTRElement row = getRow(rowIndex); return row.getCell(column); } From c7936bb91a39269d66a898f58d506410648835f7 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Mon, 22 Sep 2025 13:06:59 +0300 Subject: [PATCH 2/7] fix: Use correct ColumnRendering enum in GridColumnScrollPage Fixed compilation error by using ColumnRendering.LAZY instead of the non-existent Grid.ColumnRenderingMode.LAZY --- .../vaadin/flow/component/grid/it/GridColumnScrollPage.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vaadin-grid-flow-parent/vaadin-grid-flow-integration-tests/src/main/java/com/vaadin/flow/component/grid/it/GridColumnScrollPage.java b/vaadin-grid-flow-parent/vaadin-grid-flow-integration-tests/src/main/java/com/vaadin/flow/component/grid/it/GridColumnScrollPage.java index 9bc9b06de44..17a7d8cddfe 100644 --- a/vaadin-grid-flow-parent/vaadin-grid-flow-integration-tests/src/main/java/com/vaadin/flow/component/grid/it/GridColumnScrollPage.java +++ b/vaadin-grid-flow-parent/vaadin-grid-flow-integration-tests/src/main/java/com/vaadin/flow/component/grid/it/GridColumnScrollPage.java @@ -20,6 +20,7 @@ import com.vaadin.flow.component.grid.Grid; import com.vaadin.flow.component.grid.Grid.Column; +import com.vaadin.flow.component.grid.ColumnRendering; import com.vaadin.flow.component.html.Div; import com.vaadin.flow.router.Route; @@ -36,7 +37,7 @@ public GridColumnScrollPage() { grid.setWidth("800px"); // Enable lazy column rendering - grid.setColumnRenderingMode(Grid.ColumnRenderingMode.LAZY); + grid.setColumnRendering(ColumnRendering.LAZY); // Add many columns to ensure horizontal scrolling is needed for (int i = 0; i < 20; i++) { From 1cae056c34a300cad344e2ed862da8a72bd0433a Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Mon, 22 Sep 2025 13:21:57 +0300 Subject: [PATCH 3/7] format --- .../com/vaadin/flow/component/grid/it/GridColumnScrollPage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vaadin-grid-flow-parent/vaadin-grid-flow-integration-tests/src/main/java/com/vaadin/flow/component/grid/it/GridColumnScrollPage.java b/vaadin-grid-flow-parent/vaadin-grid-flow-integration-tests/src/main/java/com/vaadin/flow/component/grid/it/GridColumnScrollPage.java index 17a7d8cddfe..ca47ec568f6 100644 --- a/vaadin-grid-flow-parent/vaadin-grid-flow-integration-tests/src/main/java/com/vaadin/flow/component/grid/it/GridColumnScrollPage.java +++ b/vaadin-grid-flow-parent/vaadin-grid-flow-integration-tests/src/main/java/com/vaadin/flow/component/grid/it/GridColumnScrollPage.java @@ -18,9 +18,9 @@ import java.util.ArrayList; import java.util.List; +import com.vaadin.flow.component.grid.ColumnRendering; import com.vaadin.flow.component.grid.Grid; import com.vaadin.flow.component.grid.Grid.Column; -import com.vaadin.flow.component.grid.ColumnRendering; import com.vaadin.flow.component.html.Div; import com.vaadin.flow.router.Route; From 59377ceda8950243d1334f454842787e08d04edf Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Mon, 22 Sep 2025 15:09:43 +0300 Subject: [PATCH 4/7] fix: Fix horizontal scrolling implementation in GridElement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The scrollToColumn method was using a non-existent grid.$.table.scrollToColumn(index) API. Fixed to properly manipulate table.scrollLeft to scroll columns into view based on their position relative to the table viewport. This fix ensures horizontal scrolling works correctly with lazy column rendering, allowing cells to be accessed reliably even when columns are initially out of view. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../grid/it/GridScrollToColumnIT.java | 136 +++++++++--------- .../component/grid/testbench/GridElement.java | 131 +++++++++++------ 2 files changed, 156 insertions(+), 111 deletions(-) diff --git a/vaadin-grid-flow-parent/vaadin-grid-flow-integration-tests/src/test/java/com/vaadin/flow/component/grid/it/GridScrollToColumnIT.java b/vaadin-grid-flow-parent/vaadin-grid-flow-integration-tests/src/test/java/com/vaadin/flow/component/grid/it/GridScrollToColumnIT.java index 7286a218154..7da47d83943 100644 --- a/vaadin-grid-flow-parent/vaadin-grid-flow-integration-tests/src/test/java/com/vaadin/flow/component/grid/it/GridScrollToColumnIT.java +++ b/vaadin-grid-flow-parent/vaadin-grid-flow-integration-tests/src/test/java/com/vaadin/flow/component/grid/it/GridScrollToColumnIT.java @@ -47,65 +47,64 @@ public void init() { public void testScrollToColumn_bringsColumnIntoView() { // Assuming grid has many columns and some are out of view List columns = grid.getAllColumns(); + Assert.assertTrue("Grid should have more than 5 columns for this test", + columns.size() > 5); - if (columns.size() > 5) { - // Get a column that might be out of view - GridColumnElement lastColumn = columns.get(columns.size() - 1); + // Get a column that might be out of view + GridColumnElement lastColumn = columns.get(columns.size() - 1); - // Scroll to the last column - grid.scrollToColumn(lastColumn); + // Scroll to the last column + grid.scrollToColumn(lastColumn); - // Verify the column is now in view - Assert.assertTrue("Column should be in view after scrolling", - grid.isColumnInView(lastColumn)); - } + // Verify the column is now in view + Assert.assertTrue("Column should be in view after scrolling", + grid.isColumnInView(lastColumn)); } @Test public void testScrollToColumnByIndex_bringsColumnIntoView() { List columns = grid.getVisibleColumns(); + Assert.assertTrue("Grid should have more than 5 columns for this test", + columns.size() > 5); - if (columns.size() > 5) { - int lastIndex = columns.size() - 1; + int lastIndex = columns.size() - 1; - // Scroll to the last column by index - grid.scrollToColumn(lastIndex); + // Scroll to the last column by index + grid.scrollToColumn(lastIndex); - // Verify we can get the cell without it being null - GridTHTDElement cell = grid.getCell(0, lastIndex); - Assert.assertNotNull( - "Cell should not be null after scrolling to column", cell); - } + // Verify we can get the cell without it being null + GridTHTDElement cell = grid.getCell(0, lastIndex); + Assert.assertNotNull( + "Cell should not be null after scrolling to column", cell); } @Test public void testIsColumnInView_detectsVisibleColumns() { List columns = grid.getVisibleColumns(); + Assert.assertFalse("Grid should have columns", columns.isEmpty()); - if (!columns.isEmpty()) { - // First column should typically be in view - GridColumnElement firstColumn = columns.get(0); - Assert.assertTrue("First column should be in view", - grid.isColumnInView(firstColumn)); - } + // First column should typically be in view + GridColumnElement firstColumn = columns.get(0); + Assert.assertTrue("First column should be in view", + grid.isColumnInView(firstColumn)); } @Test public void testGetCell_automaticallyScrollsColumnIntoView() { List columns = grid.getAllColumns(); + Assert.assertTrue("Grid should have more than 10 columns for this test", + columns.size() > 10); - if (columns.size() > 10) { - // Try to get a cell from a column that's likely out of view - GridColumnElement farColumn = columns.get(columns.size() - 1); + // Try to get a cell from a column that's likely out of view + GridColumnElement farColumn = columns.get(columns.size() - 1); - // This should automatically scroll the column into view - GridTHTDElement cell = grid.getCell(0, farColumn); + // This should automatically scroll the column into view + GridTHTDElement cell = grid.getCell(0, farColumn); - Assert.assertNotNull( - "Cell should not be null after automatic scrolling", cell); - Assert.assertTrue("Column should be in view after getCell", - grid.isColumnInView(farColumn)); - } + Assert.assertNotNull( + "Cell should not be null after automatic scrolling", cell); + Assert.assertTrue("Column should be in view after getCell", + grid.isColumnInView(farColumn)); } @Test @@ -114,46 +113,47 @@ public void testScrollToColumn_withLazyColumnRendering() { // When columnRendering is lazy, cells out of view return null List columns = grid.getAllColumns(); - if (columns.size() > 5) { - // First, try to get cells from the first row - for (int i = 0; i < columns.size(); i++) { - GridColumnElement column = columns.get(i); - - // Ensure column is scrolled into view - if (!grid.isColumnInView(column)) { - grid.scrollToColumn(column); - } - - // Now the cell should be accessible - GridTHTDElement cell = grid.getRow(0).getCell(column); - Assert.assertNotNull("Cell at column " + i - + " should not be null after scrolling", cell); + Assert.assertTrue("Grid should have more than 5 columns for this test", + columns.size() > 5); + + // First, try to get cells from the first row + for (int i = 0; i < columns.size(); i++) { + GridColumnElement column = columns.get(i); + + // Ensure column is scrolled into view + if (!grid.isColumnInView(column)) { + grid.scrollToColumn(column); } + + // Now the cell should be accessible + GridTHTDElement cell = grid.getRow(0).getCell(column); + Assert.assertNotNull("Cell at column " + i + + " should not be null after scrolling", cell); } } @Test public void testScrollToColumn_multipleScrolls() { List columns = grid.getVisibleColumns(); - - if (columns.size() > 10) { - // Scroll to last column - GridColumnElement lastColumn = columns.get(columns.size() - 1); - grid.scrollToColumn(lastColumn); - Assert.assertTrue("Last column should be in view", - grid.isColumnInView(lastColumn)); - - // Scroll back to first column - GridColumnElement firstColumn = columns.get(0); - grid.scrollToColumn(firstColumn); - Assert.assertTrue("First column should be in view", - grid.isColumnInView(firstColumn)); - - // Scroll to middle column - GridColumnElement middleColumn = columns.get(columns.size() / 2); - grid.scrollToColumn(middleColumn); - Assert.assertTrue("Middle column should be in view", - grid.isColumnInView(middleColumn)); - } + Assert.assertTrue("Grid should have more than 10 columns for this test", + columns.size() > 10); + + // Scroll to last column + GridColumnElement lastColumn = columns.get(columns.size() - 1); + grid.scrollToColumn(lastColumn); + Assert.assertTrue("Last column should be in view", + grid.isColumnInView(lastColumn)); + + // Scroll back to first column + GridColumnElement firstColumn = columns.get(0); + grid.scrollToColumn(firstColumn); + Assert.assertTrue("First column should be in view", + grid.isColumnInView(firstColumn)); + + // Scroll to middle column + GridColumnElement middleColumn = columns.get(columns.size() / 2); + grid.scrollToColumn(middleColumn); + Assert.assertTrue("Middle column should be in view", + grid.isColumnInView(middleColumn)); } } diff --git a/vaadin-grid-flow-parent/vaadin-grid-testbench/src/main/java/com/vaadin/flow/component/grid/testbench/GridElement.java b/vaadin-grid-flow-parent/vaadin-grid-testbench/src/main/java/com/vaadin/flow/component/grid/testbench/GridElement.java index 8713ce00504..16fb5c89384 100644 --- a/vaadin-grid-flow-parent/vaadin-grid-testbench/src/main/java/com/vaadin/flow/component/grid/testbench/GridElement.java +++ b/vaadin-grid-flow-parent/vaadin-grid-testbench/src/main/java/com/vaadin/flow/component/grid/testbench/GridElement.java @@ -43,6 +43,42 @@ protected boolean isLoading() { this); } + /** + * Waits until the column's content elements are properly rendered and + * slotted. This is needed after horizontal scrolling to ensure + * lazy-rendered columns have their content properly synchronized. + * + * @param column + * the column to wait for + */ + private void waitUntilColumnContentReady(GridColumnElement column) { + waitUntil(e -> { + Boolean result = (Boolean) executeScript( + """ + const grid = arguments[0]; + const columnId = arguments[1]; + const col = grid._getColumns().find(c => c.__generatedTbId === columnId); + if (!col) return false; + const colIndex = grid._getColumns().indexOf(col); + const rows = grid._getRenderedRows(); + if (rows.length === 0) return true; + const firstRow = rows[0]; + const cells = firstRow.querySelectorAll('td, th'); + if (colIndex >= cells.length) return false; + const cell = cells[colIndex]; + if (!cell) return false; + const slot = cell.querySelector('slot'); + if (!slot) return false; + const slotName = slot.getAttribute('name'); + if (!slotName) return false; + const content = grid.querySelector('vaadin-grid-cell-content[slot="' + slotName + '"]'); + return content !== null && content.textContent.trim().length > 0; + """, + this, column.get__generatedId()); + return Boolean.TRUE.equals(result); + }, 2); + } + /** * Scrolls to the row with the given index. * @@ -73,19 +109,22 @@ protected void scrollToFlatRow(int row) { * the column to scroll into view */ public void scrollToColumn(GridColumnElement column) { - executeScript("const grid = arguments[0];" - + "const columnId = arguments[1];" - + "const col = grid._getColumns().find(c => c.__generatedTbId === columnId);" - + "if (col) {" - + " const index = grid._getColumns().indexOf(col);" - + " grid.$.table.scrollToColumn(index);" + "}", this, - column.get__generatedId()); - // Wait a bit for the scrolling to complete - try { - Thread.sleep(100); - } catch (InterruptedException e) { - // Ignore - } + // Scroll to column using its sizer cell offset + executeScript(""" + const grid = arguments[0]; + const columnId = arguments[1]; + const columns = grid._getColumns(); + const col = columns.find(c => c.__generatedTbId === columnId); + if (col && col._sizerCell) { + grid.$.table.scrollLeft = col._sizerCell.offsetLeft; + } + """, this, column.get__generatedId()); + + // Wait for scrolling to complete + waitUntilLoadingFinished(); + + // Wait for lazy column rendering and slot synchronization + waitUntilColumnContentReady(column); } /** @@ -109,15 +148,15 @@ public void scrollToColumn(int columnIndex) { * @return {@code true} if the column is visible, {@code false} otherwise */ public boolean isColumnInView(GridColumnElement column) { - return (Boolean) executeScript("const grid = arguments[0];" - + "const columnId = arguments[1];" - + "const col = grid._getColumns().find(c => c.__generatedTbId === columnId);" - + "if (!col || !col._cells || col._cells.length === 0) return false;" - + "const cell = col._cells[0];" - + "const cellRect = cell.getBoundingClientRect();" - + "const gridRect = grid.getBoundingClientRect();" - + "return cellRect.left >= gridRect.left && cellRect.right <= gridRect.right;", + Boolean result = (Boolean) executeScript( + """ + const grid = arguments[0]; + const columnId = arguments[1]; + const col = grid._getColumns().find(c => c.__generatedTbId === columnId); + return col ? grid.__isColumnInViewport(col) : false; + """, this, column.get__generatedId()); + return Boolean.TRUE.equals(result); } /** @@ -210,13 +249,15 @@ public GridTHTDElement getCell(int rowIndex, GridColumnElement column) { public GridTHTDElement getCell(String contents) throws NoSuchElementException { - String script = "const grid = arguments[0];" - + "const contents = arguments[1];" - + "const rowsInDom = Array.from(arguments[0].$.items.children);" - + "var tds = [];" - + "rowsInDom.forEach(function(tr) { Array.from(tr.children).forEach(function(td) { tds.push(td);})});" - + "const matches = tds.filter(function(td) { return td._content.textContent == contents});" - + "return matches.length ? matches[0] : null;"; + String script = """ + const grid = arguments[0]; + const contents = arguments[1]; + const rowsInDom = Array.from(arguments[0].$.items.children); + var tds = []; + rowsInDom.forEach(function(tr) { Array.from(tr.children).forEach(function(td) { tds.push(td);})}); + const matches = tds.filter(function(td) { return td._content.textContent == contents}); + return matches.length ? matches[0] : null; + """; TestBenchElement td = (TestBenchElement) executeScript(script, this, contents); if (td == null) { @@ -278,11 +319,13 @@ public List getRows(int firstRowIndex, int lastRowIndex) + (rowCount - 1) + " but were " + firstRowIndex + " and " + lastRowIndex); } - String script = "var grid = arguments[0];" - + "var firstRowIndex = arguments[1];" - + "var lastRowIndex = arguments[2];" - + "var rowsInDom = grid._getRenderedRows();" - + "return Array.from(rowsInDom).filter((row) => { return row.index >= firstRowIndex && row.index <= lastRowIndex;});"; + String script = """ + var grid = arguments[0]; + var firstRowIndex = arguments[1]; + var lastRowIndex = arguments[2]; + var rowsInDom = grid._getRenderedRows(); + return Array.from(rowsInDom).filter((row) => { return row.index >= firstRowIndex && row.index <= lastRowIndex;}); + """; Object rows = executeScript(script, this, firstRowIndex, lastRowIndex); if (rows != null) { return ((ArrayList) rows).stream().map( @@ -351,18 +394,20 @@ public List getAllColumns() { } protected void generatedColumnIdsIfNeeded() { - String generateIds = "const grid = arguments[0];" - + "if (!grid.__generatedTbId) {"// - + " grid.__generatedTbId = 1;"// - + "}" // - + "grid._getColumns().forEach(function(column) {" - + " if (!column.__generatedTbId) {" - + " column.__generatedTbId = grid.__generatedTbId++;" // - + " }" // - + "});"; + String generateIds = """ + const grid = arguments[0]; + if (!grid.__generatedTbId) { + grid.__generatedTbId = 1; + } + grid._getColumns().forEach(function(column) { + if (!column.__generatedTbId) { + column.__generatedTbId = grid.__generatedTbId++; + } + }); + return grid._getColumns().length; + """; executeScript(generateIds, this); - // } /** From 3ccbaf3d33410dd4f5348518d6bc072cdc16e3a2 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Mon, 29 Sep 2025 17:22:07 +0300 Subject: [PATCH 5/7] tweak --- .../component/grid/testbench/GridElement.java | 116 +++++++----------- 1 file changed, 41 insertions(+), 75 deletions(-) diff --git a/vaadin-grid-flow-parent/vaadin-grid-testbench/src/main/java/com/vaadin/flow/component/grid/testbench/GridElement.java b/vaadin-grid-flow-parent/vaadin-grid-testbench/src/main/java/com/vaadin/flow/component/grid/testbench/GridElement.java index b2fa4d1b8c7..b1019e28d89 100644 --- a/vaadin-grid-flow-parent/vaadin-grid-testbench/src/main/java/com/vaadin/flow/component/grid/testbench/GridElement.java +++ b/vaadin-grid-flow-parent/vaadin-grid-testbench/src/main/java/com/vaadin/flow/component/grid/testbench/GridElement.java @@ -43,42 +43,6 @@ protected boolean isLoading() { this); } - /** - * Waits until the column's content elements are properly rendered and - * slotted. This is needed after horizontal scrolling to ensure - * lazy-rendered columns have their content properly synchronized. - * - * @param column - * the column to wait for - */ - private void waitUntilColumnContentReady(GridColumnElement column) { - waitUntil(e -> { - Boolean result = (Boolean) executeScript( - """ - const grid = arguments[0]; - const columnId = arguments[1]; - const col = grid._getColumns().find(c => c.__generatedTbId === columnId); - if (!col) return false; - const colIndex = grid._getColumns().indexOf(col); - const rows = grid._getRenderedRows(); - if (rows.length === 0) return true; - const firstRow = rows[0]; - const cells = firstRow.querySelectorAll('td, th'); - if (colIndex >= cells.length) return false; - const cell = cells[colIndex]; - if (!cell) return false; - const slot = cell.querySelector('slot'); - if (!slot) return false; - const slotName = slot.getAttribute('name'); - if (!slotName) return false; - const content = grid.querySelector('vaadin-grid-cell-content[slot="' + slotName + '"]'); - return content !== null && content.textContent.trim().length > 0; - """, - this, column.get__generatedId()); - return Boolean.TRUE.equals(result); - }, 2); - } - /** * Scrolls to the row with the given index. * @@ -106,7 +70,7 @@ protected void scrollToFlatRow(int row) { * useful when working with grids that have lazy column rendering. * * @param column - * the column to scroll into view + * the column to scroll into view */ public void scrollToColumn(GridColumnElement column) { // Scroll to column using its sizer cell offset @@ -120,11 +84,12 @@ public void scrollToColumn(GridColumnElement column) { } """, this, column.get__generatedId()); - // Wait for scrolling to complete + // Wait for rendering to complete waitUntilLoadingFinished(); - // Wait for lazy column rendering and slot synchronization - waitUntilColumnContentReady(column); + // Wait for column to be in view + waitUntil(driver -> isColumnInView(column)); + } /** @@ -133,7 +98,7 @@ public void scrollToColumn(GridColumnElement column) { * rendering. * * @param columnIndex - * the index of the column to scroll into view + * the index of the column to scroll into view */ public void scrollToColumn(int columnIndex) { GridColumnElement column = getVisibleColumns().get(columnIndex); @@ -144,7 +109,7 @@ public void scrollToColumn(int columnIndex) { * Checks if the specified column is currently in the visible viewport. * * @param column - * the column to check + * the column to check * @return {@code true} if the column is visible, {@code false} otherwise */ public boolean isColumnInView(GridColumnElement column) { @@ -201,9 +166,9 @@ public int getRowCount() { * Automatically scrolls the given row into view * * @param rowIndex - * the row index + * the row index * @param colIndex - * the column index + * the column index * @return the grid cell for the given coordinates */ public GridTHTDElement getCell(int rowIndex, int colIndex) { @@ -217,9 +182,9 @@ public GridTHTDElement getCell(int rowIndex, int colIndex) { * Automatically scrolls the given row and column into view * * @param rowIndex - * the row index + * the row index * @param column - * the column element for the column + * the column element for the column * @return the grid cell for the given coordinates */ public GridTHTDElement getCell(int rowIndex, GridColumnElement column) { @@ -241,10 +206,10 @@ public GridTHTDElement getCell(int rowIndex, GridColumnElement column) { * matching the given string. * * @param contents - * the string to look for + * the string to look for * @return a grid cell containing the given string * @throws NoSuchElementException - * if no cell with the given string was found + * if no cell with the given string was found */ public GridTHTDElement getCell(String contents) throws NoSuchElementException { @@ -287,7 +252,7 @@ public int getLastVisibleRowIndex() { * Checks if the given row is in the visible viewport. * * @param rowIndex - * the row to check + * the row to check * @return true if the row is at least partially in view, * false otherwise */ @@ -301,13 +266,14 @@ private boolean isRowInView(int rowIndex) { * indexes. * * @param firstRowIndex - * the lower row index to be retrieved (inclusive) + * the lower row index to be retrieved (inclusive) * @param lastRowIndex - * the upper row index to be retrieved (inclusive) + * the upper row index to be retrieved (inclusive) * @return a {@link GridTRElement} list with the rows contained between the * given coordinates. * @throws IndexOutOfBoundsException - * if either of the provided row indexes do not exist + * if either of the provided row indexes do + * not exist */ public List getRows(int firstRowIndex, int lastRowIndex) throws IndexOutOfBoundsException { @@ -340,11 +306,11 @@ public List getRows(int firstRowIndex, int lastRowIndex) * Gets the {@code tr} element for the given row index. * * @param rowIndex - * the row index + * the row index * @return the {@code tr} element for the row, or {@code null} if the row is * not in viewport * @throws IndexOutOfBoundsException - * if no row with given index exists + * if no row with given index exists */ public GridTRElement getRow(int rowIndex) throws IndexOutOfBoundsException { return getRow(rowIndex, false); @@ -357,14 +323,14 @@ public GridTRElement getRow(int rowIndex) throws IndexOutOfBoundsException { * {@code scroll} parameter is {@code false}. * * @param rowIndex - * the row index + * the row index * @param scroll - * whether to scroll to the row index + * whether to scroll to the row index * @return the {@code tr} element for the row, or {@code null} if the row is * not in viewport and the provided {@code scroll} parameter is * {@code false} * @throws IndexOutOfBoundsException - * if no row with given index exists + * if no row with given index exists */ public GridTRElement getRow(int rowIndex, boolean scroll) throws IndexOutOfBoundsException { @@ -434,10 +400,10 @@ public List getVisibleColumns() { * first column. * * @param headerText - * the text in the header + * the text in the header * @return the grid column element for the given column * @throws NoSuchElementException - * if no column was found + * if no column was found */ public GridColumnElement getColumn(String headerText) throws NoSuchElementException { @@ -453,7 +419,7 @@ public GridColumnElement getColumn(String headerText) * Gets the header cell for the given visible column index. * * @param columnIndex - * the index of the column + * the index of the column * @return a cell element for the header cell */ public GridTHTDElement getHeaderCell(int columnIndex) { @@ -465,9 +431,9 @@ public GridTHTDElement getHeaderCell(int columnIndex) { * in header. * * @param rowIndex - * the index of the row in the header + * the index of the row in the header * @param columnIndex - * the index of the column in the header + * the index of the column in the header * @return the vaadin-grid-cell-content element for the given row and column * in header. */ @@ -488,9 +454,9 @@ public TestBenchElement getHeaderCellContent(int rowIndex, * Finds the cell element for the given row and column in header. * * @param rowIndex - * the index of the row in the header + * the index of the row in the header * @param columnIndex - * the index of the column in the header + * the index of the column in the header * @return the GridTHTDElement for the given row and column in header. */ public GridTHTDElement getHeaderCell(int rowIndex, int columnIndex) { @@ -507,7 +473,7 @@ public GridTHTDElement getHeaderCell(int rowIndex, int columnIndex) { * Gets the footer cell for the given visible column index. * * @param columnIndex - * the index of the column + * the index of the column * @return a cell element for the footer cell */ public GridTHTDElement getFooterCell(int columnIndex) { @@ -519,9 +485,9 @@ public GridTHTDElement getFooterCell(int columnIndex) { * in footer. * * @param rowIndex - * the index of the row in the footer + * the index of the row in the footer * @param columnIndex - * the index of the column in the footer + * the index of the column in the footer * @return the vaadin-grid-cell-content element for the given row and column * in footer. */ @@ -542,9 +508,9 @@ public TestBenchElement getFooterCellContent(int rowIndex, * Finds the cell element for the given row and column in footer. * * @param rowIndex - * the index of the row in the footer + * the index of the row in the footer * @param columnIndex - * the index of the column in the footer + * the index of the column in the footer * @return the GridTHTDElement for the given row and column in footer. */ public GridTHTDElement getFooterCell(int rowIndex, int columnIndex) { @@ -561,7 +527,7 @@ public GridTHTDElement getFooterCell(int rowIndex, int columnIndex) { * Selects the row with the given index. * * @param rowIndex - * the row to select + * the row to select */ public void select(int rowIndex) { select(getRow(rowIndex)); @@ -591,7 +557,7 @@ void select(GridTRElement row) { * Deselects the row with the given index. * * @param rowIndex - * the row to deselect + * the row to deselect */ public void deselect(int rowIndex) { deselect(getRow(rowIndex)); @@ -666,9 +632,9 @@ public List getVisibleRows() { * Gets the grid cells for the given row and column elements. * * @param rowIndex - * the row index + * the row index * @param columnElements - * the column elements + * the column elements * @return a {@link GridTHTDElement} list with the cells for the given * coordinates. */ @@ -682,7 +648,7 @@ public List getCells(int rowIndex, * Gets the grid cells for the given row. * * @param rowIndex - * the row index + * the row index * @return a {@link GridTHTDElement} list with the cells for the given * coordinates. */ @@ -696,7 +662,7 @@ public List getCells(int rowIndex) { * * @return the empty state content * @throws NoSuchElementException - * if no empty state content was found + * if no empty state content was found */ public TestBenchElement getEmptyStateContent() { try { From 136e74ad91bf10b6e8eedc49ddaa854c07a23291 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Mon, 29 Sep 2025 17:31:06 +0300 Subject: [PATCH 6/7] format --- .../component/grid/testbench/GridElement.java | 73 +++++++++---------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/vaadin-grid-flow-parent/vaadin-grid-testbench/src/main/java/com/vaadin/flow/component/grid/testbench/GridElement.java b/vaadin-grid-flow-parent/vaadin-grid-testbench/src/main/java/com/vaadin/flow/component/grid/testbench/GridElement.java index b1019e28d89..d7fd6e7d596 100644 --- a/vaadin-grid-flow-parent/vaadin-grid-testbench/src/main/java/com/vaadin/flow/component/grid/testbench/GridElement.java +++ b/vaadin-grid-flow-parent/vaadin-grid-testbench/src/main/java/com/vaadin/flow/component/grid/testbench/GridElement.java @@ -70,7 +70,7 @@ protected void scrollToFlatRow(int row) { * useful when working with grids that have lazy column rendering. * * @param column - * the column to scroll into view + * the column to scroll into view */ public void scrollToColumn(GridColumnElement column) { // Scroll to column using its sizer cell offset @@ -98,7 +98,7 @@ public void scrollToColumn(GridColumnElement column) { * rendering. * * @param columnIndex - * the index of the column to scroll into view + * the index of the column to scroll into view */ public void scrollToColumn(int columnIndex) { GridColumnElement column = getVisibleColumns().get(columnIndex); @@ -109,7 +109,7 @@ public void scrollToColumn(int columnIndex) { * Checks if the specified column is currently in the visible viewport. * * @param column - * the column to check + * the column to check * @return {@code true} if the column is visible, {@code false} otherwise */ public boolean isColumnInView(GridColumnElement column) { @@ -166,9 +166,9 @@ public int getRowCount() { * Automatically scrolls the given row into view * * @param rowIndex - * the row index + * the row index * @param colIndex - * the column index + * the column index * @return the grid cell for the given coordinates */ public GridTHTDElement getCell(int rowIndex, int colIndex) { @@ -182,9 +182,9 @@ public GridTHTDElement getCell(int rowIndex, int colIndex) { * Automatically scrolls the given row and column into view * * @param rowIndex - * the row index + * the row index * @param column - * the column element for the column + * the column element for the column * @return the grid cell for the given coordinates */ public GridTHTDElement getCell(int rowIndex, GridColumnElement column) { @@ -206,10 +206,10 @@ public GridTHTDElement getCell(int rowIndex, GridColumnElement column) { * matching the given string. * * @param contents - * the string to look for + * the string to look for * @return a grid cell containing the given string * @throws NoSuchElementException - * if no cell with the given string was found + * if no cell with the given string was found */ public GridTHTDElement getCell(String contents) throws NoSuchElementException { @@ -252,7 +252,7 @@ public int getLastVisibleRowIndex() { * Checks if the given row is in the visible viewport. * * @param rowIndex - * the row to check + * the row to check * @return true if the row is at least partially in view, * false otherwise */ @@ -266,14 +266,13 @@ private boolean isRowInView(int rowIndex) { * indexes. * * @param firstRowIndex - * the lower row index to be retrieved (inclusive) + * the lower row index to be retrieved (inclusive) * @param lastRowIndex - * the upper row index to be retrieved (inclusive) + * the upper row index to be retrieved (inclusive) * @return a {@link GridTRElement} list with the rows contained between the * given coordinates. * @throws IndexOutOfBoundsException - * if either of the provided row indexes do - * not exist + * if either of the provided row indexes do not exist */ public List getRows(int firstRowIndex, int lastRowIndex) throws IndexOutOfBoundsException { @@ -306,11 +305,11 @@ public List getRows(int firstRowIndex, int lastRowIndex) * Gets the {@code tr} element for the given row index. * * @param rowIndex - * the row index + * the row index * @return the {@code tr} element for the row, or {@code null} if the row is * not in viewport * @throws IndexOutOfBoundsException - * if no row with given index exists + * if no row with given index exists */ public GridTRElement getRow(int rowIndex) throws IndexOutOfBoundsException { return getRow(rowIndex, false); @@ -323,14 +322,14 @@ public GridTRElement getRow(int rowIndex) throws IndexOutOfBoundsException { * {@code scroll} parameter is {@code false}. * * @param rowIndex - * the row index + * the row index * @param scroll - * whether to scroll to the row index + * whether to scroll to the row index * @return the {@code tr} element for the row, or {@code null} if the row is * not in viewport and the provided {@code scroll} parameter is * {@code false} * @throws IndexOutOfBoundsException - * if no row with given index exists + * if no row with given index exists */ public GridTRElement getRow(int rowIndex, boolean scroll) throws IndexOutOfBoundsException { @@ -400,10 +399,10 @@ public List getVisibleColumns() { * first column. * * @param headerText - * the text in the header + * the text in the header * @return the grid column element for the given column * @throws NoSuchElementException - * if no column was found + * if no column was found */ public GridColumnElement getColumn(String headerText) throws NoSuchElementException { @@ -419,7 +418,7 @@ public GridColumnElement getColumn(String headerText) * Gets the header cell for the given visible column index. * * @param columnIndex - * the index of the column + * the index of the column * @return a cell element for the header cell */ public GridTHTDElement getHeaderCell(int columnIndex) { @@ -431,9 +430,9 @@ public GridTHTDElement getHeaderCell(int columnIndex) { * in header. * * @param rowIndex - * the index of the row in the header + * the index of the row in the header * @param columnIndex - * the index of the column in the header + * the index of the column in the header * @return the vaadin-grid-cell-content element for the given row and column * in header. */ @@ -454,9 +453,9 @@ public TestBenchElement getHeaderCellContent(int rowIndex, * Finds the cell element for the given row and column in header. * * @param rowIndex - * the index of the row in the header + * the index of the row in the header * @param columnIndex - * the index of the column in the header + * the index of the column in the header * @return the GridTHTDElement for the given row and column in header. */ public GridTHTDElement getHeaderCell(int rowIndex, int columnIndex) { @@ -473,7 +472,7 @@ public GridTHTDElement getHeaderCell(int rowIndex, int columnIndex) { * Gets the footer cell for the given visible column index. * * @param columnIndex - * the index of the column + * the index of the column * @return a cell element for the footer cell */ public GridTHTDElement getFooterCell(int columnIndex) { @@ -485,9 +484,9 @@ public GridTHTDElement getFooterCell(int columnIndex) { * in footer. * * @param rowIndex - * the index of the row in the footer + * the index of the row in the footer * @param columnIndex - * the index of the column in the footer + * the index of the column in the footer * @return the vaadin-grid-cell-content element for the given row and column * in footer. */ @@ -508,9 +507,9 @@ public TestBenchElement getFooterCellContent(int rowIndex, * Finds the cell element for the given row and column in footer. * * @param rowIndex - * the index of the row in the footer + * the index of the row in the footer * @param columnIndex - * the index of the column in the footer + * the index of the column in the footer * @return the GridTHTDElement for the given row and column in footer. */ public GridTHTDElement getFooterCell(int rowIndex, int columnIndex) { @@ -527,7 +526,7 @@ public GridTHTDElement getFooterCell(int rowIndex, int columnIndex) { * Selects the row with the given index. * * @param rowIndex - * the row to select + * the row to select */ public void select(int rowIndex) { select(getRow(rowIndex)); @@ -557,7 +556,7 @@ void select(GridTRElement row) { * Deselects the row with the given index. * * @param rowIndex - * the row to deselect + * the row to deselect */ public void deselect(int rowIndex) { deselect(getRow(rowIndex)); @@ -632,9 +631,9 @@ public List getVisibleRows() { * Gets the grid cells for the given row and column elements. * * @param rowIndex - * the row index + * the row index * @param columnElements - * the column elements + * the column elements * @return a {@link GridTHTDElement} list with the cells for the given * coordinates. */ @@ -648,7 +647,7 @@ public List getCells(int rowIndex, * Gets the grid cells for the given row. * * @param rowIndex - * the row index + * the row index * @return a {@link GridTHTDElement} list with the cells for the given * coordinates. */ @@ -662,7 +661,7 @@ public List getCells(int rowIndex) { * * @return the empty state content * @throws NoSuchElementException - * if no empty state content was found + * if no empty state content was found */ public TestBenchElement getEmptyStateContent() { try { From 5db362ef082e22aa42f0eb4a9f555650d8aa7526 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Tue, 30 Sep 2025 09:30:31 +0300 Subject: [PATCH 7/7] Make it work according to Tomi --- .../com/vaadin/flow/component/grid/testbench/GridElement.java | 1 + 1 file changed, 1 insertion(+) diff --git a/vaadin-grid-flow-parent/vaadin-grid-testbench/src/main/java/com/vaadin/flow/component/grid/testbench/GridElement.java b/vaadin-grid-flow-parent/vaadin-grid-testbench/src/main/java/com/vaadin/flow/component/grid/testbench/GridElement.java index d7fd6e7d596..0f1be451921 100644 --- a/vaadin-grid-flow-parent/vaadin-grid-testbench/src/main/java/com/vaadin/flow/component/grid/testbench/GridElement.java +++ b/vaadin-grid-flow-parent/vaadin-grid-testbench/src/main/java/com/vaadin/flow/component/grid/testbench/GridElement.java @@ -81,6 +81,7 @@ public void scrollToColumn(GridColumnElement column) { const col = columns.find(c => c.__generatedTbId === columnId); if (col && col._sizerCell) { grid.$.table.scrollLeft = col._sizerCell.offsetLeft; + grid.__updateColumnsBodyContentHidden(); } """, this, column.get__generatedId());