Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 13 additions & 18 deletions .github/actions/run-qunit-tests/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ inputs:
useCsp:
description: "Indicates if tests should run with Content Security Policy (CSP) enabled"
default: "true"
maxWorkers:
description: "Maximum number of parallel test workers"
default: ""

runs:
using: composite
Expand All @@ -36,23 +39,15 @@ runs:
echo "MATRIX_ENVS_NAME_SAFE=$MATRIX_ENVS_NAME_SAFE"
echo "MATRIX_ENVS_NAME_SAFE=$MATRIX_ENVS_NAME_SAFE" >> $GITHUB_ENV

# - name: Update apt
# run: |
# sudo apt-get update

# - name: Setup utils
# run: |
# sudo apt-get install -y dbus-x11 httping x11vnc xvfb
# - name: Setup Chrome
# uses: ./.github/actions/setup-chrome-headless-shell
# with:
# chrome-version: '141.0.7390.122'

- name: Setup Chrome
uses: ./.github/actions/setup-chrome-headless-shell
with:
chrome-version: '141.0.7390.122'

- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
# - name: Use Node.js
# uses: actions/setup-node@v4
# with:
# node-version: '20'
Comment thread
EugeniyKiyashko marked this conversation as resolved.

- name: Download artifacts
uses: actions/download-artifact@v4
Expand Down Expand Up @@ -108,14 +103,14 @@ runs:
NORENOVATION: "false"
GITHUBACTION: "true"
TARGET: "test"
DISPLAY: ":99"
CHROME_CMD: ${{ env.CHROME_SHELL }}
MAX_WORKERS: ${{ inputs.maxWorkers }}
run: |
chmod +x ./docker-ci.sh
./docker-ci.sh

- name: Copy RawLog.txt
if: ${{ failure() }}
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: RawLog-${{ env.MATRIX_ENVS_NAME_SAFE }}
Expand Down
4 changes: 2 additions & 2 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,10 @@ npm run lint-staged
- Checks wrapper regeneration is up-to-date
- Timeout: 20 minutes

**5. QUnit Tests (`.github/workflows/qunit_tests-renovation.yml`):**
**5. QUnit Tests (`.github/workflows/qunit_tests.yml`):**
- Builds with `DEVEXTREME_TEST_CI=true`
- Runs tests in parallel across multiple constellations
- Timeout: 60 minutes
- Timeout: 20 minutes

**6. TestCafe Tests (`.github/workflows/testcafe_tests.yml`):**
- Accessibility tests across multiple themes
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/demos_visual_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -737,11 +737,11 @@ jobs:
id: set-concurrency
run: |
if [[ "${{ matrix.CONSTEL }}" == react* ]]; then
echo "concurrency=3" >> $GITHUB_OUTPUT
echo "concurrency=4" >> $GITHUB_OUTPUT
elif [[ "${{ matrix.CONSTEL }}" == angular* ]]; then
echo "concurrency=2" >> $GITHUB_OUTPUT
echo "concurrency=3" >> $GITHUB_OUTPUT
else
echo "concurrency=2" >> $GITHUB_OUTPUT
echo "concurrency=3" >> $GITHUB_OUTPUT
fi

- name: Run TestCafe tests
Expand Down
38 changes: 15 additions & 23 deletions .github/workflows/qunit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,40 +89,36 @@ jobs:
needs: build
runs-on: devextreme-shr2
name: Constel ${{ matrix.CONSTEL }}${{ matrix.TIMEZONE != '' && format('-{0}', matrix.TIMEZONE) || '' }}${{ matrix.CSP == 'false' && '-no-csp' || '' }}

Copilot AI Nov 20, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The timeout is reduced from 60 minutes to 20 minutes. This is a significant change (3x reduction) that could cause legitimate long-running tests to fail. Consider adding a comment in the workflow explaining this timeout reduction, especially if it's based on observed test execution times. This helps future maintainers understand the rationale.

Suggested change
name: Constel ${{ matrix.CONSTEL }}${{ matrix.TIMEZONE != '' && format('-{0}', matrix.TIMEZONE) || '' }}${{ matrix.CSP == 'false' && '-no-csp' || '' }}
name: Constel ${{ matrix.CONSTEL }}${{ matrix.TIMEZONE != '' && format('-{0}', matrix.TIMEZONE) || '' }}${{ matrix.CSP == 'false' && '-no-csp' || '' }}
# Timeout reduced from 60 minutes to 20 minutes based on observed QUnit test execution times.
# All current test constellations reliably complete in under 20 minutes; adjust if test suite grows.

Copilot uses AI. Check for mistakes.
timeout-minutes: 60
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
CONSTEL: [
export,
misc,
ui,
ui.editors,
ui.htmlEditor,
ui.grid,
ui.scheduler(1/2),
ui.scheduler(2/2),
viz
ui.scheduler,
]
TIMEZONE: ['']
CSP: ['true']
useJQuery: ['false']
MAX_WORKERS: ['']
include:
- CONSTEL: ui.scheduler(1/2)
TIMEZONE: US/Pacific
- CONSTEL: export
MAX_WORKERS: '3'
useJQuery: 'false'
- CONSTEL: ui.scheduler(2/2)
CSP: 'true'
- CONSTEL: ui.scheduler
TIMEZONE: US/Pacific
useJQuery: 'false'
- CONSTEL: misc
CSP: 'false'
useJQuery: 'true'
- CONSTEL: ui.widgets(1/2)
CSP: 'false'
useJQuery: 'false'
- CONSTEL: ui.widgets(2/2)
- CONSTEL: ui.widgets
CSP: 'false'
useJQuery: 'false'
MAX_WORKERS: '3'

steps:
- name: Get sources
Expand All @@ -136,6 +132,7 @@ jobs:
timezone: ${{ matrix.TIMEZONE }}
useJQuery: ${{ matrix.useJQuery }}
useCsp: ${{ matrix.CSP }}
maxWorkers: ${{ matrix.MAX_WORKERS || '' }}

qunit-tests-shadow-dom:
needs: [check-should-run-all, build]
Expand All @@ -148,16 +145,10 @@ jobs:
matrix:
constel: [
'ui',
'ui.widgets(1/2)',
'ui.widgets(2/2)',
'ui.editors(1/2)',
'ui.editors(2/2)',
'ui.htmlEditor',
'ui.grid(1/2)',
'ui.grid(2/2)',
'ui.scheduler(1/2)',
'ui.scheduler(2/2)',
'viz'
'ui.widgets',
'ui.editors',
'ui.grid',
'ui.scheduler',
]

steps:
Expand All @@ -172,6 +163,7 @@ jobs:
useJQuery: 'true'
useShadowDom: 'true'
useCsp: 'true'
maxWorkers: ${{ (matrix.constel == 'ui.editors' || matrix.constel == 'ui.widgets') && '3' || '' }}

notify:
runs-on: devextreme-shr2
Expand Down
26 changes: 14 additions & 12 deletions .github/workflows/testcafe_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,10 @@ jobs:
{ name: "material - compact", theme: 'material.blue.light.compact' },

{ componentFolder: "cardView", name: "cardView" },
{ componentFolder: "dataGrid", name: "dataGrid (1/3)", indices: "1/3" },
{ componentFolder: "dataGrid", name: "dataGrid (2/3)", indices: "2/3" },
{ componentFolder: "dataGrid", name: "dataGrid (3/3)", indices: "3/3" },
{ componentFolder: "dataGrid", name: "dataGrid (1/4)", indices: "1/4", cache: true },
{ componentFolder: "dataGrid", name: "dataGrid (2/4)", indices: "2/4", cache: true },
{ componentFolder: "dataGrid", name: "dataGrid (3/4)", indices: "3/4", cache: true },
{ componentFolder: "dataGrid", name: "dataGrid (4/4)", indices: "4/4", cache: true },

{ componentFolder: "editors", name: "editors" },
{ componentFolder: "navigation", name: "navigation" },
Expand Down Expand Up @@ -139,10 +140,10 @@ jobs:
working-directory: ./packages/devextreme
run: 7z x artifacts.zip -aoa

- name: Setup Chrome
uses: ./.github/actions/setup-chrome
with:
chrome-version: '141.0.7390.122'
# - name: Setup Chrome
# uses: ./.github/actions/setup-chrome
# with:
# chrome-version: '141.0.7390.122'
Comment thread
EugeniyKiyashko marked this conversation as resolved.

- name: Use Node.js
uses: actions/setup-node@v4
Expand Down Expand Up @@ -182,24 +183,25 @@ jobs:
[ "${{ matrix.ARGS.indices }}" != "" ] && INDICES="--indices ${{ matrix.ARGS.indices }}"
[ "${{ matrix.ARGS.concurrency }}" != "" ] && CONCURRENCY="--concurrency ${{ matrix.ARGS.concurrency }}"
[ "${{ matrix.ARGS.platform }}" != "" ] && PLATFORM="--platform ${{ matrix.ARGS.platform }}"
all_args="--browsers=chrome:devextreme-shr2 --componentFolder ${{ matrix.ARGS.componentFolder }} $CONCURRENCY $INDICES $PLATFORM $THEME"
[ "${{ matrix.ARGS.cache }}" == "true" ] && CACHE="--cache true"
all_args="--browsers=chrome:devextreme-shr2 --componentFolder ${{ matrix.ARGS.componentFolder }} $CONCURRENCY $INDICES $PLATFORM $THEME $CACHE"
echo "$all_args"
pnpm run test $all_args

- name: Sanitize job name
if: ${{ failure() }}
if: ${{ always() }}
run: echo "JOB_NAME=$(echo "${{ matrix.ARGS.name }}" | tr '/' '-')" >> $GITHUB_ENV

- name: Copy compared screenshot artifacts
if: ${{ failure() }}
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: compared-screenshots-${{ env.JOB_NAME }}
path: ${{ github.workspace }}/e2e/testcafe-devextreme/artifacts/compared-screenshots/**/*
if-no-files-found: ignore

- name: Copy failed test artifacts
if: ${{ failure() }}
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: failed-tests-${{ env.JOB_NAME }}
Expand All @@ -209,7 +211,7 @@ jobs:
merge-artifacts:
runs-on: devextreme-shr2
needs: testcafe
if: ${{ failure() }}
if: ${{ always() }}

steps:
- name: Merge screenshot artifacts
Expand Down
5 changes: 1 addition & 4 deletions apps/demos/utils/visual-tests/testcafe-runner.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import createTestCafe from 'testcafe';
import { ClientFunction } from 'testcafe';
import { THEME } from './helpers/theme-utils';
import fs from 'fs';

const LAUNCH_RETRY_ATTEMPTS = 3;
Expand Down Expand Up @@ -79,9 +78,7 @@ function accessibilityTestCafeReporter() {
}

async function main() {
const tester = await createTestCafe({
cache: true,
});
const tester = await createTestCafe({});
const runner = tester.createRunner();
const concurrency = (process.env.CONCURRENCY && (+process.env.CONCURRENCY)) || 1;

Expand Down
11 changes: 5 additions & 6 deletions e2e/testcafe-devextreme/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ interface ParsedArgs {
retryFailed: boolean;
}

const TESTCAFE_CONFIG: Partial<TestCafeConfigurationOptions> = {
const getTestCafeConfig = (cache: boolean): Partial<TestCafeConfigurationOptions> => ({
hostname: 'localhost',
port1: 1437,
port2: 1438,
cache: true,
};
cache,
});

const changeTheme = async (t: TestController, themeName: string): Promise<void> => {
const changeThemeClientFn = ClientFunction(() => new Promise<void>((resolve) => {
Expand Down Expand Up @@ -106,7 +106,7 @@ function getArgs(): ParsedArgs {
reporter: 'spec-time',
componentFolder: '',
file: '*',

Copilot AI Nov 20, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default cache value is changed from true to false. This change could significantly impact test execution time by preventing TestCafe from caching compiled test files. While this may help with stalled tests, it comes at the cost of slower test runs. Consider adding a comment explaining why caching is disabled by default, or making this more discoverable for developers who might want to re-enable it for faster local development.

Suggested change
file: '*',
file: '*',
// TestCafe cache is disabled by default to help avoid issues with stalled tests and ensure fresh compilation.
// This may slow down test execution, especially for local development.
// To re-enable caching for faster local runs, set the 'cache' option to true (e.g. via CLI: --cache).

Copilot uses AI. Check for mistakes.
cache: true,
cache: false,
quarantineMode: false,
indices: '',
platform: '',
Expand All @@ -123,9 +123,8 @@ async function main() {
let testCafe: Awaited<ReturnType<typeof createTestCafe>> | null = null;

try {
testCafe = await createTestCafe(TESTCAFE_CONFIG);

const args = getArgs();
testCafe = await createTestCafe(getTestCafeConfig(args.cache));

const testName = args.test.trim();
const reporter = typeof args.reporter === 'string' ? args.reporter.trim() : args.reporter;
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { createWidget } from '../../../../helpers/createWidget';
import { getNumberData, getData } from '../../helpers/generateDataSourceData';
import { testScreenshot } from '../../../../helpers/themeUtils';

fixture.disablePageReloads`FilterRow`
fixture`FilterRow`
.page(url(__dirname, '../../../container.html'));

test('Filter should reset if the filter row editor text is cleared (T1257261)', async (t) => {
Expand Down Expand Up @@ -282,6 +282,4 @@ test('DataGrid - filter row\'s search-box\'s aria-label should be customizable v
visible: true,
},
});
}).after(async (t) => {
await t.eval(() => location.reload());
});
Original file line number Diff line number Diff line change
Expand Up @@ -5346,7 +5346,7 @@ test.meta({ unstable: true })('Focus events should be called when pressing the C
})();
});

test('Focus events should be called when pressing the Ctrl + End key when rowRenderingMode is \'virtual\'', async (t) => {
test.meta({ unstable: true })('Focus events should be called when pressing the Ctrl + End key when rowRenderingMode is \'virtual\'', async (t) => {
// arrange
const dataGrid = new DataGrid('#container');

Expand Down
20 changes: 15 additions & 5 deletions e2e/testcafe-devextreme/tests/dataGrid/common/scrolling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1702,7 +1702,7 @@ test('The row alternation should display correctly when grouping and virtual scr

test('DataGrid - Gray boxes appear when the push method is used to remove rows in infinite scrolling mode (T1240079)', async (t) => {
const dataGrid = new DataGrid('#container');
const { takeScreenshot, compareResults } = createScreenshotsComparer(t);

const data = [
{ id: 1, text: 'text 1' },
{ id: 2, text: 'text 2' },
Expand All @@ -1712,11 +1712,17 @@ test('DataGrid - Gray boxes appear when the push method is used to remove rows i
key: item.id,
}));

await t.expect(dataGrid.isReady()).ok();

await dataGrid.apiPush(changes);
await testScreenshot(t, takeScreenshot, 'T1240079.png', { element: dataGrid.element });
await t.wait(500);
Comment thread
EugeniyKiyashko marked this conversation as resolved.

await t.expect(dataGrid.isReady()).ok();

const visibleRows = await dataGrid.apiGetVisibleRows();
await t
.expect(compareResults.isValid())
.ok(compareResults.errorMessages());
.expect(visibleRows.length)
.eql(0, 'All rows should be removed after push');
}).before(async () => {
await createWidget('dxDataGrid', () => {
const data = [
Expand All @@ -1728,7 +1734,11 @@ test('DataGrid - Gray boxes appear when the push method is used to remove rows i
store: new (window as any).DevExpress.data.CustomStore({
key: 'id',
loadMode: 'raw',
load: () => Promise.resolve(data),
load: () => new Promise((resolve) => {
setTimeout(() => {
resolve(data);
}, 100);
}),
Comment thread
EugeniyKiyashko marked this conversation as resolved.
}),
};

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading