itemengine-cypress-automation 1.0.133-7thMarchFixes-0e78080.0 → 1.0.133

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. package/cypress/e2e/ILC/DesmosGraphing/previewTabContent.smoke.js +1 -2
  2. package/cypress/e2e/ILC/DrawingResponse/drawingResponsePreviewTabContents.smoke.js +53 -54
  3. package/cypress/e2e/ILC/FillInTheGapsOverImageTextNew/Scoring/partialDifferentWeightsBasic.js +0 -149
  4. package/cypress/e2e/ILC/FillInTheGapsOverImageTextNew/Scoring/partialDifferentWeightsMinimumAndPenaltyScoring.js +312 -0
  5. package/cypress/e2e/ILC/FillInTheGapsOverImageTextNew/additionalSettingsBasic.js +71 -0
  6. package/cypress/e2e/ILC/FillInTheGapsOverImageTextNew/minimumScoringPenaltyPointsAndRoundingDropdown.js +194 -0
  7. package/cypress/e2e/ILC/GeogebraActivity/additionalSettings.js +98 -0
  8. package/cypress/e2e/ILC/GeogebraActivity/editTabScoringSection.js +56 -0
  9. package/cypress/e2e/ILC/GeogebraActivity/gradingViewAndCorrectAnswerViewContents.smoke.js +106 -0
  10. package/cypress/e2e/ILC/GeogebraActivity/headerSection.js +74 -0
  11. package/cypress/e2e/ILC/GeogebraActivity/previewTabContent.smoke.js +91 -0
  12. package/cypress/e2e/ILC/GeogebraActivity/questionInstructions.js +28 -0
  13. package/cypress/e2e/ILC/Graphing/Scoring/allOrNothingPenaltyScoring.js +79 -0
  14. package/cypress/e2e/ILC/Graphing/Scoring/manuallyAndNonScoredScoring.js +253 -0
  15. package/cypress/e2e/ILC/Graphing/addBackgroundShapesSection.js +307 -0
  16. package/cypress/e2e/ILC/Graphing/additionalSettingsBasic.js +84 -0
  17. package/cypress/e2e/ILC/Graphing/editTabScoringSection.js +105 -0
  18. package/cypress/e2e/ILC/Graphing/headerSection.js +77 -0
  19. package/cypress/e2e/ILC/Graphing/layoutAndGridOptions.js +916 -0
  20. package/cypress/e2e/ILC/Graphing/minimumScoringPenaltyPointsAndRoundingDropdown.js +57 -0
  21. package/cypress/e2e/ILC/Graphing/previewContentsForAllViews.smoke.js +1 -1
  22. package/cypress/e2e/ILC/Graphing/specifyCorrectAnswerSection.js +72 -0
  23. package/cypress/e2e/ILC/Graphing/studentViewSettings.js +120 -0
  24. package/cypress/e2e/ILC/Graphing/toolsControlsAndBackgroundSection.js +858 -0
  25. package/cypress/e2e/ILC/ShortTextResponseNew/additionalSettings.js +337 -4
  26. package/cypress/fixtures/constants.js +1 -1
  27. package/cypress/fixtures/theme/ilc.json +3 -1
  28. package/cypress/pages/components/additionalSettingsAccessibilitySectionComponent.js +66 -0
  29. package/cypress/pages/components/additionalSettingsPanel.js +95 -90
  30. package/cypress/pages/components/autoScoredSpecifyCorrectAnswerSection.js +9 -7
  31. package/cypress/pages/components/backgroundImageUploadComponent.js +16 -14
  32. package/cypress/pages/components/colorPopupComponent.js +14 -17
  33. package/cypress/pages/components/commonComponents.js +1 -1
  34. package/cypress/pages/components/fillInTheGapsDropdownCommonComponent.js +1 -1
  35. package/cypress/pages/components/imageCanvasComponent.js +3 -3
  36. package/cypress/pages/components/index.js +2 -2
  37. package/cypress/pages/components/opacityComponent.js +1 -1
  38. package/cypress/pages/components/scoringSectionBaseEditTab.js +18 -0
  39. package/cypress/pages/components/studentResponseAreaAndLayoutComponent.js +1 -1
  40. package/cypress/pages/dialogBoxBase.js +1 -1
  41. package/cypress/pages/drawingResponsePage.js +35 -4
  42. package/cypress/pages/fillInTheGapsOverImageDropdownPage.js +2 -2
  43. package/cypress/pages/fillInTheGapsOverImageTextPage.js +2 -0
  44. package/cypress/pages/geogebraActivityPage.js +106 -0
  45. package/cypress/pages/graphingPage.js +1458 -77
  46. package/cypress/pages/index.js +1 -0
  47. package/cypress/pages/multipleSelectionPage.js +0 -1
  48. package/cypress/pages/shortTextResponsePage.js +155 -3
  49. package/cypress/pages/uploadResponsePage.js +0 -2
  50. package/package.json +2 -2
@@ -1,5 +1,6 @@
1
1
  import utilities from "../support/helpers/utilities";
2
- import { questionInstructionsComponent, createQuestionBasePage, scoringSectionBaseEditTab, autoScoredScoringPreviewTab, autoScoredStudentViewSettings, autoScoredSpecifyCorrectAnswerSection, commonComponents } from "./components";
2
+ import { questionInstructionsComponent, createQuestionBasePage, scoringSectionBaseEditTab, autoScoredScoringPreviewTab, autoScoredStudentViewSettings, autoScoredSpecifyCorrectAnswerSection, commonComponents, backgroundImageUploadComponent, imageCanvasComponent, opacityComponent, autoScoredScoringSectionMultiResponseType, additionalSettingsPanel } from "./components";
3
+ import { dialogBoxBase } from "./dialogBoxBase";
3
4
  const css = Cypress.env('css');
4
5
 
5
6
  const selectors = {
@@ -7,22 +8,68 @@ const selectors = {
7
8
  ...questionInstructionsComponent,
8
9
  ...autoScoredScoringPreviewTab,
9
10
  ...commonComponents,
11
+ ...imageCanvasComponent,
12
+ ...opacityComponent,
13
+ ...backgroundImageUploadComponent,
14
+ ...autoScoredScoringSectionMultiResponseType,
15
+ ...autoScoredSpecifyCorrectAnswerSection,
16
+ ...additionalSettingsPanel,
10
17
 
11
18
  //Edit tab
12
19
  graphEditTab: () => cy.get('[class*="GraphingWrapper"] .ngie-jxgbox svg'),
20
+ graphTitleGraphEditTab: () => cy.get('[class*="GraphHeaderFooter"] .title-container').eq(0),
21
+ xAxisGraphEditTab: () => cy.get('[class*="GraphingWrapper"] .ngie-jxgbox svg line[stroke-linecap="butt"]').eq(0),
22
+ yAxisGraphEditTab: () => cy.get('[class*="GraphingWrapper"] .ngie-jxgbox svg line[stroke-linecap="butt"]').eq(1),
23
+ xMinInputField: () => cy.get('[class*="GraphRightLeft"] [class*="CustomInputFieldWrapper"] input').eq(0),
24
+ xMinLabel: () => cy.get('[class*="GraphRightLeft"] [class*="CustomInputFieldLabel"]').eq(0),
25
+ xMaxInputField: () => cy.get('[class*="GraphRightLeft"] [class*="CustomInputFieldWrapper"] input').eq(1),
26
+ xMaxLabel: () => cy.get('[class*="GraphRightLeft"] [class*="CustomInputFieldLabel"]').eq(1),
27
+ yMaxLabel: () => cy.get('[class*="GraphHeaderFooter"] [class*="CustomInputFieldLabel"]').eq(0),
28
+ yMaxInputField: () => cy.get('[class*="GraphHeaderFooter"] input').eq(0),
29
+ yMinLabel: () => cy.get('[class*="GraphHeaderFooter"] [class*="CustomInputFieldLabel"]').eq(1),
30
+ yMinInputField: () => cy.get('[class*="GraphHeaderFooter"] input').eq(1),
31
+ titlePopupAddLabelLabel: () => cy.get('[aria-labelledby="alert-dialog-title"] .title-casing'),
32
+ titlePopupAddLabelInputField: () => cy.get('[aria-labelledby="alert-dialog-title"] [role="textbox"]'),
33
+ titlePopupCancelButton: () => cy.get('.compact-popup-action-button-wrapper button').eq(0),
34
+ titlePopupSaveButton: () => cy.get('.compact-popup-action-button-wrapper button').eq(1),
35
+ graphImageEditTab: () => cy.get('.ngie-jxgbox .JXGimage'),
13
36
  snapToGridCheckbox: () => cy.get('[data-ngie-testid="snap-to-grid-checkbox"] input'),
37
+ snapToGridLabel: () => cy.get('[data-ngie-testid="snap-to-grid-checkbox"] .MuiFormControlLabel-label'),
14
38
  graphLine: () => cy.get('line[tabindex="null"]'),
15
39
  graphCircle: () => cy.get('ellipse[stroke-linecap="butt"]'),
16
40
  graphPolygon: () => cy.get('polygon'),
17
41
  graphSine: () => cy.get('path[stroke-linecap="butt"][stroke-opacity="1"]'),
18
- graphPoint: (cx, cy) => cy.get(`[class*="GraphingWrapper"] .ngie-jxgbox svg ellipse[display="inline"][cx="${cx}"][cy="${cy}"]`),
42
+ textOnGraphEditTab: (graphText) => {
43
+ if (graphText) {
44
+ return cy.get('[class*="GraphingWrapper"] .ngie-jxgbox .JXGtext').contains(graphText)
45
+ } else {
46
+ return cy.get('[class*="GraphingWrapper"] .ngie-jxgbox .JXGtext')
47
+ }
48
+ },
49
+ toolsLabel: () => cy.get('[class*="CustomizedToolBarOptionsstyles__ToolbarLabel"]').eq(0),
50
+ xAxisLabelGraphEditTab: () => cy.get('.graph-left-wrapper .title-casing'),
51
+ yAxisLabelGraphEditTab: () => cy.get('.graph-footer .title-casing'),
52
+ controlsLabel: () => cy.get('[class*="CustomizedToolBarOptionsstyles__ToolbarLabel"]').eq(1),
19
53
  toolOptions: (toolOptionAriaLabel = null) => {
20
54
  if (toolOptionAriaLabel) {
21
- return cy.get('[class*="CustomizedToolBarOptionsstyles__DragAndDropWrapper"]').eq(0).find(`.icon-button-custom-format[aria-label*=${toolOptionAriaLabel}]`)
55
+ return cy.get('[class*="CustomizedToolBarOptionsstyles__DragAndDropWrapper"]').eq(0).find(`.icon-button-custom-format[aria-label*="${toolOptionAriaLabel}"]`)
22
56
  } else {
23
57
  return cy.get('[class*="CustomizedToolBarOptionsstyles__DragAndDropWrapper"]').eq(0).find(`.icon-button-custom-format`)
24
58
  }
25
59
  },
60
+ toolOptionsLabel: () => cy.get('[class*="CustomizedToolBarOptionsstyles__DragAndDropWrapper"]').eq(0).find(`[class*="DragItemstyles__LabelWrapper"]`),
61
+ toolOptionsTickIcon: () => cy.get('[class*="CustomizedToolBarOptionsstyles__DragAndDropWrapper"]').eq(0).find(`.tick-icon-wrapper`),
62
+ controlsOptionsLabel: () => cy.get('[class*="CustomizedToolBarOptionsstyles__DragAndDropWrapper"]').eq(1).find(`[class*="DragItemstyles__LabelWrapper"]`),
63
+ controlsTickIcon: () => cy.get('[class*="CustomizedToolBarOptionsstyles__DragAndDropWrapper"]').eq(1).find(`.tick-icon-wrapper`),
64
+ defaultToolDropdownLabel: () => cy.get('#Default-tool-dropdown-label'),
65
+ defaultToolDropdown: () => cy.get('#Default-tool-select'),
66
+ defaultToolDropdownOptions: (dropdownOption = null) => {
67
+ if (dropdownOption) {
68
+ return cy.get(`[aria-labelledby*="Default-tool-dropdown-label"] [role="option"][aria-label*="${dropdownOption}"]`)
69
+ } else {
70
+ return cy.get('[aria-labelledby*="Default-tool-dropdown-label"] [role="option"]')
71
+ }
72
+ },
26
73
  graphToolOptionEditTab: (toolOptionAriaLabel = null) => {
27
74
  if (toolOptionAriaLabel) {
28
75
  return cy.get('.graph-tools-wrapper').eq(0).find(`.single-select-toggle-group-double button[aria-label*=${toolOptionAriaLabel}]`)
@@ -32,60 +79,181 @@ const selectors = {
32
79
  },
33
80
  graphToolOptionSpecifyCorrectAnswer: (toolOptionAriaLabel = null) => {
34
81
  if (toolOptionAriaLabel) {
35
- return cy.get('.graph-tools-wrapper').eq(1).find(`.single-select-toggle-group-double button[aria-label*=${toolOptionAriaLabel}]`)
82
+ return cy.get('.graph-tools-wrapper').eq(1).find(`.single-select-toggle-group-double button[aria-label*="${toolOptionAriaLabel}"]`)
36
83
  } else {
37
84
  return cy.get('.graph-tools-wrapper').eq(1).find('.single-select-toggle-group-double button')
38
85
  }
39
86
  },
40
87
  graphToolOptionPreviewTab: (toolOptionAriaLabel = null) => {
41
88
  if (toolOptionAriaLabel) {
42
- return cy.get(`[class*="GraphingQuestion"] .single-select-toggle-group-double button[aria-label*=${toolOptionAriaLabel}]`)
89
+ return cy.get(`[class*="GraphingQuestion"] .single-select-toggle-group-double button[aria-label*="${toolOptionAriaLabel}"]`)
43
90
  } else {
44
91
  return cy.get('[class*="GraphingQuestion"] .single-select-toggle-group-double button')
45
92
  }
46
93
  },
47
94
  controlOptions: (toolOptionAriaLabel = null) => {
48
95
  if (toolOptionAriaLabel) {
49
- return cy.get('[class*="CustomizedToolBarOptionsstyles__DragAndDropWrapper"]').eq(1).find(`.icon-button-custom-format[aria-label*=${toolOptionAriaLabel}]`)
96
+ return cy.get('[class*="CustomizedToolBarOptionsstyles__DragAndDropWrapper"]').eq(1).find(`.icon-button-custom-format[aria-label*="${toolOptionAriaLabel}"]`)
50
97
  } else {
51
98
  return cy.get('[class*="CustomizedToolBarOptionsstyles__DragAndDropWrapper"]').eq(1).find('.icon-button-custom-format')
52
99
  }
53
100
  },
54
101
  graphControlOptionEditTab: (controlOptionAriaLabel = null) => {
55
102
  if (controlOptionAriaLabel) {
56
- return cy.get('[class*="GraphingToolsstyles__ControlsWrapper"]').eq(0).find(`button[aria-label*=${controlOptionAriaLabel}]`)
103
+ return cy.get('[class*="GraphingToolsstyles__ControlsWrapper"]').eq(0).find(`button[aria-label*="${controlOptionAriaLabel}"]`)
57
104
  } else {
58
105
  return cy.get('[class*="GraphingToolsstyles__ControlsWrapper"]').eq(0).find('button')
59
106
  }
60
107
  },
61
108
  graphControlOptionSpecifyCorrectAnswer: (controlOptionAriaLabel = null) => {
62
109
  if (controlOptionAriaLabel) {
63
- return cy.get('[class*="GraphingToolsstyles__ControlsWrapper"]').eq(1).find(`button[aria-label*=${controlOptionAriaLabel}]`)
110
+ return cy.get('[class*="GraphingToolsstyles__ControlsWrapper"]').eq(1).find(`button[aria-label*="${controlOptionAriaLabel}"]`)
64
111
  } else {
65
112
  return cy.get('[class*="GraphingToolsstyles__ControlsWrapper"]').eq(1).find('button')
66
113
  }
67
114
  },
68
115
  graphControlOptionPreviewTab: (controlOptionAriaLabel = null) => {
69
116
  if (controlOptionAriaLabel) {
70
- return cy.get(`[class*="GraphingQuestion"] [class*="GraphingToolsstyles__ControlsWrapper"] button[aria-label*=${controlOptionAriaLabel}]`)
117
+ return cy.get(`[class*="GraphingQuestion"] [class*="GraphingToolsstyles__ControlsWrapper"] button[aria-label*="${controlOptionAriaLabel}"]`)
71
118
  } else {
72
119
  return cy.get('[class*="GraphingQuestion"] [class*="GraphingToolsstyles__ControlsWrapper"] button')
73
120
  }
74
121
  },
75
122
  graphSpecifyCorrectAnswerSection: () => cy.get('.MuiAccordion-region .ngie-jxgbox svg'),
123
+ xAxisGraphSpecifyCorrectAnswerSection: () => cy.get('.MuiAccordion-region .ngie-jxgbox svg line[stroke-linecap="butt"]').eq(0),
124
+ yAxisGraphSpecifyCorrectAnswerSection: () => cy.get('.MuiAccordion-region .ngie-jxgbox svg line[stroke-linecap="butt"]').eq(1),
125
+ graphTitleSpecifyCorrectAnswerSection: () => cy.get('.MuiAccordion-region [class*="__GraphHeader"] .title-container'),
126
+ xAxisLabelGraphSpecifyCorrectAnswerSection: () => cy.get('.MuiAccordion-region .graph-left-wrapper .title-container'),
127
+ yAxisLabelGraphSpecifyCorrectAnswerSection: () => cy.get('.MuiAccordion-region .graph-footer .title-container'),
128
+ graphImageSpecifyCorrectAnswerSection: () => cy.get('.ngie-jxgbox image').eq(1),
129
+ textOnGraphSpecifyCorrectAnswerSection: (graphText) => {
130
+ if (graphText) {
131
+ return cy.get('.MuiAccordion-region .ngie-jxgbox .JXGtext').contains(graphText)
132
+ } else {
133
+ return cy.get('.MuiAccordion-region .ngie-jxgbox .JXGtext')
134
+ }
135
+ },
136
+ addBackgroundShapesLabel: () => cy.get('[class*="Graphingstyles__BackgroundShapeLabelWrapper"]'),
137
+ //Preview tab graph
76
138
  graphPreviewTab: () => cy.get('[class*="GraphingQuestion"] .ngie-jxgbox svg'),
139
+ graphTitlePreviewTab: () => cy.get('[class*="GraphingQuestion"] [class*="__GraphHeader"] .title-container'),
140
+ xAxisLabelGraphPreviewTab: () => cy.get('[class*="GraphingQuestion"] .graph-left-wrapper .title-container'),
141
+ yAxisLabelGraphPreviewTab: () => cy.get('[class*="GraphingQuestion"] .graph-footer .title-container'),
142
+ xAxisGraphPreviewTab: () => cy.get('[class*="GraphingQuestion"] .ngie-jxgbox svg line[stroke-linecap="butt"]').eq(0),
143
+ yAxisGraphPreviewTab: () => cy.get('[class*="GraphingQuestion"] .ngie-jxgbox svg line[stroke-linecap="butt"]').eq(1),
77
144
  graphLinePreviewTab: () => cy.get('[class*="GraphingQuestion"] .ngie-jxgbox svg').eq(0).find('line[tabindex="null"]'),
78
145
  graphLineSegmentsPreviewTab: () => cy.get('[class*="GraphingQuestion"] .ngie-jxgbox svg').eq(0).find('line[tabindex="0"]'),
79
146
  graphCirclePreviewTab: () => cy.get('[class*="GraphingQuestion"] .ngie-jxgbox svg').eq(0).find('ellipse[stroke-linecap="butt"]'),
80
147
  graphPolygonPreviewTab: () => cy.get('[class*="GraphingQuestion"] .ngie-jxgbox svg').eq(0).find('polygon'),
148
+ textOnGraphPreviewTab: (graphText) => {
149
+ if (graphText) {
150
+ return cy.get('[class*="GraphingQuestion"] .ngie-jxgbox .JXGtext').contains(graphText)
151
+ } else {
152
+ return cy.get('[class*="GraphingQuestion"] .ngie-jxgbox .JXGtext')
153
+ }
154
+ },
81
155
  graphSineAndParabolaPreviewTab: () => cy.get('[class*="GraphingQuestion"] .ngie-jxgbox svg').eq(0).find('path[stroke-linecap="butt"][stroke-opacity="1"]'),
156
+ repeatedPointsSwitch: () => cy.get('.repeated-points-wrapper .MuiSwitch-input'),
82
157
  graphLabelInputField: () => cy.get('.label-tool:visible'),
158
+ yAxisLabelGraphPreviewTab: () => cy.get('[class*="GraphingQuestion"] .graph-footer .title-container'),
83
159
 
84
160
  //Background
161
+ imagePropertiesLabel: () => cy.get('[class*="ImageProperties"] .settings-label'),
162
+ imageAlignmentLabel: () => cy.get('[class*="AlignmentWrapper"] .additional-settings-label'),
85
163
  patternRadioButton: () => cy.get('[type="radio"][aria-label="Pattern"]'),
164
+ patternLabel: () => cy.get('.ngie-radio-label[aria-label="Pattern"]'),
165
+ imageRadioButton: () => cy.get('[type="radio"][aria-label="Image"]'),
166
+ imageLabel: () => cy.get('.ngie-radio-label[aria-label="Image"]'),
167
+ blankCanvasRadioButton: () => cy.get('[type="radio"][aria-label="Blank canvas"]'),
168
+ blankCanvasLabel: () => cy.get('.ngie-radio-label[aria-label="Blank canvas"]'),
169
+ selectPatternLabel: () => cy.get('[class*="PatternSelectionWrapper"] .additional-settings-label'),
170
+ selectPatternOptions: (optionAriaLabel = null) => {
171
+ if (optionAriaLabel) {
172
+ return cy.get(`[class*="__StyledButton"][aria-label*="${optionAriaLabel}"]`)
173
+ } else {
174
+ return cy.get('[class*="__StyledButton"]')
175
+ }
176
+ },
177
+ selectPatternOptionsLabel: (optionAriaLabel = null) => {
178
+ if (optionAriaLabel) {
179
+ return cy.get(`[class*="__ListItem"] [aria-label*="${optionAriaLabel}"]`)
180
+ } else {
181
+ return cy.get('[class*="__ListItem"]')
182
+ }
183
+ },
184
+ selectPatternOptionSelectedIcon: () => cy.get('[class*="SelectedIcon"]'),
185
+ selectPatternImageAltTextLabel: () => cy.get('[class*="BackgroundControlsstyles__AltTextWrapper"] .text-label'),
186
+ selectPatternImageAltTextInputField: () => cy.get('[class*="BackgroundControlsstyles__AltTextWrapper"] input'),
187
+
188
+ //Grid options
189
+ gridOptionsAccordionLabel: () => cy.get('.customized-options-label').eq(1),
190
+ gridOptionsAccordion: () => cy.get('.ngie-accordion-summary').eq(1),
191
+ gridOptionsAccordionExpandIcon: () => cy.get('.ngie-accordion-summary [class*="expandIconWrapper"]').eq(1),
192
+ xToleranceLabel: () => cy.get('.xy-tolerance-input-wrapper .input-wrapper').eq(0),
193
+ xToleranceInputField: () => cy.get('.xy-tolerance-input-wrapper input').eq(0),
194
+ yToleranceLabel: () => cy.get('.xy-tolerance-input-wrapper .input-wrapper').eq(1),
195
+ yToleranceInputField: () => cy.get('.xy-tolerance-input-wrapper input').eq(1),
196
+ originOptionLabel: () => cy.get('.single-select-toggle-group-title').eq(0),
197
+ originToggleOptions: (ariaLabel = null) => {
198
+ if (ariaLabel) {
199
+ return cy.get(`[class*="single-select-toggle-button"][aria-label*="${ariaLabel}"]`)
200
+ } else {
201
+ return cy.get('[class*="single-select-toggle-button"]')
202
+ }
203
+ },
204
+ xAxisLabel: () => cy.get('[class*="AxisLabelWrapper"]').eq(0),
205
+ yAxisLabel: () => cy.get('[class*="AxisLabelWrapper"]').eq(1),
206
+ xGridSpacingLabel: () => cy.get('label[for="X grid spacing"]'),
207
+ xGridSpacingInputField: () => cy.get('input[id="X grid spacing"]'),
208
+ xTickIntervalLabel: () => cy.get('label[for="grid-options-x-tick-interval"]'),
209
+ xTickIntervalInputField: () => cy.get('input[id*="Tick interval"]').eq(0),
210
+ xDisplayAxisLabel: () => cy.get('[data-ngie-testid="display-axis-label-checkbox"] .MuiFormControlLabel-label').eq(0),
211
+ xRemoveTicksLabel: () => cy.get('[data-ngie-testid="remove-ticks-checkbox"] .MuiFormControlLabel-label').eq(0),
212
+ xShowTicksLabelsLabel: () => cy.get('[data-ngie-testid="show-tick-labels-checkbox"] .MuiFormControlLabel-label').eq(0),
213
+ xMinArrowLabel: () => cy.get('[data-ngie-testid="min-arrow-checkbox"] .MuiFormControlLabel-label').eq(0),
214
+ xMaxArrowLabel: () => cy.get('[data-ngie-testid="max-arrow-checkbox"] .MuiFormControlLabel-label').eq(0),
215
+ xDisplayCommaForThousandSeparatorLabel: () => cy.get('[data-ngie-testid="display-comma-for-thousand-separator-checkbox"] .MuiFormControlLabel-label').eq(0),
216
+ xDisplayAxisCheckbox: () => cy.get('[data-ngie-testid="display-axis-label-checkbox"] input').eq(0),
217
+ xRemoveTicksCheckbox: () => cy.get('[data-ngie-testid="remove-ticks-checkbox"] input').eq(0),
218
+ xShowTicksLabelsCheckbox: () => cy.get('[data-ngie-testid="show-tick-labels-checkbox"] input').eq(0),
219
+ xMinArrowCheckbox: () => cy.get('[data-ngie-testid="min-arrow-checkbox"] input').eq(0),
220
+ xMaxArrowCheckbox: () => cy.get('[data-ngie-testid="max-arrow-checkbox"] input').eq(0),
221
+ xDisplayCommaForThousandSeparatorCheckbox: () => cy.get('[data-ngie-testid="display-comma-for-thousand-separator-checkbox"] input').eq(0),
222
+ yGridSpacingLabel: () => cy.get('label[for="Y grid spacing"]'),
223
+ yGridSpacingInputField: () => cy.get('input[id*="Y grid spacing"]'),
224
+ yTickIntervalLabel: () => cy.get('label[for="grid-options-y-tick-interval"]'),
225
+ yTickIntervalInputField: () => cy.get('input[id*="Tick interval"]').eq(1),
226
+ yDisplayAxisLabel: () => cy.get('[data-ngie-testid="display-axis-label-checkbox"] .MuiFormControlLabel-label').eq(1),
227
+ yRemoveTicksLabel: () => cy.get('[data-ngie-testid="remove-ticks-checkbox"] .MuiFormControlLabel-label').eq(1),
228
+ yShowTicksLabelsLabel: () => cy.get('[data-ngie-testid="show-tick-labels-checkbox"] .MuiFormControlLabel-label').eq(1),
229
+ yMinArrowLabel: () => cy.get('[data-ngie-testid="min-arrow-checkbox"] .MuiFormControlLabel-label').eq(1),
230
+ yMaxArrowLabel: () => cy.get('[data-ngie-testid="max-arrow-checkbox"] .MuiFormControlLabel-label').eq(1),
231
+ yDisplayCommaForThousandSeparatorLabel: () => cy.get('[data-ngie-testid="display-comma-for-thousand-separator-checkbox"] .MuiFormControlLabel-label').eq(1),
232
+ yDisplayAxisCheckbox: () => cy.get('[data-ngie-testid="display-axis-label-checkbox"] input').eq(1),
233
+ yRemoveTicksCheckbox: () => cy.get('[data-ngie-testid="remove-ticks-checkbox"] input').eq(1),
234
+ yShowTicksLabelsCheckbox: () => cy.get('[data-ngie-testid="show-tick-labels-checkbox"] input').eq(1),
235
+ yMinArrowCheckbox: () => cy.get('[data-ngie-testid="min-arrow-checkbox"] input').eq(1),
236
+ yMaxArrowCheckbox: () => cy.get('[data-ngie-testid="max-arrow-checkbox"] input').eq(1),
237
+ yDisplayCommaForThousandSeparatorCheckbox: () => cy.get('[data-ngie-testid="display-comma-for-thousand-separator-checkbox"] input').eq(1),
238
+
239
+ //Layout
240
+ layoutAccordionLabel: () => cy.get('.customized-options-label').eq(0),
241
+ layoutAccordion: () => cy.get('.ngie-accordion-summary').eq(0),
242
+ layoutAccordionExpandIcon: () => cy.get('.ngie-accordion-summary [class*="expandIconWrapper"]').eq(0),
243
+ heightInputField: () => cy.get('.height-width-wrapper input').eq(0),
244
+ heightLabel: () => cy.get('label[for="Height (px)"]'),
245
+ widthInputField: () => cy.get('.height-width-wrapper input').eq(1),
246
+ widthLabel: () => cy.get('label[for="Width (px)"]'),
247
+ marginInputField: () => cy.get('.margin-input-wrapper input'),
248
+ marginLabel: () => cy.get('label[for="Margin (px)"]'),
249
+ makeResponsiveLabel: () => cy.get('.mobile-responsive-wrapper .MuiFormControlLabel-label'),
250
+ makeResponsiveSwitch: () => cy.get('.mobile-responsive-wrapper .MuiSwitch-switchBase'),
251
+ whatIsThisLabel: () => cy.get('.what-is-wrapper [class*="StyledLink"]'),
252
+ makeResponsiveHelpText: () => cy.get('[class*="WhatIsThisDescriptionWrapper"]'),
86
253
 
87
254
  //Reset popup
88
255
  resetPopupConfirmResetButton: () => cy.get('.accept-button'),
256
+ resetPopupCancelButton: () => cy.get('.reject-button'),
89
257
 
90
258
  //Grading view
91
259
  gradingViewQuestionSineWave: () => cy.get('.ngie-jxgbox').eq(0).find('path[stroke-linecap="butt"][stroke-opacity="1"]'),
@@ -105,93 +273,882 @@ const selectors = {
105
273
  correctIcon: () => cy.get('[data-icon="CorrectAnswer"]'),
106
274
  }
107
275
 
108
- const steps = {
109
- ...createQuestionBasePage.steps,
110
- ...questionInstructionsComponent.steps,
111
- ...scoringSectionBaseEditTab.steps,
112
- ...autoScoredScoringPreviewTab.steps,
113
- ...autoScoredStudentViewSettings.steps,
114
- ...autoScoredSpecifyCorrectAnswerSection.steps,
276
+ const steps = {
277
+ ...createQuestionBasePage.steps,
278
+ ...questionInstructionsComponent.steps,
279
+ ...scoringSectionBaseEditTab.steps,
280
+ ...autoScoredScoringPreviewTab.steps,
281
+ ...autoScoredStudentViewSettings.steps,
282
+ ...autoScoredSpecifyCorrectAnswerSection.steps,
283
+ ...imageCanvasComponent.steps,
284
+ ...opacityComponent.steps,
285
+ ...backgroundImageUploadComponent.steps,
286
+ ...autoScoredScoringSectionMultiResponseType.steps,
287
+ ...commonComponents.steps,
288
+ ...additionalSettingsPanel.steps,
289
+
290
+ //Edit tab
291
+ /**
292
+ * This function selects tool options
293
+ * @param {string[]} toolOptionAriaLabelArray array aria-label of tool options
294
+ */
295
+ selectToolOptions: (toolOptionAriaLabelArray) => {
296
+ toolOptionAriaLabelArray.forEach((toolOptionAriaLabel) => {
297
+ graphingPage.toolOptions(toolOptionAriaLabel)
298
+ .click();
299
+ });
300
+ },
301
+
302
+ /**
303
+ * This function de-selects tool options
304
+ * @param {string[]} toolOptionAriaLabelArray array aria-label of tool options
305
+ */
306
+ deselectToolOptions: (toolOptionAriaLabelArray) => {
307
+ toolOptionAriaLabelArray.forEach((toolOptionAriaLabel) => {
308
+ graphingPage.toolOptions(toolOptionAriaLabel)
309
+ .click();
310
+ });
311
+ },
312
+
313
+ /**
314
+ * This function selects tool options
315
+ * @param {string[]} controlOptionAriaLabel array aria-label of tool options
316
+ */
317
+ selectControl: (controlOptionAriaLabel) => {
318
+ graphingPage.controlOptions(controlOptionAriaLabel)
319
+ .click();
320
+ },
321
+
322
+ /**
323
+ * This function de-selects tool options
324
+ * @param {string[]} controlOptionAriaLabel array aria-label of tool options
325
+ */
326
+ deselectControl: (controlOptionAriaLabel) => {
327
+ graphingPage.controlOptions(controlOptionAriaLabel)
328
+ .click();
329
+ },
330
+
331
+ checkPatternBackground: () => {
332
+ graphingPage.patternRadioButton()
333
+ .click();
334
+ },
335
+
336
+ expandDefaultToolDropdown: () => {
337
+ graphingPage.defaultToolDropdown()
338
+ .click();
339
+ },
340
+
341
+ /**
342
+ * This function verifies checked state of radio buttons
343
+ * @param {('Blank canvas'|'Image'|'Pattern')} radioButton
344
+ */
345
+ verifyBackgroundRadioButtonChecked: (radioButton) => {
346
+ switch (radioButton) {
347
+ case 'Pattern':
348
+ graphingPage.patternRadioButton()
349
+ .should('be.checked');
350
+ break;
351
+ case 'Image':
352
+ graphingPage.imageRadioButton()
353
+ .should('be.checked');
354
+ break;
355
+ case 'Blank canvas':
356
+ graphingPage.blankCanvasRadioButton()
357
+ .should('be.checked');
358
+ break;
359
+ default:
360
+ throw new Error('Invalid radio button');
361
+ }
362
+ },
363
+
364
+ /**
365
+ * This function checks radio buttons
366
+ * @param {('Blank canvas'|'Image'|'Pattern')} radioButton
367
+ */
368
+ checkBackgroundRadioButton: (radioButton) => {
369
+ switch (radioButton) {
370
+ case 'Pattern':
371
+ graphingPage.patternRadioButton()
372
+ .click()
373
+ .should('be.checked');
374
+ break;
375
+ case 'Image':
376
+ graphingPage.imageRadioButton()
377
+ .click()
378
+ .should('be.checked');
379
+ break;
380
+ case 'Blank canvas':
381
+ graphingPage.blankCanvasRadioButton()
382
+ .click()
383
+ .should('be.checked');
384
+ break;
385
+ default:
386
+ throw new Error('Invalid radio button');
387
+ }
388
+ },
389
+
390
+ /**
391
+ * This function selects the select pattern option
392
+ * @param {string} optionLabel label of the option to be selected
393
+ */
394
+ selectSelectPatternOption: (optionLabel) => {
395
+ graphingPage.selectPatternOptions(optionLabel)
396
+ .click();
397
+ },
398
+
399
+ /**
400
+ * This function verifies the selected select pattern option
401
+ * @param {('Grid'|'Lines'|'Dots'|'Circular'|'Quadrant')} optionLabel label of the option to be selected
402
+ */
403
+ verifySelectPatternOptionSelected: (optionLabel) => {
404
+ graphingPage.selectPatternOptions(optionLabel)
405
+ .within(() => {
406
+ utilities.verifyElementVisibilityState(graphingPage.selectPatternOptionSelectedIcon(), 'exist');
407
+ })
408
+ },
409
+
410
+ /**
411
+ * This function selects dropdown option from default tool dropdown
412
+ * @param {string} dropdownOption aria-label of the dropdown option
413
+ */
414
+ selectOptionFromDefaultToolDropdown: (dropdownOption) => {
415
+ graphingPage.defaultToolDropdownOptions(dropdownOption)
416
+ .click();
417
+ },
418
+
419
+ /**
420
+ * @param {string} fileFormat format of the uploaded file in the graph
421
+ * @description this function verifies the attribute of the image has the expected file format
422
+ */
423
+ verifyUploadedImageInGraphEditTab: (fileFormat) => {
424
+ graphingPage.graphImageEditTab()
425
+ .invoke('attr', 'xlink:href')
426
+ .should('include', fileFormat);
427
+ },
428
+
429
+ /**
430
+ * This function verifies the input field of select pattern alt text
431
+ * @param {string} inputText value of input field text
432
+ */
433
+ verifySelectPatternImageAltTextInputField: (inputText) => {
434
+ graphingPage.selectPatternImageAltTextInputField()
435
+ .should('have.value', inputText)
436
+ },
437
+
438
+ verifyImagePropertiesLabel: () => {
439
+ graphingPage.imagePropertiesLabel()
440
+ .contains('Image properties');
441
+ },
442
+
443
+ verifyImageFitsToGraphEditTab: () => {
444
+ graphingPage.graphImageEditTab()
445
+ .invoke('attr', 'width')
446
+ .then((imageValue) => {
447
+ graphingPage.widthInputField()
448
+ .invoke('attr', 'value')
449
+ .then((widthInputFieldValue) => {
450
+ expect(imageValue).to.eq(widthInputFieldValue);
451
+ });
452
+ });
453
+ },
454
+
455
+ verifyImageDoesNotFitToGraphEditTab: () => {
456
+ graphingPage.graphImageEditTab()
457
+ .invoke('attr', 'width')
458
+ .then((imageValue) => {
459
+ graphingPage.widthInputField()
460
+ .invoke('attr', 'value')
461
+ .then((widthInputFieldValue) => {
462
+ expect(imageValue).to.not.eq(widthInputFieldValue);
463
+ });
464
+ });
465
+ },
466
+
467
+ verifyImageTopLeftAlignedGraphEditTab: () => {
468
+ graphingPage.graphImageEditTab()
469
+ .should('have.attr', 'x', '0')
470
+ .and('have.attr', 'y', '0');
471
+ },
472
+
473
+ verifyImageTopRightAlignedGraphEditTab: () => {
474
+ graphingPage.graphImageEditTab()
475
+ .should('not.have.attr', 'x', '0')
476
+ .and('have.attr', 'y', '0');
477
+ },
478
+
479
+ verifyImageCenterAlignedGraphEditTab: () => {
480
+ graphingPage.graphImageEditTab()
481
+ .should('not.have.attr', 'x', '0')
482
+ .and('not.have.attr', 'y', '0');
483
+ },
484
+
485
+ verifyImageOpacityGraphEditTab: (opacity) => {
486
+ const opacityValue = opacity / 100;
487
+ graphingPage.graphImageEditTab()
488
+ .should('have.attr', 'opacity', `${opacityValue}`);
489
+ },
490
+
491
+ /**
492
+ * This function plots points on the graph on Edit tab
493
+ * @param {Object[]} coordinates - An array containing x and y coordinates along with their ranges
494
+ * @param {number} coordinates[].x - x coordinate to be plotted on the graph
495
+ * @param {number} coordinates[].xRange - range of x coordinate
496
+ * @param {number} coordinates[].y - y coordinate to be plotted on the graph
497
+ * @param {number} coordinates[].yRange - range of y coordinate
498
+ */
499
+ plotPointsOnGraphEditTab: (coordinates) => {
500
+ coordinates.forEach(({ x, xRange, y, yRange }) => {
501
+ graphingPage.graphEditTab()
502
+ .then(($graphElement) => {
503
+ const graphWidth = $graphElement[0].clientWidth;
504
+ const graphHeight = $graphElement[0].clientHeight;
505
+ const originX = graphWidth / 2;
506
+ const originY = graphHeight / 2;
507
+ const xPixel = originX + x * (graphWidth / xRange);
508
+ const yPixel = originY - y * (graphHeight / yRange);
509
+ graphingPage.graphEditTab()
510
+ .click(xPixel, yPixel, { force: true });
511
+ });
512
+ });
513
+ },
514
+
515
+ /**
516
+ * This function verifies the plotted points on the graph on Edit tab
517
+ * @param {Object[]} coordinates - An array containing x and y coordinates along with their ranges
518
+ * @param {number} coordinates[].x - x coordinate to be plotted on the graph
519
+ * @param {number} coordinates[].xRange - range of x coordinate
520
+ * @param {number} coordinates[].y - y coordinate to be plotted on the graph
521
+ * @param {number} coordinates[].yRange - range of y coordinate
522
+ */
523
+ verifyPointsPlottedOnEditTabGraph: (coordinates) => {
524
+ coordinates.forEach(({ x, xRange, y, yRange }) => {
525
+ graphingPage.graphEditTab()
526
+ .then(($graphElement) => {
527
+ const graphWidth = $graphElement[0].clientWidth;
528
+ const graphHeight = $graphElement[0].clientHeight;
529
+ const originX = graphWidth / 2;
530
+ const originY = graphHeight / 2;
531
+ const xPixel = originX + x * (graphWidth / xRange);
532
+ const yPixel = originY - y * (graphHeight / yRange);
533
+ cy.get(`[class*="GraphingWrapper"] .ngie-jxgbox svg ellipse[display="inline"][cx="${xPixel}"][cy="${yPixel}"]`)
534
+ .should('be.visible');
535
+ });
536
+ });
537
+ },
538
+
539
+ /**
540
+ * This function verifies the points do not exist on the graph on Edit tab
541
+ * @param {Object[]} coordinates - An array containing x and y coordinates along with their ranges
542
+ * @param {number} coordinates[].x - x coordinate to be plotted on the graph
543
+ * @param {number} coordinates[].xRange - range of x coordinate
544
+ * @param {number} coordinates[].y - y coordinate to be plotted on the graph
545
+ * @param {number} coordinates[].yRange - range of y coordinate
546
+ */
547
+ verifyPointsPlottedNotExistOnEditTabGraph: (coordinates) => {
548
+ coordinates.forEach(({ x, xRange, y, yRange }) => {
549
+ graphingPage.graphEditTab()
550
+ .then(($graphElement) => {
551
+ const graphWidth = $graphElement[0].clientWidth;
552
+ const graphHeight = $graphElement[0].clientHeight;
553
+ const originX = graphWidth / 2;
554
+ const originY = graphHeight / 2;
555
+ const xPixel = originX + x * (graphWidth / xRange);
556
+ const yPixel = originY - y * (graphHeight / yRange);
557
+ cy.get(`[class*="GraphingWrapper"] .ngie-jxgbox svg ellipse[display="inline"][cx="${xPixel}"][cy="${yPixel}"]`)
558
+ .should('not.exist');
559
+ });
560
+ });
561
+ },
562
+
563
+ /**
564
+ * @description This function selects the control option from graph
565
+ * @param {string} controlOption aria label of the control option to be selected
566
+ */
567
+ selectGraphControlOptionEditTab: (controlOption) => {
568
+ graphingPage.graphControlOptionEditTab(controlOption)
569
+ .click();
570
+ },
571
+
572
+ /**
573
+ * This function verifies the x min value
574
+ * @param {number} xMinValue input field value of x min
575
+ */
576
+ verifyXMinInputFieldValue: (xMinValue) => {
577
+ graphingPage.xMinInputField()
578
+ .should('have.value', xMinValue)
579
+ },
580
+
581
+ /**
582
+ * This function verifies the x max value
583
+ * @param {number} xMaxValue input field value of x max
584
+ */
585
+ verifyXMaxInputFieldValue: (xMaxValue) => {
586
+ graphingPage.xMaxInputField()
587
+ .should('have.value', xMaxValue)
588
+ },
589
+
590
+ /**
591
+ * This function verifies the y min value
592
+ * @param {number} yMinValue input field value of y min
593
+ */
594
+ verifyYMinInputFieldValue: (yMinValue) => {
595
+ graphingPage.yMinInputField()
596
+ .should('have.value', yMinValue)
597
+ },
598
+
599
+ /**
600
+ * This function verifies the y max value
601
+ * @param {number} yMaxValue input field value of y max
602
+ */
603
+ verifyYMaxInputFieldValue: (yMaxValue) => {
604
+ graphingPage.yMaxInputField()
605
+ .should('have.value', yMaxValue)
606
+ },
607
+
608
+ /**
609
+ * This function enters and verifies the text in X max input field
610
+ * @param {number} xMaxValue value to be added to x max input field
611
+ */
612
+ enterTextInXMaxInputField: (xMaxValue) => {
613
+ graphingPage.xMaxInputField()
614
+ .clear()
615
+ .type(xMaxValue)
616
+ .should('have.value', xMaxValue)
617
+ },
618
+
619
+ /**
620
+ * This function enters and verifies the text in X min input field
621
+ * @param {number} xMinValue value to be added to x min input field
622
+ */
623
+ enterTextInXMinInputField: (xMinValue) => {
624
+ graphingPage.xMinInputField()
625
+ .clear()
626
+ .type(xMinValue)
627
+ .should('have.value', xMinValue)
628
+ },
629
+
630
+ /**
631
+ * This function enters and verifies the text in Y max input field
632
+ * @param {number} yMaxValue value to be added to y max input field
633
+ */
634
+ enterTextInYMaxInputField: (yMaxValue) => {
635
+ graphingPage.yMaxInputField()
636
+ .clear()
637
+ .type(yMaxValue)
638
+ .should('have.value', yMaxValue)
639
+ },
640
+
641
+ /**
642
+ * This function enters and verifies the text in Y min input field
643
+ * @param {number} yMinValue value to be added to y min input field
644
+ */
645
+ enterTextInYMinInputField: (yMinValue) => {
646
+ graphingPage.yMaxInputField()
647
+ .clear()
648
+ .type(yMinValue)
649
+ .should('have.value', yMinValue)
650
+ },
651
+
652
+ clickOnGraphTitle: () => {
653
+ graphingPage.graphTitleGraphEditTab()
654
+ .click();
655
+ },
656
+
657
+ clickOnXAxisLabel: () => {
658
+ graphingPage.xAxisLabel()
659
+ .click();
660
+ },
661
+
662
+ clickOnYAxisLabel: () => {
663
+ graphingPage.yAxisLabel()
664
+ .click();
665
+ },
666
+
667
+ enterTextInTitlePopupAddLabelInputField: (text) => {
668
+ graphingPage.titlePopupAddLabelInputField()
669
+ .clear()
670
+ .type(text)
671
+ .should('have.text', text);
672
+ },
673
+
674
+ clickOnTitlePopupCancelButton: () => {
675
+ graphingPage.titlePopupCancelButton()
676
+ .click();
677
+ },
678
+
679
+ clickOnTitlePopupSaveButton: () => {
680
+ graphingPage.titlePopupSaveButton()
681
+ .click();
682
+ },
683
+
684
+ verifyXAxisMinArrowNotExistGraphEditTab: () => {
685
+ graphingPage.xAxisGraphEditTab()
686
+ .should('not.have.attr', 'marker-start');
687
+ },
688
+
689
+ verifyXAxisMinArrowExistGraphEditTab: () => {
690
+ graphingPage.xAxisGraphEditTab()
691
+ .should('have.attr', 'marker-start');
692
+ },
693
+
694
+ verifyXAxisMaxArrowExistGraphEditTab: () => {
695
+ graphingPage.xAxisGraphEditTab()
696
+ .should('have.attr', 'marker-end');
697
+ },
698
+
699
+ verifyXAxisMaxArrowNotExistGraphEditTab: () => {
700
+ graphingPage.xAxisGraphEditTab()
701
+ .should('not.have.attr', 'marker-end');
702
+ },
703
+
704
+ verifyYAxisMinArrowNotExistGraphEditTab: () => {
705
+ graphingPage.yAxisGraphEditTab()
706
+ .should('not.have.attr', 'marker-start');
707
+ },
708
+
709
+ verifyYAxisMinArrowExistGraphEditTab: () => {
710
+ graphingPage.yAxisGraphEditTab()
711
+ .should('have.attr', 'marker-start');
712
+ },
713
+
714
+ verifyYAxisMaxArrowExistGraphEditTab: () => {
715
+ graphingPage.yAxisGraphEditTab()
716
+ .should('have.attr', 'marker-end');
717
+ },
718
+
719
+ verifyYAxisMaxArrowNotExistGraphEditTab: () => {
720
+ graphingPage.yAxisGraphEditTab()
721
+ .should('not.have.attr', 'marker-end');
722
+ },
723
+
724
+ /**
725
+ * @description This function selects the tool option from graph
726
+ * @param {string} toolOption aria label of the tool option to be selected
727
+ */
728
+ selectGraphToolOptionEditTab: (toolOption) => {
729
+ graphingPage.graphToolOptionEditTab(toolOption)
730
+ .click();
731
+ },
732
+
733
+ /**
734
+ * @description This function verifies the tool option is in selected state
735
+ * @param {string} toolOption aria label of the tool option to be verified selected
736
+ */
737
+ verifyToolOptionSelectedEditTab: (toolOptionAriaLabel) => {
738
+ graphingPage.graphToolOptionEditTab(toolOptionAriaLabel)
739
+ .should('have.class', 'single-select-toggle-button-selected');
740
+ },
741
+
742
+ /**
743
+ * @description This function verifies the tool option is not in selected state
744
+ * @param {string} toolOption aria label of the tool option to be verified not selected
745
+ */
746
+ verifyToolOptionNotSelectedEditTab: (toolOptionAriaLabelArray) => {
747
+ toolOptionAriaLabelArray.forEach((toolOptionAriaLabel) => {
748
+ graphingPage.graphToolOptionEditTab(toolOptionAriaLabel)
749
+ .should('not.have.class', 'single-select-toggle-button-selected');
750
+ });
751
+ },
752
+
753
+ //Grid options
754
+ verifyGridOptionsAccordionExpanded: () => {
755
+ graphingPage.gridOptionsAccordion()
756
+ .should('have.attr', 'aria-expanded', 'true')
757
+ },
758
+
759
+ collapseGridOptionsAccordion: () => {
760
+ graphingPage.gridOptionsAccordion()
761
+ .click()
762
+ .should('have.attr', 'aria-expanded', 'false')
763
+ },
764
+
765
+ expandGridOptionsAccordion: () => {
766
+ graphingPage.gridOptionsAccordion()
767
+ .click();
768
+ steps.verifyGridOptionsAccordionExpanded();
769
+ },
770
+
771
+ checkSnapToGridCheckbox: () => {
772
+ graphingPage.snapToGridCheckbox()
773
+ .click()
774
+ .should('be.checked');
775
+ },
776
+
777
+ verifySnapToCheckboxIsUnchecked: () => {
778
+ graphingPage.snapToGridCheckbox()
779
+ .should('not.be.checked');
780
+ },
781
+
782
+ /**
783
+ * This function selects toggle option
784
+ * @param {string} ariaLabel of the toggle option
785
+ */
786
+ selectOriginOption: (ariaLabel) => {
787
+ graphingPage.originToggleOptions(ariaLabel)
788
+ .click();
789
+ },
790
+
791
+ /**
792
+ * This function verifies the value of x tolerance input field
793
+ * @param {number} xTol value of x tolerance input field
794
+ */
795
+ verifyXToleranceInputFieldValue: (xTol) => {
796
+ graphingPage.xToleranceInputField()
797
+ .should('have.value', xTol)
798
+ },
799
+
800
+ /**
801
+ * This function enters and verifies the value of x tolerance input field
802
+ * @param {number} xTol value of x tolerance input field
803
+ */
804
+ enterInputToXToleranceInputFieldValue: (xTol) => {
805
+ graphingPage.xToleranceInputField()
806
+ .clear()
807
+ .type(xTol)
808
+ .should('have.value', xTol)
809
+ },
810
+
811
+ /**
812
+ * This function verifies the value of y tolerance input field
813
+ * @param {number} yTol value of y tolerance input field
814
+ */
815
+ verifyYToleranceInputFieldValue: (yTol) => {
816
+ graphingPage.xToleranceInputField()
817
+ .should('have.value', yTol)
818
+ },
819
+
820
+ /**
821
+ * This function enters and verifies the value of y tolerance input field
822
+ * @param {number} yTol value of y tolerance input field
823
+ */
824
+ enterInputToYToleranceInputFieldValue: (yTol) => {
825
+ graphingPage.yToleranceInputField()
826
+ .clear()
827
+ .type(yTol)
828
+ .should('have.value', yTol)
829
+ },
830
+
831
+ /**
832
+ * This verifies the value in x grid spacing
833
+ * @param {number} xGridSpacing x grid spacing
834
+ */
835
+ verifyXGridSpacingInputFieldValue: (xGridSpacing) => {
836
+ graphingPage.xGridSpacingInputField()
837
+ .should('have.value', xGridSpacing)
838
+ },
839
+
840
+ /**
841
+ * This enters and verifies the value in x grid spacing
842
+ * @param {number} xGridSpacing x grid spacing
843
+ */
844
+ enterTextInXGridSpacingInputFieldValue: (xGridSpacing) => {
845
+ graphingPage.xGridSpacingInputField()
846
+ .clear()
847
+ .type(xGridSpacing)
848
+ .blur()
849
+ .should('have.value', xGridSpacing)
850
+ },
851
+
852
+ /**
853
+ * This verifies the value in x tick interval
854
+ * @param {number} xTickInterval x tick interval
855
+ */
856
+ verifyXTickIntervalInputFieldValue: (xTickInterval) => {
857
+ graphingPage.xTickIntervalInputField()
858
+ .should('have.value', xTickInterval)
859
+ },
860
+
861
+ /**
862
+ * This enters and verifies the value in x tick interval
863
+ * @param {number} xTickInterval x tick interval
864
+ */
865
+ enterTextInXTickIntervalInputFieldValue: (xTickInterval) => {
866
+ graphingPage.xTickIntervalInputField()
867
+ .clear()
868
+ .type(xTickInterval)
869
+ .should('have.value', xTickInterval)
870
+ },
871
+
872
+ verifyXDisplayAxisCheckboxChecked: () => {
873
+ graphingPage.xDisplayAxisCheckbox()
874
+ .should('be.checked')
875
+ },
876
+
877
+ uncheckXDisplayAxisCheckbox: () => {
878
+ graphingPage.xDisplayAxisCheckbox()
879
+ .click()
880
+ .should('not.be.checked')
881
+ },
882
+
883
+ verifyXRemoveTicksCheckboxChecked: () => {
884
+ graphingPage.xRemoveTicksCheckbox()
885
+ .should('be.checked')
886
+ },
887
+
888
+ uncheckXRemoveTicksCheckbox: () => {
889
+ graphingPage.xRemoveTicksCheckbox()
890
+ .click()
891
+ .should('not.be.checked')
892
+ },
893
+
894
+ checkXRemoveTicksCheckbox: () => {
895
+ graphingPage.xRemoveTicksCheckbox()
896
+ .click()
897
+ .should('be.checked')
898
+ },
899
+
900
+ verifyXShowTicksLabelCheckboxChecked: () => {
901
+ graphingPage.xShowTicksLabelsCheckbox()
902
+ .should('be.checked')
903
+ },
904
+
905
+ uncheckXShowTicksLabelCheckbox: () => {
906
+ graphingPage.xShowTicksLabelsCheckbox()
907
+ .click()
908
+ .should('not.be.checked')
909
+ },
910
+
911
+ checkXShowTicksLabelCheckbox: () => {
912
+ graphingPage.xShowTicksLabelsCheckbox()
913
+ .click()
914
+ .should('be.checked')
915
+ },
916
+
917
+ verifyXMinArrowCheckboxChecked: () => {
918
+ graphingPage.xMinArrowCheckbox()
919
+ .should('be.checked')
920
+ },
921
+
922
+ uncheckXMinArrowCheckbox: () => {
923
+ graphingPage.xMinArrowCheckbox()
924
+ .click()
925
+ .should('not.be.checked')
926
+ },
927
+
928
+ verifyXMaxArrowCheckboxChecked: () => {
929
+ graphingPage.xMaxArrowCheckbox()
930
+ .should('be.checked')
931
+ },
932
+
933
+ uncheckXMaxArrowCheckbox: () => {
934
+ graphingPage.xMaxArrowCheckbox()
935
+ .click()
936
+ .should('not.be.checked')
937
+ },
938
+
939
+ verifyXDisplayCommaForThousandSeparatorCheckboxChecked: () => {
940
+ graphingPage.xDisplayCommaForThousandSeparatorCheckbox()
941
+ .should('be.checked')
942
+ },
943
+
944
+ uncheckXDisplayCommaForThousandSeparatorCheckbox: () => {
945
+ graphingPage.xDisplayCommaForThousandSeparatorCheckbox()
946
+ .click()
947
+ .should('not.be.checked')
948
+ },
949
+
950
+ /**
951
+ * This verifies the value in y grid spacing
952
+ * @param {number} yGridSpacing y grid spacing
953
+ */
954
+ verifyYGridSpacingInputFieldValue: (yGridSpacing) => {
955
+ graphingPage.yGridSpacingInputField()
956
+ .should('have.value', yGridSpacing)
957
+ },
958
+
959
+ /**
960
+ * This enters and verifies the value in y grid spacing
961
+ * @param {number} yGridSpacing y grid spacing
962
+ */
963
+ enterTextInYGridSpacingInputFieldValue: (yGridSpacing) => {
964
+ graphingPage.yGridSpacingInputField()
965
+ .clear()
966
+ .type(yGridSpacing)
967
+ .blur()
968
+ .should('have.value', yGridSpacing)
969
+ },
970
+
971
+ /**
972
+ * This verifies the value in y tick interval
973
+ * @param {number} yTickInterval y tick interval
974
+ */
975
+ verifyYTickIntervalInputFieldValue: (yTickInterval) => {
976
+ graphingPage.yTickIntervalInputField()
977
+ .should('have.value', yTickInterval)
978
+ },
979
+
980
+ /**
981
+ * This enters and verifies the value in y tick interval
982
+ * @param {number} yTickInterval y tick interval
983
+ */
984
+ enterTextInYTickIntervalInputFieldValue: (yTickInterval) => {
985
+ graphingPage.yTickIntervalInputField()
986
+ .clear()
987
+ .type(yTickInterval)
988
+ .should('have.value', yTickInterval)
989
+ },
990
+
991
+ verifyYDisplayAxisCheckboxChecked: () => {
992
+ graphingPage.yDisplayAxisCheckbox()
993
+ .should('be.checked')
994
+ },
995
+
996
+ uncheckYDisplayAxisCheckbox: () => {
997
+ graphingPage.yDisplayAxisCheckbox()
998
+ .click()
999
+ .should('not.be.checked')
1000
+ },
1001
+
1002
+ verifyYRemoveTicksCheckboxChecked: () => {
1003
+ graphingPage.yRemoveTicksCheckbox()
1004
+ .should('be.checked')
1005
+ },
1006
+
1007
+ uncheckYRemoveTicksCheckbox: () => {
1008
+ graphingPage.yRemoveTicksCheckbox()
1009
+ .click()
1010
+ .should('not.be.checked')
1011
+ },
1012
+
1013
+ verifyYShowTicksLabelCheckboxChecked: () => {
1014
+ graphingPage.yShowTicksLabelsCheckbox()
1015
+ .should('be.checked')
1016
+ },
1017
+
1018
+ uncheckYShowTicksLabelCheckbox: () => {
1019
+ graphingPage.yShowTicksLabelsCheckbox()
1020
+ .click()
1021
+ .should('not.be.checked')
1022
+ },
1023
+
1024
+ checkYShowTicksLabelCheckbox: () => {
1025
+ graphingPage.yShowTicksLabelsCheckbox()
1026
+ .click()
1027
+ .should('be.checked')
1028
+ },
1029
+
1030
+ verifyYMinArrowCheckboxChecked: () => {
1031
+ graphingPage.yMinArrowCheckbox()
1032
+ .should('be.checked')
1033
+ },
1034
+
1035
+ uncheckYMinArrowCheckbox: () => {
1036
+ graphingPage.yMinArrowCheckbox()
1037
+ .click()
1038
+ .should('not.be.checked')
1039
+ },
1040
+
1041
+ verifyYMaxArrowCheckboxChecked: () => {
1042
+ graphingPage.yMaxArrowCheckbox()
1043
+ .should('be.checked')
1044
+ },
115
1045
 
116
- //Edit tab
117
- /**
118
- * This function selects tool options
119
- * @param {string[]} toolOptionAriaLabelArray array aria-label of tool options
120
- */
121
- selectToolOptions: (toolOptionAriaLabelArray) => {
122
- toolOptionAriaLabelArray.forEach((toolOptionAriaLabel) => {
123
- graphingPage.toolOptions(toolOptionAriaLabel)
124
- .click();
125
- });
1046
+ uncheckYMaxArrowCheckbox: () => {
1047
+ graphingPage.yMaxArrowCheckbox()
1048
+ .click()
1049
+ .should('not.be.checked')
126
1050
  },
127
1051
 
128
- checkSnapToGridCheckbox: () => {
129
- graphingPage.snapToGridCheckbox()
130
- .click();
1052
+ verifyYDisplayCommaForThousandSeparatorCheckboxChecked: () => {
1053
+ graphingPage.yDisplayCommaForThousandSeparatorCheckbox()
1054
+ .should('be.checked')
131
1055
  },
132
1056
 
133
- checkPatternBackground: () => {
134
- graphingPage.patternRadioButton()
1057
+ uncheckYDisplayCommaForThousandSeparatorCheckbox: () => {
1058
+ graphingPage.yDisplayCommaForThousandSeparatorCheckbox()
1059
+ .click()
1060
+ .should('not.be.checked')
1061
+ },
1062
+
1063
+ //Layout
1064
+ verifyLayoutAccordionExpanded: () => {
1065
+ graphingPage.layoutAccordion()
1066
+ .should('have.attr', 'aria-expanded', 'true')
1067
+ },
1068
+
1069
+ collapseLayoutAccordion: () => {
1070
+ graphingPage.layoutAccordion()
1071
+ .click()
1072
+ .should('have.attr', 'aria-expanded', 'false')
1073
+ },
1074
+
1075
+ expandLayoutAccordion: () => {
1076
+ graphingPage.layoutAccordion()
135
1077
  .click();
1078
+ steps.verifyLayoutAccordionExpanded();
136
1079
  },
137
1080
 
138
1081
  /**
139
- * This function plots points on the graph on Edit tab
140
- * @param {Object[]} coordinates - An array containing x and y coordinates along with their ranges
141
- * @param {number} coordinates[].x - x coordinate to be plotted on the graph
142
- * @param {number} coordinates[].xRange - range of x coordinate
143
- * @param {number} coordinates[].y - y coordinate to be plotted on the graph
144
- * @param {number} coordinates[].yRange - range of y coordinate
145
- */
146
- plotPointsOnGraphEditTab: (coordinates) => {
147
- coordinates.forEach(({ x, xRange, y, yRange }) => {
148
- graphingPage.graphEditTab()
149
- .then(($graphElement) => {
150
- const graphWidth = $graphElement[0].clientWidth;
151
- const graphHeight = $graphElement[0].clientHeight;
152
- const originX = graphWidth / 2;
153
- const originY = graphHeight / 2;
154
- const xPixel = originX + x * (graphWidth / xRange);
155
- const yPixel = originY - y * (graphHeight / yRange);
156
- graphingPage.graphEditTab()
157
- .click(xPixel, yPixel, { force: true });
158
- });
159
- });
1082
+ * This function verifies height and width of graph
1083
+ * @param {number} width width of graph
1084
+ * @param {number} height height of graph
1085
+ */
1086
+ verifyHeightWidthOfGraphEditTab: (width, height) => {
1087
+ graphingPage.graphEditTab()
1088
+ .should('have.attr', 'height', height)
1089
+ .and('have.attr', 'width', width)
160
1090
  },
161
1091
 
162
1092
  /**
163
- * This function verifies the plotted points on the graph on Edit tab
164
- * @param {Object[]} coordinates - An array containing x and y coordinates along with their ranges
165
- * @param {number} coordinates[].x - x coordinate to be plotted on the graph
166
- * @param {number} coordinates[].xRange - range of x coordinate
167
- * @param {number} coordinates[].y - y coordinate to be plotted on the graph
168
- * @param {number} coordinates[].yRange - range of y coordinate
1093
+ * This function verifies the input field value
1094
+ * @param {('Height'|'Width'|'Margin')} inputField
1095
+ * @param {number} value value of input field
1096
+ */
1097
+ verifyLayoutInputFieldValue: (inputField, value) => {
1098
+ switch (inputField) {
1099
+ case 'Height':
1100
+ graphingPage.heightInputField()
1101
+ .should('have.value', value);
1102
+ break;
1103
+ case 'Width':
1104
+ graphingPage.widthInputField()
1105
+ .should('have.value', value);
1106
+ break;
1107
+ case 'Margin':
1108
+ graphingPage.marginInputField()
1109
+ .should('have.value', value);
1110
+ break;
1111
+ default:
1112
+ throw new Error('Invalid field');
1113
+ }
1114
+ },
1115
+
1116
+ /**
1117
+ * This function enters text in the input field
1118
+ * @param {number} value value of input field
169
1119
  */
170
- verifyPointsPlottedOnEditTabGraph: (coordinates) => {
171
- coordinates.forEach(({ x, xRange, y, yRange }) => {
172
- graphingPage.graphEditTab()
173
- .then(($graphElement) => {
174
- const graphWidth = $graphElement[0].clientWidth;
175
- const graphHeight = $graphElement[0].clientHeight;
176
- const originX = graphWidth / 2;
177
- const originY = graphHeight / 2;
178
- const xPixel = originX + x * (graphWidth / xRange);
179
- const yPixel = originY - y * (graphHeight / yRange);
180
- cy.get(`[class*="GraphingWrapper"] .ngie-jxgbox svg ellipse[display="inline"][cx="${xPixel}"][cy="${yPixel}"]`)
181
- .should('be.visible');
182
- });
183
- });
1120
+ enterValueInHeightInputField: (value) => {
1121
+ graphingPage.heightInputField()
1122
+ .clear()
1123
+ .type(value)
1124
+ .should('have.value', value)
184
1125
  },
185
1126
 
186
1127
  /**
187
- * @description This function selects the tool option from graph
188
- * @param {string} toolOption aria label of the tool option to be selected
189
- */
190
- selectGraphToolOptionEditTab: (toolOption) => {
191
- graphingPage.graphToolOptionEditTab(toolOption)
1128
+ * This function enters text in the input field
1129
+ * @param {number} value value of input field
1130
+ */
1131
+ enterValueInWidthInputField: (value) => {
1132
+ graphingPage.widthInputField()
1133
+ .clear()
1134
+ .type(value)
1135
+ .should('have.value', value)
1136
+ },
1137
+
1138
+ verifyMakeResponsiveIsChecked: () => {
1139
+ graphingPage.makeResponsiveSwitch()
1140
+ .should('have.class', 'Mui-checked');
1141
+ },
1142
+
1143
+ clickMakeResponsive: () => {
1144
+ graphingPage.makeResponsiveSwitch()
192
1145
  .click();
193
1146
  },
194
1147
 
1148
+ verifyMakeResponsiveIsUnchecked: () => {
1149
+ graphingPage.makeResponsiveSwitch()
1150
+ .should('not.have.class', 'Mui-checked');
1151
+ },
195
1152
 
196
1153
  //Specify correct answer section
197
1154
  /**
@@ -242,6 +1199,79 @@ const steps = {
242
1199
  });
243
1200
  },
244
1201
 
1202
+ /**
1203
+ * This function verifies plotted points on the graph in set correct answer section
1204
+ * @param {Object[]} coordinates - An array containing x and x coordinates along with their range
1205
+ * @param {number} coordinates[].x - x coordinate to be plotted on the graph
1206
+ * @param {number} coordinates[].xRange - range of x coordinate
1207
+ * @param {number} coordinates[].y - y coordinate to be plotted on the graph
1208
+ * @param {number} coordinates[].yRange - range of y coordinate
1209
+ */
1210
+ verifyPointsPlottedNotExistOnSpecifyCorrectAnswerSection: (coordinates) => {
1211
+ coordinates.forEach(({ x, xRange, y, yRange }) => {
1212
+ graphingPage.graphSpecifyCorrectAnswerSection()
1213
+ .then(($graphElement) => {
1214
+ const graphWidth = $graphElement[0].clientWidth;
1215
+ const graphHeight = $graphElement[0].clientHeight;
1216
+ const originX = graphWidth / 2;
1217
+ const originY = graphHeight / 2;
1218
+ const xPixel = originX + x * (graphWidth / xRange);
1219
+ const yPixel = originY - y * (graphHeight / yRange);
1220
+ cy.get(`.MuiAccordion-region .ngie-jxgbox svg ellipse[display="inline"][cx="${xPixel}"][cy="${yPixel}"]`)
1221
+ .should('not.exist');
1222
+ });
1223
+ });
1224
+ },
1225
+
1226
+ /**
1227
+ * @description This function selects the control option from graph
1228
+ * @param {string} controlOption aria label of the control option to be selected
1229
+ */
1230
+ selectGraphControlOptionSpecifyCorrectAnswerSection: (controlOption) => {
1231
+ graphingPage.graphControlOptionSpecifyCorrectAnswer(controlOption)
1232
+ .click();
1233
+ },
1234
+
1235
+ verifyXAxisMinArrowNotExistGraphSpecifyCorrectAnswerSection: () => {
1236
+ graphingPage.xAxisGraphSpecifyCorrectAnswerSection()
1237
+ .should('not.have.attr', 'marker-start');
1238
+ },
1239
+
1240
+ verifyXAxisMinArrowExistGraphSpecifyCorrectAnswerSection: () => {
1241
+ graphingPage.xAxisGraphSpecifyCorrectAnswerSection()
1242
+ .should('have.attr', 'marker-start');
1243
+ },
1244
+
1245
+ verifyXAxisMaxArrowExistGraphSpecifyCorrectAnswerSection: () => {
1246
+ graphingPage.xAxisGraphSpecifyCorrectAnswerSection()
1247
+ .should('have.attr', 'marker-end');
1248
+ },
1249
+
1250
+ verifyXAxisMaxArrowNotExistGraphSpecifyCorrectAnswerSection: () => {
1251
+ graphingPage.xAxisGraphSpecifyCorrectAnswerSection()
1252
+ .should('not.have.attr', 'marker-end');
1253
+ },
1254
+
1255
+ verifyYAxisMinArrowNotExistGraphSpecifyCorrectAnswerSection: () => {
1256
+ graphingPage.yAxisGraphSpecifyCorrectAnswerSection()
1257
+ .should('not.have.attr', 'marker-start');
1258
+ },
1259
+
1260
+ verifyYAxisMinArrowExistGraphSpecifyCorrectAnswerSection: () => {
1261
+ graphingPage.yAxisGraphSpecifyCorrectAnswerSection()
1262
+ .should('have.attr', 'marker-start');
1263
+ },
1264
+
1265
+ verifyYAxisMaxArrowExistGraphSpecifyCorrectAnswerSection: () => {
1266
+ graphingPage.yAxisGraphSpecifyCorrectAnswerSection()
1267
+ .should('have.attr', 'marker-end');
1268
+ },
1269
+
1270
+ verifyYAxisMaxArrowNotExistGraphSpecifyCorrectAnswerSection: () => {
1271
+ graphingPage.yAxisGraphSpecifyCorrectAnswerSection()
1272
+ .should('not.have.attr', 'marker-end');
1273
+ },
1274
+
245
1275
  /**
246
1276
  * @description This function selects the tool option from graph
247
1277
  * @param {string} toolOption aria label of the tool option to be selected
@@ -251,6 +1281,101 @@ const steps = {
251
1281
  .click();
252
1282
  },
253
1283
 
1284
+ /**
1285
+ * @description This function verifies the tool option is in selected state
1286
+ * @param {string} toolOption aria label of the tool option to be verified selected
1287
+ */
1288
+ verifyToolOptionSelectedSpecifyCorrectAnswerSection: (toolOptionAriaLabel) => {
1289
+ graphingPage.graphToolOptionSpecifyCorrectAnswer(toolOptionAriaLabel)
1290
+ .should('have.class', 'single-select-toggle-button-selected');
1291
+ },
1292
+
1293
+ /**
1294
+ * @description This function verifies the tool option is not in selected state
1295
+ * @param {string} toolOption aria label of the tool option to be verified not selected
1296
+ */
1297
+ verifyToolOptionNotSelectedSpecifyCorrectAnswerSection: (toolOptionAriaLabelArray) => {
1298
+ toolOptionAriaLabelArray.forEach((toolOptionAriaLabel) => {
1299
+ graphingPage.graphToolOptionSpecifyCorrectAnswer(toolOptionAriaLabel)
1300
+ .should('not.have.class', 'single-select-toggle-button-selected');
1301
+ });
1302
+ },
1303
+
1304
+ /**
1305
+ * @param {string} fileFormat format of the uploaded file in the highlight region
1306
+ * @description this function verifies the attribute of the image has the expected file format
1307
+ */
1308
+ verifyUploadedImageInGraphSpecifyCorrectAnswerSection: (fileFormat) => {
1309
+ graphingPage.graphSpecifyCorrectAnswerSection()
1310
+ .find('image')
1311
+ .invoke('attr', 'xlink:href')
1312
+ .should('include', fileFormat);
1313
+ },
1314
+
1315
+ verifyImageFitsToGraphSpecifyCorrectAnswerSection: () => {
1316
+ graphingPage.graphSpecifyCorrectAnswerSection()
1317
+ .find('image')
1318
+ .invoke('attr', 'width')
1319
+ .then((imageValue) => {
1320
+ graphingPage.widthInputField()
1321
+ .invoke('attr', 'value')
1322
+ .then((widthInputFieldValue) => {
1323
+ expect(imageValue).to.eq(widthInputFieldValue);
1324
+ });
1325
+ });
1326
+ },
1327
+
1328
+ verifyImageDoesNotFitToGraphSpecifyCorrectAnswerSection: () => {
1329
+ graphingPage.graphSpecifyCorrectAnswerSection()
1330
+ .find('image')
1331
+ .invoke('attr', 'width')
1332
+ .then((imageValue) => {
1333
+ graphingPage.widthInputField()
1334
+ .invoke('attr', 'value')
1335
+ .then((widthInputFieldValue) => {
1336
+ expect(imageValue).to.not.eq(widthInputFieldValue);
1337
+ });
1338
+ });
1339
+ },
1340
+
1341
+ verifyImageTopLeftAlignedGraphSpecifyCorrectAnswerSection: () => {
1342
+ graphingPage.graphSpecifyCorrectAnswerSection()
1343
+ .find('image')
1344
+ .should('have.attr', 'x', '0')
1345
+ .and('have.attr', 'y', '0');
1346
+ },
1347
+
1348
+ verifyImageTopRightAlignedGraphSpecifyCorrectAnswerSection: () => {
1349
+ graphingPage.graphSpecifyCorrectAnswerSection()
1350
+ .find('image')
1351
+ .should('not.have.attr', 'x', '0')
1352
+ .and('have.attr', 'y', '0');
1353
+ },
1354
+
1355
+ verifyImageCenterAlignedGraphSpecifyCorrectAnswerSection: () => {
1356
+ graphingPage.graphSpecifyCorrectAnswerSection()
1357
+ .find('image')
1358
+ .should('not.have.attr', 'x', '0')
1359
+ .and('not.have.attr', 'y', '0');
1360
+ },
1361
+
1362
+ verifyImageOpacityGraphSpecifyCorrectAnswerSection: (opacity) => {
1363
+ const opacityValue = opacity / 100;
1364
+ graphingPage.graphSpecifyCorrectAnswerSection()
1365
+ .find('image')
1366
+ .should('have.attr', 'opacity', `${opacityValue}`);
1367
+ },
1368
+
1369
+ /**
1370
+ * This function verifies height and width of graph
1371
+ * @param {number} width width of graph
1372
+ * @param {number} height height of graph
1373
+ */
1374
+ verifyHeightWidthOfGraphSpecifyCorrectAnswerSection: (width, height) => {
1375
+ graphingPage.graphSpecifyCorrectAnswerSection()
1376
+ .should('have.attr', 'height', height)
1377
+ .and('have.attr', 'width', width)
1378
+ },
254
1379
 
255
1380
  //Preview tab
256
1381
  /**
@@ -301,6 +1426,30 @@ const steps = {
301
1426
  });
302
1427
  },
303
1428
 
1429
+ /**
1430
+ * This function verifies plotted points on the graph in preview tab
1431
+ * @param {Object[]} coordinates - An array containing x and x coordinates along with their range
1432
+ * @param {number} coordinates[].x - x coordinate to be plotted on the graph
1433
+ * @param {number} coordinates[].xRange - range of x coordinate
1434
+ * @param {number} coordinates[].y - y coordinate to be plotted on the graph
1435
+ * @param {number} coordinates[].yRange - range of y coordinate
1436
+ */
1437
+ verifyPointsPlottedNotExistOnPreviewTab: (coordinates) => {
1438
+ coordinates.forEach(({ x, xRange, y, yRange }) => {
1439
+ graphingPage.graphPreviewTab()
1440
+ .then(($graphElement) => {
1441
+ const graphWidth = $graphElement[0].clientWidth;
1442
+ const graphHeight = $graphElement[0].clientHeight;
1443
+ const originX = graphWidth / 2;
1444
+ const originY = graphHeight / 2;
1445
+ const xPixel = originX + x * (graphWidth / xRange);
1446
+ const yPixel = originY - y * (graphHeight / yRange);
1447
+ cy.get(`[class*="GraphingQuestion"] .ngie-jxgbox svg ellipse[display="inline"][cx="${xPixel}"][cy="${yPixel}"]`)
1448
+ .should('not.exist');
1449
+ });
1450
+ });
1451
+ },
1452
+
304
1453
  /**
305
1454
  * This function verifies the plotted points are incorrect
306
1455
  * @param {Object[]} coordinates - An array containing x and x coordinates along with their range
@@ -349,6 +1498,122 @@ const steps = {
349
1498
  });
350
1499
  },
351
1500
 
1501
+ verifyXAxisMinArrowNotExistGraphPreviewTab: () => {
1502
+ graphingPage.xAxisGraphPreviewTab()
1503
+ .should('not.have.attr', 'marker-start');
1504
+ },
1505
+
1506
+ verifyXAxisMinArrowExistGraphPreviewTab: () => {
1507
+ graphingPage.xAxisGraphPreviewTab()
1508
+ .should('have.attr', 'marker-start');
1509
+ },
1510
+
1511
+ verifyXAxisMaxArrowExistGraphPreviewTab: () => {
1512
+ graphingPage.xAxisGraphPreviewTab()
1513
+ .should('have.attr', 'marker-end');
1514
+ },
1515
+
1516
+ verifyXAxisMaxArrowNotExistGraphPreviewTab: () => {
1517
+ graphingPage.xAxisGraphPreviewTab()
1518
+ .should('not.have.attr', 'marker-end');
1519
+ },
1520
+
1521
+ verifyYAxisMinArrowNotExistGraphPreviewTab: () => {
1522
+ graphingPage.yAxisGraphPreviewTab()
1523
+ .should('not.have.attr', 'marker-start');
1524
+ },
1525
+
1526
+ verifyYAxisMinArrowExistGraphPreviewTab: () => {
1527
+ graphingPage.yAxisGraphPreviewTab()
1528
+ .should('have.attr', 'marker-start');
1529
+ },
1530
+
1531
+ verifyYAxisMaxArrowExistGraphPreviewTab: () => {
1532
+ graphingPage.yAxisGraphPreviewTab()
1533
+ .should('have.attr', 'marker-end');
1534
+ },
1535
+
1536
+ verifyYAxisMaxArrowNotExistGraphPreviewTab: () => {
1537
+ graphingPage.yAxisGraphPreviewTab()
1538
+ .should('not.have.attr', 'marker-end');
1539
+ },
1540
+
1541
+ /**
1542
+ * @param {string} fileFormat format of the uploaded file in the graph
1543
+ * @description this function verifies the attribute of the image has the expected file format
1544
+ */
1545
+ verifyUploadedImageInGraphPreviewTab: (fileFormat) => {
1546
+ graphingPage.graphPreviewTab()
1547
+ .find('image')
1548
+ .invoke('attr', 'xlink:href')
1549
+ .should('include', fileFormat);
1550
+ },
1551
+
1552
+ /**
1553
+ * This function verifies height and width of graph
1554
+ * @param {number} width width of graph
1555
+ * @param {number} height height of graph
1556
+ */
1557
+ verifyHeightWidthOfGraphPreviewTab: (width, height) => {
1558
+ graphingPage.graphPreviewTab()
1559
+ .should('have.attr', 'height', height)
1560
+ .and('have.attr', 'width', width)
1561
+ },
1562
+
1563
+ verifyImageFitsToGraphPreviewTab: () => {
1564
+ graphingPage.graphPreviewTab()
1565
+ .find('image')
1566
+ .invoke('attr', 'width')
1567
+ .then((imageValue) => {
1568
+ graphingPage.widthInputField()
1569
+ .invoke('attr', 'value')
1570
+ .then((widthInputFieldValue) => {
1571
+ expect(imageValue).to.eq(widthInputFieldValue);
1572
+ });
1573
+ });
1574
+ },
1575
+
1576
+ verifyImageDoesNotFitToGraphPreviewTab: () => {
1577
+ graphingPage.graphPreviewTab()
1578
+ .find('image')
1579
+ .invoke('attr', 'width')
1580
+ .then((imageValue) => {
1581
+ graphingPage.widthInputField()
1582
+ .invoke('attr', 'value')
1583
+ .then((widthInputFieldValue) => {
1584
+ expect(imageValue).to.not.eq(widthInputFieldValue);
1585
+ });
1586
+ });
1587
+ },
1588
+
1589
+ verifyImageTopLeftAlignedGraphPreviewTab: () => {
1590
+ graphingPage.graphPreviewTab()
1591
+ .find('image')
1592
+ .should('have.attr', 'x', '0')
1593
+ .and('have.attr', 'y', '0');
1594
+ },
1595
+
1596
+ verifyImageTopRightAlignedGraphPreviewTab: () => {
1597
+ graphingPage.graphPreviewTab()
1598
+ .find('image')
1599
+ .should('not.have.attr', 'x', '0')
1600
+ .and('have.attr', 'y', '0');
1601
+ },
1602
+
1603
+ verifyImageCenterAlignedGraphPreviewTab: () => {
1604
+ graphingPage.graphPreviewTab()
1605
+ .find('image')
1606
+ .should('not.have.attr', 'x', '0')
1607
+ .and('not.have.attr', 'y', '0');
1608
+ },
1609
+
1610
+ verifyImageOpacityGraphPreviewTab: (opacity) => {
1611
+ const opacityValue = opacity / 100;
1612
+ graphingPage.graphPreviewTab()
1613
+ .find('image')
1614
+ .should('have.attr', 'opacity', `${opacityValue}`);
1615
+ },
1616
+
352
1617
  /**
353
1618
  * @description This function selects the tool option from graph
354
1619
  * @param {string} toolOption aria label of the tool option to be selected
@@ -402,6 +1667,11 @@ const steps = {
402
1667
  .click();
403
1668
  },
404
1669
 
1670
+ cancelReset: () => {
1671
+ graphingPage.resetPopupCancelButton()
1672
+ .click();
1673
+ },
1674
+
405
1675
  /**
406
1676
  * This function plots points on the graph in correct answer section
407
1677
  * @param {Object[]} coordinates - An array containing x and x coordinates along with their range
@@ -475,6 +1745,117 @@ const steps = {
475
1745
 
476
1746
  const tests = {
477
1747
  ...autoScoredScoringPreviewTab.tests,
1748
+ ...backgroundImageUploadComponent.tests,
1749
+ ...opacityComponent.tests,
1750
+ ...scoringSectionBaseEditTab.tests,
1751
+ ...autoScoredScoringSectionMultiResponseType.tests,
1752
+ ...autoScoredStudentViewSettings.tests,
1753
+ ...createQuestionBasePage.tests,
1754
+ ...commonComponents.tests,
1755
+ ...additionalSettingsPanel.tests,
1756
+ ...autoScoredSpecifyCorrectAnswerSection.tests,
1757
+
1758
+ verifyContentsOfSpecifyCorrectAnswerSection: () => {
1759
+ it('When user selects a scoring type then in the \'Correct\' accordion, all the contents should be displayed', () => {
1760
+ utilities.verifyElementVisibilityState(graphingPage.graphSpecifyCorrectAnswerSection(), 'visible');
1761
+ utilities.verifyElementVisibilityState(graphingPage.graphToolOptionSpecifyCorrectAnswer(), 'visible');
1762
+ utilities.verifyElementVisibilityState(graphingPage.graphControlOptionSpecifyCorrectAnswer(), 'visible');
1763
+ utilities.verifyElementVisibilityState(graphingPage.repeatedPointsSwitch(), 'exist');
1764
+ });
1765
+ },
1766
+
1767
+ /**
1768
+ * Verifies the contents and functionality of the 'Specify correct answer' accordion for multiple selection questions.
1769
+ * @param {{'Correct' | 'Alternative'}} accordionName - The name of the accordion to be used in the validation.
1770
+ * @example - verifySpecifyCorrectAnswerAccordionContentsAndFunctionality('Correct');
1771
+ */
1772
+ verifySpecifyCorrectAnswerAccordionContentsAndFunctionality: (accordionName) => {
1773
+ it(`The user should be able to plot the graph in the specify correct answer section ${accordionName} accordion`, () => {
1774
+ graphingPage.steps.selectGraphToolOptionSpecifyCorrectAnswer('Circle');
1775
+ graphingPage.steps.plotPointsOnGraphSpecifyCorrectAnswerSection([{ x: 0, xRange: 20, y: 1, yRange: 20 }, { x: 0, xRange: 20, y: 2, yRange: 20 }]);
1776
+ graphingPage.steps.verifyPointsPlottedOnSpecifyCorrectAnswerSection([{ x: 0, xRange: 20, y: 1, yRange: 20 }, { x: 0, xRange: 20, y: 2, yRange: 20 }]);
1777
+ });
1778
+
1779
+ it(`When the user resets the graph in the ${accordionName} accordion, \'Error: Please set a correct answer.\' error message should be thrown along with an error icon on the \'${accordionName}\' accordion`, () => {
1780
+ graphingPage.graphControlOptionSpecifyCorrectAnswer('Reset')
1781
+ .click();
1782
+ graphingPage.resetPopupConfirmResetButton()
1783
+ .click();
1784
+ utilities.verifyElementVisibilityState(commonComponents.errorMessage(), 'visible')
1785
+ utilities.verifyInnerText(commonComponents.errorMessage(), 'Error: Please set a correct answer.');
1786
+ if (accordionName == 'Correct') {
1787
+ autoScoredSpecifyCorrectAnswerSection.correctAnswerAccordion()
1788
+ .within(() => {
1789
+ utilities.verifyElementVisibilityState(autoScoredSpecifyCorrectAnswerSection.specifyCorrectAnswerErrorIcon(), 'visible');
1790
+ });
1791
+ } else {
1792
+ autoScoredSpecifyCorrectAnswerSection.alternativeAnswerAccordion()
1793
+ .within(() => {
1794
+ utilities.verifyElementVisibilityState(autoScoredSpecifyCorrectAnswerSection.specifyCorrectAnswerErrorIcon(), 'visible');
1795
+ });
1796
+ };
1797
+ });
1798
+
1799
+ autoScoredSpecifyCorrectAnswerSection.tests.verifyAutoScoredCorrectAnswerErrorMessageCSSAndA11y();
1800
+
1801
+ it('When the user plots on the graph then the error message should disappear', () => {
1802
+ graphingPage.steps.selectGraphToolOptionSpecifyCorrectAnswer('Circle');
1803
+ graphingPage.steps.plotPointsOnGraphSpecifyCorrectAnswerSection([{ x: 0, xRange: 20, y: 1, yRange: 20 }, { x: 0, xRange: 20, y: 2, yRange: 20 }]);
1804
+ graphingPage.steps.verifyPointsPlottedOnSpecifyCorrectAnswerSection([{ x: 0, xRange: 20, y: 1, yRange: 20 }, { x: 0, xRange: 20, y: 2, yRange: 20 }]);
1805
+ });
1806
+
1807
+ autoScoredSpecifyCorrectAnswerSection.tests.verifyAutoScoredPointsErrorMessageWhenPointsFieldIsEmpty(accordionName);
1808
+
1809
+ it('Accessibility of \'Correct\' accordion contents', { tags: 'a11y' }, () => {
1810
+ cy.checkAccessibility(graphingPage.graphSpecifyCorrectAnswerSection());
1811
+ });
1812
+ },
1813
+
1814
+ verifyResetPopupContentWithCSSAndA11y: () => {
1815
+ it('When the user clicks on the \'Reset\' button then a dialog box should appear with title \'Reset\'', () => {
1816
+ utilities.verifyElementVisibilityState(dialogBoxBase.dialogBox(), 'exist');
1817
+ utilities.verifyInnerText(dialogBoxBase.dialogBoxTitle(), 'Reset');
1818
+ });
1819
+
1820
+ it('The dialog box should have content \'Are you sure you want to reset the graph? This will clear all objects and revert all settings to their default values.\' with \'Cancel\' and \'Confirm reset\' buttons should be displayed', () => {
1821
+ utilities.verifyInnerText(dialogBoxBase.dialogBoxContent(), 'Are you sure you want to reset the graph? This will clear all objects and revert all settings to their default values.');
1822
+ utilities.verifyInnerText(graphingPage.resetPopupConfirmResetButton(), 'Confirm reset');
1823
+ utilities.verifyInnerText(graphingPage.resetPopupCancelButton(), 'Cancel');
1824
+ });
1825
+
1826
+ it('CSS of Reset dialog box', { tags: 'css' }, () => {
1827
+ utilities.verifyCSS(dialogBoxBase.dialogBoxTitle(), {
1828
+ 'color': css.color.flyoutTitle,
1829
+ 'font-size': css.fontSize.default,
1830
+ 'font-weight': css.fontWeight.regular
1831
+ });
1832
+ utilities.verifyCSS(dialogBoxBase.dialogBoxContent(), {
1833
+ 'color': css.color.labels,
1834
+ 'font-size': css.fontSize.default,
1835
+ 'font-weight': css.fontWeight.regular
1836
+ });
1837
+ utilities.verifyCSS(graphingPage.resetPopupCancelButton().find('p'), {
1838
+ 'color': css.color.secondaryBtn,
1839
+ 'font-size': css.fontSize.default,
1840
+ 'font-weight': css.fontWeight.semibold
1841
+ });
1842
+ utilities.verifyCSS(graphingPage.resetPopupCancelButton(), {
1843
+ 'background-color': css.color.transparent
1844
+ });
1845
+ utilities.verifyCSS(graphingPage.resetPopupConfirmResetButton().find('p'), {
1846
+ 'color': css.color.whiteText,
1847
+ 'font-size': css.fontSize.default,
1848
+ 'font-weight': css.fontWeight.semibold
1849
+ });
1850
+ utilities.verifyCSS(graphingPage.resetPopupConfirmResetButton(), {
1851
+ 'background-color': css.color.editTableDeleteButton
1852
+ });
1853
+ });
1854
+
1855
+ it('Accessibility of Reset dialog box', { tags: 'a11y' }, () => {
1856
+ cy.checkAccessibility(dialogBoxBase.dialogBox());
1857
+ });
1858
+ }
478
1859
  }
479
1860
 
480
1861
  export const graphingPage = {