itemengine-cypress-automation 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. package/.build_wna +4 -0
  2. package/README.md +3 -0
  3. package/currents.config.js +6 -0
  4. package/cypress/API/createItem/toggleItemMode.js +15 -0
  5. package/cypress/config-files/ildev.json +15 -0
  6. package/cypress/config-files/ilprod.json +15 -0
  7. package/cypress/config-files/ilqa.json +15 -0
  8. package/cypress/config-files/ilstage.json +15 -0
  9. package/cypress/e2e/ILC/sorry-cypress-test/spec1.js +18 -0
  10. package/cypress/e2e/ILC/sorry-cypress-test/spec2.js +18 -0
  11. package/cypress/e2e/ILC/sorry-cypress-test/spec3.js +18 -0
  12. package/cypress/fixtures/accessibilityConfig.json +6 -0
  13. package/cypress/fixtures/constants.js +18 -0
  14. package/cypress/fixtures/equationEditorCategoriesAndSymbols .js +2271 -0
  15. package/cypress/fixtures/specialAndMathCharacters.js +118 -0
  16. package/cypress/fixtures/theme/ilc.json +150 -0
  17. package/cypress/fixtures/theme/ngie.json +26 -0
  18. package/cypress/fixtures/uploads/20mbFile.png +0 -0
  19. package/cypress/fixtures/uploads/80mbFile.pdf +0 -0
  20. package/cypress/fixtures/uploads/highlightImage.jpg +0 -0
  21. package/cypress/fixtures/uploads/image.png +0 -0
  22. package/cypress/fixtures/uploads/sample.aac +0 -0
  23. package/cypress/fixtures/uploads/sample.accdb +0 -0
  24. package/cypress/fixtures/uploads/sample.csv +100 -0
  25. package/cypress/fixtures/uploads/sample.doc +0 -0
  26. package/cypress/fixtures/uploads/sample.gif +0 -0
  27. package/cypress/fixtures/uploads/sample.heic +0 -0
  28. package/cypress/fixtures/uploads/sample.heif +0 -0
  29. package/cypress/fixtures/uploads/sample.hevc +0 -0
  30. package/cypress/fixtures/uploads/sample.jpeg +0 -0
  31. package/cypress/fixtures/uploads/sample.jpg +0 -0
  32. package/cypress/fixtures/uploads/sample.mp3 +0 -0
  33. package/cypress/fixtures/uploads/sample.mp4 +0 -0
  34. package/cypress/fixtures/uploads/sample.pdf +0 -0
  35. package/cypress/fixtures/uploads/sample.ppt +0 -0
  36. package/cypress/fixtures/uploads/sample.pub +0 -0
  37. package/cypress/fixtures/uploads/sample.rtf +7902 -0
  38. package/cypress/fixtures/uploads/sample.svg +10 -0
  39. package/cypress/fixtures/uploads/sample.txt +1 -0
  40. package/cypress/fixtures/uploads/sample.wav +0 -0
  41. package/cypress/fixtures/uploads/sample.xlsx +0 -0
  42. package/cypress/fixtures/uploads/sample.xps +0 -0
  43. package/cypress/fixtures/uploads/sample.zip +0 -0
  44. package/cypress/fixtures/uploads/sample1.jpg +0 -0
  45. package/cypress/fixtures/uploads/sample1.mp3 +0 -0
  46. package/cypress/fixtures/uploads/sample1.zip +0 -0
  47. package/cypress/fixtures/uploads/sample10Sec.mp3 +0 -0
  48. package/cypress/fixtures/uploads/sample2.jpg +0 -0
  49. package/cypress/fixtures/uploads/sample2.mp3 +0 -0
  50. package/cypress/fixtures/uploads/sampleVirus.zip +0 -0
  51. package/cypress/pages/audioPlayerPage.js +628 -0
  52. package/cypress/pages/audioResponsePage.js +264 -0
  53. package/cypress/pages/components/additionalSettingsPanel.js +174 -0
  54. package/cypress/pages/components/answerNumerationComponent.js +109 -0
  55. package/cypress/pages/components/autoScoredAdditionalSettings.js +183 -0
  56. package/cypress/pages/components/autoScoredPreviewBase.js +94 -0
  57. package/cypress/pages/components/autoScoredScoringSection.js +195 -0
  58. package/cypress/pages/components/autoScoredScoringSectionMultipleResponsesType.js +268 -0
  59. package/cypress/pages/components/autoScoredSetCorrectAnswerSection.js +291 -0
  60. package/cypress/pages/components/ckEditorToolbar.js +64 -0
  61. package/cypress/pages/components/colorPopupComponent.js +293 -0
  62. package/cypress/pages/components/commonComponents.js +93 -0
  63. package/cypress/pages/components/componentsFlowChart/figFlowChart.png +0 -0
  64. package/cypress/pages/components/createCustomCategoryFlyout.js +138 -0
  65. package/cypress/pages/components/createQuestionBasePage.js +225 -0
  66. package/cypress/pages/components/customizeHighlightPropertiesComponent.js +318 -0
  67. package/cypress/pages/components/dragAndDropResponseOptions.js +738 -0
  68. package/cypress/pages/components/dragAndDropSetCorrectAnswerCheckboxComponents.js +124 -0
  69. package/cypress/pages/components/draggableOptionsContainer.js +857 -0
  70. package/cypress/pages/components/editCategoryFlyout.js +40 -0
  71. package/cypress/pages/components/equationEditorFlyout.js +158 -0
  72. package/cypress/pages/components/essayResponseCommonComponents.js +86 -0
  73. package/cypress/pages/components/figOverImageCommonComponent.js +924 -0
  74. package/cypress/pages/components/fillInTheGapsCommonComponents.js +687 -0
  75. package/cypress/pages/components/fillInTheGapsDropdownCommonComponent.js +442 -0
  76. package/cypress/pages/components/fillInTheGapsTextCommonComponent.js +884 -0
  77. package/cypress/pages/components/gridCommonComponents.js +951 -0
  78. package/cypress/pages/components/index.js +38 -0
  79. package/cypress/pages/components/listSortingAndOrderingBase.js +401 -0
  80. package/cypress/pages/components/maximumRecorderLengthComponent.js +116 -0
  81. package/cypress/pages/components/mcqAdditionalSettingsBase.js +390 -0
  82. package/cypress/pages/components/mcqOptionsComponent.js +263 -0
  83. package/cypress/pages/components/mcqPreviewComponents.js +78 -0
  84. package/cypress/pages/components/mcqQuestionCommonComponents.js +265 -0
  85. package/cypress/pages/components/mcqScoringComponent.js +120 -0
  86. package/cypress/pages/components/mcqSetCorrectAnswerSection.js +143 -0
  87. package/cypress/pages/components/optionsWrapperComponent.js +221 -0
  88. package/cypress/pages/components/playbackControlsBaseComponent.js +163 -0
  89. package/cypress/pages/components/previewScoringAndShowCorrectAnswerComponent.js +90 -0
  90. package/cypress/pages/components/questionInstructionsComponent.js +112 -0
  91. package/cypress/pages/components/scoringSectionBase.js +308 -0
  92. package/cypress/pages/components/setPointsPopupBase.js +79 -0
  93. package/cypress/pages/components/specialAndCustomSpecialCharactersComponent.js +79 -0
  94. package/cypress/pages/components/specialCharactersFlyoutComponent.js +58 -0
  95. package/cypress/pages/components/studentResponseAreaAndLayoutComponent.js +28 -0
  96. package/cypress/pages/components/uploadImageSectionComponent.js +594 -0
  97. package/cypress/pages/createItemPage.js +28 -0
  98. package/cypress/pages/dialogBoxBase.js +111 -0
  99. package/cypress/pages/dragAndDropIntoCategoriesAllOrNothingScoring.js +1161 -0
  100. package/cypress/pages/dragAndDropIntoCategoriesCellsScoring.js +1559 -0
  101. package/cypress/pages/dragAndDropIntoCategoriesPage.js +1556 -0
  102. package/cypress/pages/dragAndDropIntoCategoriesResponseScoring.js +1396 -0
  103. package/cypress/pages/essayResponseBasicPage.js +57 -0
  104. package/cypress/pages/essayResponseMathPage.js +47 -0
  105. package/cypress/pages/essayResponsePage.js +385 -0
  106. package/cypress/pages/feedbackScalePage.js +698 -0
  107. package/cypress/pages/fillInTheGapsDragAndDropPage.js +742 -0
  108. package/cypress/pages/fillInTheGapsDropdownPage.js +99 -0
  109. package/cypress/pages/fillInTheGapsOverImageDropdownPage.js +232 -0
  110. package/cypress/pages/fillInTheGapsOverImageTextPage.js +135 -0
  111. package/cypress/pages/fillInTheGapsScoring.js +5974 -0
  112. package/cypress/pages/fillInTheGapsSetCorrectAnswerSection.js +260 -0
  113. package/cypress/pages/fillInTheGapsTextPage.js +225 -0
  114. package/cypress/pages/highlightImagePage.js +1316 -0
  115. package/cypress/pages/highlightPage.js +870 -0
  116. package/cypress/pages/index.js +30 -0
  117. package/cypress/pages/listMatchingPage.js +1330 -0
  118. package/cypress/pages/listMatchingScoring.js +2635 -0
  119. package/cypress/pages/listOrderingPage.js +751 -0
  120. package/cypress/pages/listSortingPage.js +1201 -0
  121. package/cypress/pages/multipleSelectionGridPage.js +359 -0
  122. package/cypress/pages/multipleSelectionPage.js +88 -0
  123. package/cypress/pages/passagePage.js +426 -0
  124. package/cypress/pages/readingRulerPage.js +302 -0
  125. package/cypress/pages/selectQuestionResourceToolPage.js +64 -0
  126. package/cypress/pages/shortTextResponsePage.js +197 -0
  127. package/cypress/pages/singleSelectionGridPage.js +370 -0
  128. package/cypress/pages/singleSelectionPage.js +65 -0
  129. package/cypress/pages/uploadResponsePage.js +110 -0
  130. package/cypress/pages/videoResponsePage.js +375 -0
  131. package/cypress/support/commands.js +140 -0
  132. package/cypress/support/e2e.js +14 -0
  133. package/cypress/support/helpers/abortEarly.js +19 -0
  134. package/cypress/support/helpers/accessibility.js +34 -0
  135. package/cypress/support/helpers/cypressUtilities.js +64 -0
  136. package/cypress/support/helpers/localStorage.js +13 -0
  137. package/cypress/support/helpers/selectText.js +77 -0
  138. package/cypress/support/helpers/utilities.js +126 -0
  139. package/cypress.config.js +76 -0
  140. package/il.yaml +14 -0
  141. package/language +1 -0
  142. package/package.json +26 -0
@@ -0,0 +1,738 @@
1
+ import { commonComponents } from "./commonComponents";
2
+ import { optionsWrapperComponent } from "./optionsWrapperComponent";
3
+ const optionsForResponses = ['Response 1', 'Response 2'];
4
+ const optionsForThreeResponses = ['Response 1', 'Response 2', 'Response 3'];
5
+ const responseForGroup2 = ['Response 3', 'Response 4'];
6
+ const css = Cypress.env('css');
7
+
8
+ const selectors = {
9
+ optionsInputField: () => cy.get('[data-rbd-droppable-id="assessment-option-item-options"] .option-component [title*="Enter"][title*="ption"]'),
10
+ responseOptionsLabel: () => cy.get('.response-option-label'),
11
+ responseOptionsLayoutLabel: () => cy.get('#Response-options-layout-dropdown-label'),
12
+ responseOptionsLayoutDropdown: () => cy.get('#Response-options-layout-select'),
13
+ responseOptionsLayoutDropdownOptions: (ariaLabel) => cy.get(`[role="listbox"] .response-options-menu-item[aria-label*="${ariaLabel}"]`),
14
+ responseOptionsLayoutDropdownOptions: (ariaLabel = null) => {
15
+ if (ariaLabel) {
16
+ return cy.get(`[role="listbox"] .response-options-menu-item[aria-label*="${ariaLabel}"]`)
17
+ } else {
18
+ return cy.get('[role="listbox"] .response-options-menu-item')
19
+ }
20
+ },
21
+ optionNumeration: () => cy.get('[class*="AdornmentDiv"]'),
22
+ optionsForDragAndDropLabel: () => cy.get('.cloze-with-drag-and-drop-options-label'),
23
+ groupResponseContainer: () => cy.get('.group-container-box'),
24
+ groupResponseTitle: () => cy.get('.group-label-wrapper'),
25
+ groupResponseTitleWrapper: () => cy.get('.group-title-wrapper'),
26
+ deleteGroupButton: () => cy.get('.group-title-wrapper .ngie-button'),
27
+ groupTitleLabel: () => cy.get('.group-title'),
28
+ groupTitleInputField: () => cy.get('.group-title-input [aria-label="Group title"]'),
29
+ addGroupButton: () => cy.get('.add-group-wrapper .ngie-button'),
30
+ }
31
+
32
+ //TODO: will need to remove questionType parameter from all steps once, common selectors are made available and then add description for all functions
33
+ const steps = {
34
+ verifyOptionsForDragAndDropSectionOptionFieldContents: () => {
35
+ optionsWrapperComponent.optionWrapper()
36
+ .each(($el, index) => {
37
+ cy.wrap($el)
38
+ .within(() => {
39
+ optionsWrapperComponent.optionsInputField()
40
+ .verifyPseudoClassBeforeProperty('content', '"Enter option"');
41
+ commonComponents.dragHandleButton()
42
+ .should('be.visible');
43
+ optionsWrapperComponent.deleteOptionButton()
44
+ .should('be.visible');
45
+ dragAndDropResponseOptions.optionNumeration()
46
+ .should('have.text', index + 1)
47
+ });
48
+ });
49
+ },
50
+
51
+ addInputToOptionsForDragAndDropFields: (responseTextArray) => {
52
+ optionsWrapperComponent.optionsSectionWrapper()
53
+ .within(() => {
54
+ responseTextArray.forEach((responseFieldText, optionIndex) => {
55
+ optionsWrapperComponent.optionsInputField()
56
+ .eq(optionIndex)
57
+ .type(responseFieldText, { delay: 0 })
58
+ .blur()
59
+ .focus()
60
+ .should('have.text', responseFieldText);
61
+ });
62
+ });
63
+ },
64
+
65
+ addInputToOptionsForGroupedResponseLayout: (groupIndex, responseTextArray) => {
66
+ dragAndDropResponseOptions.groupResponseContainer()
67
+ .eq(groupIndex)
68
+ .within(() => {
69
+ dragAndDropResponseOptions.steps.addInputToOptionsForDragAndDropFields(responseTextArray);
70
+ });
71
+ },
72
+
73
+ selectResponseOptionsLayout: (layoutOption) => {
74
+ dragAndDropResponseOptions.responseOptionsLayoutDropdown()
75
+ .should('be.visible');
76
+ dragAndDropResponseOptions.responseOptionsLayoutDropdown()
77
+ .click();
78
+ dragAndDropResponseOptions.responseOptionsLayoutDropdownOptions(layoutOption)
79
+ .click();
80
+ dragAndDropResponseOptions.responseOptionsLayoutDropdown()
81
+ .verifyInnerText(layoutOption);
82
+ },
83
+
84
+ addGroupTitle: (groupIndex, groupTitle) => {
85
+ dragAndDropResponseOptions.groupTitleInputField()
86
+ .eq(groupIndex)
87
+ .type(groupTitle, { delay: 0 })
88
+ .should('have.value', groupTitle);
89
+ },
90
+
91
+ addGroup: () => {
92
+ dragAndDropResponseOptions.addGroupButton()
93
+ .click();
94
+ },
95
+
96
+ deleteGroup: (groupIndex) => {
97
+ dragAndDropResponseOptions.deleteGroupButton()
98
+ .eq(groupIndex)
99
+ .click();
100
+ },
101
+
102
+ /**
103
+ * @param {number} groupIndex index of the group
104
+ * @param {string} groupTitle group title
105
+ * @param {string[]} optionArray array of options for a particular group
106
+ * @description add a group with title and options in the response options section
107
+ */
108
+ addGroupWithTitleAndOptionsInResponseOptionsSection: (groupIndex, groupTitle, optionArray) => {
109
+ const numOptionsToAdd = Math.max(0, optionArray.length - 2);
110
+ dragAndDropResponseOptions.addGroupButton()
111
+ .click();
112
+ dragAndDropResponseOptions.steps.addGroupTitle(groupIndex, groupTitle);
113
+ for (let i = 0; i < numOptionsToAdd; i++) {
114
+ dragAndDropResponseOptions.groupResponseContainer()
115
+ .eq(groupIndex)
116
+ .within(() => {
117
+ optionsWrapperComponent.steps.addOption();
118
+ });
119
+ }
120
+ dragAndDropResponseOptions.groupResponseContainer()
121
+ .eq(groupIndex)
122
+ .within(() => {
123
+ dragAndDropResponseOptions.steps.addInputToOptionsForDragAndDropFields(optionArray);
124
+ });
125
+ },
126
+
127
+ /**
128
+ * @param {string[]} responseTextArray array of options in options input fields
129
+ * @description verify the text content present in the option input fields
130
+ */
131
+ verifyOptionFieldContentsInOptionsSection: (responseTextArray) => {
132
+ optionsWrapperComponent.optionsSectionWrapper()
133
+ .within(() => {
134
+ responseTextArray.forEach((responseFieldText, optionIndex) => {
135
+ optionsWrapperComponent.optionsInputField()
136
+ .should('have.length', responseTextArray.length);
137
+ optionsWrapperComponent.optionsInputField()
138
+ .eq(optionIndex)
139
+ .should('have.text', responseFieldText);
140
+ optionsWrapperComponent.optionNumeration()
141
+ .eq(optionIndex)
142
+ .should('have.text', optionIndex + 1);
143
+ });
144
+ });
145
+ },
146
+
147
+ /**
148
+ * @param {number} groupIndex index of group
149
+ * @description verify if a group does not exist in the response options section
150
+ */
151
+ verifyGroupInResponseOptionSectionNotExists: (groupIndex) => {
152
+ dragAndDropResponseOptions.groupResponseContainer()
153
+ .eq(groupIndex)
154
+ .should('not.exist');
155
+
156
+ },
157
+
158
+ /**
159
+ * @param {number} countOfOptions count of options input fields
160
+ * @description this function verifies the number of options input fields
161
+ */
162
+ verifyCountOfOptionsForDragAndDropInputFields: (countOfOptions) => {
163
+ dragAndDropResponseOptions.optionsInputField()
164
+ .should('have.length', countOfOptions);
165
+ },
166
+ }
167
+
168
+ const tests = {
169
+ verifyResponseOptionsLayoutDropdownSection: () => {
170
+ it('\'Response options\' label should be displayed', () => {
171
+ dragAndDropResponseOptions.responseOptionsLabel()
172
+ .verifyInnerText('Response options');
173
+ });
174
+
175
+ it('\'Response options layout\' label and dropdown should be displayed and option \'Standard\' should be selected by default', () => {
176
+ dragAndDropResponseOptions.responseOptionsLayoutLabel()
177
+ .verifyInnerText('Response options layout');
178
+ dragAndDropResponseOptions.responseOptionsLayoutDropdown()
179
+ .verifyInnerText('Standard')
180
+ .and('be.visible');
181
+ });
182
+
183
+ it('CSS of \'Response options\',\'Response options layout\' labels and \'Response options layout\' dropdown in default state', { tags: 'css' }, () => {
184
+ dragAndDropResponseOptions.responseOptionsLabel()
185
+ .verifyCSS(css.color.labels, css.fontSize.default, css.fontWeight.semibold);
186
+ dragAndDropResponseOptions.responseOptionsLayoutLabel()
187
+ .verifyCSS(css.color.labels, css.fontSize.normal, css.fontWeight.semibold);
188
+ dragAndDropResponseOptions.responseOptionsLayoutDropdown()
189
+ .should('have.css', 'background-color', css.color.secondaryBtnBg)
190
+ .and('have.css', 'border', `1px solid ${css.color.defaultDropdownBorder}`)
191
+ .find('.dropdown-label-text')
192
+ .verifyCSS(css.color.liText, css.fontSize.default, css.fontWeight.regular)
193
+ .verifyPseudoClassBeforeProperty('color', css.color.secondaryBtn);
194
+ });
195
+
196
+ it('Accessibility of \'Response options\', \'Response options layout\' labels and \'Response options layout\' dropdown in default state', { tags: 'a11y' }, () => {
197
+ cy.checkAccessibility(dragAndDropResponseOptions.responseOptionsLabel())
198
+ cy.checkAccessibility(dragAndDropResponseOptions.responseOptionsLayoutLabel().parents('.response-options-dropdown'));
199
+ });
200
+
201
+ it('When the user clicks on \'Response options layout\' dropdown, a list of 2 options should open - Standard and Grouped', () => {
202
+ dragAndDropResponseOptions.responseOptionsLayoutDropdown()
203
+ .click();
204
+ let dropdownOptions = ['Standard', 'Grouped'];
205
+ dropdownOptions.forEach((option, count) => {
206
+ dragAndDropResponseOptions.responseOptionsLayoutDropdownOptions()
207
+ .eq(count)
208
+ .verifyInnerText(option);
209
+ });
210
+ });
211
+
212
+ it('CSS of \'Response options layout\' dropdown and dropdown content in active state', { tags: 'css' }, () => {
213
+ dragAndDropResponseOptions.responseOptionsLayoutDropdown()
214
+ .should('have.css', 'background-color', css.color.secondaryBtnBg)
215
+ .and('have.css', 'border', `1px solid ${css.color.activeComponentBorder}`);
216
+ dragAndDropResponseOptions.responseOptionsLayoutDropdownOptions()
217
+ .eq(1)
218
+ .should('have.css', 'background-color', css.color.transparent);
219
+ dragAndDropResponseOptions.responseOptionsLayoutDropdownOptions()
220
+ .eq(0)
221
+ .verifyCSS(css.color.liText, css.fontSize.default, css.fontWeight.regular)
222
+ .should('have.css', 'background-color', css.color.liTextSelectedBg);
223
+ });
224
+
225
+ it('Accessibility of \'Response options layout\' dropdown and dropdown content in active state', { tags: 'a11y' }, () => {
226
+ cy.checkAccessibility(dragAndDropResponseOptions.responseOptionsLayoutDropdown());
227
+ cy.checkAccessibility(dragAndDropResponseOptions.responseOptionsLayoutDropdownOptions().parents('.dropdown-list-ul'));
228
+ });
229
+ },
230
+
231
+ verifyOptionsSectionContentAndFunctionality: () => {
232
+ it('\'Options for drag & drop\' label should be displayed', () => {
233
+ dragAndDropResponseOptions.optionsForDragAndDropLabel()
234
+ .verifyInnerText('Options for drag & drop')
235
+ .and('be.visible');
236
+ });
237
+
238
+ it('By default, 2 \'Options\' input fields with numeric counts should be displayed with placeholder text and drag handle and delete option icon buttons should be displayed besides each input field', () => {
239
+ dragAndDropResponseOptions.steps.verifyOptionsForDragAndDropSectionOptionFieldContents();
240
+ optionsWrapperComponent.optionWrapper()
241
+ .each(($el) => {
242
+ cy.wrap($el)
243
+ .within(() => {
244
+ optionsWrapperComponent.deleteOptionButton()
245
+ .should('be.visible');
246
+ });
247
+ });
248
+ });
249
+
250
+ tests.verifyDisabledStateOfOptionDeleteButton();
251
+
252
+ it('CSS of disabled delete option buttons', { tags: 'css' }, () => {
253
+ optionsWrapperComponent.optionsSectionWrapper()
254
+ .within(() => {
255
+ optionsWrapperComponent.deleteOptionButton()
256
+ .should('have.css', 'opacity', '0.5')
257
+ .verifyPseudoClassBeforeProperty('color', css.color.deleteIcon);
258
+ });
259
+ });
260
+
261
+ it('When the user hovers over the drag handle of the options then \'Drag to reorder\' message should be displayed on a tooltip and the tooltip should disappear if focus is removed from the drag handle', () => {
262
+ optionsWrapperComponent.optionWrapper()
263
+ .eq(0)
264
+ .within(() => {
265
+ commonComponents.dragHandleButton()
266
+ .trigger('mouseover');
267
+ });
268
+ commonComponents.tooltipText()
269
+ .should('be.visible')
270
+ .verifyInnerText('Drag to reorder');
271
+ optionsWrapperComponent.optionWrapper()
272
+ .eq(0)
273
+ .within(() => {
274
+ commonComponents.dragHandleButton()
275
+ .trigger('mouseout');
276
+ });
277
+ commonComponents.tooltipText()
278
+ .should('not.exist');
279
+ });
280
+
281
+ it('CSS of drag handle tooltip', { tags: 'css' }, () => {
282
+ optionsWrapperComponent.optionWrapper()
283
+ .eq(0)
284
+ .within(() => {
285
+ commonComponents.dragHandleButton()
286
+ .trigger('mouseover');
287
+ });
288
+ commonComponents.tooltipText()
289
+ .should('be.visible')
290
+ .verifyCSS(css.color.whiteText, css.fontSize.small, css.fontWeight.regular);
291
+ optionsWrapperComponent.optionWrapper()
292
+ .eq(0)
293
+ .within(() => {
294
+ commonComponents.dragHandleButton()
295
+ .trigger('mouseout');
296
+ });
297
+ commonComponents.tooltipText()
298
+ .should('not.exist');
299
+ });
300
+
301
+ it('Accessibility of drag handle tooltip', { tags: 'a11y' }, () => {
302
+ optionsWrapperComponent.optionWrapper()
303
+ .eq(0)
304
+ .within(() => {
305
+ commonComponents.dragHandleButton()
306
+ .trigger('mouseover');
307
+ });
308
+ commonComponents.tooltipText()
309
+ .should('be.visible');
310
+ cy.checkAccessibility(commonComponents.tooltipText());
311
+ optionsWrapperComponent.optionWrapper()
312
+ .eq(0)
313
+ .within(() => {
314
+ commonComponents.dragHandleButton()
315
+ .trigger('mouseout');
316
+ });
317
+ commonComponents.tooltipText()
318
+ .should('not.exist');
319
+ });
320
+
321
+ it('When the user hovers over the disabled delete buttons of the options then \'Minimum two options are required\' message should be displayed on a tooltip and the tooltip should disappear if focus is removed from the delete button', () => {
322
+ optionsWrapperComponent.deleteOptionButton()
323
+ .eq(0)
324
+ .trigger('mouseover', { force: true });
325
+ commonComponents.tooltipText()
326
+ .verifyInnerText('Minimum two options are required');
327
+ optionsWrapperComponent.deleteOptionButton()
328
+ .eq(0)
329
+ .trigger('mouseout', { force: true });
330
+ commonComponents.tooltipText()
331
+ .should('not.exist');
332
+ });
333
+
334
+ it('CSS of disabled delete button tooltip', { tags: 'css' }, () => {
335
+ optionsWrapperComponent.deleteOptionButton()
336
+ .eq(0)
337
+ .trigger('mouseover', { force: true });
338
+ commonComponents.tooltipText()
339
+ .should('be.visible')
340
+ .verifyCSS(css.color.whiteText, css.fontSize.small, css.fontWeight.regular);
341
+ optionsWrapperComponent.deleteOptionButton()
342
+ .eq(0)
343
+ .trigger('mouseout', { force: true });
344
+ commonComponents.tooltipText()
345
+ .should('not.exist');
346
+ });
347
+
348
+ it('Accessibility of disabled delete button tooltip', { tags: 'a11y' }, () => {
349
+ optionsWrapperComponent.deleteOptionButton()
350
+ .eq(0)
351
+ .trigger('mouseover', { force: true });
352
+ commonComponents.tooltipText()
353
+ .should('be.visible');
354
+ cy.checkAccessibility(commonComponents.tooltipText());
355
+ optionsWrapperComponent.deleteOptionButton()
356
+ .eq(0)
357
+ .trigger('mouseout', { force: true });
358
+ commonComponents.tooltipText()
359
+ .should('not.exist');
360
+ });
361
+
362
+ it('\'Add Option\' button should be present', () => {
363
+ optionsWrapperComponent.addOptionButton()
364
+ .verifyInnerText('Add option')
365
+ .and('be.visible');
366
+ });
367
+
368
+ it('CSS of Options section', { tags: 'css' }, () => {
369
+ dragAndDropResponseOptions.optionsForDragAndDropLabel()
370
+ .verifyCSS(css.color.sectionHeading, css.fontSize.normal, css.fontWeight.semibold);
371
+ optionsWrapperComponent.optionWrapper()
372
+ .eq(0)
373
+ .within(() => {
374
+ commonComponents.dragHandleButton()
375
+ .verifyCSS(css.color.secondaryBtnActive, css.fontSize.normal, css.fontWeight.regular);
376
+ optionsWrapperComponent.deleteOptionButton()
377
+ .verifyPseudoClassBeforeProperty('color', css.color.deleteIcon);
378
+ });
379
+ dragAndDropResponseOptions.optionsInputField()
380
+ .verifyCSS(css.color.text, css.fontSize.default, css.fontWeight.regular);
381
+ optionsWrapperComponent.addOptionButton()
382
+ .verifyCSS(css.color.secondaryBtnActive, css.fontSize.normal, css.fontWeight.medium);
383
+ });
384
+
385
+ it('Accessibility of Options section', { tags: 'a11y' }, () => {
386
+ cy.checkAccessibility(optionsWrapperComponent.optionsSectionWrapper());
387
+ });
388
+
389
+ it('When user adds an option using \'Add Option\' button then the added option input field should be displayed and option numeration should increment', () => {
390
+ optionsWrapperComponent.addOptionButton()
391
+ .click();
392
+ dragAndDropResponseOptions.steps.verifyOptionsForDragAndDropSectionOptionFieldContents();
393
+ });
394
+
395
+ it('When user focus in and out of any of the \'Options\' input field without typing anything, an error message should be thrown', () => {
396
+ dragAndDropResponseOptions.optionsInputField()
397
+ .eq(2)
398
+ .click()
399
+ .blur();
400
+ optionsWrapperComponent.optionWrapper()
401
+ .eq(2)
402
+ .within(() => {
403
+ commonComponents.errorMessage()
404
+ .verifyInnerText('Error: Option is required.');
405
+ });
406
+ });
407
+
408
+ commonComponents.tests.verifyCSSAnda11yOfErrorMessage();
409
+
410
+ it('When user enters text in options input field then the error message \'Error: Option is required.\' should disappear', () => {
411
+ dragAndDropResponseOptions.steps.addInputToOptionsForDragAndDropFields(['Response 1', 'Response 2', 'Response 3']);
412
+ commonComponents.errorMessage()
413
+ .should('not.exist');
414
+ });
415
+
416
+ it('When the number of options are greater than 2 then the \'Delete\' icon buttons should get enabled', () => {
417
+ optionsWrapperComponent.deleteOptionButton()
418
+ .should('be.enabled');
419
+ });
420
+
421
+ it('CSS of enabled \'Delete\' option button', { tags: 'css' }, () => {
422
+ optionsWrapperComponent.deleteOptionButton()
423
+ .verifyPseudoClassBeforeProperty('color', css.color.deleteIcon)
424
+ .should('have.css', 'opacity', '1');
425
+ })
426
+
427
+ it('Accessibility of enabled \'Delete\' option button', { tags: 'a11y' }, () => {
428
+ cy.checkAccessibility(optionsWrapperComponent.deleteOptionButton().parents('.cloze-with-drag-and-drop-delete'))
429
+ });
430
+
431
+ it('when the user hovers over the enabled \'Delete\' icon buttons, then \'Delete option\' message should be displayed on a tooltip and the tooltip should disappear if focus is removed from the \'Delete\' icon button', () => {
432
+ cy.log('Pre step: Focusing out of the newly added option input field')
433
+ dragAndDropResponseOptions.optionsInputField()
434
+ .eq(2)
435
+ .blur();
436
+ optionsWrapperComponent.deleteOptionButton()
437
+ .eq(0)
438
+ .trigger('mouseover');
439
+ commonComponents.tooltipText()
440
+ .verifyInnerText('Delete option');
441
+ optionsWrapperComponent.deleteOptionButton()
442
+ .eq(0)
443
+ .trigger('mouseout');
444
+ commonComponents.tooltipText()
445
+ .should('not.exist');
446
+ });
447
+
448
+ it('CSS of enabled delete button tooltip', { tags: 'css' }, () => {
449
+ optionsWrapperComponent.deleteOptionButton()
450
+ .eq(0)
451
+ .trigger('mouseover');
452
+ commonComponents.tooltipText()
453
+ .should('be.visible')
454
+ .verifyCSS(css.color.whiteText, css.fontSize.small, css.fontWeight.regular);
455
+ optionsWrapperComponent.deleteOptionButton()
456
+ .eq(0)
457
+ .trigger('mouseout');
458
+ commonComponents.tooltipText()
459
+ .should('not.exist');
460
+ });
461
+
462
+ it('Accessibility of enabled delete button tooltip', { tags: 'a11y' }, () => {
463
+ optionsWrapperComponent.deleteOptionButton()
464
+ .eq(0)
465
+ .trigger('mouseover');
466
+ commonComponents.tooltipText()
467
+ .should('be.visible');
468
+ cy.checkAccessibility(commonComponents.tooltipText());
469
+ optionsWrapperComponent.deleteOptionButton()
470
+ .eq(0)
471
+ .trigger('mouseout');
472
+ commonComponents.tooltipText()
473
+ .should('not.exist');
474
+ });
475
+
476
+ it('When user clicks on the \'Delete\' option button then the respective options input field should get deleted and option numeration should change accordingly', () => {
477
+ const optionsAfterDeleting = optionsForThreeResponses.filter((el) => el !== 'Response 2')
478
+ cy.log('Clicking the \'Delete\' icon button for the 2nd option input field')
479
+ optionsWrapperComponent.deleteOptionButton()
480
+ .eq(1)
481
+ .click();
482
+ cy.log('Checking that the 3rd option input field should be deleted and option numeration should update accordingly')
483
+ optionsWrapperComponent.optionWrapper()
484
+ .should('have.length', 2);
485
+ optionsWrapperComponent.optionWrapper()
486
+ .eq(1)
487
+ .within(() => {
488
+ dragAndDropResponseOptions.optionNumeration()
489
+ .should('have.text', 2)
490
+ })
491
+ cy.log('Verifying the input text given to input fields after deletion of 2nd option')
492
+ optionsAfterDeleting.forEach((inputFieldText, optionIndex) => {
493
+ dragAndDropResponseOptions.optionsInputField()
494
+ .eq(optionIndex)
495
+ .should('have.text', inputFieldText);
496
+ });
497
+ });
498
+
499
+ tests.verifyDisabledStateOfOptionDeleteButton();
500
+ },
501
+
502
+ verifyGroupedOptionsContentAndFunctionality: () => {
503
+ it('When the user selects the \'Grouped\' option from the \'Response options layout\' dropdown, a section of options with label \'Group A\' should be displayed with a delete button', () => {
504
+ dragAndDropResponseOptions.steps.selectResponseOptionsLayout('Grouped');
505
+ dragAndDropResponseOptions.groupResponseContainer()
506
+ .should('be.visible')
507
+ .and('have.length', 1);
508
+ dragAndDropResponseOptions.groupResponseTitle()
509
+ .verifyInnerText('Group A')
510
+ .and('be.visible');
511
+ dragAndDropResponseOptions.deleteGroupButton()
512
+ .should('be.visible');
513
+ });
514
+
515
+ dragAndDropResponseOptions.tests.verifyDisabledStateOfGroupDeleteButton();
516
+
517
+ it('CSS of disabled delete group button', { tags: 'css' }, () => {
518
+ dragAndDropResponseOptions.deleteGroupButton()
519
+ .should('have.css', 'opacity', '0.5')
520
+ .verifyPseudoClassBeforeProperty('color', css.color.deleteIcon);
521
+ });
522
+
523
+ it('When the user hovers over the disabled delete button of the group then \'Minimum one group is required\' message should be displayed on a tooltip and the tooltip should disappear if focus is removed from the delete button', () => {
524
+ dragAndDropResponseOptions.deleteGroupButton()
525
+ .trigger('mouseover', { force: true });
526
+ commonComponents.tooltipText()
527
+ .verifyInnerText('Minimum one group is required');
528
+ dragAndDropResponseOptions.deleteGroupButton()
529
+ .trigger('mouseout', { force: true });
530
+ commonComponents.tooltipText()
531
+ .should('not.exist');
532
+ });
533
+
534
+ it('CSS of disabled delete button tooltip', { tags: 'css' }, () => {
535
+ dragAndDropResponseOptions.deleteGroupButton()
536
+ .trigger('mouseover', { force: true });
537
+ commonComponents.tooltipText()
538
+ .should('be.visible')
539
+ .verifyCSS(css.color.whiteText, css.fontSize.small, css.fontWeight.regular);
540
+ dragAndDropResponseOptions.deleteGroupButton()
541
+ .trigger('mouseout', { force: true });
542
+ commonComponents.tooltipText()
543
+ .should('not.exist');
544
+ });
545
+
546
+ it('Accessibility of disabled delete button tooltip', { tags: 'a11y' }, () => {
547
+ dragAndDropResponseOptions.deleteGroupButton()
548
+ .trigger('mouseover', { force: true });
549
+ commonComponents.tooltipText()
550
+ .should('be.visible');
551
+ cy.checkAccessibility(commonComponents.tooltipText());
552
+ dragAndDropResponseOptions.deleteGroupButton()
553
+ .trigger('mouseout', { force: true });
554
+ commonComponents.tooltipText()
555
+ .should('not.exist');
556
+ });
557
+
558
+ it('\'Group title\' label and input field should be displayed and by default, the input field should be empty', () => {
559
+ dragAndDropResponseOptions.groupTitleLabel()
560
+ .verifyInnerText('Group title')
561
+ .and('be.visible');
562
+ dragAndDropResponseOptions.groupTitleInputField()
563
+ .should('have.value', '')
564
+ .and('be.visible');
565
+ });
566
+
567
+ it('\'Enter group title\' placeholder should be displayed inside the group title input field, when the user enters text in the input field, the placeholder should disappear and when the user clears the input field, the placeholder text should appear again', () => {
568
+ dragAndDropResponseOptions.groupTitleInputField()
569
+ .should('have.attr', 'placeholder', 'Enter group title');
570
+ dragAndDropResponseOptions.steps.addGroupTitle(0, 'Group title A')
571
+ dragAndDropResponseOptions.groupTitleInputField()
572
+ .should('not.have.attr', 'placeholder');
573
+ dragAndDropResponseOptions.groupTitleInputField()
574
+ .clear();
575
+ dragAndDropResponseOptions.groupTitleInputField()
576
+ .should('have.attr', 'placeholder', 'Enter group title');
577
+ cy.log('Post step: adding the group title again')
578
+ dragAndDropResponseOptions.steps.addGroupTitle(0, 'Group title A')
579
+ });
580
+
581
+ it('CSS of Grouped section contents', { tags: 'css' }, () => {
582
+ dragAndDropResponseOptions.groupResponseTitle()
583
+ .verifyCSS(css.color.sectionHeading, css.fontSize.default, css.fontWeight.semibold);
584
+ dragAndDropResponseOptions.groupTitleLabel()
585
+ .verifyCSS(css.color.labels, css.fontSize.normal, css.fontWeight.semibold);
586
+ dragAndDropResponseOptions.groupTitleInputField()
587
+ .verifyCSS(css.color.text, css.fontSize.default, css.fontWeight.regular);
588
+ });
589
+
590
+ dragAndDropResponseOptions.tests.verifyOptionsSectionContentAndFunctionality();
591
+
592
+ it('\'Add Group\' button should be present', () => {
593
+ dragAndDropResponseOptions.addGroupButton()
594
+ .verifyInnerText('Add group')
595
+ .and('be.visible');
596
+ });
597
+
598
+ it('When the user clicks on the \'Add Group\' button, a new group should get added with label \'Group B\'', () => {
599
+ dragAndDropResponseOptions.addGroupButton()
600
+ .click();
601
+ dragAndDropResponseOptions.groupResponseContainer()
602
+ .should('have.length', 2);
603
+ dragAndDropResponseOptions.groupResponseContainer()
604
+ .eq(1)
605
+ .should('be.visible');
606
+ dragAndDropResponseOptions.groupResponseTitle()
607
+ .eq(1)
608
+ .verifyInnerText('Group B');
609
+ });
610
+
611
+ it('By default, the newly added group should have a delete button next to the group title, \'Group title\' label and input field, \'Options\' label and 2 option input fields with drag handles and disabled delete buttons and the user should be able to add input to the text fields', () => {
612
+ dragAndDropResponseOptions.deleteGroupButton()
613
+ .eq(1)
614
+ .should('be.visible');
615
+ dragAndDropResponseOptions.groupResponseContainer()
616
+ .eq(1)
617
+ .within(() => {
618
+ dragAndDropResponseOptions.groupTitleLabel()
619
+ .verifyInnerText('Group title')
620
+ .and('be.visible');
621
+ dragAndDropResponseOptions.groupTitleInputField()
622
+ .should('have.value', '')
623
+ .and('be.visible');
624
+ dragAndDropResponseOptions.steps.verifyOptionsForDragAndDropSectionOptionFieldContents();
625
+ });
626
+ cy.log('Entering text into the text fields of group 2 response container')
627
+ dragAndDropResponseOptions.groupResponseContainer()
628
+ .eq(1)
629
+ .within(() => {
630
+ dragAndDropResponseOptions.steps.addInputToOptionsForDragAndDropFields(responseForGroup2);
631
+ });
632
+ dragAndDropResponseOptions.steps.addGroupTitle(1, 'Group title B');
633
+ });
634
+
635
+ it('When the number of groups are more than 1 then the \'Delete\' icon buttons should get enabled', () => {
636
+ dragAndDropResponseOptions.deleteGroupButton()
637
+ .should('be.enabled');
638
+ });
639
+
640
+ it('CSS of enabled delete group button', { tags: 'css' }, () => {
641
+ dragAndDropResponseOptions.deleteGroupButton()
642
+ .should('have.css', 'opacity', '1')
643
+ .verifyPseudoClassBeforeProperty('color', css.color.deleteIcon);
644
+ });
645
+
646
+ it('Accessibility of enabled delete group button', { tags: 'a11y' }, () => {
647
+ cy.checkAccessibility(dragAndDropResponseOptions.groupResponseTitleWrapper());
648
+ });
649
+
650
+ it('when the user hovers over the enabled \'Delete\' icon button, then \'Delete group\' message should be displayed on a tooltip and the tooltip should disappear if focus is removed from the \'Delete\' icon button', () => {
651
+ dragAndDropResponseOptions.deleteGroupButton()
652
+ .eq(0)
653
+ .trigger('mouseover');
654
+ commonComponents.tooltipText()
655
+ .should('be.visible')
656
+ .verifyInnerText('Delete group');
657
+ dragAndDropResponseOptions.deleteGroupButton()
658
+ .eq(0)
659
+ .trigger('mouseout');
660
+ commonComponents.tooltipText()
661
+ .should('not.exist');
662
+ });
663
+
664
+ it('CSS of enabled delete button tooltip', { tags: 'css' }, () => {
665
+ dragAndDropResponseOptions.deleteGroupButton()
666
+ .eq(0)
667
+ .trigger('mouseover');
668
+ commonComponents.tooltipText()
669
+ .should('be.visible')
670
+ .verifyCSS(css.color.whiteText, css.fontSize.small, css.fontWeight.regular);
671
+ dragAndDropResponseOptions.deleteGroupButton()
672
+ .eq(0)
673
+ .trigger('mouseout');
674
+ commonComponents.tooltipText()
675
+ .should('not.exist');
676
+ });
677
+
678
+ it('Accessibility of enabled delete button tooltip', { tags: 'a11y' }, () => {
679
+ dragAndDropResponseOptions.deleteGroupButton()
680
+ .eq(0)
681
+ .trigger('mouseover', { force: true });
682
+ cy.checkAccessibility(commonComponents.tooltipText());
683
+ dragAndDropResponseOptions.deleteGroupButton()
684
+ .eq(0)
685
+ .trigger('mouseout', { force: true });
686
+ commonComponents.tooltipText()
687
+ .should('not.exist');
688
+ });
689
+
690
+ it('When the user deletes a group the response options section should get updated accordingly', () => {
691
+ dragAndDropResponseOptions.deleteGroupButton()
692
+ .eq(0)
693
+ .click();
694
+ dragAndDropResponseOptions.groupResponseContainer()
695
+ .should('have.length', 1);
696
+ dragAndDropResponseOptions.groupResponseTitle()
697
+ .verifyInnerText('Group A');
698
+ cy.log('Verifying the text content of the 2nd group after deletion of 1st group')
699
+ dragAndDropResponseOptions.groupResponseContainer()
700
+ .within(() => {
701
+ responseForGroup2.forEach((inputFieldText, optionIndex) => {
702
+ dragAndDropResponseOptions.optionsInputField()
703
+ .eq(optionIndex)
704
+ .should('have.text', inputFieldText);
705
+ });
706
+ dragAndDropResponseOptions.groupTitleInputField()
707
+ .should('have.value', 'Group title B');
708
+ });
709
+ });
710
+
711
+ dragAndDropResponseOptions.tests.verifyDisabledStateOfGroupDeleteButton();
712
+ },
713
+
714
+ verifyDisabledStateOfGroupDeleteButton: () => {
715
+ it('When only one group is present, the delete button should be in disabled state', () => {
716
+ dragAndDropResponseOptions.deleteGroupButton()
717
+ .should('be.disabled');
718
+ });
719
+ },
720
+
721
+ verifyDisabledStateOfOptionDeleteButton: () => {
722
+ it('When only two options are present, the delete buttons should be in disabled state', () => {
723
+ optionsWrapperComponent.optionsSectionWrapper()
724
+ .within(() => {
725
+ optionsWrapperComponent.deleteOptionButton()
726
+ .each(($element) => {
727
+ cy.wrap($element)
728
+ .should('be.disabled');
729
+ });
730
+ });
731
+ });
732
+ },
733
+ }
734
+ export const dragAndDropResponseOptions = {
735
+ ...selectors,
736
+ steps,
737
+ tests
738
+ }