required.test.js 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. Feature("Test required param");
  2. const createConfig = ({ visibleWhen = "choice-selected" } = {}) => {
  3. return `
  4. <View>
  5. <Text name="text" value="$text"></Text>
  6. <Choices name="validation-label" required="true" toName="text">
  7. <Choice value="Missing words" alias="missing-words"></Choice>
  8. <Choice value="Valid" alias="valid"></Choice>
  9. </Choices>
  10. <Choices name="second" required="true" toName="text">
  11. <Choice value="Don't select me" alias="dont"></Choice>
  12. <Choice value="Me neither" alias="neither"></Choice>
  13. </Choices>
  14. <Choices name="easter-egg" required="true" toName="text"
  15. visibleWhen="${visibleWhen}"
  16. whenTagName="second"
  17. whenChoiceValue="Me neither"
  18. >
  19. <Choice value="Secret level"></Choice>
  20. <Choice value="Click on me now"></Choice>
  21. </Choices>
  22. </View>
  23. `;
  24. };
  25. const complex = `
  26. <View>
  27. <Text name="text" value="$text"></Text>
  28. <Labels name="toggle">
  29. <Label value="Hidden" />
  30. <Label value="Useless" />
  31. </Labels>
  32. <View>(select region to see more required controls)</View>
  33. <View visibleWhen="region-selected">
  34. <Header>Required per-region choices</Header>
  35. <Choices name="validation-label" required="true" toName="text" perRegion="true">
  36. <Choice value="Missing words" alias="missing-words"></Choice>
  37. <Choice value="Valid" alias="valid"></Choice>
  38. </Choices>
  39. </View>
  40. <Header>Required common description</Header>
  41. <Textarea name="common-description" toName="text" required="true" />
  42. <View visibleWhen="region-selected">
  43. <Header>Required region description</Header>
  44. <Textarea name="region-description" toName="text" required="true" perRegion="true" />
  45. </View>
  46. <Header>Nested controls are required, but only when you select one of those:</Header>
  47. <Choices name="switch" toName="text">
  48. <Choice value="Required textarea" alias="dont"></Choice>
  49. <Choice value="Required choices" alias="neither"></Choice>
  50. </Choices>
  51. <View visibleWhen="choice-selected"
  52. whenTagName="switch"
  53. whenChoiceValue="Required textarea">
  54. <Header>Required only when "Required textarea" selected</Header>
  55. <Textarea name="choice-description" toName="text" required="true" />
  56. </View>
  57. <View visibleWhen="choice-selected"
  58. whenTagName="switch"
  59. whenChoiceValue="Required choices">
  60. <Header>Required only when "Required choices" selected</Header>
  61. <Choices name="choice" toName="text" required="true">
  62. <Choice value="Don't select me" alias="dont"></Choice>
  63. <Choice value="Me neither" alias="neither"></Choice>
  64. </Choices>
  65. </View>
  66. </View>
  67. `;
  68. const text = "To have faith is to trust yourself to the water";
  69. const result = {
  70. id: "qwerty",
  71. from_name: "toggle",
  72. to_name: "text",
  73. type: "labels",
  74. origin: "manual",
  75. value: { start: 3, end: 7, labels: ["Hidden"] },
  76. };
  77. const annotations = [{ id: "1", result: [result] }];
  78. Scenario("Check required param", async ({ I, LabelStudio, Modals }) => {
  79. const params = { config: createConfig(), data: { text } };
  80. const waitForError = (name) => {
  81. Modals.seeWarning(`Checkbox "${name}" is required`);
  82. Modals.closeWarning();
  83. };
  84. I.amOnPage("/");
  85. LabelStudio.init(params);
  86. // Add new Annotation to be able to submit it
  87. I.click('[aria-label="Annotations List Toggle"]');
  88. I.click('[aria-label="Create Annotation"]');
  89. I.submitAnnotation();
  90. waitForError("validation-label");
  91. I.click("Me neither");
  92. I.submitAnnotation();
  93. waitForError("validation-label");
  94. I.click("Valid");
  95. I.submitAnnotation();
  96. waitForError("easter-egg");
  97. I.click("Don't select me");
  98. I.submitAnnotation();
  99. // Annotation is submitted, so now we can only update it
  100. I.seeAnnotationSubmitted();
  101. // Reload to check another combination
  102. LabelStudio.init(params);
  103. // Page is reloaded, there are no new annotation from prev steps
  104. I.dontSee("New annotation");
  105. I.click('[aria-label="Annotations List Toggle"]');
  106. I.click('[aria-label="Create Annotation"]');
  107. I.click("Valid");
  108. I.submitAnnotation();
  109. I.see("Warning");
  110. I.see('Checkbox "second" is required');
  111. });
  112. Scenario("Check required param in complex config", async ({ I, LabelStudio, AtOutliner, Modals }) => {
  113. const params = { annotations, config: complex, data: { text } };
  114. const waitForError = (name) => {
  115. // Two possible errors:
  116. // - Checkbox "name" is required.
  117. // - Input for the textarea "name" is required.
  118. Modals.seeWarning(`"${name}" is required`);
  119. Modals.closeWarning();
  120. };
  121. I.amOnPage("/");
  122. LabelStudio.init(params);
  123. // we already have an annotation
  124. I.updateAnnotation();
  125. waitForError("validation-label");
  126. // region stays selected after error, so per-region controls are visible
  127. I.click("Valid");
  128. I.updateAnnotation();
  129. waitForError("common-description");
  130. I.fillField("common-description", "some text");
  131. I.updateAnnotation();
  132. waitForError("region-description");
  133. // again stays visible
  134. I.fillField("region-description", "some description");
  135. I.updateAnnotation();
  136. // after successful update region is unselected and no modals shown
  137. I.dontSee("Valid");
  138. I.dontSeeElement(".ant-modal");
  139. I.click("Required textarea");
  140. I.updateAnnotation();
  141. waitForError("choice-description");
  142. I.click("Required choices");
  143. I.updateAnnotation();
  144. waitForError("choice");
  145. I.click("Me neither");
  146. // select labeled region
  147. AtOutliner.clickRegion("have");
  148. I.see("Valid");
  149. I.updateAnnotation();
  150. I.dontSee("Valid");
  151. I.click("Required textarea");
  152. I.updateAnnotation();
  153. waitForError("choice-description");
  154. I.fillField("choice-description", "test text");
  155. // select labeled region
  156. AtOutliner.clickRegion("have");
  157. I.see("Valid");
  158. I.updateAnnotation();
  159. I.dontSee("Valid");
  160. I.click('[aria-label="Annotations List Toggle"]');
  161. I.click('[aria-label="Create Annotation"]');
  162. I.submitAnnotation();
  163. waitForError("common-description");
  164. I.fillField("common-description", "some text");
  165. I.submitAnnotation();
  166. I.seeAnnotationSubmitted();
  167. });
  168. Scenario("Check required param with visibleWhen='choice-unselected'", async ({ I, LabelStudio, Modals }) => {
  169. const params = { config: createConfig({ visibleWhen: "choice-unselected" }), data: { text } };
  170. const waitForError = (name) => {
  171. Modals.seeWarning(`Checkbox "${name}" is required`);
  172. Modals.closeWarning();
  173. };
  174. I.amOnPage("/");
  175. LabelStudio.init(params);
  176. // Add new Annotation to be able to submit it
  177. I.click('[aria-label="Annotations List Toggle"]');
  178. I.click('[aria-label="Create Annotation"]');
  179. // Select one from each choices groups, except the one with visibleWhen condition
  180. I.click("Valid");
  181. I.click("Don't select me");
  182. // We should get error, cause "easter-egg" is visible and required
  183. I.submitAnnotation();
  184. waitForError("easter-egg");
  185. // Select the "Me neither" option to make the "easter-egg" block not required
  186. I.click("Me neither");
  187. I.submitAnnotation();
  188. // Annotation is submitted, so now we can only update it
  189. I.seeAnnotationSubmitted();
  190. // Reset to check another scenario
  191. LabelStudio.init(params);
  192. // LabelStudio is reloaded, there are no new annotation from prev steps
  193. I.dontSee("New annotation");
  194. I.click('[aria-label="Annotations List Toggle"]');
  195. I.click('[aria-label="Create Annotation"]');
  196. // Select all required options we have
  197. I.click("Valid");
  198. I.click("Don't select me");
  199. I.click("Secret level");
  200. I.submitAnnotation();
  201. // Annotation is submitted, so now we can only update it
  202. I.seeAnnotationSubmitted();
  203. });