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 bd956a13034a..36e67bb172d1 100644 --- a/e2e/testcafe-devextreme/tests/dataGrid/common/keyboardNavigation/keyboardNavigation.functional.ts +++ b/e2e/testcafe-devextreme/tests/dataGrid/common/keyboardNavigation/keyboardNavigation.functional.ts @@ -1,5 +1,6 @@ import { Selector, ClientFunction } from 'testcafe'; import { createScreenshotsComparer } from 'devextreme-screenshot-comparer'; +import Button from 'devextreme-testcafe-models/button'; import DataGrid from 'devextreme-testcafe-models/dataGrid'; import CommandCell from 'devextreme-testcafe-models/dataGrid/commandCell'; import { ClassNames } from 'devextreme-testcafe-models/dataGrid/classNames'; @@ -6576,3 +6577,66 @@ test('The last cell should be focused after changing the page size (T1063530)', })(); }); }); + +test('Focus should be set to the grid to allow keyboard navigation when the focus method is called (T1308919)', async (t) => { + // arrange + const button = new Button('#otherContainer'); + const dataGrid = new DataGrid('#container'); + const firstDataCell = dataGrid.getDataCell(0, 0); + const firstRow = dataGrid.getDataRow(0); + const secondRow = dataGrid.getDataRow(1); + + // assert + await t.expect(dataGrid.isReady()).ok(); + + // act + await dataGrid.apiFocus(firstDataCell.element); + + // assert + await t + .expect(firstDataCell.isFocused).ok() + .expect(firstRow.isFocusedRow).ok(); + + // act + await button.focus(); + + // assert + await t + .expect(button.isFocused) + .ok() + .expect(firstDataCell.isFocused) + .notOk('focus should be on the button') + .expect(firstRow.isFocusedRow) + .ok('row should still have the focused-row style'); + + // act + await t.pressKey('down'); + + // assert + await t + .expect(secondRow.isFocusedRow) + .notOk('grid kbn should not work'); + + // act + await t + .pressKey('enter') // trigger button click + .pressKey('down'); + + // assert + await t + .expect(secondRow.isFocusedRow) + .ok('grid is focused, so kbn should work'); +}).before(async () => { + await createWidget('dxDataGrid', { + dataSource: [{ id: 1, name: 'test1' }, { id: 2, name: 'test2' }], + keyExpr: 'id', + focusedRowEnabled: true, + }); + await createWidget('dxButton', { + text: 'Focus Grid', + onClick() { + const grid = ($ as any)('#container').dxDataGrid('instance'); + grid.focus(); + }, + }, '#otherContainer'); +}); 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 ac4bfc7fb4e0..d860e27ac746 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 @@ -1674,6 +1674,12 @@ export class KeyboardNavigationController extends KeyboardNavigationControllerCo $focusElement .removeClass(CELL_FOCUS_DISABLED_CLASS) .removeClass(FOCUSED_CLASS); + + const isTargetInGrid = gridCoreUtils.isElementInCurrentGrid(this, $(e.relatedTarget)); + if (!isTargetInGrid) { + this._resetFocusedCell(true); + this._resetFocusedView(); + } } }); if (!skipFocusEvent) { diff --git a/packages/testcafe-models/dataGrid/index.ts b/packages/testcafe-models/dataGrid/index.ts index 081a5b388722..39a5ab53d919 100644 --- a/packages/testcafe-models/dataGrid/index.ts +++ b/packages/testcafe-models/dataGrid/index.ts @@ -742,16 +742,12 @@ export default class DataGrid extends GridCore { )(); } - apiFocus(): Promise { + apiFocus(cellElement?: Selector): Promise { const { getInstance } = this; return ClientFunction( - () => (getInstance() as any).focus(), - { - dependencies: { - getInstance, - }, - }, + () => (getInstance() as any).focus(cellElement?.()), + { dependencies: { getInstance, cellElement } }, )(); }