Skip to content

Commit 3fdd8dd

Browse files
authored
DataGrid: Fix Tab key navigation to the next editable cell in virtual column display mode if the next column is not in the viewing area (T1287665) (#31878)
Co-authored-by: Alyar <>
1 parent 4da7e62 commit 3fdd8dd

File tree

35 files changed

+760
-355
lines changed

35 files changed

+760
-355
lines changed
Lines changed: 323 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,323 @@
1+
import DataGrid from 'devextreme-testcafe-models/dataGrid';
2+
import url from '../../../../helpers/getPageUrl';
3+
import { createWidget } from '../../../../helpers/createWidget';
4+
import { triggerEvent } from '../../helpers/eventUtils';
5+
6+
fixture.disablePageReloads`Virtual Columns.Functional`
7+
.page(url(__dirname, '../../../container.html'));
8+
9+
const generateData = (rowCount: number, columnCount: number): Record<string, unknown>[] => {
10+
const items: Record<string, unknown>[] = [];
11+
12+
for (let i = 0; i < rowCount; i += 1) {
13+
const item = {};
14+
15+
for (let j = 0; j < columnCount; j += 1) {
16+
item[`field${j + 1}`] = `${i + 1}-${j + 1}`;
17+
}
18+
19+
items.push(item);
20+
}
21+
22+
return items;
23+
};
24+
25+
test('DataGrid should scroll to the first cell of the next row and focus it when navigating with Tab key', async (t) => {
26+
// arrange
27+
const dataGrid = new DataGrid('#container');
28+
29+
// assert
30+
await t
31+
.expect(dataGrid.isReady())
32+
.ok();
33+
34+
// act
35+
await dataGrid.scrollTo(t, { x: 10000 });
36+
37+
// assert
38+
await t
39+
.expect(dataGrid.getScrollLeft())
40+
.eql(1500)
41+
.expect(dataGrid.getDataCell(0, 19).element.exists)
42+
.ok();
43+
44+
// act
45+
await t.click(dataGrid.getDataCell(0, 19).element);
46+
47+
// assert
48+
await t
49+
.expect(dataGrid.getDataCell(0, 19).element.focused)
50+
.ok();
51+
52+
// act
53+
await t.pressKey('tab');
54+
55+
// assert
56+
await t
57+
.expect(dataGrid.getScrollLeft())
58+
.eql(0)
59+
.expect(dataGrid.getDataCell(1, 0).element.focused)
60+
.ok();
61+
}).before(async () => createWidget('dxDataGrid', {
62+
width: 500,
63+
dataSource: generateData(10, 20),
64+
columnWidth: 100,
65+
scrolling: {
66+
columnRenderingMode: 'virtual',
67+
},
68+
}));
69+
70+
test('DataGrid should scroll to the last cell of the previous row and focus it when navigating with Shift+Tab keys', async (t) => {
71+
// arrange
72+
const dataGrid = new DataGrid('#container');
73+
74+
// assert
75+
await t
76+
.expect(dataGrid.isReady())
77+
.ok();
78+
79+
// act
80+
await t.click(dataGrid.getDataCell(1, 0).element);
81+
82+
// assert
83+
await t
84+
.expect(dataGrid.getDataCell(1, 0).element.focused)
85+
.ok();
86+
87+
// act
88+
await t.pressKey('shift+tab');
89+
90+
// assert
91+
await t
92+
.expect(dataGrid.getScrollLeft())
93+
.eql(1500)
94+
.expect(dataGrid.getDataCell(0, 19).element.focused)
95+
.ok();
96+
}).before(async () => createWidget('dxDataGrid', {
97+
width: 500,
98+
dataSource: generateData(10, 20),
99+
columnWidth: 100,
100+
scrolling: {
101+
columnRenderingMode: 'virtual',
102+
},
103+
}));
104+
105+
[true, false].forEach((rtlEnabled) => {
106+
[true, false].forEach((useNative) => {
107+
test(`DataGrid should scroll to the next virtual cell and focus it when navigating with Tab key (rtlEnabled: ${rtlEnabled}, useNative: ${useNative})`, async (t) => {
108+
// arrange
109+
const dataGrid = new DataGrid('#container');
110+
const headerRow = dataGrid.getHeaders().getHeaderRow(0);
111+
const expectedScrollLeft = rtlEnabled ? 1400 : 100;
112+
113+
// assert
114+
await t
115+
.expect(dataGrid.isReady())
116+
.ok()
117+
.expect(headerRow.getDataHeaderCells().count)
118+
.eql(5);
119+
120+
// act
121+
/*
122+
We can't use the TestCafe API (for example, click)
123+
because it doesn't work correctly in RTL mode.
124+
Specifically, the negative scroll position is reset
125+
when calling the click method.
126+
*/
127+
await triggerEvent(dataGrid.getDataCell(0, 4).element, 'dxpointerdown');
128+
129+
// assert
130+
await t
131+
.expect(dataGrid.getDataCell(0, 4).element.focused)
132+
.ok();
133+
134+
// act
135+
await t.pressKey('tab');
136+
137+
// assert
138+
await t
139+
.expect(dataGrid.getScrollLeft())
140+
.eql(expectedScrollLeft)
141+
.expect(dataGrid.getDataCell(0, 5).element.focused)
142+
.ok()
143+
.expect(headerRow.getDataHeaderCells().count)
144+
.eql(10);
145+
}).before(async () => createWidget('dxDataGrid', {
146+
width: 500,
147+
rtlEnabled,
148+
dataSource: generateData(10, 20),
149+
columnWidth: 100,
150+
scrolling: {
151+
columnRenderingMode: 'virtual',
152+
useNative,
153+
},
154+
}));
155+
156+
test(`DataGrid should scroll to the previous virtual cell and focus it when navigating with Shift+Tab key (rtlEnabled: ${rtlEnabled}, useNative: ${useNative})`, async (t) => {
157+
// arrange
158+
const dataGrid = new DataGrid('#container');
159+
const headerRow = dataGrid.getHeaders().getHeaderRow(0);
160+
161+
// assert
162+
await t
163+
.expect(dataGrid.isReady())
164+
.ok();
165+
166+
// act
167+
await dataGrid.scrollTo(t, { x: rtlEnabled ? 0 : 10000 });
168+
169+
// assert
170+
await t
171+
.expect(await dataGrid.getScrollLeft())
172+
.eql(rtlEnabled ? 0 : 1500)
173+
.expect(dataGrid.getDataCell(0, 19).element.exists)
174+
.ok()
175+
.expect(headerRow.getDataHeaderCells().count)
176+
.eql(5);
177+
178+
// act
179+
/*
180+
We can't use the TestCafe API (for example, click)
181+
because it doesn't work correctly in RTL mode.
182+
Specifically, the negative scroll position is reset
183+
when calling the click method.
184+
*/
185+
await triggerEvent(dataGrid.getDataCell(0, 15).element, 'dxpointerdown');
186+
187+
// assert
188+
await t
189+
.expect(dataGrid.getDataCell(0, 15).element.focused)
190+
.ok();
191+
192+
// act
193+
await t.pressKey('shift+tab');
194+
195+
// assert
196+
await t
197+
.expect(dataGrid.getScrollLeft())
198+
.eql(rtlEnabled ? 100 : 1400)
199+
.expect(dataGrid.getDataCell(0, 14).element.focused)
200+
.ok()
201+
.expect(headerRow.getDataHeaderCells().count)
202+
.eql(10);
203+
}).before(async () => createWidget('dxDataGrid', {
204+
width: 500,
205+
rtlEnabled,
206+
dataSource: generateData(10, 20),
207+
columnWidth: 100,
208+
scrolling: {
209+
columnRenderingMode: 'virtual',
210+
useNative,
211+
},
212+
}));
213+
214+
test(`DataGrid should scroll to the next virtual cell and focus it when navigating with Right key (rtlEnabled: ${rtlEnabled}, useNative: ${useNative})`, async (t) => {
215+
// arrange
216+
const dataGrid = new DataGrid('#container');
217+
const headerRow = dataGrid.getHeaders().getHeaderRow(0);
218+
const expectedScrollLeft = rtlEnabled ? 1400 : 100;
219+
const navigationDirection = rtlEnabled ? 'left' : 'right';
220+
221+
// assert
222+
await t
223+
.expect(dataGrid.isReady())
224+
.ok()
225+
.expect(headerRow.getDataHeaderCells().count)
226+
.eql(5);
227+
228+
// act
229+
/*
230+
We can't use the TestCafe API (for example, click)
231+
because it doesn't work correctly in RTL mode.
232+
Specifically, the negative scroll position is reset
233+
when calling the click method.
234+
*/
235+
await triggerEvent(dataGrid.getDataCell(0, 4).element, 'dxpointerdown');
236+
237+
// assert
238+
await t
239+
.expect(dataGrid.getDataCell(0, 4).element.focused)
240+
.ok();
241+
242+
// act
243+
await t.pressKey(navigationDirection);
244+
245+
// assert
246+
await t
247+
.expect(dataGrid.getScrollLeft())
248+
.eql(expectedScrollLeft)
249+
.expect(dataGrid.getDataCell(0, 5).element.focused)
250+
.ok()
251+
.expect(headerRow.getDataHeaderCells().count)
252+
.eql(10);
253+
}).before(async () => createWidget('dxDataGrid', {
254+
width: 500,
255+
rtlEnabled,
256+
dataSource: generateData(10, 20),
257+
columnWidth: 100,
258+
scrolling: {
259+
columnRenderingMode: 'virtual',
260+
useNative,
261+
},
262+
}));
263+
264+
test(`DataGrid should scroll to the previous virtual cell and focus it when navigating with Left key (rtlEnabled: ${rtlEnabled}, useNative: ${useNative})`, async (t) => {
265+
// arrange
266+
const dataGrid = new DataGrid('#container');
267+
const headerRow = dataGrid.getHeaders().getHeaderRow(0);
268+
const navigationDirection = rtlEnabled ? 'right' : 'left';
269+
270+
// assert
271+
await t
272+
.expect(dataGrid.isReady())
273+
.ok();
274+
275+
// act
276+
await dataGrid.scrollTo(t, { x: rtlEnabled ? 0 : 10000 });
277+
278+
// assert
279+
await t
280+
.expect(await dataGrid.getScrollLeft())
281+
.eql(rtlEnabled ? 0 : 1500)
282+
.expect(dataGrid.getDataCell(0, 19).element.exists)
283+
.ok()
284+
.expect(headerRow.getDataHeaderCells().count)
285+
.eql(5);
286+
287+
// act
288+
/*
289+
We can't use the TestCafe API (for example, click)
290+
because it doesn't work correctly in RTL mode.
291+
Specifically, the negative scroll position is reset
292+
when calling the click method.
293+
*/
294+
await triggerEvent(dataGrid.getDataCell(0, 15).element, 'dxpointerdown');
295+
296+
// assert
297+
await t
298+
.expect(dataGrid.getDataCell(0, 15).element.focused)
299+
.ok();
300+
301+
// act
302+
await t.pressKey(navigationDirection);
303+
304+
// assert
305+
await t
306+
.expect(dataGrid.getScrollLeft())
307+
.eql(rtlEnabled ? 100 : 1400)
308+
.expect(dataGrid.getDataCell(0, 14).element.focused)
309+
.ok()
310+
.expect(headerRow.getDataHeaderCells().count)
311+
.eql(10);
312+
}).before(async () => createWidget('dxDataGrid', {
313+
width: 500,
314+
rtlEnabled,
315+
dataSource: generateData(10, 20),
316+
columnWidth: 100,
317+
scrolling: {
318+
columnRenderingMode: 'virtual',
319+
useNative,
320+
},
321+
}));
322+
});
323+
});

e2e/testcafe-devextreme/tests/dataGrid/common/etalons/T1090735-grid-virtual-columns (fluent.blue.light).png renamed to e2e/testcafe-devextreme/tests/dataGrid/common/virtualColumns/etalons/T1090735-grid-virtual-columns (fluent.blue.light).png

File renamed without changes.

e2e/testcafe-devextreme/tests/dataGrid/common/etalons/T1176160-master-detail-with-virtual-columns-and-useNative=false-1 (fluent.blue.light).png renamed to e2e/testcafe-devextreme/tests/dataGrid/common/virtualColumns/etalons/T1176160-master-detail-with-virtual-columns-and-useNative=false-1 (fluent.blue.light).png

File renamed without changes.

e2e/testcafe-devextreme/tests/dataGrid/common/etalons/T1176160-master-detail-with-virtual-columns-and-useNative=false-2 (fluent.blue.light).png renamed to e2e/testcafe-devextreme/tests/dataGrid/common/virtualColumns/etalons/T1176160-master-detail-with-virtual-columns-and-useNative=false-2 (fluent.blue.light).png

File renamed without changes.

e2e/testcafe-devextreme/tests/dataGrid/common/etalons/T1176160-master-detail-with-virtual-columns-and-useNative=true-1 (fluent.blue.light).png renamed to e2e/testcafe-devextreme/tests/dataGrid/common/virtualColumns/etalons/T1176160-master-detail-with-virtual-columns-and-useNative=true-1 (fluent.blue.light).png

File renamed without changes.

e2e/testcafe-devextreme/tests/dataGrid/common/etalons/T1176160-master-detail-with-virtual-columns-and-useNative=true-2 (fluent.blue.light).png renamed to e2e/testcafe-devextreme/tests/dataGrid/common/virtualColumns/etalons/T1176160-master-detail-with-virtual-columns-and-useNative=true-2 (fluent.blue.light).png

File renamed without changes.

e2e/testcafe-devextreme/tests/dataGrid/common/etalons/T1176161-master-detail-with-virtual-columns-1 (fluent.blue.light).png renamed to e2e/testcafe-devextreme/tests/dataGrid/common/virtualColumns/etalons/T1176161-master-detail-with-virtual-columns-1 (fluent.blue.light).png

File renamed without changes.

e2e/testcafe-devextreme/tests/dataGrid/common/etalons/T1176161-master-detail-with-virtual-columns-2 (fluent.blue.light).png renamed to e2e/testcafe-devextreme/tests/dataGrid/common/virtualColumns/etalons/T1176161-master-detail-with-virtual-columns-2 (fluent.blue.light).png

File renamed without changes.

e2e/testcafe-devextreme/tests/dataGrid/common/etalons/T1221369_fixed-summary-with-virtual-cols_0 (fluent.blue.light).png renamed to e2e/testcafe-devextreme/tests/dataGrid/common/virtualColumns/etalons/T1221369_fixed-summary-with-virtual-cols_0 (fluent.blue.light).png

File renamed without changes.

e2e/testcafe-devextreme/tests/dataGrid/common/etalons/T1221369_fixed-summary-with-virtual-cols_1 (fluent.blue.light).png renamed to e2e/testcafe-devextreme/tests/dataGrid/common/virtualColumns/etalons/T1221369_fixed-summary-with-virtual-cols_1 (fluent.blue.light).png

File renamed without changes.

0 commit comments

Comments
 (0)