Skip to content

Commit 7a1c33f

Browse files
Merge branch '25_2' into 25_2_odata_deserialize_dates
2 parents 9796b40 + 7ef3f16 commit 7a1c33f

File tree

179 files changed

+2689
-2107
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

179 files changed

+2689
-2107
lines changed

.github/workflows/demos_visual_tests_frameworks.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
needs: check-should-run
3636
if: needs.check-should-run.outputs.should-run == 'true'
3737
env:
38-
NODE_OPTIONS: "--max-old-space-size=8192"
38+
NODE_OPTIONS: --max-old-space-size=8192
3939
timeout-minutes: 40
4040

4141
steps:
@@ -152,7 +152,7 @@ jobs:
152152
if: github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'force all tests')
153153
working-directory: apps/demos
154154
env:
155-
NODE_OPTIONS: "--max-old-space-size=8192"
155+
NODE_OPTIONS: --max-old-space-size=8192
156156
run: pnpx nx prepare-bundles
157157

158158
- name: Demos - Run tsc

.github/workflows/qunit_tests.yml

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -148,19 +148,15 @@ jobs:
148148
matrix:
149149
constel: [
150150
'ui',
151-
'ui.widgets(1/3)',
152-
'ui.widgets(2/3)',
153-
'ui.widgets(3/3)',
151+
'ui.widgets(1/2)',
152+
'ui.widgets(2/2)',
154153
'ui.editors(1/2)',
155154
'ui.editors(2/2)',
156155
'ui.htmlEditor',
157-
'ui.grid(1/4)',
158-
'ui.grid(2/4)',
159-
'ui.grid(3/4)',
160-
'ui.grid(4/4)',
161-
'ui.scheduler(1/3)',
162-
'ui.scheduler(2/3)',
163-
'ui.scheduler(3/3)',
156+
'ui.grid(1/2)',
157+
'ui.grid(2/2)',
158+
'ui.scheduler(1/2)',
159+
'ui.scheduler(2/2)',
164160
'viz'
165161
]
166162

.github/workflows/testcafe_tests.yml

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ jobs:
7070

7171
- name: Build
7272
shell: bash
73-
run: pnpx nx build devextreme
73+
env:
74+
NODE_OPTIONS: --max-old-space-size=8192
75+
run: pnpx nx build devextreme --uglify
7476

7577
- name: Zip artifacts
7678
working-directory: ./packages/devextreme
@@ -92,18 +94,13 @@ jobs:
9294
fail-fast: false
9395
matrix:
9496
ARGS: [
95-
{ componentFolder: "accessibility", name: "accessibility (1/2)", indices: "1/2" },
96-
{ componentFolder: "accessibility", name: "accessibility (2/2)", indices: "2/2" },
97+
{ componentFolder: "accessibility", name: "accessibility" },
9798
{ componentFolder: "common", name: "common" },
9899

99100
# Grids tests need to be reworked to work in fluent theme
100-
{ componentFolder: "dataGrid/common", name: "dataGrid / common (1/5)", indices: "1/5" },
101-
{ componentFolder: "dataGrid/common", name: "dataGrid / common (2/5)", indices: "2/5" },
102-
{ componentFolder: "dataGrid/common", name: "dataGrid / common (3/5)", indices: "3/5" },
103-
{ componentFolder: "dataGrid/common", name: "dataGrid / common (4/5)", indices: "4/5" },
104-
{ componentFolder: "dataGrid/common", name: "dataGrid / common (5/5)", indices: "5/5" },
105-
{ componentFolder: "dataGrid/sticky", name: "dataGrid / sticky (1/2)", indices: "1/2" },
106-
{ componentFolder: "dataGrid/sticky", name: "dataGrid / sticky (2/2)", indices: "2/2" },
101+
{ componentFolder: "dataGrid", name: "dataGrid (1/3)", indices: "1/3" },
102+
{ componentFolder: "dataGrid", name: "dataGrid (2/3)", indices: "2/3" },
103+
{ componentFolder: "dataGrid", name: "dataGrid (3/3)", indices: "3/3" },
107104
{ componentFolder: "cardView", name: "cardView" },
108105

109106
# Scheduler tests need to be reworked to work in fluent theme
@@ -162,8 +159,8 @@ jobs:
162159
run: |
163160
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
164161
165-
- uses: actions/cache@v4
166-
name: Setup pnpm cache
162+
- uses: actions/cache/restore@v4
163+
name: Restore pnpm cache
167164
with:
168165
path: |
169166
${{ env.STORE_PATH }}
@@ -177,6 +174,8 @@ jobs:
177174

178175
- name: Run TestCafe tests
179176
working-directory: ./e2e/testcafe-devextreme
177+
env:
178+
NODE_OPTIONS: --max-old-space-size=8192
180179
run: |
181180
if [ "${{ matrix.ARGS.theme }}" != "" ]; then
182181
THEME="--theme ${{ matrix.ARGS.theme }}"

apps/demos/README.md

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,68 @@
11
# DevExtreme Demos
22

3-
This repository contains technical DevExtreme demos for Angular, React, Vue, jQuery, ASP.NET MVC, and ASP.NET Core.
3+
This repository contains technical DevExtreme demos for Angular, React, Vue, and jQuery.
44

55
To run the demos on your machine, clone this repository, run `pnpm install`, and follow the instructions below.
66

77
## Prepare Demos for Development
8-
Before running you need execute in `monorepo/root`:
98

10-
```
11-
pnpm run all:build-dev
12-
```
9+
### Run demos locally
1310

14-
To prepare demos for development:
11+
In `monorepo/root`
1512

13+
Build all dependencies and prepare systemJS configs by executing:
1614
```
17-
pnpm run prepare-js
15+
pnpm run demos:prepare
1816
```
1917

20-
Angular, Vue, and React demos can use bundles instead of separate files from `node_modules`. With bundles, demos launch faster but become harder to debug. Run the following command to create the bundles and replace the SystemJS configuration:
21-
18+
Start webserver:
2219
```
23-
pnpm run prepare-bundles
20+
pnpm run demos:start
2421
```
22+
Navigate to http://localhost:8080/.
23+
24+
You can pass additional parameter to specify port. It can be useful when you need to fast switching between one demo on different frameworks.
25+
2526

26-
To return to using separate files from `node_modules`, run `pnpm run prepare-js`.
27+
### Bundled mode
2728

29+
Angular, Vue, and React demos can use bundles instead of separate files from `node_modules`. With bundles, demos launch faster but become harder to debug.
2830

29-
### Launch
31+
In `apps/demos`
32+
33+
Run the following command to create the bundles and replace the SystemJS configuration:
3034

31-
#### Option 1
3235
```
33-
pnpm run launch-demo
36+
pnpm run prepare-bundles
3437
```
3538

36-
#### Option 2
37-
1. Run ```pnpm run webserver ``` from `monorepo/root`
38-
2. Navigate to http://localhost:8080/apps/demos.
39+
To return to using separate files from `node_modules`, run:
3940

40-
You can pass additional parameter to specify port. It can be useful when you need to fast switching between one demo on different frameworks:
41+
```
42+
pnpm run prepare-js
43+
```
4144

42-
### Before Commiting Сhanges
45+
### Before Commiting Changes
4346

44-
For fix autofixed errors:
47+
Auto-fix lint errors:
4548

4649
```
4750
pnpm run fix-lint
4851
```
4952

50-
### Development
53+
### Adding new demo
5154

5255
1. Run the following script to add a new demo:
5356

5457
```
5558
pnpm run add-demo
5659
```
5760
58-
1. Use the built-in CLI to choose or enter the category, the demo name, and the technology for the new demo.
61+
2. Use the built-in CLI to choose or enter the category, the demo name, and the technology for the new demo.
5962
6063
### TS React Infrastructure
6164
62-
1. After you make any changes in React TypeScript sources, run the following command:
65+
After you make any changes in React TypeScript sources, run the following command:
6366
6467
```
6568
pnpm run convert-to-js split
@@ -71,9 +74,7 @@ If you want to run this script on specific folder you can pass it to the argumen
7174
pnpm run convert-to-js "JSDemos/Demos/Diagram/**/React"
7275
```
7376
74-
1. To ensure that React JavaScript and TypeScript sources are always in sync, the following GitHub action is used: "Check generated JS demos".
75-
76-
77+
The "Check generated JS demos" GitHub Action ensures that the React JavaScript and TypeScript sources remain in sync.
7778
## See Also
7879
7980
- [Technical demos online](https://js.devexpress.com/Demos/)

apps/demos/project.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,25 @@
102102
"{projectRoot}/**/*"
103103
],
104104
"cache": true
105+
},
106+
"prepare-js": {
107+
"executor": "nx:run-script",
108+
"options": {
109+
"script": "prepare-js"
110+
},
111+
"dependsOn": [
112+
{ "projects": ["devextreme"], "target": "build" },
113+
{ "projects": ["devextreme-angular", "devextreme-react", "devextreme-vue"], "target": "pack" }
114+
],
115+
"inputs": [
116+
"default",
117+
"{projectRoot}/gulpfile.js/**/*",
118+
"{projectRoot}/rollup.devextreme-angular.umd.config.mjs"
119+
],
120+
"outputs": [
121+
"{projectRoot}/Demos/**/config.js"
122+
],
123+
"cache": true
105124
}
106125
},
107126
"namedInputs": {

e2e/testcafe-devextreme/.testcaferc.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"screenshots": {
33
"path": "./",
44
"takeOnFails": true,
5+
"thumbnails": false,
56
"pathPattern": "/artifacts/failedtests/${TEST}"
67
},
78
"screenshots-comparer": {

e2e/testcafe-devextreme/helpers/domUtils.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,23 @@ export const addCaptionTo = ClientFunction((
116116

117117
element?.insertAdjacentText(where, caption);
118118
});
119+
120+
export const addFocusableElementBefore = ClientFunction((
121+
targetSelector: string,
122+
elementId = 'focusable-start',
123+
) => {
124+
const existing = document.getElementById(elementId);
125+
existing?.remove();
126+
127+
const target = document.querySelector(targetSelector);
128+
const button = document.createElement('button');
129+
button.id = elementId;
130+
button.textContent = 'Start';
131+
button.style.position = 'fixed';
132+
button.style.top = '0';
133+
button.style.left = '0';
134+
button.style.zIndex = '-1';
135+
button.style.opacity = '0';
136+
target?.parentElement?.insertBefore(button, target);
137+
return button.id;
138+
});

e2e/testcafe-devextreme/helpers/getPageUrl.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,7 @@ import { pathToFileURL } from 'url';
22
import { join } from 'path';
33

44
export default (currentDir: string, pagePath: string): string => {
5-
let path = pagePath;
6-
7-
if (process.env.shadowDom === 'true') {
8-
const lastIndexOfSlash = path.lastIndexOf('/');
9-
10-
path = `${path.substring(0, lastIndexOfSlash + 1)}shadowDom/${path.substring(lastIndexOfSlash + 1)}`;
11-
}
5+
const path = pagePath;
126

137
const fullPath = join(currentDir, path);
148

e2e/testcafe-devextreme/helpers/testPageUtils.ts

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@ import {
44
removeStylesheetRulesFromPage,
55
} from './domUtils';
66

7-
export async function clearTestPage(testController: TestController): Promise<void> {
8-
const shadowDom = process.env.shadowDom === 'true';
9-
10-
const clearTestPageFn = ClientFunction(() => {
7+
export async function clearTestPage(t: TestController): Promise<void> {
8+
await ClientFunction(() => {
119
const widgetSelector = '.dx-widget';
1210
const $elements = $(widgetSelector)
1311
.filter((_, element) => $(element).parents(widgetSelector).length === 0);
@@ -23,6 +21,9 @@ export async function clearTestPage(testController: TestController): Promise<voi
2321
$widgetElement.empty();
2422
});
2523

24+
const element = document.getElementById('focusable-start');
25+
element?.remove();
26+
2627
const body = document.querySelector('body');
2728
if (body) {
2829
body.innerHTML = '';
@@ -40,29 +41,58 @@ export async function clearTestPage(testController: TestController): Promise<voi
4041
`;
4142

4243
body?.prepend(temp.firstElementChild!);
43-
}, {
44-
dependencies: {
45-
shadowDom,
46-
},
47-
});
44+
}).with({ boundTestRun: t })();
4845

49-
await clearTestPageFn.with({ boundTestRun: testController })();
50-
await removeStylesheetRulesFromPage.with({ boundTestRun: testController })();
46+
await removeStylesheetRulesFromPage.with({ boundTestRun: t })();
5147
}
5248

5349
export async function loadAxeCore(t: TestController): Promise<void> {
54-
await t.eval(() => new Promise<void>((resolve, reject) => {
50+
await ClientFunction(() => new Promise<void>((resolve, reject) => {
5551
// @ts-expect-error ts-error
5652
if (window.axe) {
5753
resolve();
5854
return;
5955
}
6056

6157
const script = document.createElement('script');
58+
script.id = 'axe-core-script';
6259
script.src = '../../../node_modules/axe-core/axe.min.js';
6360
// @ts-expect-error ts-error
6461
script.onload = resolve;
6562
script.onerror = reject;
6663
document.head.appendChild(script);
67-
}));
64+
})).with({ boundTestRun: t })();
65+
}
66+
67+
export async function loadShadowDomExtension(t: TestController): Promise<void> {
68+
await ClientFunction(() => new Promise<void>((resolve, reject) => {
69+
if (document.getElementById('shadow-dom-extension-script')) {
70+
resolve();
71+
return;
72+
}
73+
74+
const script = document.createElement('script');
75+
script.id = 'shadow-dom-extension-script';
76+
script.src = '../../helpers/shadowDom/shadowDomExtension.js';
77+
// @ts-expect-error ts-error
78+
script.onload = resolve;
79+
script.onerror = reject;
80+
document.head.appendChild(script);
81+
})).with({ boundTestRun: t })();
6882
}
83+
84+
export const addShadowRootTree = async (t: TestController): Promise<void> => {
85+
await ClientFunction(() => {
86+
const root = document.querySelector('#parentContainer') as HTMLElement;
87+
const { childNodes } = root;
88+
89+
if (!root.shadowRoot) {
90+
root.attachShadow({ mode: 'open' });
91+
}
92+
93+
const shadowContainer = document.createElement('div');
94+
shadowContainer.append(...Array.from(childNodes));
95+
96+
root.shadowRoot!.appendChild(shadowContainer);
97+
}).with({ boundTestRun: t })();
98+
};

e2e/testcafe-devextreme/helpers/themeUtils.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { isString } from 'devextreme/core/utils/type';
2+
import { ClientFunction } from 'testcafe';
23
import { changeTheme } from './changeTheme';
34

45
const defaultThemeName = 'fluent.blue.light';
@@ -8,6 +9,13 @@ export const getThemePostfix = (theme?: string): string => {
89
return ` (${themeName})`;
910
};
1011

12+
export const getCurrentTheme = async (t: TestController): Promise<string> => {
13+
// eslint-disable-next-line @stylistic/max-len
14+
const currentTheme = await ClientFunction(() => (window as any).DevExpress?.ui.themes.current()).with({ boundTestRun: t })();
15+
16+
return currentTheme;
17+
};
18+
1119
export const isMaterial = (): boolean => process.env.theme === 'material.blue.light';
1220

1321
export const isFluent = (): boolean => process.env.theme === 'fluent.blue.light';

0 commit comments

Comments
 (0)