From 1d8abf20beb4020ed747aad5533bcdd4777ae282 Mon Sep 17 00:00:00 2001 From: Mark Allen Ramirez Date: Mon, 6 Apr 2026 20:54:44 +0800 Subject: [PATCH 01/10] spike --- .../keyboard_navigation/m_keyboard_navigation.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts b/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts index c7aeb3dde3f9..2e9e561521f7 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts @@ -312,7 +312,8 @@ export class KeyboardNavigationController extends KeyboardNavigationControllerCo if (needUpdateFocus) { const isScrollEvent = !!e?.event?.type; const skipFocusEvent = e?.virtualColumnsScrolling && isScrollEvent; - this._updateFocus(true, skipFocusEvent); + const preventScroll = !isFullUpdate; + this._updateFocus(true, skipFocusEvent, preventScroll); } } } @@ -1743,7 +1744,7 @@ export class KeyboardNavigationController extends KeyboardNavigationControllerCo gridCoreUtils.focusAndSelectElement(this, $focusedElement); } - public _focus($cell, disableFocus?, skipFocusEvent?) { + public _focus($cell, disableFocus?, skipFocusEvent?, preventScroll = false) { const $row = $cell && !$cell.hasClass(ROW_CLASS) ? $cell.closest(`.${ROW_CLASS}`) : $cell; @@ -1795,8 +1796,7 @@ export class KeyboardNavigationController extends KeyboardNavigationControllerCo }); if (!skipFocusEvent) { this._applyTabIndexToElement($focusElement); - // @ts-expect-error - eventsEngine.trigger($focusElement, 'focus'); + $focusElement.get(0)?.focus({ preventScroll }); } if (disableFocus) { $focusElement.addClass(CELL_FOCUS_DISABLED_CLASS); @@ -1809,7 +1809,7 @@ export class KeyboardNavigationController extends KeyboardNavigationControllerCo } } - public _updateFocus(isRenderView?, skipFocusEvent = false) { + public _updateFocus(isRenderView?, skipFocusEvent = false, preventScroll = false) { this._updateFocusTimeout = setTimeout(() => { if (this._needFocusEditingCell()) { this._editingController._focusEditingCell(); @@ -1853,7 +1853,7 @@ export class KeyboardNavigationController extends KeyboardNavigationControllerCo !isFocusedElementDefined && (this._isNeedFocus || this._isHiddenFocus) ) { - this._focus($cell, this._isHiddenFocus, skipFocusEvent); + this._focus($cell, this._isHiddenFocus, skipFocusEvent, preventScroll); } if (isEditing && !column?.showEditorAlways) { this._focusInteractiveElement.bind(this)($cell); From b2810db38e7ce93840fb3f052fd85902e2011084 Mon Sep 17 00:00:00 2001 From: Mark Allen Ramirez Date: Tue, 7 Apr 2026 16:50:39 +0800 Subject: [PATCH 02/10] fix --- .../keyboard_navigation/m_keyboard_navigation.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts b/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts index 2e9e561521f7..958644d57aff 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts @@ -312,8 +312,7 @@ export class KeyboardNavigationController extends KeyboardNavigationControllerCo if (needUpdateFocus) { const isScrollEvent = !!e?.event?.type; const skipFocusEvent = e?.virtualColumnsScrolling && isScrollEvent; - const preventScroll = !isFullUpdate; - this._updateFocus(true, skipFocusEvent, preventScroll); + this._updateFocus(true, skipFocusEvent, true); } } } @@ -1744,7 +1743,7 @@ export class KeyboardNavigationController extends KeyboardNavigationControllerCo gridCoreUtils.focusAndSelectElement(this, $focusedElement); } - public _focus($cell, disableFocus?, skipFocusEvent?, preventScroll = false) { + public _focus($cell: dxElementWrapper, disableFocus?: boolean, skipFocusEvent?: boolean, preventScroll?: boolean) { const $row = $cell && !$cell.hasClass(ROW_CLASS) ? $cell.closest(`.${ROW_CLASS}`) : $cell; @@ -1796,7 +1795,12 @@ export class KeyboardNavigationController extends KeyboardNavigationControllerCo }); if (!skipFocusEvent) { this._applyTabIndexToElement($focusElement); - $focusElement.get(0)?.focus({ preventScroll }); + if (preventScroll) { + $focusElement.get(0)?.focus({ preventScroll }); + } else { + // @ts-expect-error + eventsEngine.trigger($focusElement, 'focus'); + } } if (disableFocus) { $focusElement.addClass(CELL_FOCUS_DISABLED_CLASS); @@ -1848,7 +1852,7 @@ export class KeyboardNavigationController extends KeyboardNavigationControllerCo ); return; } - !isFocusedElementDefined && this._focus($cell, false, skipFocusEvent); + !isFocusedElementDefined && this._focus($cell, false, skipFocusEvent, preventScroll); } else if ( !isFocusedElementDefined && (this._isNeedFocus || this._isHiddenFocus) From 8e7b7ea8152ceee97750f6ab2b566ff2fb53018b Mon Sep 17 00:00:00 2001 From: Mark Allen Ramirez Date: Tue, 7 Apr 2026 16:54:30 +0800 Subject: [PATCH 03/10] additional fix --- .../grids/grid_core/keyboard_navigation/scrollable_a11y.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/scrollable_a11y.ts b/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/scrollable_a11y.ts index 0a7087cb9ede..67e1631d9373 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/scrollable_a11y.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/scrollable_a11y.ts @@ -61,8 +61,8 @@ export const keyboardNavigationScrollableA11yExtender = (Base: ModuleType Date: Tue, 7 Apr 2026 17:11:30 +0800 Subject: [PATCH 04/10] typings --- .../grid_core/keyboard_navigation/m_keyboard_navigation.ts | 2 +- .../grids/grid_core/keyboard_navigation/scrollable_a11y.ts | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts b/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts index 958644d57aff..2907f240e527 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts @@ -1813,7 +1813,7 @@ export class KeyboardNavigationController extends KeyboardNavigationControllerCo } } - public _updateFocus(isRenderView?, skipFocusEvent = false, preventScroll = false) { + public _updateFocus(isRenderView?: boolean, skipFocusEvent = false, preventScroll = false) { this._updateFocusTimeout = setTimeout(() => { if (this._needFocusEditingCell()) { this._editingController._focusEditingCell(); diff --git a/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/scrollable_a11y.ts b/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/scrollable_a11y.ts index 67e1631d9373..b2f327fc28d8 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/scrollable_a11y.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/scrollable_a11y.ts @@ -61,7 +61,12 @@ export const keyboardNavigationScrollableA11yExtender = (Base: ModuleType Date: Wed, 8 Apr 2026 17:04:19 +0800 Subject: [PATCH 05/10] testcafe --- .../keyboardNavigation.functional.ts | 77 ++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/e2e/testcafe-devextreme/tests/dataGrid/common/keyboardNavigation/keyboardNavigation.functional.ts b/e2e/testcafe-devextreme/tests/dataGrid/common/keyboardNavigation/keyboardNavigation.functional.ts index b40343483443..61c682ffbe97 100644 --- a/e2e/testcafe-devextreme/tests/dataGrid/common/keyboardNavigation/keyboardNavigation.functional.ts +++ b/e2e/testcafe-devextreme/tests/dataGrid/common/keyboardNavigation/keyboardNavigation.functional.ts @@ -18,7 +18,7 @@ import { resetFocusedEventsTestData, } from '../../helpers/eventUtils'; import { testScreenshot } from '../../../../helpers/themeUtils'; -import { addFocusableElementBefore } from '../../../../helpers/domUtils'; +import { addFocusableElementBefore, getDocumentScrollTop } from '../../../../helpers/domUtils'; const CLASS = ClassNames; @@ -6724,3 +6724,78 @@ test('Focus should be set to the grid to allow keyboard navigation when the focu }, }, '#otherContainer'); }); + +test('Browser should not scroll back to the grid when a focused cell is updated or rerendered (T1310557)', async (t) => { + // arrange + const dataGrid = new DataGrid('#container'); + const firstCell = dataGrid.getDataCell(0, 0); + const secondCell = dataGrid.getDataCell(0, 1); + + // assert + await t.expect(dataGrid.isReady()).ok(); + + // act + await t + .click(firstCell.element) + .pressKey('tab'); + + // assert + await t.expect(secondCell.element.focused).ok(); + + // act + await ClientFunction(() => { + window.scrollTo(0, 300); + })(); + + // assert + await t.expect(getDocumentScrollTop()).eql(300); + + // act + await dataGrid.apiPush([{ + type: 'update', + key: 1, + data: { name: 'updated' }, + }]); + + // assert + await t + .expect(secondCell.element.textContent) + .eql('updated') + .expect(getDocumentScrollTop()) + .eql(300); + + // act + await dataGrid.apiRefresh(); + + // assert + await t.expect(getDocumentScrollTop()).eql(300); + + // act + await dataGrid.repaint(); + + // assert + await t.expect(getDocumentScrollTop()).eql(300); + + // act + await t.pressKey('left'); + + // assert + await t + .expect(firstCell.isFocused) + .ok() + .expect(getDocumentScrollTop()) + .eql(0); +}).before(async () => { + await ClientFunction(() => { + $('#container').css('padding-bottom', '1000px'); + })(); + + await createWidget('dxDataGrid', { + dataSource: [{ id: 1, name: 'test1' }], + keyExpr: 'id', + }); +}).after(async () => { + await ClientFunction(() => { + $('#container').css('padding-bottom', ''); + })(); +}); From 59fadb128eff2d04290f229da11ff5cbc6ceff05 Mon Sep 17 00:00:00 2001 From: Mark Allen Ramirez Date: Wed, 8 Apr 2026 20:27:51 +0800 Subject: [PATCH 06/10] Revert "testcafe" This reverts commit 8b4814def5cece48a038d3c39e155683951c171f. --- .../keyboardNavigation.functional.ts | 77 +------------------ 1 file changed, 1 insertion(+), 76 deletions(-) diff --git a/e2e/testcafe-devextreme/tests/dataGrid/common/keyboardNavigation/keyboardNavigation.functional.ts b/e2e/testcafe-devextreme/tests/dataGrid/common/keyboardNavigation/keyboardNavigation.functional.ts index 61c682ffbe97..b40343483443 100644 --- a/e2e/testcafe-devextreme/tests/dataGrid/common/keyboardNavigation/keyboardNavigation.functional.ts +++ b/e2e/testcafe-devextreme/tests/dataGrid/common/keyboardNavigation/keyboardNavigation.functional.ts @@ -18,7 +18,7 @@ import { resetFocusedEventsTestData, } from '../../helpers/eventUtils'; import { testScreenshot } from '../../../../helpers/themeUtils'; -import { addFocusableElementBefore, getDocumentScrollTop } from '../../../../helpers/domUtils'; +import { addFocusableElementBefore } from '../../../../helpers/domUtils'; const CLASS = ClassNames; @@ -6724,78 +6724,3 @@ test('Focus should be set to the grid to allow keyboard navigation when the focu }, }, '#otherContainer'); }); - -test('Browser should not scroll back to the grid when a focused cell is updated or rerendered (T1310557)', async (t) => { - // arrange - const dataGrid = new DataGrid('#container'); - const firstCell = dataGrid.getDataCell(0, 0); - const secondCell = dataGrid.getDataCell(0, 1); - - // assert - await t.expect(dataGrid.isReady()).ok(); - - // act - await t - .click(firstCell.element) - .pressKey('tab'); - - // assert - await t.expect(secondCell.element.focused).ok(); - - // act - await ClientFunction(() => { - window.scrollTo(0, 300); - })(); - - // assert - await t.expect(getDocumentScrollTop()).eql(300); - - // act - await dataGrid.apiPush([{ - type: 'update', - key: 1, - data: { name: 'updated' }, - }]); - - // assert - await t - .expect(secondCell.element.textContent) - .eql('updated') - .expect(getDocumentScrollTop()) - .eql(300); - - // act - await dataGrid.apiRefresh(); - - // assert - await t.expect(getDocumentScrollTop()).eql(300); - - // act - await dataGrid.repaint(); - - // assert - await t.expect(getDocumentScrollTop()).eql(300); - - // act - await t.pressKey('left'); - - // assert - await t - .expect(firstCell.isFocused) - .ok() - .expect(getDocumentScrollTop()) - .eql(0); -}).before(async () => { - await ClientFunction(() => { - $('#container').css('padding-bottom', '1000px'); - })(); - - await createWidget('dxDataGrid', { - dataSource: [{ id: 1, name: 'test1' }], - keyExpr: 'id', - }); -}).after(async () => { - await ClientFunction(() => { - $('#container').css('padding-bottom', ''); - })(); -}); From f7967f69fdecc57b753688090b2dbaa3889fc4e7 Mon Sep 17 00:00:00 2001 From: Mark Allen Ramirez Date: Wed, 8 Apr 2026 20:34:42 +0800 Subject: [PATCH 07/10] qunit --- .../focus.integration.tests.js | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/focus.integration.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/focus.integration.tests.js index 21e9e8149bd0..147053607101 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/focus.integration.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/focus.integration.tests.js @@ -4980,4 +4980,86 @@ QUnit.module('Column Resizing', baseModuleConfig, () => { // assert assert.equal(dataGrid.getScrollable().scrollTop(), 10, 'scroll top is not changed'); }); + + // T1310557 + QUnit.testInActiveWindow('Browser should not scroll back to the grid when a focused cell is updated or rerendered', function(assert) { + // arrange + const dataGrid = createDataGrid({ + dataSource: { + store: new ArrayStore({ + key: 'id', + data: [{ id: 1, name: 'test1' }], + }), + pushAggregationTimeout: 0, + }, + }); + $('body').css('height', 2000); + window.scrollTo(0, 0); + this.clock.tick(10); + + const keyboardController = dataGrid.getController('keyboardNavigation'); + const $firstCell = $(dataGrid.getCellElement(0, 0)); + const scrollPosition = 300; + + // assert + assert.strictEqual(window.pageYOffset, 0, 'document scroll is at the top'); + + // act + $firstCell.trigger(CLICK_EVENT); + this.clock.tick(10); + + keyboardController.keyDownHandler({ + key: 'Tab', + keyName: 'tab', + originalEvent: $.Event('keydown', { target: $firstCell.get(0) }), + }); + this.clock.tick(10); + + // assert + assert.ok($(dataGrid.getCellElement(0, 1)).hasClass('dx-focused'), 'second cell is focused'); + + // act + window.scrollTo(0, scrollPosition); + + // assert + assert.strictEqual(window.pageYOffset, scrollPosition, 'document scroll is changed'); + + // act + dataGrid.getDataSource().store().push([{ type: 'update', key: 1, data: { name: 'updated' } }]); + this.clock.tick(10); + + // assert + assert.strictEqual($(dataGrid.getCellElement(0, 1)).text(), 'updated', 'second cell text is updated'); + assert.strictEqual(window.pageYOffset, scrollPosition, 'document scroll is preserved after push update'); + + // act + dataGrid.refresh(); + this.clock.tick(10); + + // assert + assert.strictEqual(window.pageYOffset, scrollPosition, 'document scroll is preserved after refresh'); + + // act + dataGrid.repaint(); + this.clock.tick(10); + + // assert + assert.strictEqual(window.pageYOffset, scrollPosition, 'document scroll is preserved after repaint'); + + // act + keyboardController.keyDownHandler({ + key: 'ArrowLeft', + keyName: 'leftArrow', + originalEvent: $.Event('keydown', { target: $(dataGrid.getCellElement(0, 1)).get(0) }), + }); + this.clock.tick(10); + + // assert + assert.ok($(dataGrid.getCellElement(0, 0)).hasClass('dx-focused'), 'first cell is focused'); + assert.strictEqual(window.pageYOffset, 0, 'document scroll is changed after keyboard navigation'); + + // cleanup + $('body').css('height', ''); + window.scrollTo(0, 0); + }); }); From c4349be38eed88aa93b85867ed3f305a98716085 Mon Sep 17 00:00:00 2001 From: Mark Allen Ramirez Date: Fri, 10 Apr 2026 15:59:54 +0800 Subject: [PATCH 08/10] update fix --- .../keyboard_navigation/m_keyboard_navigation.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts b/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts index 2907f240e527..7eba0da2e591 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts @@ -312,7 +312,7 @@ export class KeyboardNavigationController extends KeyboardNavigationControllerCo if (needUpdateFocus) { const isScrollEvent = !!e?.event?.type; const skipFocusEvent = e?.virtualColumnsScrolling && isScrollEvent; - this._updateFocus(true, skipFocusEvent, true); + this._updateFocus(true, skipFocusEvent); } } } @@ -1813,7 +1813,7 @@ export class KeyboardNavigationController extends KeyboardNavigationControllerCo } } - public _updateFocus(isRenderView?: boolean, skipFocusEvent = false, preventScroll = false) { + public _updateFocus(isRenderView?: boolean, skipFocusEvent = false) { this._updateFocusTimeout = setTimeout(() => { if (this._needFocusEditingCell()) { this._editingController._focusEditingCell(); @@ -1852,12 +1852,12 @@ export class KeyboardNavigationController extends KeyboardNavigationControllerCo ); return; } - !isFocusedElementDefined && this._focus($cell, false, skipFocusEvent, preventScroll); + !isFocusedElementDefined && this._focus($cell, false, skipFocusEvent, !!isRenderView); } else if ( !isFocusedElementDefined && (this._isNeedFocus || this._isHiddenFocus) ) { - this._focus($cell, this._isHiddenFocus, skipFocusEvent, preventScroll); + this._focus($cell, this._isHiddenFocus, skipFocusEvent, !!isRenderView); } if (isEditing && !column?.showEditorAlways) { this._focusInteractiveElement.bind(this)($cell); From 36c670d4f32ee9e334bf51d4b049c0069175cb1d Mon Sep 17 00:00:00 2001 From: Mark Allen Ramirez Date: Fri, 10 Apr 2026 16:02:08 +0800 Subject: [PATCH 09/10] update test --- .../focus.integration.tests.js | 164 +++++++++--------- 1 file changed, 82 insertions(+), 82 deletions(-) diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/focus.integration.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/focus.integration.tests.js index 147053607101..11327d770061 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/focus.integration.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/focus.integration.tests.js @@ -4318,6 +4318,88 @@ QUnit.module('View\'s focus', { assert.equal(this.dataGrid.option('focusedRowKey'), 2, 'row key is changed'); assert.ok($(this.dataGrid.getRowElement(1)).hasClass('dx-row-focused'), 'second row is focused'); }); + + // T1310557 + QUnit.testInActiveWindow('Browser should not scroll back to the grid when a focused cell is updated or rerendered', function(assert) { + // arrange + const dataGrid = createDataGrid({ + dataSource: { + store: new ArrayStore({ + key: 'id', + data: [{ id: 1, name: 'test1' }], + }), + pushAggregationTimeout: 0, + }, + }); + $('body').css('height', 2000); + window.scrollTo(0, 0); + this.clock.tick(10); + + const keyboardController = dataGrid.getController('keyboardNavigation'); + const $firstCell = $(dataGrid.getCellElement(0, 0)); + const scrollPosition = 300; + + // assert + assert.strictEqual(window.pageYOffset, 0, 'document scroll is at the top'); + + // act + $firstCell.trigger(CLICK_EVENT); + this.clock.tick(10); + + keyboardController.keyDownHandler({ + key: 'Tab', + keyName: 'tab', + originalEvent: $.Event('keydown', { target: $firstCell.get(0) }), + }); + this.clock.tick(10); + + // assert + assert.ok($(dataGrid.getCellElement(0, 1)).hasClass('dx-focused'), 'second cell is focused'); + + // act + window.scrollTo(0, scrollPosition); + + // assert + assert.strictEqual(window.pageYOffset, scrollPosition, 'document scroll is changed'); + + // act + dataGrid.getDataSource().store().push([{ type: 'update', key: 1, data: { name: 'updated' } }]); + this.clock.tick(10); + + // assert + assert.strictEqual($(dataGrid.getCellElement(0, 1)).text(), 'updated', 'second cell text is updated'); + assert.strictEqual(window.pageYOffset, scrollPosition, 'document scroll is preserved after push update'); + + // act + dataGrid.refresh(); + this.clock.tick(10); + + // assert + assert.strictEqual(window.pageYOffset, scrollPosition, 'document scroll is preserved after refresh'); + + // act + dataGrid.repaint(); + this.clock.tick(10); + + // assert + assert.strictEqual(window.pageYOffset, scrollPosition, 'document scroll is preserved after repaint'); + + // act + keyboardController.keyDownHandler({ + key: 'ArrowLeft', + keyName: 'leftArrow', + originalEvent: $.Event('keydown', { target: $(dataGrid.getCellElement(0, 1)).get(0) }), + }); + this.clock.tick(10); + + // assert + assert.ok($(dataGrid.getCellElement(0, 0)).hasClass('dx-focused'), 'first cell is focused'); + assert.strictEqual(window.pageYOffset, 0, 'document scroll is changed after keyboard navigation'); + + // cleanup + $('body').css('height', ''); + window.scrollTo(0, 0); + }); }); QUnit.module('API methods', baseModuleConfig, () => { @@ -4980,86 +5062,4 @@ QUnit.module('Column Resizing', baseModuleConfig, () => { // assert assert.equal(dataGrid.getScrollable().scrollTop(), 10, 'scroll top is not changed'); }); - - // T1310557 - QUnit.testInActiveWindow('Browser should not scroll back to the grid when a focused cell is updated or rerendered', function(assert) { - // arrange - const dataGrid = createDataGrid({ - dataSource: { - store: new ArrayStore({ - key: 'id', - data: [{ id: 1, name: 'test1' }], - }), - pushAggregationTimeout: 0, - }, - }); - $('body').css('height', 2000); - window.scrollTo(0, 0); - this.clock.tick(10); - - const keyboardController = dataGrid.getController('keyboardNavigation'); - const $firstCell = $(dataGrid.getCellElement(0, 0)); - const scrollPosition = 300; - - // assert - assert.strictEqual(window.pageYOffset, 0, 'document scroll is at the top'); - - // act - $firstCell.trigger(CLICK_EVENT); - this.clock.tick(10); - - keyboardController.keyDownHandler({ - key: 'Tab', - keyName: 'tab', - originalEvent: $.Event('keydown', { target: $firstCell.get(0) }), - }); - this.clock.tick(10); - - // assert - assert.ok($(dataGrid.getCellElement(0, 1)).hasClass('dx-focused'), 'second cell is focused'); - - // act - window.scrollTo(0, scrollPosition); - - // assert - assert.strictEqual(window.pageYOffset, scrollPosition, 'document scroll is changed'); - - // act - dataGrid.getDataSource().store().push([{ type: 'update', key: 1, data: { name: 'updated' } }]); - this.clock.tick(10); - - // assert - assert.strictEqual($(dataGrid.getCellElement(0, 1)).text(), 'updated', 'second cell text is updated'); - assert.strictEqual(window.pageYOffset, scrollPosition, 'document scroll is preserved after push update'); - - // act - dataGrid.refresh(); - this.clock.tick(10); - - // assert - assert.strictEqual(window.pageYOffset, scrollPosition, 'document scroll is preserved after refresh'); - - // act - dataGrid.repaint(); - this.clock.tick(10); - - // assert - assert.strictEqual(window.pageYOffset, scrollPosition, 'document scroll is preserved after repaint'); - - // act - keyboardController.keyDownHandler({ - key: 'ArrowLeft', - keyName: 'leftArrow', - originalEvent: $.Event('keydown', { target: $(dataGrid.getCellElement(0, 1)).get(0) }), - }); - this.clock.tick(10); - - // assert - assert.ok($(dataGrid.getCellElement(0, 0)).hasClass('dx-focused'), 'first cell is focused'); - assert.strictEqual(window.pageYOffset, 0, 'document scroll is changed after keyboard navigation'); - - // cleanup - $('body').css('height', ''); - window.scrollTo(0, 0); - }); }); From 096a9c9a7cc1ed2668a70fd084154bb7ab82ec79 Mon Sep 17 00:00:00 2001 From: Mark Allen Ramirez Date: Fri, 10 Apr 2026 16:19:55 +0800 Subject: [PATCH 10/10] update test --- .../focus.integration.tests.js | 104 +++++++++--------- 1 file changed, 53 insertions(+), 51 deletions(-) diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/focus.integration.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/focus.integration.tests.js index 11327d770061..3e0aa16a7a9a 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/focus.integration.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/focus.integration.tests.js @@ -4331,74 +4331,76 @@ QUnit.module('View\'s focus', { pushAggregationTimeout: 0, }, }); - $('body').css('height', 2000); - window.scrollTo(0, 0); this.clock.tick(10); - const keyboardController = dataGrid.getController('keyboardNavigation'); - const $firstCell = $(dataGrid.getCellElement(0, 0)); - const scrollPosition = 300; + try { + $('body').css('height', 2000); + window.scrollTo(0, 0); - // assert - assert.strictEqual(window.pageYOffset, 0, 'document scroll is at the top'); + const keyboardController = dataGrid.getController('keyboardNavigation'); + const $firstCell = $(dataGrid.getCellElement(0, 0)); + const scrollPosition = 300; - // act - $firstCell.trigger(CLICK_EVENT); - this.clock.tick(10); + // assert + assert.strictEqual(window.pageYOffset, 0, 'document scroll is at the top'); - keyboardController.keyDownHandler({ - key: 'Tab', - keyName: 'tab', - originalEvent: $.Event('keydown', { target: $firstCell.get(0) }), - }); - this.clock.tick(10); + // act + $firstCell.trigger(CLICK_EVENT); + this.clock.tick(10); - // assert - assert.ok($(dataGrid.getCellElement(0, 1)).hasClass('dx-focused'), 'second cell is focused'); + keyboardController.keyDownHandler({ + key: 'Tab', + keyName: 'tab', + originalEvent: $.Event('keydown', { target: $firstCell.get(0) }), + }); + this.clock.tick(10); - // act - window.scrollTo(0, scrollPosition); + // assert + assert.ok($(dataGrid.getCellElement(0, 1)).hasClass('dx-focused'), 'second cell is focused'); - // assert - assert.strictEqual(window.pageYOffset, scrollPosition, 'document scroll is changed'); + // act + window.scrollTo(0, scrollPosition); - // act - dataGrid.getDataSource().store().push([{ type: 'update', key: 1, data: { name: 'updated' } }]); - this.clock.tick(10); + // assert + assert.strictEqual(window.pageYOffset, scrollPosition, 'document scroll is changed'); - // assert - assert.strictEqual($(dataGrid.getCellElement(0, 1)).text(), 'updated', 'second cell text is updated'); - assert.strictEqual(window.pageYOffset, scrollPosition, 'document scroll is preserved after push update'); + // act + dataGrid.getDataSource().store().push([{ type: 'update', key: 1, data: { name: 'updated' } }]); + this.clock.tick(10); - // act - dataGrid.refresh(); - this.clock.tick(10); + // assert + assert.strictEqual($(dataGrid.getCellElement(0, 1)).text(), 'updated', 'second cell text is updated'); + assert.strictEqual(window.pageYOffset, scrollPosition, 'document scroll is preserved after push update'); - // assert - assert.strictEqual(window.pageYOffset, scrollPosition, 'document scroll is preserved after refresh'); + // act + dataGrid.refresh(); + this.clock.tick(10); - // act - dataGrid.repaint(); - this.clock.tick(10); + // assert + assert.strictEqual(window.pageYOffset, scrollPosition, 'document scroll is preserved after refresh'); - // assert - assert.strictEqual(window.pageYOffset, scrollPosition, 'document scroll is preserved after repaint'); + // act + dataGrid.repaint(); + this.clock.tick(10); - // act - keyboardController.keyDownHandler({ - key: 'ArrowLeft', - keyName: 'leftArrow', - originalEvent: $.Event('keydown', { target: $(dataGrid.getCellElement(0, 1)).get(0) }), - }); - this.clock.tick(10); + // assert + assert.strictEqual(window.pageYOffset, scrollPosition, 'document scroll is preserved after repaint'); - // assert - assert.ok($(dataGrid.getCellElement(0, 0)).hasClass('dx-focused'), 'first cell is focused'); - assert.strictEqual(window.pageYOffset, 0, 'document scroll is changed after keyboard navigation'); + // act + keyboardController.keyDownHandler({ + key: 'ArrowLeft', + keyName: 'leftArrow', + originalEvent: $.Event('keydown', { target: $(dataGrid.getCellElement(0, 1)).get(0) }), + }); + this.clock.tick(10); - // cleanup - $('body').css('height', ''); - window.scrollTo(0, 0); + // assert + assert.ok($(dataGrid.getCellElement(0, 0)).hasClass('dx-focused'), 'first cell is focused'); + assert.strictEqual(window.pageYOffset, 0, 'document scroll is changed after keyboard navigation'); + } finally { + $('body').css('height', ''); + window.scrollTo(0, 0); + } }); });