From 2e64fa851f26baf3b77e452c4dea4b0a45c54dfe Mon Sep 17 00:00:00 2001 From: Alyar <> Date: Thu, 5 Mar 2026 13:57:25 +0400 Subject: [PATCH 1/3] Revert the fix for T1282595 --- .../scss/widgets/fluent/gridBase/layout/cell.scss | 6 ------ .../scss/widgets/material/gridBase/layout/cell.scss | 6 ------ 2 files changed, 12 deletions(-) diff --git a/packages/devextreme-scss/scss/widgets/fluent/gridBase/layout/cell.scss b/packages/devextreme-scss/scss/widgets/fluent/gridBase/layout/cell.scss index 6a3c05a0fb08..93c8dda8e6b5 100644 --- a/packages/devextreme-scss/scss/widgets/fluent/gridBase/layout/cell.scss +++ b/packages/devextreme-scss/scss/widgets/fluent/gridBase/layout/cell.scss @@ -128,12 +128,6 @@ border-bottom-color: $datagrid-row-focused-bg; } - // (0,4,1) - .dx-#{$widget-name}-headers.dx-header-multi-row .dx-row.dx-header-row > td { - border-right: 1px solid; - border-right-color: $fluent-grid-base-border-color; - } - // (0,4,1) .dx-#{$widget-name}-rowsview .dx-row.dx-edit-row:first-child > td { border-top-width: 0; diff --git a/packages/devextreme-scss/scss/widgets/material/gridBase/layout/cell.scss b/packages/devextreme-scss/scss/widgets/material/gridBase/layout/cell.scss index aa44044d4cf5..5e7fd72f6ef8 100644 --- a/packages/devextreme-scss/scss/widgets/material/gridBase/layout/cell.scss +++ b/packages/devextreme-scss/scss/widgets/material/gridBase/layout/cell.scss @@ -164,12 +164,6 @@ border-bottom-color: $datagrid-row-selected-border-color; } - // (0,5,1) - .dx-#{$widget-name}-headers.dx-header-multi-row .dx-row.dx-header-row > td { - border-right: 1px solid; - border-right-color: $material-grid-base-border-color; - } - // (0,7,1) .dx-#{$widget-name}-headers.dx-header-multi-row:not(.dx-#{$widget-name}-sticky-columns) .dx-#{$widget-name}-content .dx-#{$widget-name}-table .dx-row.dx-header-row > td { border-left: 1px solid; From 2ab741eb8e7a392f5a985782b29adaec3ac70a18 Mon Sep 17 00:00:00 2001 From: Alyar <> Date: Mon, 2 Feb 2026 13:44:54 +0400 Subject: [PATCH 2/3] separate TestCafe tests into functional and visual tests --- .../dataGrid/common/bandColumns/functional.ts | 77 +++++++++++++++++++ .../{runtimeChange.ts => visual.ts} | 71 +---------------- 2 files changed, 78 insertions(+), 70 deletions(-) create mode 100644 e2e/testcafe-devextreme/tests/dataGrid/common/bandColumns/functional.ts rename e2e/testcafe-devextreme/tests/dataGrid/common/bandColumns/{runtimeChange.ts => visual.ts} (57%) diff --git a/e2e/testcafe-devextreme/tests/dataGrid/common/bandColumns/functional.ts b/e2e/testcafe-devextreme/tests/dataGrid/common/bandColumns/functional.ts new file mode 100644 index 000000000000..70eafa829c61 --- /dev/null +++ b/e2e/testcafe-devextreme/tests/dataGrid/common/bandColumns/functional.ts @@ -0,0 +1,77 @@ +import Button from 'devextreme-testcafe-models/button'; +import DataGrid from 'devextreme-testcafe-models/dataGrid'; +import url from '../../../../helpers/getPageUrl'; +import { createWidget } from '../../../../helpers/createWidget'; + +fixture.disablePageReloads`Band columns.Functional` + .page(url(__dirname, '../../../container.html')); + +const GRID_CONTAINER = '#container'; + +test('Changing dataField for a banded column with the columnOption method does not work as expected (T1210340)', async (t) => { + const dataGrid = new DataGrid(GRID_CONTAINER); + const changeFieldButton = new Button('#otherContainer'); + + await t + .expect(dataGrid.getDataCell(0, 4).element.innerText) + .eql('2353025') + .click(changeFieldButton.element) + .expect(dataGrid.getDataCell(0, 4).element.innerText) + .eql('0.672'); +}).before(async () => { + await createWidget('dxDataGrid', { + dataSource: [{ + id: 1, + Country: 'Brazil', + Area: 8515767, + Population_Urban: 0.85, + Population_Rural: 0.15, + Population_Total: 205809000, + GDP_Agriculture: 0.054, + GDP_Industry: 0.274, + GDP_Services: 0.672, + GDP_Total: 2353025, + }], + columns: [ + 'Country', + 'Area', { + caption: 'Population', + columns: [ + 'Population_Total', + 'Population_Urban', + ], + }, { + caption: 'Nominal GDP', + columns: [{ + caption: 'Total, mln $', + dataField: 'GDP_Total', + name: 'GDP_Total', + }, { + caption: 'By Sector', + columns: [{ + caption: 'Agriculture', + dataField: 'GDP_Agriculture', + }, { + caption: 'Industry', + dataField: 'GDP_Industry', + format: { + type: 'percent', + }, + }, { + caption: 'Services', + dataField: 'GDP_Services', + }], + }], + }], + keyExpr: 'id', + showBorders: true, + }); + + await createWidget('dxButton', { + text: 'Change fields', + onClick() { + const grid = ($('#container') as any).dxDataGrid('instance'); + grid.columnOption('GDP_Total', 'dataField', 'GDP_Services'); + }, + }, '#otherContainer'); +}); diff --git a/e2e/testcafe-devextreme/tests/dataGrid/common/bandColumns/runtimeChange.ts b/e2e/testcafe-devextreme/tests/dataGrid/common/bandColumns/visual.ts similarity index 57% rename from e2e/testcafe-devextreme/tests/dataGrid/common/bandColumns/runtimeChange.ts rename to e2e/testcafe-devextreme/tests/dataGrid/common/bandColumns/visual.ts index a3c1a686041c..bcdbac329620 100644 --- a/e2e/testcafe-devextreme/tests/dataGrid/common/bandColumns/runtimeChange.ts +++ b/e2e/testcafe-devextreme/tests/dataGrid/common/bandColumns/visual.ts @@ -1,12 +1,11 @@ import { ClientFunction } from 'testcafe'; import { createScreenshotsComparer } from 'devextreme-screenshot-comparer'; -import Button from 'devextreme-testcafe-models/button'; import DataGrid from 'devextreme-testcafe-models/dataGrid'; import url from '../../../../helpers/getPageUrl'; import { createWidget } from '../../../../helpers/createWidget'; import { testScreenshot } from '../../../../helpers/themeUtils'; -fixture.disablePageReloads`Band columns: runtime change` +fixture.disablePageReloads`Band columns.Visual` .page(url(__dirname, '../../../container.html')); const GRID_CONTAINER = '#container'; @@ -114,71 +113,3 @@ test('Should change usual columns to band columns without error in React (T12136 showBorders: true, }); }); - -test('Changing dataField for a banded column with the columnOption method does not work as expected (T1210340)', async (t) => { - const dataGrid = new DataGrid(GRID_CONTAINER); - const changeFieldButton = new Button('#otherContainer'); - - await t - .expect(dataGrid.getDataCell(0, 4).element.innerText) - .eql('2353025') - .click(changeFieldButton.element) - .expect(dataGrid.getDataCell(0, 4).element.innerText) - .eql('0.672'); -}).before(async () => { - await createWidget('dxDataGrid', { - dataSource: [{ - id: 1, - Country: 'Brazil', - Area: 8515767, - Population_Urban: 0.85, - Population_Rural: 0.15, - Population_Total: 205809000, - GDP_Agriculture: 0.054, - GDP_Industry: 0.274, - GDP_Services: 0.672, - GDP_Total: 2353025, - }], - columns: [ - 'Country', - 'Area', { - caption: 'Population', - columns: [ - 'Population_Total', - 'Population_Urban', - ], - }, { - caption: 'Nominal GDP', - columns: [{ - caption: 'Total, mln $', - dataField: 'GDP_Total', - name: 'GDP_Total', - }, { - caption: 'By Sector', - columns: [{ - caption: 'Agriculture', - dataField: 'GDP_Agriculture', - }, { - caption: 'Industry', - dataField: 'GDP_Industry', - format: { - type: 'percent', - }, - }, { - caption: 'Services', - dataField: 'GDP_Services', - }], - }], - }], - keyExpr: 'id', - showBorders: true, - }); - - await createWidget('dxButton', { - text: 'Change fields', - onClick() { - const grid = ($('#container') as any).dxDataGrid('instance'); - grid.columnOption('GDP_Total', 'dataField', 'GDP_Services'); - }, - }, '#otherContainer'); -}); From 8d8240f7bcc9d4da15db7cd5a0f17ecd636187dc Mon Sep 17 00:00:00 2001 From: Alyar <> Date: Thu, 5 Mar 2026 17:47:04 +0400 Subject: [PATCH 3/3] DataGrid: Fix the banded Columns' vertical borders (T1318812) --- .../dataGrid/common/bandColumns/matrix.ts | 101 ++++++++++++++++++ .../widgets/fluent/gridBase/layout/cell.scss | 30 +++--- .../widgets/generic/gridBase/layout/cell.scss | 13 +++ .../material/gridBase/layout/cell.scss | 23 ++-- 4 files changed, 138 insertions(+), 29 deletions(-) create mode 100644 e2e/testcafe-devextreme/tests/dataGrid/common/bandColumns/matrix.ts diff --git a/e2e/testcafe-devextreme/tests/dataGrid/common/bandColumns/matrix.ts b/e2e/testcafe-devextreme/tests/dataGrid/common/bandColumns/matrix.ts new file mode 100644 index 000000000000..20fac32f10e6 --- /dev/null +++ b/e2e/testcafe-devextreme/tests/dataGrid/common/bandColumns/matrix.ts @@ -0,0 +1,101 @@ +import { createScreenshotsComparer } from 'devextreme-screenshot-comparer'; +import DataGrid from 'devextreme-testcafe-models/dataGrid'; +import url from '../../../../helpers/getPageUrl'; +import { createWidget } from '../../../../helpers/createWidget'; +import { testScreenshot } from '../../../../helpers/themeUtils'; + +fixture.disablePageReloads`Band columns.Matrix` + .page(url(__dirname, '../../../container.html')); + +const GRID_CONTAINER = '#container'; + +const configs = [{ + showColumnLines: true, + rtlEnabled: false, +}, { + showColumnLines: true, + rtlEnabled: true, +}, { + showColumnLines: false, + rtlEnabled: false, +}, { + showColumnLines: false, + rtlEnabled: true, +}]; + +configs.forEach(( + { showColumnLines, rtlEnabled }: { showColumnLines: boolean; rtlEnabled: boolean; }, +): void => { + test('test', async (t) => { + const { takeScreenshot, compareResults } = createScreenshotsComparer(t); + const dataGrid = new DataGrid(GRID_CONTAINER); + + await t.expect(dataGrid.isReady()).ok(); + + await testScreenshot( + t, + takeScreenshot, + `T1318812__datagrid__band-columns__vertical-borders(showColumnLines=${showColumnLines},rtl=${rtlEnabled}).png`, + { element: dataGrid.element }, + ); + + await t.expect(compareResults.isValid()) + .ok(compareResults.errorMessages()); + }).before(async () => { + await createWidget('dxDataGrid', { + dataSource: [ + { + Col1: 'Data A', Col2: 'Desc A', Col3: 'Group 1', Col4: 'X', Col5: 100, Col6: 50, + }, + { + Col1: 'Data B', Col2: 'Desc B', Col3: 'Group 1', Col4: 'Y', Col5: 200, Col6: 20, + }, + { + Col1: 'Data C', Col2: 'Desc C', Col3: 'Group 2', Col4: 'Z', Col5: 300, Col6: 10, + }, + ], + columns: [ + { + caption: 'Band Column 1', + columns: [ + { + caption: 'Nested BandColumn 1', + columns: [ + { dataField: 'Col1', width: 150 }, + { dataField: 'Col2', width: 300 }, + { dataField: 'Col3', width: 300, groupIndex: 0 }, + ], + }, + ], + }, + { + caption: 'Band Column 2', + fixed: true, + columns: [ + { + caption: 'Nested Band Column 2', + columns: [ + { dataField: 'Col4', width: 120 }, + ], + }, + ], + }, + { + caption: 'Band Column 3', + columns: [ + { + caption: 'Nested Band Column 3', + columns: [ + { dataField: 'Col5', width: 150 }, + { dataField: 'Col6', width: 150 }, + ], + }, + ], + }, + ], + showColumnLines, + rtlEnabled, + columnWidth: 100, + }); + }); +}); diff --git a/packages/devextreme-scss/scss/widgets/fluent/gridBase/layout/cell.scss b/packages/devextreme-scss/scss/widgets/fluent/gridBase/layout/cell.scss index 93c8dda8e6b5..8ce6164282d0 100644 --- a/packages/devextreme-scss/scss/widgets/fluent/gridBase/layout/cell.scss +++ b/packages/devextreme-scss/scss/widgets/fluent/gridBase/layout/cell.scss @@ -135,6 +135,12 @@ border-bottom-color: $datagrid-border-color; } + // (0,4,1) + .dx-#{$widget-name}-headers.dx-header-multi-row .dx-header-row:not(.dx-column-lines) > td { + border-left: 1px solid; + border-left-color: $datagrid-border-color; + } + // (0,4,1) - (0,5,1) .dx-#{$widget-name}-rowsview.dx-#{$widget-name}-sticky-columns .dx-row-removed.dx-row-lines > td, .dx-#{$widget-name}-rowsview.dx-#{$widget-name}-sticky-columns .dx-row.dx-row-lines.dx-edit-row > td { @@ -173,22 +179,6 @@ border-bottom-color: $datagrid-row-selected-border-color; } - // (0,7,1) - .dx-#{$widget-name}-headers.dx-header-multi-row:not(.dx-#{$widget-name}-sticky-columns) .dx-#{$widget-name}-content .dx-#{$widget-name}-table .dx-row.dx-header-row > td { - border-left: 1px solid; - border-left-color: $fluent-grid-base-border-color; - } - - // (0,8,1) - .dx-#{$widget-name}-headers.dx-header-multi-row:not(.dx-#{$widget-name}-sticky-columns) .dx-#{$widget-name}-content .dx-#{$widget-name}-table .dx-row.dx-header-row > td:first-child { - border-left: none; - } - - // (0,8,1) - .dx-#{$widget-name}-headers.dx-header-multi-row:not(.dx-#{$widget-name}-sticky-columns) .dx-#{$widget-name}-content .dx-#{$widget-name}-table .dx-row.dx-header-row > td:last-child { - border-right: none; - } - // (0,10,1) .dx-rtl .dx-data-row.dx-state-hover:not(.dx-selection):not(.dx-row-inserted):not(.dx-row-removed):not(.dx-edit-row):not(.dx-row-focused) > td:not(.dx-focused).dx-#{$widget-name}-group-space { border-left-color: $datagrid-hover-bg; @@ -205,6 +195,14 @@ border-right-color: $datagrid-row-selected-border-color; } + // (0,5,1) + .dx-rtl .dx-#{$widget-name}-headers.dx-header-multi-row .dx-header-row:not(.dx-column-lines) > td { + border-left: none; + border-right: 1px solid; + border-right-color: $datagrid-border-color; + } + + // (0,5,1) - (0,6,2) .dx-rtl .dx-#{$widget-name}-rowsview .dx-selection.dx-row > td.dx-pointer-events-none, .dx-rtl .dx-#{$widget-name}-rowsview .dx-selection.dx-row > tr > td.dx-pointer-events-none, diff --git a/packages/devextreme-scss/scss/widgets/generic/gridBase/layout/cell.scss b/packages/devextreme-scss/scss/widgets/generic/gridBase/layout/cell.scss index 3a7eb9169271..7a36d92a11a9 100644 --- a/packages/devextreme-scss/scss/widgets/generic/gridBase/layout/cell.scss +++ b/packages/devextreme-scss/scss/widgets/generic/gridBase/layout/cell.scss @@ -153,6 +153,12 @@ border-right-color: $datagrid-selection-bg; } + // (0,4,1) + .dx-#{$widget-name}-headers.dx-header-multi-row .dx-header-row:not(.dx-column-lines) > td { + border-left: 1px solid; + border-left-color: $datagrid-border-color; + } + // (0,4,1) - (0,4,2) .dx-#{$widget-name}-rowsview .dx-selection.dx-row:not(.dx-row-focused) > td.dx-pointer-events-none, .dx-#{$widget-name}-rowsview .dx-selection.dx-row:not(.dx-row-focused) > tr > td.dx-pointer-events-none, @@ -278,6 +284,13 @@ border-left-color: $datagrid-row-selected-border-color; } + // (0,5,1) + .dx-rtl .dx-#{$widget-name}-headers.dx-header-multi-row .dx-header-row:not(.dx-column-lines) > td { + border-left: none; + border-right: 1px solid; + border-right-color: $datagrid-border-color; + } + // #endregion // #region padding diff --git a/packages/devextreme-scss/scss/widgets/material/gridBase/layout/cell.scss b/packages/devextreme-scss/scss/widgets/material/gridBase/layout/cell.scss index 5e7fd72f6ef8..0ba45b3d12c8 100644 --- a/packages/devextreme-scss/scss/widgets/material/gridBase/layout/cell.scss +++ b/packages/devextreme-scss/scss/widgets/material/gridBase/layout/cell.scss @@ -164,20 +164,10 @@ border-bottom-color: $datagrid-row-selected-border-color; } - // (0,7,1) - .dx-#{$widget-name}-headers.dx-header-multi-row:not(.dx-#{$widget-name}-sticky-columns) .dx-#{$widget-name}-content .dx-#{$widget-name}-table .dx-row.dx-header-row > td { + // (0,4,1) + .dx-#{$widget-name}-headers.dx-header-multi-row .dx-header-row:not(.dx-column-lines) > td { border-left: 1px solid; - border-left-color: $material-grid-base-border-color; - } - - // (0,8,1) - .dx-#{$widget-name}-headers.dx-header-multi-row:not(.dx-#{$widget-name}-sticky-columns) .dx-#{$widget-name}-content .dx-#{$widget-name}-table .dx-row.dx-header-row > td:first-child { - border-left: none; - } - - // (0,8,1) - .dx-#{$widget-name}-headers.dx-header-multi-row:not(.dx-#{$widget-name}-sticky-columns) .dx-#{$widget-name}-content .dx-#{$widget-name}-table .dx-row.dx-header-row > td:last-child { - border-right: none; + border-left-color: $datagrid-border-color; } // sticky-columns border @@ -229,6 +219,13 @@ border-left-color: $datagrid-row-selected-border-color; } + // (0,5,1) + .dx-rtl .dx-#{$widget-name}-headers.dx-header-multi-row .dx-header-row:not(.dx-column-lines) > td { + border-left: none; + border-right: 1px solid; + border-right-color: $datagrid-border-color; + } + // #endregion // #region padding