Skip to content

Commit 4166129

Browse files
Merge branch '25_2' into 25_2_sptit_axe_tests
2 parents 10c7531 + e50a006 commit 4166129

4 files changed

Lines changed: 125 additions & 117 deletions

File tree

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
Our DevExtreme [SpeechToText](/Documentation/ApiReference/UI_Components/dxSpeechToText) component allows you to integrate voice input to your app. The component implements the [Web Speech API SpeechRecognition](https://developer.mozilla.org/en-US/docs/Web/API/SpeechRecognition) interface and supports [custom speech recognizers](/Documentation/ApiReference/UI_Components/dxSpeechToText/Configuration/#customSpeechRecognizer).
1+
Our DevExtreme [SpeechToText](/Documentation/ApiReference/UI_Components/dxSpeechToText) component allows you to integrate voice input into your app. The component implements the [Web Speech API SpeechRecognition](https://developer.mozilla.org/en-US/docs/Web/API/SpeechRecognition) interface and supports [custom speech recognizers](/Documentation/ApiReference/UI_Components/dxSpeechToText/Configuration/#customSpeechRecognizer).
22

33
<!--split-->
44

5-
You can integrate SpeechToText with any text input, including other [DevExtreme components](https://js.devexpress.com/jQuery/Demos/WidgetsGallery/). To do this, set the component's **value** property to the transcribed text. SpeechToText returns transcribed text in the [onResult](/Documentation/ApiReference/UI_Components/dxSpeechToText/Configuration/#onResult) handler as users speak. When speech stops, the component calls the [onEnd](/Documentation/ApiReference/UI_Components/dxSpeechToText/Configuration/#onEnd) handler and switches from the "listening" state to the initial state. SpeechToText implements different icon ([startIcon](/Documentation/ApiReference/UI_Components/dxSpeechToText/Configuration/#startIcon)/[stopIcon](/Documentation/ApiReference/UI_Components/dxSpeechToText/Configuration/#stopIcon)), text ([startText](/Documentation/ApiReference/UI_Components/dxSpeechToText/Configuration/#startText)/[stopText](/Documentation/ApiReference/UI_Components/dxSpeechToText/Configuration/#stopText)), and click handler ([onStartClick](/Documentation/ApiReference/UI_Components/dxSpeechToText/Configuration/#onStartClick)/[onStopClick](/Documentation/ApiReference/UI_Components/dxSpeechToText/Configuration/#onStopClick)) properties in each component state.
5+
You can integrate SpeechToText with any text input, including other [DevExtreme components](https://js.devexpress.com/jQuery/Demos/WidgetsGallery/). To do this, set a component's **value** property to the transcribed text. SpeechToText returns transcribed text in the [onResult](/Documentation/ApiReference/UI_Components/dxSpeechToText/Configuration/#onResult) handler as users speak. When speech stops, the component calls the [onEnd](/Documentation/ApiReference/UI_Components/dxSpeechToText/Configuration/#onEnd) handler and switches from the "listening" state to the initial state. SpeechToText implements different icon ([startIcon](/Documentation/ApiReference/UI_Components/dxSpeechToText/Configuration/#startIcon)/[stopIcon](/Documentation/ApiReference/UI_Components/dxSpeechToText/Configuration/#stopIcon)), text ([startText](/Documentation/ApiReference/UI_Components/dxSpeechToText/Configuration/#startText)/[stopText](/Documentation/ApiReference/UI_Components/dxSpeechToText/Configuration/#stopText)), and click handler ([onStartClick](/Documentation/ApiReference/UI_Components/dxSpeechToText/Configuration/#onStartClick)/[onStopClick](/Documentation/ApiReference/UI_Components/dxSpeechToText/Configuration/#onStopClick)) properties in each component state.
66

77
For a complete overview of SpeechToText options (including [Web Speech API options](/Documentation/ApiReference/UI_Components/dxSpeechToText/Configuration/speechRecognitionConfig/)), refer to the following topic: [SpeechToText API Reference](/Documentation/ApiReference/UI_Components/dxSpeechToText/).
Lines changed: 107 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,120 +1,120 @@
1-
// import Scheduler from 'devextreme-testcafe-models/scheduler';
2-
// import { createWidget } from '../../../helpers/createWidget';
3-
// import url from '../../../helpers/getPageUrl';
1+
import Scheduler from 'devextreme-testcafe-models/scheduler';
2+
import { createWidget } from '../../../helpers/createWidget';
3+
import url from '../../../helpers/getPageUrl';
44

5-
// fixture.disablePageReloads`Scheduler - Status`
6-
// .page(url(__dirname, '../../container.html'));
5+
fixture.disablePageReloads`Scheduler - Status`
6+
.page(url(__dirname, '../../container.html'));
77

8-
// const today = '2025-04-30T15:00:00.000Z';
9-
// const appointments = [
10-
// {
11-
// startDate: '2025-04-25T21:30:00.000Z',
12-
// endDate: '2025-04-25T23:30:00.000Z',
13-
// recurrenceRule: 'FREQ=HOURLY;INTERVAL=15;COUNT=15',
14-
// }, {
15-
// startDate: '2025-04-30T15:00:00.000Z',
16-
// endDate: '2025-04-30T16:00:00.000Z',
17-
// }, {
18-
// startDate: '2025-04-26T00:30:00.000Z',
19-
// endDate: '2025-04-26T02:30:00.000Z',
20-
// recurrenceRule: 'FREQ=HOURLY;INTERVAL=15;COUNT=15',
21-
// }, {
22-
// startDate: '2025-05-02T15:00:00.000Z',
23-
// endDate: '2025-05-02T16:00:00.000Z',
24-
// },
25-
// ];
8+
const today = '2025-04-30T15:00:00.000Z';
9+
const appointments = [
10+
{
11+
startDate: '2025-04-25T21:30:00.000Z',
12+
endDate: '2025-04-25T23:30:00.000Z',
13+
recurrenceRule: 'FREQ=HOURLY;INTERVAL=15;COUNT=15',
14+
}, {
15+
startDate: '2025-04-30T15:00:00.000Z',
16+
endDate: '2025-04-30T16:00:00.000Z',
17+
}, {
18+
startDate: '2025-04-26T00:30:00.000Z',
19+
endDate: '2025-04-26T02:30:00.000Z',
20+
recurrenceRule: 'FREQ=HOURLY;INTERVAL=15;COUNT=15',
21+
}, {
22+
startDate: '2025-05-02T15:00:00.000Z',
23+
endDate: '2025-05-02T16:00:00.000Z',
24+
},
25+
];
2626

27-
// const statusCheck = async (t: TestController, scheduler: Scheduler, status: string) => {
28-
// await t.expect(scheduler.element.getAttribute('aria-label')).contains(status);
29-
// await t.expect(scheduler.getGeneralStatusContainer().textContent).contains(status);
30-
// };
31-
// const statusCheckEql = async (t: TestController, scheduler: Scheduler, status: string) => {
32-
// await t.expect(scheduler.element.getAttribute('aria-label')).match(new RegExp(status));
33-
// await t.expect(scheduler.getGeneralStatusContainer().textContent).match(new RegExp(status));
34-
// };
27+
const statusCheck = async (t: TestController, scheduler: Scheduler, status: string) => {
28+
await t.expect(scheduler.element.getAttribute('aria-label')).contains(status);
29+
await t.expect(scheduler.getGeneralStatusContainer().textContent).contains(status);
30+
};
31+
const statusCheckEql = async (t: TestController, scheduler: Scheduler, status: string) => {
32+
await t.expect(scheduler.element.getAttribute('aria-label')).match(new RegExp(status));
33+
await t.expect(scheduler.getGeneralStatusContainer().textContent).match(new RegExp(status));
34+
};
3535

36-
// const options = [
37-
// ['agenda', 'Agenda view: from April 30, 2025 to May 6, 2025', [0, 9, 19]],
38-
// ['day', 'Day view: April 30, 2025', [0, 3, 5]],
39-
// ['month', 'Month view: from March 2025 to May 2025', [0, 17, 35]],
40-
// ['timelineDay', 'Timeline Day view: April 30, 2025', [0, 3, 5]],
41-
// ['timelineMonth', 'Timeline Month view: April 2025', [0, 11, 21]],
42-
// ['timelineWeek', 'Timeline Week view: from April 27, 2025 to May 3, 2025', [0, 12, 25]],
43-
// ['timelineWorkWeek', 'Timeline Work Week view: from April 28, 2025 to May 2, 2025', [0, 9, 18]],
44-
// ['week', 'Week view: from April 27, 2025 to May 3, 2025', [0, 13, 27]],
45-
// ['workWeek', 'Work Week view: from April 28, 2025 to May 2, 2025', [0, 10, 20]],
46-
// ['Two Weeks', 'Two Weeks view: from April 27, 2025 to May 10, 2025', [0, 14, 29]],
47-
// ] as const;
48-
// const indicatorOnView = 'The current time indicator is visible in the view';
49-
// const indicatorNotOnView = 'The current time indicator is not visible on the screen';
36+
const options = [
37+
['agenda', 'Agenda view: from April 30, 2025 to May 6, 2025', [0, 9, 19]],
38+
['day', 'Day view: April 30, 2025', [0, 3, 5]],
39+
['month', 'Month view: from March 2025 to May 2025', [0, 17, 35]],
40+
['timelineDay', 'Timeline Day view: April 30, 2025', [0, 3, 5]],
41+
['timelineMonth', 'Timeline Month view: April 2025', [0, 11, 21]],
42+
['timelineWeek', 'Timeline Week view: from April 27, 2025 to May 3, 2025', [0, 12, 25]],
43+
['timelineWorkWeek', 'Timeline Work Week view: from April 28, 2025 to May 2, 2025', [0, 9, 18]],
44+
['week', 'Week view: from April 27, 2025 to May 3, 2025', [0, 13, 27]],
45+
['workWeek', 'Work Week view: from April 28, 2025 to May 2, 2025', [0, 10, 20]],
46+
['Two Weeks', 'Two Weeks view: from April 27, 2025 to May 10, 2025', [0, 14, 29]],
47+
] as const;
48+
const indicatorOnView = 'The current time indicator is visible in the view';
49+
const indicatorNotOnView = 'The current time indicator is not visible on the screen';
5050

51-
// options.forEach(([currentView, title, counts]) => {
52-
// counts.forEach((appointmentsCount, index) => {
53-
// const schedulerConfig = {
54-
// timeZone: 'America/Los_Angeles',
55-
// dataSource: appointments.slice(0, 2 * index),
56-
// views: [
57-
// 'agenda', 'day', 'month', 'timelineDay', 'timelineMonth', 'timelineWeek', 'timelineWorkWeek', 'week', 'workWeek', {
58-
// name: 'Two Weeks',
59-
// type: 'week',
60-
// intervalCount: 2,
61-
// },
62-
// ],
63-
// currentView,
64-
// indicatorTime: today,
65-
// currentDate: today,
66-
// };
67-
// // TODO(2): use `appointmentsCount` here
68-
// const generalStatus = `Scheduler. ${title} with ${index === 0 ? 0 : '\\d*'} appointments`;
51+
options.forEach(([currentView, title, counts]) => {
52+
counts.forEach((appointmentsCount, index) => {
53+
const schedulerConfig = {
54+
timeZone: 'America/Los_Angeles',
55+
dataSource: appointments.slice(0, 2 * index),
56+
views: [
57+
'agenda', 'day', 'month', 'timelineDay', 'timelineMonth', 'timelineWeek', 'timelineWorkWeek', 'week', 'workWeek', {
58+
name: 'Two Weeks',
59+
type: 'week',
60+
intervalCount: 2,
61+
},
62+
],
63+
currentView,
64+
indicatorTime: today,
65+
currentDate: today,
66+
};
67+
// TODO(2): use `appointmentsCount` here
68+
const generalStatus = `Scheduler. ${title} with ${index === 0 ? 0 : '\\d*'} appointments`;
6969

70-
// test(`Scheduler should have correct status message [view=${currentView}, count=${appointmentsCount}, indicator=false]`, async (t) => {
71-
// const scheduler = new Scheduler('#container');
70+
test(`Scheduler should have correct status message [view=${currentView}, count=${appointmentsCount}, indicator=false]`, async (t) => {
71+
const scheduler = new Scheduler('#container');
7272

73-
// await statusCheckEql(t, scheduler, generalStatus);
74-
// }).before(async () => {
75-
// await createWidget('dxScheduler', { ...schedulerConfig, showCurrentTimeIndicator: false });
76-
// });
73+
await statusCheckEql(t, scheduler, generalStatus);
74+
}).before(async () => {
75+
await createWidget('dxScheduler', { ...schedulerConfig, showCurrentTimeIndicator: false });
76+
});
7777

78-
// test(`Scheduler should have correct status message [view=${currentView}, count=${appointmentsCount}, indicator=true]`, async (t) => {
79-
// const scheduler = new Scheduler('#container');
78+
test(`Scheduler should have correct status message [view=${currentView}, count=${appointmentsCount}, indicator=true]`, async (t) => {
79+
const scheduler = new Scheduler('#container');
8080

81-
// await t.click(scheduler.toolbar.navigator.nextButton);
82-
// await statusCheck(t, scheduler, currentView === 'month' ? indicatorOnView : indicatorNotOnView);
81+
await t.click(scheduler.toolbar.navigator.nextButton);
82+
await statusCheck(t, scheduler, currentView === 'month' ? indicatorOnView : indicatorNotOnView);
8383

84-
// await t.click(scheduler.toolbar.navigator.prevButton);
85-
// await statusCheckEql(t, scheduler, `${generalStatus}. ${indicatorOnView}`);
84+
await t.click(scheduler.toolbar.navigator.prevButton);
85+
await statusCheckEql(t, scheduler, `${generalStatus}. ${indicatorOnView}`);
8686

87-
// await t.click(scheduler.toolbar.navigator.prevButton);
88-
// await statusCheck(t, scheduler, indicatorNotOnView);
89-
// }).before(async () => {
90-
// await createWidget('dxScheduler', { ...schedulerConfig, showCurrentTimeIndicator: true });
91-
// });
92-
// });
93-
// });
87+
await t.click(scheduler.toolbar.navigator.prevButton);
88+
await statusCheck(t, scheduler, indicatorNotOnView);
89+
}).before(async () => {
90+
await createWidget('dxScheduler', { ...schedulerConfig, showCurrentTimeIndicator: true });
91+
});
92+
});
93+
});
9494

95-
// [
96-
// ['timelineWeek', 'Scheduler. Timeline Week view: from April 27, 2025 to May 3, 2025 with 5 appointments'],
97-
// ['week', 'Scheduler. Week view: from April 27, 2025 to May 3, 2025 with 5 appointments'],
98-
// ].forEach(([currentView, title]) => {
99-
// test(`Scheduler should have correct status message if the appointments are partial [view=${currentView}]`, async (t) => {
100-
// const scheduler = new Scheduler('#container');
95+
[
96+
['timelineWeek', 'Scheduler. Timeline Week view: from April 27, 2025 to May 3, 2025 with 5 appointments'],
97+
['week', 'Scheduler. Week view: from April 27, 2025 to May 3, 2025 with 5 appointments'],
98+
].forEach(([currentView, title]) => {
99+
test(`Scheduler should have correct status message if the appointments are partial [view=${currentView}]`, async (t) => {
100+
const scheduler = new Scheduler('#container');
101101

102-
// await statusCheckEql(t, scheduler, title);
103-
// }).before(async () => {
104-
// await createWidget('dxScheduler', {
105-
// timeZone: 'America/Los_Angeles',
106-
// dataSource: [{
107-
// startDate: '2025-04-29T23:18:00.000Z',
108-
// endDate: '2025-04-30T16:12:00.000Z',
109-
// }, {
110-
// startDate: '2025-04-26T23:18:00.000Z',
111-
// endDate: '2025-04-27T12:12:00.000Z',
112-
// recurrenceRule: 'FREQ=DAILY;INTERVAL=2;COUNT=5',
113-
// }],
114-
// views: ['timelineWeek', 'week'],
115-
// currentView,
116-
// indicatorTime: today,
117-
// currentDate: today,
118-
// });
119-
// });
120-
// });
102+
await statusCheckEql(t, scheduler, title);
103+
}).before(async () => {
104+
await createWidget('dxScheduler', {
105+
timeZone: 'America/Los_Angeles',
106+
dataSource: [{
107+
startDate: '2025-04-29T23:18:00.000Z',
108+
endDate: '2025-04-30T16:12:00.000Z',
109+
}, {
110+
startDate: '2025-04-26T23:18:00.000Z',
111+
endDate: '2025-04-27T12:12:00.000Z',
112+
recurrenceRule: 'FREQ=DAILY;INTERVAL=2;COUNT=5',
113+
}],
114+
views: ['timelineWeek', 'week'],
115+
currentView,
116+
indicatorTime: today,
117+
currentDate: today,
118+
});
119+
});
120+
});

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

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -88,19 +88,21 @@ test('Aria expanded should be toggled true on Ctrl + → keypress', async (t) =>
8888
.expect(expandableRow.getAttribute('aria-expanded'))
8989
.eql('false');
9090

91-
expandableCells.map(async (cell) => {
91+
// eslint-disable-next-line no-restricted-syntax
92+
for (const cell of expandableCells) {
9293
await t.expect(cell.getAttribute('aria-expanded')).eql('false');
93-
});
94+
}
9495

9596
await t
9697
.click(expandableRow)
9798
.pressKey('ctrl+right')
9899
.expect(expandableRow.getAttribute('aria-expanded'))
99100
.eql('true');
100101

101-
expandableCells.map(async (cell) => {
102+
// eslint-disable-next-line no-restricted-syntax
103+
for (const cell of expandableCells) {
102104
await t.expect(cell.getAttribute('aria-expanded')).eql('true');
103-
});
105+
}
104106
}).before(async () => createWidget('dxTreeList', options));
105107

106108
test('Aria expanded should be toggled false on Ctrl + ← keypress', async (t) => {
@@ -118,19 +120,21 @@ test('Aria expanded should be toggled false on Ctrl + ← keypress', async (t) =
118120
.expect(expandableRow.getAttribute('aria-expanded'))
119121
.eql('true');
120122

121-
expandableCells.map(async (cell) => {
123+
// eslint-disable-next-line no-restricted-syntax
124+
for (const cell of expandableCells) {
122125
await t.expect(cell.getAttribute('aria-expanded')).eql('true');
123-
});
126+
}
124127

125128
await t
126129
.click(expandableRow)
127130
.pressKey('ctrl+left')
128131
.expect(expandableRow.getAttribute('aria-expanded'))
129132
.eql('false');
130133

131-
expandableCells.map(async (cell) => {
134+
// eslint-disable-next-line no-restricted-syntax
135+
for (const cell of expandableCells) {
132136
await t.expect(cell.getAttribute('aria-expanded')).eql('false');
133-
});
137+
}
134138
}).before(async () => {
135139
options.expandedRowKeys = [1];
136140
await createWidget('dxTreeList', options);

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,10 @@ test('Ungrouping after grouping should work correctly if row rendering mode is v
304304
test('Scroll position after grouping when RTL (T388508)', async (t) => {
305305
const dataGrid = new DataGrid('#container');
306306

307+
await t
308+
.expect(dataGrid.isReady())
309+
.ok();
310+
307311
// assert
308312
await t
309313
.expect(dataGrid.getScrollLeft())

0 commit comments

Comments
 (0)