itemengine-cypress-automation 1.0.121 → 1.0.122

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,160 @@
1
+ import { autoScoredScoringPreviewTab } from "../../pages/components";
2
+ import utilities from "../../support/helpers/utilities";
3
+ import { extractLrnQuestionData, lrnPage } from "../../support/migrationHelpers/extractLrnQuestionData";
4
+ import lrnQuestionTypesENUM from "../../support/migrationHelpers/lrnQestionTypesENUM";
5
+ import { iePage, verifyIeQuestionData } from "../../support/migrationHelpers/verifyIeQuestionData";
6
+
7
+ Cypress.Commands.add('learnosityLoaderWait', () => {
8
+ // cy.get('.lrn-spinner')
9
+ // .should('be.visible');
10
+ lrnPage.questionsLoader()
11
+ .should('not.be.visible');
12
+ lrnPage.questionWrapper()
13
+ .eq(0)
14
+ .should('be.visible');
15
+ });
16
+
17
+ Cypress.Commands.add('lazyLoadPreviewQuestions', (count, retries = 5) => {
18
+ iePage.questionWrapper()
19
+ .then((elements) => {
20
+ if (retries <= 0) {
21
+ throw new Error('Itemengine questions did not lazy load in time');
22
+ };
23
+ if (elements.length < count) {
24
+ iePage.questionWrapper()
25
+ .last()
26
+ .scrollIntoView()
27
+ .wait(1000);
28
+ cy.lazyLoadPreviewQuestions(count, retries - 1)
29
+ };
30
+ cy.log('All question parts loaded');
31
+ });
32
+ iePage.barsPreloader()
33
+ .should('not.exist');
34
+ cy.learnosityLoaderWait();
35
+ })
36
+
37
+ const migrationQuestionTypes = Cypress.env('migrationQuestionTypes');//["essayResponse"]
38
+ const migrationQuestionTypesLrn = migrationQuestionTypes.map((questionType) => lrnQuestionTypesENUM[questionType]);
39
+ let lrnMcqTypesRegex = /Multiple choice – standard|Multiple choice – multiple response|True or false|Multiple choice – block layout/;
40
+ let lrnEssayResponseRegex = /Math essay with rich text|Essay with rich text/
41
+
42
+
43
+ let lrnQuestionDataArr = [];
44
+ let lrnGradingDataArr = [];
45
+
46
+ let referenceIds = JSON.parse(Cypress.env('referenceIds')).slice(800, 900);//["0715a48c-4c1f-4eed-8058-793ad9402f89", "c476e9ca-2ac6-4ebc-b548-241ef3cd13bb"]
47
+
48
+ if (referenceIds.length > 0) {
49
+ describe('Migration item check for MCQ questions', () => {
50
+ before(() => {
51
+ cy.loginAs('technicalTester');
52
+ });
53
+
54
+ referenceIds.forEach((referenceId) => {
55
+ describe(`Migration item check for item "${referenceId}"`, () => {
56
+ before(() => {
57
+ cy.interceptGraphql('getItemPreview');
58
+ cy.setGraphqlWait();
59
+ cy.visit(`/items-list/item/${utilities.base64Encoding(referenceId)}`);
60
+ cy.pageLoadWait('getItemPreview');
61
+ cy.get('@getItemPreview').then((req) => {
62
+ let questionCount = req.response.body.data.getItemPreview.item.questionParts.length;
63
+ cy.lazyLoadPreviewQuestions(questionCount);
64
+ });
65
+ });
66
+
67
+ after(() => {
68
+ console.log(lrnQuestionDataArr)
69
+ console.log(lrnGradingDataArr)
70
+ lrnQuestionDataArr = [];
71
+ lrnGradingDataArr = [];
72
+ });
73
+
74
+ it(`Extracting learnosity preview data for item "${referenceId}"`, () => {
75
+ lrnPage.questionTypeDiv()
76
+ .each(($el, index) => {
77
+ let currQuestionType = $el[0].innerText
78
+ if (lrnMcqTypesRegex.test(currQuestionType)) {
79
+ currQuestionType = lrnQuestionTypesENUM.mcq;
80
+ }
81
+ if (lrnEssayResponseRegex.test(currQuestionType)) {
82
+ ;
83
+ currQuestionType = lrnQuestionTypesENUM.essayResponse;
84
+ }
85
+ if (migrationQuestionTypesLrn.includes(currQuestionType)) {
86
+ switch (currQuestionType) {
87
+ case lrnQuestionTypesENUM.mcq: return extractLrnQuestionData.mcq(lrnQuestionDataArr, index);
88
+ case lrnQuestionTypesENUM.textEntryMath: return extractLrnQuestionData.textEntryMath(lrnQuestionDataArr, index);
89
+ case lrnQuestionTypesENUM.textEntryMathImage: return extractLrnQuestionData.textEntryMathImage(lrnQuestionDataArr, index);
90
+ case lrnQuestionTypesENUM.essayResponse: return extractLrnQuestionData.essayResponse(lrnQuestionDataArr, index);
91
+ default: throw new Error('Invalid lrn question type');
92
+ }
93
+ }
94
+ });
95
+ });
96
+
97
+ it(`Verifying itemengine preview data for item "${referenceId}"`, () => {
98
+ migrationQuestionTypes.forEach((questionType) => {
99
+ cy.log(`Verifying data for all ${questionType} question type`);
100
+ let currQuestionTypeArr = lrnQuestionDataArr.filter((question) => question.questionType === questionType);
101
+ currQuestionTypeArr.forEach((questionData, index) => {
102
+ cy.log(`Verifying data for ${questionType} ${index}`);
103
+ switch (questionType) {
104
+ case 'mcq': return verifyIeQuestionData.mcq(questionData, index);
105
+ case 'textEntryMath': return verifyIeQuestionData.textEntryMath(questionData, index);
106
+ case 'textEntryMathImage': return verifyIeQuestionData.textEntryMathImage(questionData, index);
107
+ case 'essayResponse': return verifyIeQuestionData.essayResponse(questionData, index);
108
+ default: throw new Error('Invalid ngie question type');
109
+ }
110
+ });
111
+ });
112
+ });
113
+
114
+ it(`Extracting learnosity grading data for item "${referenceId}"`, () => {
115
+ lrnPage.authorItemToolbarControlsWrapper()
116
+ .then(($element) => {
117
+ if ($element[0].innerHTML.includes('lrn-author-validate-questions-toggle')) {
118
+ lrnPage.steps.checkShowAnswersToggle();
119
+ lrnPage.questionTypeDiv()
120
+ .each(($el, index) => {
121
+ let currQuestionType = $el[0].innerText
122
+ if (lrnMcqTypesRegex.test(currQuestionType)) {
123
+ currQuestionType = lrnQuestionTypesENUM.mcq
124
+ }
125
+ if (migrationQuestionTypesLrn.includes(currQuestionType)) {
126
+ switch (currQuestionType) {
127
+ case lrnQuestionTypesENUM.mcq: return extractLrnQuestionData.mcqGrading(lrnGradingDataArr, index);
128
+ case lrnQuestionTypesENUM.textEntryMath: return extractLrnQuestionData.textEntryMathGrading(lrnGradingDataArr, index);
129
+ case lrnQuestionTypesENUM.textEntryMathImage: return extractLrnQuestionData.textEntryMathImageGrading(lrnGradingDataArr, index);
130
+ default: throw new Error('Invalid lrn question type');
131
+ }
132
+ }
133
+ });
134
+ }
135
+ });
136
+ });
137
+
138
+ it(`Verifying itemengine grading data for item "${referenceId}"`, () => {
139
+ autoScoredScoringPreviewTab.steps.switchToGradingView();
140
+ cy.wait(500);
141
+ migrationQuestionTypes.forEach((questionType) => {
142
+ cy.log(`Verifying grading data for all ${questionType} question type`);
143
+ let currQuestionTypeArr = lrnGradingDataArr.filter((question) => question.questionType === questionType);
144
+ currQuestionTypeArr.forEach((questionData, index) => {
145
+ cy.log(`Verifying grading data for ${questionType} ${index}`);
146
+ switch (questionType) {
147
+ case 'mcq': return verifyIeQuestionData.mcqGrading(questionData, index);
148
+ case 'textEntryMath': return verifyIeQuestionData.textEntryMathGrading(questionData, index);
149
+ case 'textEntryMathImage': return verifyIeQuestionData.textEntryMathImageGrading(questionData, index);
150
+ default: throw new Error('Invalid ngie question type');
151
+ }
152
+ });
153
+ });
154
+ });
155
+ });
156
+ });
157
+ });
158
+ }
159
+
160
+ //https://s3.console.aws.amazon.com/s3/object/itemengine-qa-bucket?region=us-west-2&bucketType=general&prefix=cypressAutomation/migrationFixtures.json
@@ -0,0 +1,30 @@
1
+ const essayResponseToolbarOptionsENUM = {
2
+ "Bold": "Bold (Ctrl+B)",
3
+ "Italic": "Italic (Ctrl+I)",
4
+ "Underline": "Underline (Ctrl+U)",
5
+ "Increase indent": "Increase Indent",
6
+ "Decrease indent": "Decrease Indent",
7
+ "Formula keypad": "Equation Editor",
8
+ "Undo": "Undo (Ctrl+Z)",
9
+ "Redo": "Redo (Ctrl+Y)",
10
+ "Clear formatting": "Remove Format",
11
+ "Code Inline": "Code Inline",
12
+ "Code Editor": "Code Editor",
13
+ "Align left": "Align Left",
14
+ "Align center": "Align Center",
15
+ "Align right": "Align Right",
16
+ "Align justify": "Align Justify",
17
+ "Bullet list": "Insert/Remove Bulleted List",
18
+ "Numbered list": "Insert/Remove Numbered List",
19
+ "Block quote": "Block Quote",
20
+ "Superscript": "Superscript",
21
+ "Subscript": "Subscript",
22
+ "Text direction left to right": "Text direction left to right",
23
+ "Text direction right to left": "Text direction right to left",
24
+ "Insert horizontal rule": "Insert Horizontal Line",
25
+ "Table": "Insert Table",
26
+ "Special Characters": "Special characters",
27
+ "Image (12 image limit)": "Insert Image"
28
+ }
29
+
30
+ export default essayResponseToolbarOptionsENUM;
@@ -1,4 +1,5 @@
1
1
  export const lrnPage = {
2
+ authorItemToolbarControlsWrapper: () => cy.get('.lrn-author-item-toolbar-controls-alt'),
2
3
  questionTypeDiv: () => cy.get('.lrn-widget-drag-name'),
3
4
  questionInstructions: () => cy.get('.lrn_question'),
4
5
  questionWrapper: () => cy.get('.lrn-widget-drag-wrapper'),
@@ -11,6 +12,8 @@ export const lrnPage = {
11
12
  clozeMathCorrectAnswerMathMl: () => cy.get('.lrn_correctAnswerList math'),
12
13
  correctAnswersResponseText: () => cy.get('.lrn_responseText'),
13
14
  backgroundCanvasImage: () => cy.get('.lrn_imagecloze_image'),
15
+ essayResponseTextArea: () => cy.get('.lrn_texteditor_editable'),
16
+ essayResponseToolbarButton: () => cy.get('[aria-label="Text controls"] button.lrn_btn'),
14
17
  steps: {
15
18
  checkShowAnswersToggle: () => {
16
19
  lrnPage.showAnswersToggle()
@@ -260,11 +263,17 @@ export const extractLrnQuestionData = {
260
263
  lrnGradingDataArr.push(obj);
261
264
  },
262
265
 
263
- essayResponseMath: (lrnQuestionDataArr, index) => {
266
+ essayResponse: (lrnQuestionDataArr, index) => {
267
+ //instructions
268
+ //text in the input field
269
+ //placeholder
270
+ //wordlimit and stuff
271
+ //toolbar icons
272
+ //check with abhishek if we need to cover the grading view/else we can just check if the questino is not giving any error in grading view, i.e it is visible
264
273
  let obj = {};
265
274
  cy.log(`Extracting the question instructions and options from question ${index}`);
266
275
  obj.questionIndex = index;
267
- obj.questionType = 'essayResponseMath'
276
+ obj.questionType = 'essayResponse'
268
277
  lrnPage.questionWrapper()
269
278
  .eq(index)
270
279
  .within(() => {
@@ -273,6 +282,19 @@ export const extractLrnQuestionData = {
273
282
  let text = $ins[0].innerText;
274
283
  obj.previewQuestionInstructions = text;
275
284
  });
285
+ lrnPage.essayResponseTextArea()
286
+ .then(($element) => {
287
+ let textAreaPlaceholder = $element[0].attributes["data-placeholder"]?.nodeValue;
288
+ obj.textAreaPlaceholder = textAreaPlaceholder;
289
+ });
290
+ let toolbarButtons = [];
291
+ lrnPage.essayResponseToolbarButton()
292
+ .each(($button) => {
293
+ let ariaLabel = $button[0].attributes["aria-label"].nodeValue;
294
+ if (!ariaLabel) ariaLabel = $button[0].attributes["title"].nodeValue;
295
+ if (ariaLabel != 'Edit table') toolbarButtons.push(ariaLabel);
296
+ })
297
+ obj.toolbarButtons = toolbarButtons;
276
298
  });
277
299
  lrnQuestionDataArr.push(obj);
278
300
  },
@@ -2,7 +2,7 @@ const lrnQuestionTypesENUM = {
2
2
  mcq: 'mcq',
3
3
  textEntryMath: 'Cloze math',
4
4
  textEntryMathImage: 'Cloze math with image',
5
- essayResponseMath: 'Math essay with rich text',
5
+ essayResponse: 'essayResponse',
6
6
  singleSelection: 'Multiple choice – standard',
7
7
  multipleSelection: 'Multiple choice – multiple response',
8
8
  trueOrFalse: 'True or false',
@@ -1,6 +1,7 @@
1
- import { multipleSelectionPage } from "../../pages";
1
+ import { essayResponsePage, multipleSelectionPage } from "../../pages";
2
2
  import { singleSelectionPage } from "../../pages/singleSelectionPage"
3
3
  import utilities from "../helpers/utilities";
4
+ import essayResponseToolbarOptionsENUM from "./essayResponseToolbarOptionsENUM";
4
5
 
5
6
  export const iePage = {
6
7
  mcqOption: () => cy.get('.mcq_Label'),
@@ -155,12 +156,27 @@ export const verifyIeQuestionData = {
155
156
  });
156
157
  },
157
158
 
158
- essayResponseMath: (expectedQuestionData, index) => {
159
- cy.get('.ngie-essay-response-math')
159
+ essayResponse: (expectedQuestionData, index) => {
160
+ cy.get('[class*="ngie-essay-response"]')
160
161
  .eq(index)
161
162
  .within(() => {
162
- singleSelectionPage.questionInstructionsText()
163
- .verifyInnerText(expectedQuestionData.previewQuestionInstructions);
163
+ utilities.verifyInnerText(singleSelectionPage.questionInstructionsText(), expectedQuestionData.previewQuestionInstructions);
164
+ essayResponsePage.responseField()
165
+ .then(($element) => {
166
+ let textAreaPlaceholder = $element[0].attributes["data-cke-editorplaceholder"]?.nodeValue;
167
+ expect(textAreaPlaceholder).to.be.eq(expectedQuestionData.textAreaPlaceholder);
168
+ });
169
+ let ieButtonsTitle = [];
170
+ let ieButtonsExpected = expectedQuestionData.toolbarButtons.map((button) => {
171
+ return essayResponseToolbarOptionsENUM[button];
172
+ });
173
+ essayResponsePage.previewTabToolbarOption()
174
+ .each(($button) => {
175
+ let title = $button[0].attributes["title"].nodeValue;
176
+ ieButtonsTitle.push(title);
177
+ }).then(() => {
178
+ expect(ieButtonsTitle).to.have.deep.members(ieButtonsExpected);
179
+ });
164
180
  });
165
181
  },
166
182
 
@@ -9,8 +9,8 @@ variables:
9
9
  deployment:
10
10
  job:
11
11
  activeDeadlineSeconds: 7200
12
- parallelism: 5
13
- completions: 5
12
+ parallelism: 10
13
+ completions: 10
14
14
 
15
15
  image:
16
16
  cmd: /ie-e2e/deploy/migration/run.sh
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "itemengine-cypress-automation",
3
- "version": "1.0.121",
3
+ "version": "1.0.122",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {