Skip to content
This repository was archived by the owner on Apr 18, 2024. It is now read-only.

Commit 9a1a0d3

Browse files
authored
feat: LSDV-5252: Audio player segment visual identification (#1494)
* feat: LSDV-5298: Paragraphs must sync seek, play and pause with Audio in both directions * removing unused SyncMixin * Allow playingId to correctly track over time * updating tests for sync with contextual scrolling on/off * removing unused TimeSync class * adding test for contextual scrolling state change during playback * feat: LSDV-5252: Audio player segment visual identification * fix region loading * adding tests to ensure audio regions do not regress * fix the loading of audio when not synced * trimming down tests ran with both flag states to keep runtime in check * trying to reduce gh action times as it is taking way too long * fix e2e name, was treating as two inputs * linting * we don't want node_modules in the artifacts * download path not required since tar has dir within * remove node_modules from artifact upload of cypress test suite * linting * don't need the download paths now * leave snapshots for comparison * add snapshots for testing audio paragraph segment loading * update test helpers * update to include image snapshot coverage reports * update snapshots * update snapshots * fix px ratio * check just the canvas drawing area to avoid text difference * update snapshots * update snapshots * update to use percentage image diff * fix parallel coverage reports * fix custom tasks * add audio playback tests with paragraph segment audio highlighting * fix linting * fix visual match naming options * remove diff files * put FF setting in a before each
1 parent 0807819 commit 9a1a0d3

22 files changed

+737
-234
lines changed

e2e/tests/audio/audio-regions.test.js

+168-152
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
const { FFlagMatrix, FFlagScenario } = require('../../utils/feature-flags');
2+
13
Feature('Audio Regions');
24

35
const config = `
@@ -73,210 +75,224 @@ const annotations = [
7375
const params = { annotations: [{ id: 'test', result: annotations }], config, data };
7476
const paramsSpeech = { annotations: [{ id: 'test', result: [] }], config: configSpeech, data };
7577

76-
Scenario('Check if regions are selected', async function({ I, LabelStudio, AtAudioView, AtSidebar }) {
77-
LabelStudio.setFeatureFlags({
78-
ff_front_dev_2715_audio_3_280722_short: true,
79-
});
80-
I.amOnPage('/');
78+
FFlagMatrix([
79+
'fflag_feat_front_lsdv_e_278_contextual_scrolling_short',
80+
], function(flags) {
8181

82-
LabelStudio.init(params);
82+
FFlagScenario('Check if regions are selected', async function({ I, LabelStudio, AtAudioView, AtSidebar }) {
83+
LabelStudio.setFeatureFlags({
84+
ff_front_dev_2715_audio_3_280722_short: true,
85+
...flags,
86+
});
87+
I.amOnPage('/');
8388

84-
await AtAudioView.waitForAudio();
85-
await AtAudioView.lookForStage();
89+
LabelStudio.init(params);
8690

87-
AtSidebar.seeRegions(1);
91+
await AtAudioView.waitForAudio();
92+
await AtAudioView.lookForStage();
8893

89-
// creating a new region
90-
I.pressKey('1');
91-
AtAudioView.dragAudioElement(160,80);
92-
I.pressKey('u');
94+
AtSidebar.seeRegions(1);
9395

94-
AtSidebar.seeRegions(2);
96+
// creating a new region
97+
I.pressKey('1');
98+
AtAudioView.dragAudioElement(160,80);
99+
I.pressKey('u');
95100

96-
AtAudioView.clickAt(170);
97-
AtSidebar.seeSelectedRegion();
98-
AtAudioView.clickAt(170);
99-
AtSidebar.dontSeeSelectedRegion();
100-
AtAudioView.dragAudioElement(170,40);
101-
AtSidebar.seeSelectedRegion();
102-
AtAudioView.clickAt(220);
103-
AtSidebar.dontSeeSelectedRegion();
104-
});
101+
AtSidebar.seeRegions(2);
105102

106-
Scenario('Check if multiple regions are working changing labels', async function({ I, LabelStudio, AtAudioView, AtSidebar }) {
107-
LabelStudio.setFeatureFlags({
108-
ff_front_dev_2715_audio_3_280722_short: true,
103+
AtAudioView.clickAt(170);
104+
AtSidebar.seeSelectedRegion();
105+
AtAudioView.clickAt(170);
106+
AtSidebar.dontSeeSelectedRegion();
107+
AtAudioView.dragAudioElement(170,40);
108+
AtSidebar.seeSelectedRegion();
109+
AtAudioView.clickAt(220);
110+
AtSidebar.dontSeeSelectedRegion();
109111
});
110-
I.amOnPage('/');
111112

112-
LabelStudio.init(paramsSpeech);
113+
// Don't need to test this for both scenarios of flags, as it is the same code and is verified in the above test
114+
if (!flags['fflag_feat_front_lsdv_e_278_contextual_scrolling_short']) {
115+
FFlagScenario('Check if multiple regions are working changing labels', async function({ I, LabelStudio, AtAudioView, AtSidebar }) {
116+
LabelStudio.setFeatureFlags({
117+
ff_front_dev_2715_audio_3_280722_short: true,
118+
...flags,
119+
});
120+
I.amOnPage('/');
113121

114-
await AtAudioView.waitForAudio();
115-
await AtAudioView.lookForStage();
122+
LabelStudio.init(paramsSpeech);
116123

117-
for (let i = 0; i < 20; i++) {
118-
// creating a new region
119-
I.pressKey('1');
120-
AtAudioView.dragAudioElement((40 * i) + 10,30);
121-
AtAudioView.clickAt((40 * i) + 20);
122-
I.pressKey('2');
123-
I.pressKey('1');
124-
I.pressKey('u');
125-
}
124+
await AtAudioView.waitForAudio();
125+
await AtAudioView.lookForStage();
126126

127-
AtSidebar.seeRegions(20);
127+
for (let i = 0; i < 20; i++) {
128+
// creating a new region
129+
I.pressKey('1');
130+
AtAudioView.dragAudioElement((40 * i) + 10,30);
131+
AtAudioView.clickAt((40 * i) + 20);
132+
I.pressKey('2');
133+
I.pressKey('1');
134+
I.pressKey('u');
135+
}
128136

129-
for (let i = 0; i < 20; i++) {
130-
// creating a new region
131-
AtAudioView.clickAt((40 * i) + 20);
132-
AtSidebar.seeSelectedRegion();
133-
I.pressKey('u');
134-
}
137+
AtSidebar.seeRegions(20);
135138

136-
AtSidebar.seeRegions(20);
139+
for (let i = 0; i < 20; i++) {
140+
// creating a new region
141+
AtAudioView.clickAt((40 * i) + 20);
142+
AtSidebar.seeSelectedRegion();
143+
I.pressKey('u');
144+
}
137145

138-
I.pressKey('u');
146+
AtSidebar.seeRegions(20);
139147

140-
AtSidebar.dontSeeSelectedRegion();
141-
});
148+
I.pressKey('u');
142149

143-
Scenario('Can select a region below a hidden region', async function({ I, LabelStudio, AtAudioView, AtSidebar }) {
144-
LabelStudio.setFeatureFlags({
145-
ff_front_dev_2715_audio_3_280722_short: true,
146-
});
147-
I.amOnPage('/');
150+
AtSidebar.dontSeeSelectedRegion();
151+
});
148152

149-
LabelStudio.init(paramsSpeech);
153+
FFlagScenario('Can select a region below a hidden region', async function({ I, LabelStudio, AtAudioView, AtSidebar }) {
154+
LabelStudio.setFeatureFlags({
155+
ff_front_dev_2715_audio_3_280722_short: true,
156+
...flags,
157+
});
158+
I.amOnPage('/');
150159

151-
await AtAudioView.waitForAudio();
152-
await AtAudioView.lookForStage();
160+
LabelStudio.init(paramsSpeech);
153161

154-
// create a new region
155-
I.pressKey('1');
156-
AtAudioView.dragAudioElement(50, 80);
157-
I.pressKey('u');
162+
await AtAudioView.waitForAudio();
163+
await AtAudioView.lookForStage();
158164

159-
AtSidebar.seeRegions(1);
165+
// create a new region
166+
I.pressKey('1');
167+
AtAudioView.dragAudioElement(50, 80);
168+
I.pressKey('u');
160169

161-
// create a new region above the first one
162-
I.pressKey('2');
163-
AtAudioView.dragAudioElement(49, 81);
164-
I.pressKey('u');
170+
AtSidebar.seeRegions(1);
165171

166-
AtSidebar.seeRegions(2);
172+
// create a new region above the first one
173+
I.pressKey('2');
174+
AtAudioView.dragAudioElement(49, 81);
175+
I.pressKey('u');
167176

168-
// click on the top-most region visible to select it
169-
AtAudioView.clickAt(50);
170-
AtSidebar.seeSelectedRegion('Noise');
177+
AtSidebar.seeRegions(2);
171178

172-
// hide the region
173-
AtSidebar.hideRegion('Noise');
179+
// click on the top-most region visible to select it
180+
AtAudioView.clickAt(50);
181+
AtSidebar.seeSelectedRegion('Noise');
174182

175-
// click on the region below the hidden one to select it
176-
AtAudioView.clickAt(50);
177-
AtSidebar.seeSelectedRegion('Speech');
178-
});
183+
// hide the region
184+
AtSidebar.hideRegion('Noise');
179185

180-
Scenario('Selecting a region brings it to the front of the stack', async function({ I, LabelStudio, AtAudioView, AtSidebar }) {
181-
LabelStudio.setFeatureFlags({
182-
ff_front_dev_2715_audio_3_280722_short: true,
183-
});
184-
I.amOnPage('/');
186+
// click on the region below the hidden one to select it
187+
AtAudioView.clickAt(50);
188+
AtSidebar.seeSelectedRegion('Speech');
189+
});
185190

186-
LabelStudio.init(paramsSpeech);
191+
FFlagScenario('Selecting a region brings it to the front of the stack', async function({ I, LabelStudio, AtAudioView, AtSidebar }) {
192+
LabelStudio.setFeatureFlags({
193+
ff_front_dev_2715_audio_3_280722_short: true,
194+
...flags,
195+
});
196+
I.amOnPage('/');
187197

188-
await AtAudioView.waitForAudio();
189-
await AtAudioView.lookForStage();
198+
LabelStudio.init(paramsSpeech);
190199

191-
// create a new region
192-
I.pressKey('1');
193-
AtAudioView.dragAudioElement(50, 80);
194-
I.pressKey('u');
200+
await AtAudioView.waitForAudio();
201+
await AtAudioView.lookForStage();
195202

196-
AtSidebar.seeRegions(1);
203+
// create a new region
204+
I.pressKey('1');
205+
AtAudioView.dragAudioElement(50, 80);
206+
I.pressKey('u');
197207

198-
// create a new region above the first one
199-
I.pressKey('2');
200-
AtAudioView.dragAudioElement(49, 81);
201-
I.pressKey('u');
208+
AtSidebar.seeRegions(1);
202209

203-
AtSidebar.seeRegions(2);
210+
// create a new region above the first one
211+
I.pressKey('2');
212+
AtAudioView.dragAudioElement(49, 81);
213+
I.pressKey('u');
204214

205-
// click on the top-most region visible to select it
206-
AtAudioView.clickAt(50);
207-
AtSidebar.seeSelectedRegion('Noise');
215+
AtSidebar.seeRegions(2);
208216

209-
// Select the bottom most region to bring it to the top
210-
AtSidebar.clickRegion('Speech');
211-
AtSidebar.seeSelectedRegion('Speech');
217+
// click on the top-most region visible to select it
218+
AtAudioView.clickAt(50);
219+
AtSidebar.seeSelectedRegion('Noise');
212220

213-
// click on the overlapping region will deselect it, which shows that it is now the top in the list
214-
AtAudioView.clickAt(50);
215-
AtSidebar.dontSeeSelectedRegion('Speech');
216-
AtSidebar.dontSeeSelectedRegion('Noise');
221+
// Select the bottom most region to bring it to the top
222+
AtSidebar.clickRegion('Speech');
223+
AtSidebar.seeSelectedRegion('Speech');
217224

218-
// click on the overlapping region will select the top item of the list, which will now be the item which was brought to the front by the original interaction.
219-
AtAudioView.clickAt(50);
220-
AtSidebar.seeSelectedRegion('Speech');
221-
});
225+
// click on the overlapping region will deselect it, which shows that it is now the top in the list
226+
AtAudioView.clickAt(50);
227+
AtSidebar.dontSeeSelectedRegion('Speech');
228+
AtSidebar.dontSeeSelectedRegion('Noise');
222229

223-
Scenario('Delete region by pressing delete hotkey', async function({ I, LabelStudio, AtAudioView, AtSidebar }) {
224-
LabelStudio.setFeatureFlags({
225-
ff_front_dev_2715_audio_3_280722_short: true,
226-
});
227-
I.amOnPage('/');
230+
// click on the overlapping region will select the top item of the list, which will now be the item which was brought to the front by the original interaction.
231+
AtAudioView.clickAt(50);
232+
AtSidebar.seeSelectedRegion('Speech');
233+
});
228234

229-
LabelStudio.init(params);
235+
FFlagScenario('Delete region by pressing delete hotkey', async function({ I, LabelStudio, AtAudioView, AtSidebar }) {
236+
LabelStudio.setFeatureFlags({
237+
ff_front_dev_2715_audio_3_280722_short: true,
238+
...flags,
239+
});
240+
I.amOnPage('/');
230241

231-
await AtAudioView.waitForAudio();
232-
await AtAudioView.lookForStage();
242+
LabelStudio.init(params);
233243

234-
AtSidebar.seeRegions(1);
244+
await AtAudioView.waitForAudio();
245+
await AtAudioView.lookForStage();
235246

236-
// creating a new region
237-
AtAudioView.dragAudioElement(160,80);
247+
AtSidebar.seeRegions(1);
238248

239-
I.pressKey('Delete');
249+
// creating a new region
250+
AtAudioView.dragAudioElement(160,80);
240251

241-
I.pressKey('1');
252+
I.pressKey('Delete');
242253

243-
AtSidebar.seeRegions(1);
244-
});
254+
I.pressKey('1');
245255

246-
Scenario('Check if there are ghost regions', async function({ I, LabelStudio, AtAudioView, AtSidebar }) {
247-
LabelStudio.setFeatureFlags({
248-
ff_front_dev_2715_audio_3_280722_short: true,
249-
});
250-
I.amOnPage('/');
256+
AtSidebar.seeRegions(1);
257+
});
258+
259+
FFlagScenario('Check if there are ghost regions', async function({ I, LabelStudio, AtAudioView, AtSidebar }) {
260+
LabelStudio.setFeatureFlags({
261+
ff_front_dev_2715_audio_3_280722_short: true,
262+
...flags,
263+
});
264+
I.amOnPage('/');
251265

252-
LabelStudio.init(paramsSpeech);
266+
LabelStudio.init(paramsSpeech);
253267

254-
await AtAudioView.waitForAudio();
255-
await AtAudioView.lookForStage();
268+
await AtAudioView.waitForAudio();
269+
await AtAudioView.lookForStage();
256270

257-
// creating a new region
258-
I.pressKey('1');
259-
AtAudioView.dragAudioElement(300,80);
260-
I.pressKey('u');
271+
// creating a new region
272+
I.pressKey('1');
273+
AtAudioView.dragAudioElement(300,80);
274+
I.pressKey('u');
261275

262276

263-
// creating a ghost region
264-
I.pressKey('1');
265-
AtAudioView.dragAudioElement(160,80, false);
266-
I.pressKey('1');
267-
I.wait(1);
268-
I.pressMouseUp();
269-
I.wait(1);
277+
// creating a ghost region
278+
I.pressKey('1');
279+
AtAudioView.dragAudioElement(160,80, false);
280+
I.pressKey('1');
281+
I.wait(1);
282+
I.pressMouseUp();
283+
I.wait(1);
270284

271-
// checking if the created region is selected
272-
AtAudioView.clickAt(310);
273-
AtSidebar.seeSelectedRegion();
285+
// checking if the created region is selected
286+
AtAudioView.clickAt(310);
287+
AtSidebar.seeSelectedRegion();
274288

275-
// trying to select the ghost region, if there is no ghost region, the region will keep selected
276-
// as ghost region is not selectable and impossible to change the label, the created region will be deselected if there is a ghost region created.
277-
AtAudioView.clickAt(170);
278-
I.pressKey('2');
279-
AtSidebar.seeSelectedRegion();
289+
// trying to select the ghost region, if there is no ghost region, the region will keep selected
290+
// as ghost region is not selectable and impossible to change the label, the created region will be deselected if there is a ghost region created.
291+
AtAudioView.clickAt(170);
292+
I.pressKey('2');
293+
AtSidebar.seeSelectedRegion();
280294

281-
AtSidebar.seeRegions(2);
295+
AtSidebar.seeRegions(2);
296+
});
297+
}
282298
});

src/components/TimeDurationControl/TimeBox.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export const TimeBox: FC<TimerProps> = ({
1818
inverted = false,
1919
readonly = false,
2020
onChange,
21+
...props
2122
}) => {
2223
const inputRef = React.createRef<HTMLInputElement>();
2324
const [currentInputTime, setCurrentInputTime] = useState<string | number | undefined>(value);
@@ -100,7 +101,7 @@ export const TimeBox: FC<TimerProps> = ({
100101
};
101102

102103
return (
103-
<Block name="time-box" mod={{ inverted, sidepanel }}>
104+
<Block name="time-box" mod={{ inverted, sidepanel }} {...props}>
104105
{renderInputTime()}
105106
</Block>
106107
);

0 commit comments

Comments
 (0)