1+ const assert = require ( 'assert' ) ;
2+
13Feature ( 'Skip duplicates (textarea)' ) ;
24
35const SKIP_DUPLICATES_ERROR = 'There is already an entry with that text. Please enter unique text.' ;
@@ -206,4 +208,321 @@ Scenario('Independent skip duplicate values', async ({ I, LabelStudio, AtSidebar
206208 I . pressKey ( 'Enter' ) ;
207209
208210 Modals . dontSeeWarning ( SKIP_DUPLICATES_ERROR ) ;
209- } ) ;
211+ } ) ;
212+
213+ Scenario ( 'Skip duplicate values on editing' , async ( { I, LabelStudio, AtOutliner, Modals } ) => {
214+ I . amOnPage ( '/' ) ;
215+ LabelStudio . setFeatureFlags ( {
216+ ff_front_1170_outliner_030222_short : true ,
217+ } ) ;
218+ LabelStudio . init ( {
219+ data : { letter : 'Aa' } ,
220+ config : `<View>
221+ <Text name="letter" value="$letter"/>
222+ <Labels name="label" toName="letter">
223+ <Label value="Letter A" background="yellow"/>
224+ </Labels>
225+ <TextArea name="perText" toName="letter" skipDuplicates="true" editable="true"/>
226+ <TextArea name="perRegion" toName="letter" skipDuplicates="true" perRegion="true" maxsubmissions="5" editable="true"/>
227+ <TextArea name="perRegionAndAside" toName="letter" skipDuplicates="true" perRegion="true" maxsubmissions="5" displayMode="region-list" editable="true"/>
228+ </View>` ,
229+ annotations : [ {
230+ id : 'test' ,
231+ result : [
232+ {
233+ id : 'letter_A' ,
234+ from_name : 'label' ,
235+ to_name : 'letter' ,
236+ type : 'labels' ,
237+ value : { start : 0 , end : 1 , labels : [ 'Letter A' ] , text : 'A' } ,
238+ } ,
239+ {
240+ id : 'letter_a' ,
241+ from_name : 'label' ,
242+ to_name : 'letter' ,
243+ type : 'labels' ,
244+ value : { start : 1 , end : 2 , labels : [ 'Letter A' ] , text : 'a' } ,
245+ } ,
246+ ] ,
247+ } ] ,
248+ } ) ;
249+ LabelStudio . waitForObjectsReady ( ) ;
250+ AtOutliner . seeRegions ( 2 ) ;
251+
252+ I . say ( 'Check perText Textarea regions editing' ) ;
253+ {
254+ I . say ( 'Create some random values in perText Textarea' ) ;
255+ I . fillField ( '[name="perText"]' , 'A' ) ;
256+ I . pressKey ( 'Enter' ) ;
257+ I . fillField ( '[name="perText"]' , '1' ) ;
258+ I . pressKey ( 'Enter' ) ;
259+ I . fillField ( '[name="perText"]' , 'letter' ) ;
260+ I . pressKey ( 'Enter' ) ;
261+ I . fillField ( '[name="perText"]' , 'last' ) ;
262+ I . pressKey ( 'Enter' ) ;
263+
264+ I . say ( 'Try to create duplicate value by editing' ) ;
265+
266+ I . click ( locate ( '[aria-label="Edit Region"]' ) . inside ( '[data-testid="textarea-region"]' ) . at ( 2 ) , locate ( '.lsf-text-area' ) . at ( 1 ) ) ;
267+ I . pressKey ( 'Backspace' ) ;
268+ I . pressKey ( 'A' ) ;
269+ I . pressKey ( 'Enter' ) ;
270+
271+ Modals . seeWarning ( SKIP_DUPLICATES_ERROR ) ;
272+ Modals . closeWarning ( ) ;
273+
274+ I . say ( 'Check that these changes were not committed' ) ;
275+
276+ I . see ( '1' , locate ( '.lsf-text-area' ) . at ( 1 ) . find ( locate ( './/*[./@data-testid = \'textarea-region\'][position()=2]' ) ) ) ;
277+ I . dontSee ( 'A' , locate ( '.lsf-text-area' ) . at ( 1 ) . find ( locate ( './/*[./@data-testid = \'textarea-region\'][position()=2]' ) ) ) ;
278+
279+ I . say ( 'Delete second region and check results after that' ) ;
280+ I . click ( locate ( '[aria-label="Delete Region"]' ) , locate ( '.lsf-text-area' ) . at ( 1 ) . find ( locate ( './/*[./@data-testid = \'textarea-region\'][position()=2]' ) ) ) ;
281+
282+ I . see ( 'A' , locate ( '.lsf-text-area' ) . at ( 1 ) . find ( locate ( './/*[./@data-testid = \'textarea-region\'][position()=1]' ) ) ) ;
283+ I . see ( 'letter' , locate ( '.lsf-text-area' ) . at ( 1 ) . find ( locate ( './/*[./@data-testid = \'textarea-region\'][position()=2]' ) ) ) ;
284+ I . see ( 'last' , locate ( '.lsf-text-area' ) . at ( 1 ) . find ( locate ( './/*[./@data-testid = \'textarea-region\'][position()=3]' ) ) ) ;
285+
286+ {
287+ const result = await LabelStudio . serialize ( ) ;
288+
289+ assert . deepStrictEqual (
290+ result [ 2 ] . value . text ,
291+ [ 'A' , 'letter' , 'last' ] ,
292+ `There should be 3 specific text lines in the textarea result: ${ JSON . stringify ( [ 'A' , 'letter' , 'last' ] ) } but ${ result [ 2 ] . value . text } was given.` ,
293+ ) ;
294+ }
295+
296+ I . say ( 'Check that skip duplication allow us to keep the same value after editing without errors' ) ;
297+
298+ I . click ( locate ( '[aria-label="Edit Region"]' ) . inside ( '[data-testid="textarea-region"]' ) . at ( 2 ) , locate ( '.lsf-text-area' ) . at ( 1 ) ) ;
299+ I . pressKey ( [ 'CommandOrControl' , 'a' ] ) ;
300+ I . pressKey ( 'Backspace' ) ;
301+ Array . from ( 'letter' ) . forEach ( v => {
302+ I . pressKey ( v ) ;
303+ } ) ;
304+ I . pressKey ( 'Enter' ) ;
305+
306+ I . see ( 'letter' , locate ( '.lsf-text-area' ) . at ( 1 ) . find ( locate ( './/*[./@data-testid = \'textarea-region\'][position()=2]' ) ) ) ;
307+ Modals . dontSeeWarning ( SKIP_DUPLICATES_ERROR ) ;
308+
309+ {
310+ const result = await LabelStudio . serialize ( ) ;
311+
312+ assert . deepStrictEqual (
313+ result [ 2 ] . value . text ,
314+ [ 'A' , 'letter' , 'last' ] ,
315+ `There should be 3 specific text lines in the textarea result: ${ JSON . stringify ( [ 'A' , 'letter' , 'last' ] ) } but ${ result [ 2 ] . value . text } was given.` ,
316+ ) ;
317+ }
318+
319+ I . say ( 'Check that skip duplication allow us to set different value by editing and do not get errors' ) ;
320+
321+ I . click ( locate ( '[aria-label="Edit Region"]' ) . inside ( '[data-testid="textarea-region"]' ) . at ( 2 ) , locate ( '.lsf-text-area' ) . at ( 1 ) ) ;
322+ I . pressKey ( [ 'CommandOrControl' , 'a' ] ) ;
323+ I . pressKey ( 'Backspace' ) ;
324+ Array . from ( 'other' ) . forEach ( v => {
325+ I . pressKey ( v ) ;
326+ } ) ;
327+ I . pressKey ( 'Enter' ) ;
328+
329+ I . see ( 'other' , locate ( '.lsf-text-area' ) . at ( 1 ) . find ( locate ( './/*[./@data-testid = \'textarea-region\'][position()=2]' ) ) ) ;
330+ Modals . dontSeeWarning ( SKIP_DUPLICATES_ERROR ) ;
331+
332+ {
333+ const result = await LabelStudio . serialize ( ) ;
334+
335+ assert . deepStrictEqual (
336+ result [ 2 ] . value . text ,
337+ [ 'A' , 'other' , 'last' ] ,
338+ `There should be 3 specific text lines in the textarea result: ${ JSON . stringify ( [ 'A' , 'other' , 'last' ] ) } but ${ result [ 2 ] . value . text } was given.` ,
339+ ) ;
340+ }
341+ }
342+
343+ I . say ( 'Check perRegion Textarea regions editing' ) ;
344+ {
345+ AtOutliner . clickRegion ( 1 ) ;
346+ I . say ( 'Create some random values in perRegion Textarea' ) ;
347+ I . fillField ( '[name="perRegion"]' , 'a' ) ;
348+ I . pressKey ( 'Enter' ) ;
349+ I . fillField ( '[name="perRegion"]' , '1' ) ;
350+ I . pressKey ( 'Enter' ) ;
351+ I . fillField ( '[name="perRegion"]' , 'letter' ) ;
352+ I . pressKey ( 'Enter' ) ;
353+ I . fillField ( '[name="perRegion"]' , 'last' ) ;
354+ I . pressKey ( 'Enter' ) ;
355+
356+ I . say ( 'Try to create duplicate value by editing' ) ;
357+
358+ I . click ( locate ( '[aria-label="Edit Region"]' ) . inside ( '[data-testid="textarea-region"]' ) . at ( 2 ) , locate ( '.lsf-text-area' ) . at ( 2 ) ) ;
359+ I . pressKey ( 'Backspace' ) ;
360+ I . pressKey ( 'a' ) ;
361+ I . pressKey ( 'Enter' ) ;
362+
363+ Modals . seeWarning ( SKIP_DUPLICATES_ERROR ) ;
364+ Modals . closeWarning ( ) ;
365+
366+ I . say ( 'Check that these changes were not committed' ) ;
367+ I . see ( '1' , locate ( '.lsf-text-area' ) . at ( 2 ) . find ( locate ( './/*[./@data-testid = \'textarea-region\'][position()=2]' ) ) ) ;
368+ I . dontSee ( 'a' , locate ( '.lsf-text-area' ) . at ( 2 ) . find ( locate ( './/*[./@data-testid = \'textarea-region\'][position()=2]' ) ) ) ;
369+
370+ I . say ( 'Delete second region and check results after that' ) ;
371+ I . click ( locate ( '[aria-label="Delete Region"]' ) , locate ( '.lsf-text-area' ) . at ( 2 ) . find ( locate ( './/*[./@data-testid = \'textarea-region\'][position()=2]' ) ) ) ;
372+
373+ I . see ( 'a' , locate ( '.lsf-text-area' ) . at ( 2 ) . find ( locate ( './/*[./@data-testid = \'textarea-region\'][position()=1]' ) ) ) ;
374+ I . see ( 'letter' , locate ( '.lsf-text-area' ) . at ( 2 ) . find ( locate ( './/*[./@data-testid = \'textarea-region\'][position()=2]' ) ) ) ;
375+ I . see ( 'last' , locate ( '.lsf-text-area' ) . at ( 2 ) . find ( locate ( './/*[./@data-testid = \'textarea-region\'][position()=3]' ) ) ) ;
376+
377+ {
378+ const result = await LabelStudio . serialize ( ) ;
379+
380+ assert . deepStrictEqual (
381+ result [ 1 ] . value . text ,
382+ [ 'a' , 'letter' , 'last' ] ,
383+ `There should be 3 specific text lines in the textarea result: ${ JSON . stringify ( [ 'a' , 'letter' , 'last' ] ) } but ${ result [ 1 ] . value . text } was given.` ,
384+ ) ;
385+ }
386+
387+ I . say ( 'Check that skip duplication allow us to keep the same value after editing without errors' ) ;
388+
389+ I . click ( locate ( '[aria-label="Edit Region"]' ) . inside ( '[data-testid="textarea-region"]' ) . at ( 2 ) , locate ( '.lsf-text-area' ) . at ( 2 ) ) ;
390+ I . pressKey ( [ 'CommandOrControl' , 'a' ] ) ;
391+ I . pressKey ( 'Backspace' ) ;
392+ Array . from ( 'letter' ) . forEach ( v => {
393+ I . pressKey ( v ) ;
394+ } ) ;
395+ I . pressKey ( 'Enter' ) ;
396+
397+ I . see ( 'letter' , locate ( '.lsf-text-area' ) . at ( 2 ) . find ( locate ( './/*[./@data-testid = \'textarea-region\'][position()=2]' ) ) ) ;
398+ Modals . dontSeeWarning ( SKIP_DUPLICATES_ERROR ) ;
399+
400+ {
401+ const result = await LabelStudio . serialize ( ) ;
402+
403+ assert . deepStrictEqual (
404+ result [ 1 ] . value . text ,
405+ [ 'a' , 'letter' , 'last' ] ,
406+ `There should be 3 specific text lines in the textarea result: ${ JSON . stringify ( [ 'a' , 'letter' , 'last' ] ) } but ${ result [ 1 ] . value . text } was given.` ,
407+ ) ;
408+ }
409+
410+ I . say ( 'Check that skip duplication allow us to set different value by editing and do not get errors' ) ;
411+
412+ I . click ( locate ( '[aria-label="Edit Region"]' ) . inside ( '[data-testid="textarea-region"]' ) . at ( 2 ) , locate ( '.lsf-text-area' ) . at ( 2 ) ) ;
413+ I . pressKey ( [ 'CommandOrControl' , 'a' ] ) ;
414+ I . pressKey ( 'Backspace' ) ;
415+ Array . from ( 'other' ) . forEach ( v => {
416+ I . pressKey ( v ) ;
417+ } ) ;
418+ I . pressKey ( 'Enter' ) ;
419+
420+ I . see ( 'other' , locate ( '.lsf-text-area' ) . at ( 2 ) . find ( locate ( './/*[./@data-testid = \'textarea-region\'][position()=2]' ) ) ) ;
421+ Modals . dontSeeWarning ( SKIP_DUPLICATES_ERROR ) ;
422+
423+ {
424+ const result = await LabelStudio . serialize ( ) ;
425+
426+ assert . deepStrictEqual (
427+ result [ 1 ] . value . text ,
428+ [ 'a' , 'other' , 'last' ] ,
429+ `There should be 3 specific text lines in the textarea result: ${ JSON . stringify ( [ 'a' , 'other' , 'last' ] ) } but ${ result [ 1 ] . value . text } was given.` ,
430+ ) ;
431+ }
432+ }
433+
434+ I . say ( 'Check ocr-like perRegion Textarea regions editing' ) ;
435+ {
436+ AtOutliner . clickRegion ( 2 ) ;
437+
438+ I . say ( 'Create some random values in ocr-like perRegion Textarea' ) ;
439+ I . fillField ( AtOutliner . locateSelectedItem ( '.lsf-textarea-tag__form input' ) , 'One' ) ;
440+ I . pressKey ( 'Enter' ) ;
441+ I . fillField ( AtOutliner . locateSelectedItem ( '.lsf-textarea-tag__form input' ) , 'Two' ) ;
442+ I . pressKey ( 'Enter' ) ;
443+ I . fillField ( AtOutliner . locateSelectedItem ( '.lsf-textarea-tag__form input' ) , 'Three' ) ;
444+ I . pressKey ( 'Enter' ) ;
445+ I . fillField ( AtOutliner . locateSelectedItem ( '.lsf-textarea-tag__form input' ) , 'Four' ) ;
446+ I . pressKey ( 'Enter' ) ;
447+
448+ I . say ( 'Try to create duplicate value by editing' ) ;
449+
450+ I . click ( AtOutliner . locateSelectedItem ( locate ( '.lsf-textarea-tag__item:nth-child(2) input' ) ) ) ;
451+ I . pressKey ( [ 'CommandOrControl' , 'a' ] ) ;
452+ I . pressKey ( 'Backspace' ) ;
453+ I . pressKey ( 'O' ) ;
454+ I . pressKey ( 'n' ) ;
455+ I . pressKey ( 'e' ) ;
456+ I . pressKey ( 'Enter' ) ;
457+
458+ Modals . seeWarning ( SKIP_DUPLICATES_ERROR ) ;
459+ Modals . closeWarning ( ) ;
460+
461+ I . say ( 'Check that these changes were not committed' ) ;
462+ I . seeInField ( AtOutliner . locateSelectedItem ( locate ( '.lsf-textarea-tag__item:nth-child(2) input' ) ) , 'Two' ) ;
463+ I . dontSeeInField ( AtOutliner . locateSelectedItem ( locate ( '.lsf-textarea-tag__item:nth-child(2) input' ) ) , 'One' ) ;
464+
465+ I . say ( 'Delete second region and check results after that' ) ;
466+ I . click ( locate ( '[aria-label="Delete Region"]' ) , AtOutliner . locateSelectedItem ( locate ( '.lsf-textarea-tag__item:nth-child(2)' ) ) ) ;
467+
468+ I . seeInField ( AtOutliner . locateSelectedItem ( locate ( '.lsf-textarea-tag__item:nth-child(1) input' ) ) , 'One' ) ;
469+ I . seeInField ( AtOutliner . locateSelectedItem ( locate ( '.lsf-textarea-tag__item:nth-child(2) input' ) ) , 'Three' ) ;
470+ I . seeInField ( AtOutliner . locateSelectedItem ( locate ( '.lsf-textarea-tag__item:nth-child(3) input' ) ) , 'Four' ) ;
471+
472+ {
473+ const result = await LabelStudio . serialize ( ) ;
474+
475+ assert . deepStrictEqual (
476+ result [ 3 ] . value . text ,
477+ [ 'One' , 'Three' , 'Four' ] ,
478+ `There should be 3 specific text lines in the textarea result: ${ JSON . stringify ( [ 'One' , 'Three' , 'Four' ] ) } but ${ result [ 3 ] . value . text } was given.` ,
479+ ) ;
480+ }
481+
482+ I . say ( 'Check that skip duplication allow us to keep the same value after editing without errors' ) ;
483+
484+ I . click ( AtOutliner . locateSelectedItem ( locate ( '.lsf-textarea-tag__item:nth-child(2) input' ) ) ) ;
485+ I . pressKey ( [ 'CommandOrControl' , 'a' ] ) ;
486+ I . pressKey ( 'Backspace' ) ;
487+ Array . from ( 'Three' ) . forEach ( v => {
488+ I . pressKey ( v ) ;
489+ } ) ;
490+ I . pressKey ( 'Enter' ) ;
491+
492+ I . seeInField ( AtOutliner . locateSelectedItem ( locate ( '.lsf-textarea-tag__item:nth-child(2) input' ) ) , 'Three' ) ;
493+ Modals . dontSeeWarning ( SKIP_DUPLICATES_ERROR ) ;
494+
495+ {
496+ const result = await LabelStudio . serialize ( ) ;
497+
498+ assert . deepStrictEqual (
499+ result [ 3 ] . value . text ,
500+ [ 'One' , 'Three' , 'Four' ] ,
501+ `There should be 3 specific text lines in the textarea result: ${ JSON . stringify ( [ 'One' , 'Three' , 'Four' ] ) } but ${ result [ 3 ] . value . text } was given.` ,
502+ ) ;
503+ }
504+
505+ I . say ( 'Check that skip duplication allow us to set different value by editing and do not get errors' ) ;
506+
507+ I . click ( AtOutliner . locateSelectedItem ( locate ( '.lsf-textarea-tag__item:nth-child(2) input' ) ) ) ;
508+ I . pressKey ( [ 'CommandOrControl' , 'a' ] ) ;
509+ I . pressKey ( 'Backspace' ) ;
510+ Array . from ( 'other' ) . forEach ( v => {
511+ I . pressKey ( v ) ;
512+ } ) ;
513+ I . pressKey ( 'Enter' ) ;
514+
515+ I . seeInField ( AtOutliner . locateSelectedItem ( locate ( '.lsf-textarea-tag__item:nth-child(2) input' ) ) , 'other' ) ;
516+ Modals . dontSeeWarning ( SKIP_DUPLICATES_ERROR ) ;
517+
518+ {
519+ const result = await LabelStudio . serialize ( ) ;
520+
521+ assert . deepStrictEqual (
522+ result [ 3 ] . value . text ,
523+ [ 'One' , 'other' , 'Four' ] ,
524+ `There should be 3 specific text lines in the textarea result: ${ JSON . stringify ( [ 'One' , 'other' , 'Four' ] ) } but ${ result [ 3 ] . value . text } was given.` ,
525+ ) ;
526+ }
527+ }
528+ } ) ;
0 commit comments