Skip to content

Commit 0f10556

Browse files
update treelist
1 parent 7f33dc6 commit 0f10556

21 files changed

Lines changed: 216 additions & 94 deletions

File tree

.github/workflows/testcafe_tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ jobs:
106106
{ componentFolder: "chat", name: "chat" },
107107
{ componentFolder: "chat", name: "chat - material", theme: 'material.blue.light' },
108108
{ componentFolder: "chat", name: "chat - fluent", theme: 'fluent.blue.light' },
109-
{ componentFolder: "treeList", name: "treeList", concurrency: 1 },
109+
{ componentFolder: "treeList", name: "treeList" },
110110
{ componentFolder: "dataGrid/common", name: "dataGrid / common (1/5)", indices: "1/5" },
111111
{ componentFolder: "dataGrid/common", name: "dataGrid / common (2/5)", indices: "2/5" },
112112
{ componentFolder: "dataGrid/common", name: "dataGrid / common (3/5)", indices: "3/5" },

e2e/testcafe-devextreme/helpers/clearPage.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
const testCafe = require('testcafe');
22

33
module.exports = {
4-
clearTestPage: async function() {
4+
clearTestPage: async function(testController) {
55
const shadowDom = process.env.shadowDom === 'true';
66

7-
await testCafe.ClientFunction(() => {
7+
const clearPageFunction = testCafe.ClientFunction(() => {
88
const widgetSelector = '.dx-widget';
99
const $elements = $(widgetSelector)
1010
.filter((_, element) => $(element).parents(widgetSelector).length === 0);
@@ -45,6 +45,8 @@ module.exports = {
4545
dependencies: {
4646
shadowDom,
4747
}
48-
})();
48+
});
49+
50+
await clearPageFunction.with({ boundTestRun: testController })();
4951
}
5052
};

e2e/testcafe-devextreme/runner.ts

Lines changed: 139 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ import { DEFAULT_BROWSER_SIZE } from './helpers/const';
88
import * as testPageUtils from './helpers/clearPage';
99
import 'nconf';
1010

11+
interface TestInfo {
12+
testName: string;
13+
fixtureName: string;
14+
testId: string;
15+
attemptNumber: number;
16+
startTime?: number;
17+
}
18+
1119
interface ParsedArgs {
1220
concurrency: number;
1321
browsers: string;
@@ -237,13 +245,76 @@ createTestCafe(TESTCAFE_CONFIG)
237245
(runner as any).cache = args.cache;
238246
}
239247

248+
const testAttempts = new Map<string, number>();
249+
240250
const runOptions: RunOptions = {
241251
quarantineMode: { successThreshold: 1, attemptLimit: 10 },
242252
disableNativeAutomation: true,
243253
// @ts-expect-error ts-error
244254
hooks: {
245255
test: {
246256
before: async (t: TestController) => {
257+
let testName = 'Current Test';
258+
let fixtureName = 'Current Fixture';
259+
260+
try {
261+
// Пробуем разные способы получения имени теста
262+
const testController = t as any;
263+
264+
if (testController.testRun?.test?.name) {
265+
testName = testController.testRun.test.name;
266+
fixtureName = testController.testRun.test.fixture?.name || 'Unknown Fixture';
267+
console.log(`✅ Got test name via testRun: "${testName}"`);
268+
} else if (testController.test?.name) {
269+
testName = testController.test.name;
270+
fixtureName = testController.test.fixture?.name || 'Unknown Fixture';
271+
console.log(`✅ Got test name via test: "${testName}"`);
272+
} else if (testController._testRun?.test?.name) {
273+
testName = testController._testRun.test.name;
274+
fixtureName = testController._testRun.test.fixture?.name || 'Unknown Fixture';
275+
console.log(`✅ Got test name via _testRun: "${testName}"`);
276+
} else {
277+
console.log('❌ Could not access test name via any internal API');
278+
console.log('Available properties on TestController:', Object.keys(testController));
279+
}
280+
} catch (e) {
281+
console.log('❌ Error getting test names from internal API:', e);
282+
}
283+
284+
const testMetadata = await ClientFunction(() => {
285+
return {
286+
url: window.location.href,
287+
timestamp: Date.now()
288+
};
289+
}).with({ boundTestRun: t })();
290+
291+
const testInfo: TestInfo = {
292+
testName: testName,
293+
fixtureName: fixtureName,
294+
testId: `test_${testMetadata.timestamp}`,
295+
attemptNumber: 0,
296+
};
297+
298+
299+
const testKey = testInfo.testId;
300+
const attemptNumber = (testAttempts.get(testKey) || 0) + 1;
301+
testAttempts.set(testKey, attemptNumber);
302+
303+
304+
testInfo.attemptNumber = attemptNumber;
305+
testInfo.startTime = Date.now();
306+
t.ctx.testInfo = testInfo;
307+
t.ctx.testKey = testKey;
308+
309+
console.log(`🚀 [Attempt ${attemptNumber}/10] Starting test: "${testInfo.testName}"`);
310+
console.log(`📋 Fixture: "${testInfo.fixtureName}"`);
311+
console.log(`🔑 Test ID: ${testInfo.testId}`);
312+
console.log(`⏰ Start time: ${new Date(testInfo.startTime).toISOString()}`);
313+
314+
if (attemptNumber > 1) {
315+
console.log(`⚠️ QUARANTINE MODE: Retry attempt ${attemptNumber} for failed test "${testInfo.testName}"`);
316+
}
317+
247318
if (!componentFolder.includes('accessibility')) {
248319
const [width, height] = DEFAULT_BROWSER_SIZE;
249320
await t.resizeWindow(width, height);
@@ -253,17 +324,79 @@ createTestCafe(TESTCAFE_CONFIG)
253324
await addShadowRootTree(t);
254325
}
255326

256-
if (args.theme) {
257-
await changeTheme(t, args.theme);
327+
const themeName = args.theme || 'generic.light';
328+
console.log(`🎨 [Attempt ${attemptNumber}] Setting theme: ${themeName}`);
329+
330+
const currentTheme = await ClientFunction(() => {
331+
try {
332+
return (window as any).DevExpress?.ui?.themes?.current();
333+
} catch (e) {
334+
return 'Theme API not available';
335+
}
336+
}).with({ boundTestRun: t })();
337+
338+
console.log(`✅ [Attempt ${attemptNumber}] Current theme before change: ${currentTheme}`);
339+
340+
try {
341+
if(currentTheme !== themeName) {
342+
await changeTheme(t, themeName);
343+
}
344+
345+
const newTheme = await ClientFunction(() => {
346+
try {
347+
return (window as any).DevExpress?.ui?.themes?.current();
348+
} catch (e) {
349+
return 'Theme API not available';
350+
}
351+
}).with({ boundTestRun: t })();
352+
353+
console.log(`🎯 [Attempt ${attemptNumber}] Theme after change: ${newTheme}`);
354+
} catch (error) {
355+
console.error(`❌ [Attempt ${attemptNumber}] Error setting theme:`, error);
258356
}
259357
},
260-
after: async () => {
261-
await testPageUtils.clearTestPage();
358+
359+
after: async (t: TestController) => {
360+
const testInfo = t.ctx.testInfo as TestInfo;
361+
362+
if (testInfo) {
363+
const endTime = Date.now();
364+
const durationMs = testInfo.startTime ? endTime - testInfo.startTime : 0;
365+
const durationSec = (durationMs / 1000).toFixed(2);
366+
console.log(`🏁 [Attempt ${testInfo.attemptNumber}] Test completed: "${testInfo.testName}" in ${durationSec}s (${durationMs}ms)`);
367+
console.log(`🔑 [Attempt ${testInfo.attemptNumber}] Test ID: ${testInfo.testId}`);
368+
console.log(`🧹 [Attempt ${testInfo.attemptNumber}] After hook - clearing page`);
369+
try {
370+
await testPageUtils.clearTestPage(t);
371+
console.log(`✅ ${testInfo ? `[Attempt ${testInfo.attemptNumber}]` : ''} Page cleared successfully`);
372+
} catch (error) {
373+
console.error(`❌ ${testInfo ? `[Attempt ${testInfo.attemptNumber}]` : ''} Error clearing page:`, error);
374+
}
375+
} else {
376+
console.log(`🧹 After hook - clearing page (test info not available)`);
377+
}
262378
},
263379
},
380+
381+
// fixture: {
382+
// afterEach: async (t: TestController) => {
383+
// const testInfo = t.ctx.testInfo as TestInfo;
384+
// const testKey = t.ctx.testKey as string;
385+
386+
// if (testInfo && testKey) {
387+
// console.log(`🏁 Test completed: ${testInfo.testId} (Final attempt: ${testInfo.attemptNumber})`);
388+
389+
// if (testInfo.attemptNumber > 1) {
390+
// console.log(`🎯 QUARANTINE RESULT: Test ${testInfo.testId} required ${testInfo.attemptNumber} attempts to pass`);
391+
// }
392+
393+
// testAttempts.delete(testKey);
394+
// }
395+
// }
396+
// }
264397
},
265-
};
266-
398+
};
399+
267400
if (args.browsers === 'chrome:docker') {
268401
runOptions.disableScreenshots = true;
269402
}

e2e/testcafe-devextreme/tests/dataGrid/common/masterDetail.ts

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,6 @@ fixture.disablePageReloads`Master detail`
1111

1212
['material.blue.light', 'generic.light'].forEach((theme) => {
1313
test(`Checkbox align right in masterdetail (T1045321) ${theme}`, async (t) => {
14-
await t.expect(ClientFunction(() => {
15-
// @ts-ignore
16-
return window.DevExpress.ui.themes.current();
17-
})())
18-
.eql('generic.light2');
1914
const { takeScreenshot, compareResults } = createScreenshotsComparer(t);
2015

2116
// assert
@@ -24,11 +19,7 @@ fixture.disablePageReloads`Master detail`
2419
.ok()
2520
.expect(compareResults.isValid())
2621
.ok(compareResults.errorMessages());
27-
}).before(async (t) => {
28-
await t.expect(ClientFunction(() => {
29-
// @ts-ignore
30-
return window.DevExpress.ui.themes.current();
31-
})()).eql('generic.light3');
22+
}).before(async () => {
3223
await changeTheme(theme);
3324
return createWidget('dxDataGrid', {
3425
dataSource: [{
@@ -84,8 +75,6 @@ fixture.disablePageReloads`Master detail`
8475
},
8576
},
8677
});
87-
}).after(async () => {
88-
await changeTheme('generic.light');
8978
});
9079
});
9180

e2e/testcafe-devextreme/tests/navigation/splitter/resize.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@ import { clearTestPage } from '../../../helpers/clearPage';
55
import { safeSizeTest } from '../../../helpers/safeSizeTest';
66

77
fixture.disablePageReloads`Splitter_integration`
8-
.page(url(__dirname, '../../container.html'))
9-
.afterEach(async () => clearTestPage());
8+
.page(url(__dirname, '../../container.html'));
109

11-
safeSizeTest('non resizable pane should not change its size during resize', async (t) => {
10+
test('non resizable pane should not change its size during resize', async (t) => {
1211
const splitter = new Splitter('#container');
1312

1413
await t
@@ -20,13 +19,13 @@ safeSizeTest('non resizable pane should not change its size during resize', asyn
2019
await t
2120
.expect(splitter.getItem(2).element.clientWidth)
2221
.eql(145);
23-
}, [800, 800]).before(async () => createWidget('dxSplitter', {
22+
}).before(async () => createWidget('dxSplitter', {
2423
width: '100%',
2524
height: 300,
2625
dataSource: [{
2726
text: 'Pane_1',
2827
}, {
29-
text: 'Pane_1',
28+
text: 'Pane_2',
3029
}, {
3130
text: 'Pane_3',
3231
size: '300px',

e2e/testcafe-devextreme/tests/treeList/API.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { createScreenshotsComparer } from 'devextreme-screenshot-comparer';
33
import url from '../../helpers/getPageUrl';
44
import { createWidget } from '../../helpers/createWidget';
55

6-
fixture`Public methods`
6+
fixture.disablePageReloads`Public methods`
77
.page(url(__dirname, '../container.html'));
88

99
const getItems = (): Record<string, unknown>[] => {

e2e/testcafe-devextreme/tests/treeList/accessibility/aria.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import TreeList from 'devextreme-testcafe-models/treeList';
22
import { createWidget } from '../../../helpers/createWidget';
33
import url from '../../../helpers/getPageUrl';
44

5-
fixture`Aria Label tests`.page(url(__dirname, '../../container.html'));
5+
fixture.disablePageReloads`Aria Label tests`.page(url(__dirname, '../../container.html'));
66

77
const tasks = [
88
{

0 commit comments

Comments
 (0)