diff --git a/e2e/testcafe-devextreme/tests/common/pivotGrid/etalons/rows_do_not_overlap_data_fields_if_virtual_scrolling_enabled_T1210807 (fluent.blue.light).png b/e2e/testcafe-devextreme/tests/common/pivotGrid/etalons/rows_do_not_overlap_data_fields_if_virtual_scrolling_enabled_T1210807 (fluent.blue.light).png index 08c88eb851e0..925dcf13dc31 100644 Binary files a/e2e/testcafe-devextreme/tests/common/pivotGrid/etalons/rows_do_not_overlap_data_fields_if_virtual_scrolling_enabled_T1210807 (fluent.blue.light).png and b/e2e/testcafe-devextreme/tests/common/pivotGrid/etalons/rows_do_not_overlap_data_fields_if_virtual_scrolling_enabled_T1210807 (fluent.blue.light).png differ diff --git a/e2e/testcafe-devextreme/tests/common/pivotGrid/etalons/rows_do_not_overlap_data_fields_if_virtual_scrolling_enabled_T1210807 (material.blue.light).png b/e2e/testcafe-devextreme/tests/common/pivotGrid/etalons/rows_do_not_overlap_data_fields_if_virtual_scrolling_enabled_T1210807 (material.blue.light).png index 1177b56aefb8..6c8dc9deb5be 100644 Binary files a/e2e/testcafe-devextreme/tests/common/pivotGrid/etalons/rows_do_not_overlap_data_fields_if_virtual_scrolling_enabled_T1210807 (material.blue.light).png and b/e2e/testcafe-devextreme/tests/common/pivotGrid/etalons/rows_do_not_overlap_data_fields_if_virtual_scrolling_enabled_T1210807 (material.blue.light).png differ diff --git a/e2e/testcafe-devextreme/tests/common/treeList/etalons/T1189118-treelist-select-all-with-virtual-scrolling-2 (fluent.blue.light).png b/e2e/testcafe-devextreme/tests/common/treeList/etalons/T1189118-treelist-select-all-with-virtual-scrolling-2 (fluent.blue.light).png index 07884ce84848..2746a5195ed3 100644 Binary files a/e2e/testcafe-devextreme/tests/common/treeList/etalons/T1189118-treelist-select-all-with-virtual-scrolling-2 (fluent.blue.light).png and b/e2e/testcafe-devextreme/tests/common/treeList/etalons/T1189118-treelist-select-all-with-virtual-scrolling-2 (fluent.blue.light).png differ diff --git a/e2e/testcafe-devextreme/tests/dataGrid/common/editing/etalons/grid-new-row_position-viewportTop_scroll-mode-virtual_top-162 (fluent.blue.light).png b/e2e/testcafe-devextreme/tests/dataGrid/common/editing/etalons/grid-new-row_position-viewportTop_scroll-mode-virtual_top-162 (fluent.blue.light).png index 9db7f152ea68..bae8a75b4de9 100644 Binary files a/e2e/testcafe-devextreme/tests/dataGrid/common/editing/etalons/grid-new-row_position-viewportTop_scroll-mode-virtual_top-162 (fluent.blue.light).png and b/e2e/testcafe-devextreme/tests/dataGrid/common/editing/etalons/grid-new-row_position-viewportTop_scroll-mode-virtual_top-162 (fluent.blue.light).png differ diff --git a/e2e/testcafe-devextreme/tests/dataGrid/common/etalons/T1136896-virtual-scrolling_editing-buttons (fluent.blue.light).png b/e2e/testcafe-devextreme/tests/dataGrid/common/etalons/T1136896-virtual-scrolling_editing-buttons (fluent.blue.light).png index f8e95fe69f04..08b0f9037967 100644 Binary files a/e2e/testcafe-devextreme/tests/dataGrid/common/etalons/T1136896-virtual-scrolling_editing-buttons (fluent.blue.light).png and b/e2e/testcafe-devextreme/tests/dataGrid/common/etalons/T1136896-virtual-scrolling_editing-buttons (fluent.blue.light).png differ diff --git a/e2e/testcafe-devextreme/tests/dataGrid/common/keyboardNavigation/etalons/navigate_to_last_cell_in_last_row_when_virtual_scrolling_is_enabled (fluent.blue.light).png b/e2e/testcafe-devextreme/tests/dataGrid/common/keyboardNavigation/etalons/navigate_to_last_cell_in_last_row_when_virtual_scrolling_is_enabled (fluent.blue.light).png index 4ca36322368c..eeb7ea957f1f 100644 Binary files a/e2e/testcafe-devextreme/tests/dataGrid/common/keyboardNavigation/etalons/navigate_to_last_cell_in_last_row_when_virtual_scrolling_is_enabled (fluent.blue.light).png and b/e2e/testcafe-devextreme/tests/dataGrid/common/keyboardNavigation/etalons/navigate_to_last_cell_in_last_row_when_virtual_scrolling_is_enabled (fluent.blue.light).png differ diff --git a/e2e/testcafe-devextreme/tests/dataGrid/common/rowDragging/etalons/T1179218-virtual-scrolling-dragging-row (fluent.blue.light).png b/e2e/testcafe-devextreme/tests/dataGrid/common/rowDragging/etalons/T1179218-virtual-scrolling-dragging-row (fluent.blue.light).png index f4ec46b97a53..62c9e691ee4e 100644 Binary files a/e2e/testcafe-devextreme/tests/dataGrid/common/rowDragging/etalons/T1179218-virtual-scrolling-dragging-row (fluent.blue.light).png and b/e2e/testcafe-devextreme/tests/dataGrid/common/rowDragging/etalons/T1179218-virtual-scrolling-dragging-row (fluent.blue.light).png differ diff --git a/e2e/testcafe-devextreme/tests/dataGrid/common/scrolling.ts b/e2e/testcafe-devextreme/tests/dataGrid/common/scrolling.ts index 2cc9f393d7f9..8dae14cdbc05 100644 --- a/e2e/testcafe-devextreme/tests/dataGrid/common/scrolling.ts +++ b/e2e/testcafe-devextreme/tests/dataGrid/common/scrolling.ts @@ -2115,3 +2115,82 @@ test('Horizontal scrollbar should not appear when columnHidingEnabled is true an useNative: true, }, })); + +test('navigateToRow should scroll to the correct row with virtual scrolling (T1220800)', async (t) => { + const dataGrid = new DataGrid('#container'); + const targetKey = 901; + + await t.expect(dataGrid.isReady()).ok(); + + // act + await dataGrid.apiNavigateToRow(targetKey); + + // assert + await t + .expect(dataGrid.isReady()) + .ok() + .expect(dataGrid.getDataCells(0).nth(0).textContent) + .eql(String(targetKey)); + + const visibleRows = await dataGrid.apiGetVisibleRows(); + + await t.expect(visibleRows[0].key).eql(targetKey, `Row with key ${targetKey} should be the first visible row after navigation`); +}).before(async (t) => { + const initStore = ClientFunction(() => { + const getItems = (): Record[] => { + const items: Record[] = []; + for (let i = 0; i < 1000000; i += 1) { + items.push({ + ID: i + 1, + Name: `Name ${i + 1}`, + Description: `Text text text text text text text text text text ${i + 1}`, + }); + } + return items; + }; + + (window as any).myStore = new (window as any).DevExpress.data.ArrayStore({ + key: 'ID', + data: getItems(), + }); + }); + + await initStore.with({ boundTestRun: t })(); + + return createWidget('dxDataGrid', () => ({ + dataSource: new (window as any).DevExpress.data.CustomStore({ + key: 'ID', + loadMode: 'raw', + load(loadOptions) { + return new Promise((resolve) => { + (window as any).myStore.load(loadOptions).done((data) => { + resolve(data); + }); + }); + }, + totalCount() { + return (window as any).myStore.totalCount(); + }, + }), + width: 900, + height: 250, + wordWrapEnabled: true, + showBorders: true, + scrolling: { + mode: 'virtual', + rowRenderingMode: 'virtual', + useNative: false, + }, + paging: { + pageSize: 20, + }, + columns: [ + { + dataField: 'ID', + width: 90, + }, + 'Name', + 'Description', + ], + })); +}); diff --git a/packages/devextreme/js/__internal/grids/grid_core/virtual_scrolling/m_virtual_scrolling_core.ts b/packages/devextreme/js/__internal/grids/grid_core/virtual_scrolling/m_virtual_scrolling_core.ts index 6126c458ccc9..87397bf88cce 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/virtual_scrolling/m_virtual_scrolling_core.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/virtual_scrolling/m_virtual_scrolling_core.ts @@ -321,7 +321,7 @@ class VirtualScrollController { } }); - return Math.floor(offset + itemCount * this._viewportItemSize * this._sizeRatio); + return offset + itemCount * this._viewportItemSize * this._sizeRatio; } private getContentOffset(type) { diff --git a/packages/testcafe-models/dataGrid/index.ts b/packages/testcafe-models/dataGrid/index.ts index 2c0a662c005e..7355fa988adf 100644 --- a/packages/testcafe-models/dataGrid/index.ts +++ b/packages/testcafe-models/dataGrid/index.ts @@ -193,10 +193,18 @@ export default class DataGrid extends GridCore { return this.getRowsView().find(`.${CLASS.row}`); } + getDataRows(): Selector { + return this.getRows().filter(`.${CLASS.dataRow}`); + } + getCells(): Selector { return this.getRowsView().find('td'); } + getDataCells(rowIndex: number): Selector { + return this.getDataRows().nth(rowIndex).find('td'); + } + getDataRow(index: number): DataRow { return new DataRow(this.element.find(`.${CLASS.dataRow}[aria-rowindex='${index + 1}']`), this.getName()); } @@ -965,8 +973,10 @@ export default class DataGrid extends GridCore { const isElementInRowsView = (element) => { const rowsViewRect = rowsViewElement[0].getBoundingClientRect(); const elementRect = element.getBoundingClientRect(); + const tolerance = 1; - return elementRect.top >= rowsViewRect.top && elementRect.bottom <= rowsViewRect.bottom; + return elementRect.top >= rowsViewRect.top - tolerance + && elementRect.bottom <= rowsViewRect.bottom + tolerance; }; const rowElement = rowsViewElement.find('.dx-row-focused');